001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.portal.kernel.language.LanguageUtil;
018 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
019 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
020 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
021 import com.liferay.portal.kernel.lar.PortletDataContext;
022 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
023 import com.liferay.portal.kernel.lar.PortletDataHandler;
024 import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
025 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
026 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
027 import com.liferay.portal.kernel.lar.StagedModelType;
028 import com.liferay.portal.kernel.log.Log;
029 import com.liferay.portal.kernel.log.LogFactoryUtil;
030 import com.liferay.portal.kernel.servlet.ServletContextPool;
031 import com.liferay.portal.kernel.util.ArrayUtil;
032 import com.liferay.portal.kernel.util.Constants;
033 import com.liferay.portal.kernel.util.FileUtil;
034 import com.liferay.portal.kernel.util.GetterUtil;
035 import com.liferay.portal.kernel.util.LocaleUtil;
036 import com.liferay.portal.kernel.util.MapUtil;
037 import com.liferay.portal.kernel.util.ReleaseInfo;
038 import com.liferay.portal.kernel.util.StringBundler;
039 import com.liferay.portal.kernel.util.StringPool;
040 import com.liferay.portal.kernel.util.StringUtil;
041 import com.liferay.portal.kernel.util.Time;
042 import com.liferay.portal.kernel.util.UnicodeProperties;
043 import com.liferay.portal.kernel.util.Validator;
044 import com.liferay.portal.kernel.xml.Document;
045 import com.liferay.portal.kernel.xml.Element;
046 import com.liferay.portal.kernel.xml.SAXReaderUtil;
047 import com.liferay.portal.kernel.zip.ZipWriter;
048 import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
049 import com.liferay.portal.model.Group;
050 import com.liferay.portal.model.Image;
051 import com.liferay.portal.model.Layout;
052 import com.liferay.portal.model.LayoutConstants;
053 import com.liferay.portal.model.LayoutPrototype;
054 import com.liferay.portal.model.LayoutSet;
055 import com.liferay.portal.model.LayoutSetPrototype;
056 import com.liferay.portal.model.LayoutTypePortlet;
057 import com.liferay.portal.model.Portlet;
058 import com.liferay.portal.model.Theme;
059 import com.liferay.portal.model.impl.LayoutImpl;
060 import com.liferay.portal.service.GroupLocalServiceUtil;
061 import com.liferay.portal.service.ImageLocalServiceUtil;
062 import com.liferay.portal.service.LayoutLocalServiceUtil;
063 import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
064 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
065 import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
066 import com.liferay.portal.service.PortletLocalServiceUtil;
067 import com.liferay.portal.service.ServiceContext;
068 import com.liferay.portal.service.ServiceContextThreadLocal;
069 import com.liferay.portal.service.UserLocalServiceUtil;
070 import com.liferay.portal.service.permission.PortletPermissionUtil;
071 import com.liferay.portal.theme.ThemeLoader;
072 import com.liferay.portal.theme.ThemeLoaderFactory;
073 import com.liferay.portlet.PortletPreferencesFactoryUtil;
074 import com.liferay.portlet.asset.model.AssetCategory;
075 import com.liferay.portlet.asset.model.AssetVocabulary;
076 import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
077 import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
078 import com.liferay.util.ContentUtil;
079
080 import java.io.File;
081
082 import java.util.ArrayList;
083 import java.util.Date;
084 import java.util.HashSet;
085 import java.util.Iterator;
086 import java.util.LinkedHashMap;
087 import java.util.List;
088 import java.util.Map;
089 import java.util.Set;
090
091 import javax.servlet.ServletContext;
092
093 import org.apache.commons.lang.time.StopWatch;
094
095
107 public class LayoutExporter {
108
109 public static final String SAME_GROUP_FRIENDLY_URL =
110 "/[$SAME_GROUP_FRIENDLY_URL$]";
111
112 public static List<Portlet> getDataSiteLevelPortlets(long companyId)
113 throws Exception {
114
115 List<Portlet> portlets = PortletLocalServiceUtil.getPortlets(companyId);
116
117 Iterator<Portlet> itr = portlets.iterator();
118
119 while (itr.hasNext()) {
120 Portlet portlet = itr.next();
121
122 if (!portlet.isActive()) {
123 itr.remove();
124
125 continue;
126 }
127
128 PortletDataHandler portletDataHandler =
129 portlet.getPortletDataHandlerInstance();
130
131 if ((portletDataHandler == null) ||
132 !portletDataHandler.isDataSiteLevel()) {
133
134 itr.remove();
135 }
136 }
137
138 return portlets;
139 }
140
141 public static List<Portlet> getPortletDataHandlerPortlets(
142 List<Layout> layouts)
143 throws Exception {
144
145 List<Portlet> portlets = new ArrayList<Portlet>();
146 Set<String> rootPortletIds = new HashSet<String>();
147
148 for (Layout layout : layouts) {
149 if (!layout.isTypePortlet()) {
150 continue;
151 }
152
153 LayoutTypePortlet layoutTypePortlet =
154 (LayoutTypePortlet)layout.getLayoutType();
155
156 for (String portletId : layoutTypePortlet.getPortletIds()) {
157 Portlet portlet = PortletLocalServiceUtil.getPortletById(
158 layout.getCompanyId(), portletId);
159
160 if ((portlet == null) ||
161 rootPortletIds.contains(portlet.getRootPortletId())) {
162
163 continue;
164 }
165
166 PortletDataHandler portletDataHandler =
167 portlet.getPortletDataHandlerInstance();
168
169 PortletDataHandlerControl[] portletDataHandlerControls =
170 portletDataHandler.getExportConfigurationControls(
171 layout.getCompanyId(), layout.getGroupId(), portlet,
172 layout.getPrivateLayout());
173
174 if ((portletDataHandlerControls != null) &&
175 (portletDataHandlerControls.length > 0)) {
176
177 rootPortletIds.add(portlet.getRootPortletId());
178
179 portlets.add(portlet);
180 }
181 }
182 }
183
184 return portlets;
185 }
186
187 public static List<Portlet> getPortletDataHandlerPortlets(
188 long groupId, boolean privateLayout)
189 throws Exception {
190
191 return getPortletDataHandlerPortlets(
192 LayoutLocalServiceUtil.getLayouts(groupId, privateLayout));
193 }
194
195 public static void updateLastPublishDate(
196 LayoutSet layoutSet, long lastPublishDate)
197 throws Exception {
198
199 UnicodeProperties settingsProperties =
200 layoutSet.getSettingsProperties();
201
202 if (lastPublishDate <= 0) {
203 settingsProperties.remove("last-publish-date");
204 }
205 else {
206 settingsProperties.setProperty(
207 "last-publish-date", String.valueOf(lastPublishDate));
208 }
209
210 LayoutSetLocalServiceUtil.updateSettings(
211 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
212 settingsProperties.toString());
213 }
214
215 public byte[] exportLayouts(
216 long groupId, boolean privateLayout, long[] layoutIds,
217 Map<String, String[]> parameterMap, Date startDate, Date endDate)
218 throws Exception {
219
220 File file = exportLayoutsAsFile(
221 groupId, privateLayout, layoutIds, parameterMap, startDate,
222 endDate);
223
224 try {
225 return FileUtil.getBytes(file);
226 }
227 finally {
228 file.delete();
229 }
230 }
231
232 public File exportLayoutsAsFile(
233 long groupId, boolean privateLayout, long[] layoutIds,
234 Map<String, String[]> parameterMap, Date startDate, Date endDate)
235 throws Exception {
236
237 try {
238 ExportImportThreadLocal.setLayoutExportInProcess(true);
239
240 return doExportLayoutsAsFile(
241 groupId, privateLayout, layoutIds, parameterMap, startDate,
242 endDate);
243 }
244 finally {
245 ExportImportThreadLocal.setLayoutExportInProcess(false);
246 }
247 }
248
249 protected File doExportLayoutsAsFile(
250 long groupId, boolean privateLayout, long[] layoutIds,
251 Map<String, String[]> parameterMap, Date startDate, Date endDate)
252 throws Exception {
253
254 boolean exportCategories = MapUtil.getBoolean(
255 parameterMap, PortletDataHandlerKeys.CATEGORIES);
256 boolean exportIgnoreLastPublishDate = MapUtil.getBoolean(
257 parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE);
258 boolean exportPermissions = MapUtil.getBoolean(
259 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
260 boolean exportPortletDataAll = MapUtil.getBoolean(
261 parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
262 boolean exportTheme = MapUtil.getBoolean(
263 parameterMap, PortletDataHandlerKeys.THEME);
264 boolean exportThemeSettings = MapUtil.getBoolean(
265 parameterMap, PortletDataHandlerKeys.THEME_REFERENCE);
266 boolean exportLogo = MapUtil.getBoolean(
267 parameterMap, PortletDataHandlerKeys.LOGO);
268 boolean exportLayoutSetSettings = MapUtil.getBoolean(
269 parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
270 boolean updateLastPublishDate = MapUtil.getBoolean(
271 parameterMap, PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
272
273 if (_log.isDebugEnabled()) {
274 _log.debug("Export permissions " + exportPermissions);
275 _log.debug("Export theme " + exportTheme);
276 }
277
278 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
279 groupId, privateLayout);
280
281 long companyId = layoutSet.getCompanyId();
282 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
283
284 ServiceContext serviceContext =
285 ServiceContextThreadLocal.getServiceContext();
286
287 if (serviceContext == null) {
288 serviceContext = new ServiceContext();
289
290 serviceContext.setCompanyId(companyId);
291 serviceContext.setSignedIn(false);
292 serviceContext.setUserId(defaultUserId);
293
294 ServiceContextThreadLocal.pushServiceContext(serviceContext);
295 }
296
297 serviceContext.setAttribute("exporting", Boolean.TRUE);
298
299 long layoutSetBranchId = MapUtil.getLong(
300 parameterMap, "layoutSetBranchId");
301
302 serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);
303
304 long lastPublishDate = System.currentTimeMillis();
305
306 if (endDate != null) {
307 lastPublishDate = endDate.getTime();
308 }
309
310 if (exportIgnoreLastPublishDate) {
311 endDate = null;
312 startDate = null;
313 }
314
315 StopWatch stopWatch = null;
316
317 if (_log.isInfoEnabled()) {
318 stopWatch = new StopWatch();
319
320 stopWatch.start();
321 }
322
323 LayoutCache layoutCache = new LayoutCache();
324
325 ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
326
327 PortletDataContext portletDataContext =
328 PortletDataContextFactoryUtil.createExportPortletDataContext(
329 companyId, groupId, parameterMap, startDate, endDate,
330 zipWriter);
331
332 portletDataContext.setPortetDataContextListener(
333 new PortletDataContextListenerImpl(portletDataContext));
334
335 Document document = SAXReaderUtil.createDocument();
336
337 Element rootElement = document.addElement("root");
338
339 portletDataContext.setExportDataRootElement(rootElement);
340
341 Element headerElement = rootElement.addElement("header");
342
343 headerElement.addAttribute(
344 "available-locales",
345 StringUtil.merge(
346 LanguageUtil.getAvailableLocales(
347 portletDataContext.getScopeGroupId())));
348 headerElement.addAttribute(
349 "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
350 headerElement.addAttribute("export-date", Time.getRFC822());
351
352 if (portletDataContext.hasDateRange()) {
353 headerElement.addAttribute(
354 "start-date",
355 String.valueOf(portletDataContext.getStartDate()));
356 headerElement.addAttribute(
357 "end-date", String.valueOf(portletDataContext.getEndDate()));
358 }
359
360 headerElement.addAttribute(
361 "company-id", String.valueOf(portletDataContext.getCompanyId()));
362 headerElement.addAttribute(
363 "company-group-id",
364 String.valueOf(portletDataContext.getCompanyGroupId()));
365 headerElement.addAttribute("group-id", String.valueOf(groupId));
366 headerElement.addAttribute(
367 "user-personal-site-group-id",
368 String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
369 headerElement.addAttribute(
370 "private-layout", String.valueOf(privateLayout));
371
372 Group group = layoutSet.getGroup();
373
374 String type = "layout-set";
375
376 if (group.isLayoutPrototype()) {
377 type = "layout-prototype";
378
379 LayoutPrototype layoutPrototype =
380 LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
381 group.getClassPK());
382
383 headerElement.addAttribute("type-uuid", layoutPrototype.getUuid());
384 }
385 else if (group.isLayoutSetPrototype()) {
386 type ="layout-set-prototype";
387
388 LayoutSetPrototype layoutSetPrototype =
389 LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
390 group.getClassPK());
391
392 headerElement.addAttribute(
393 "type-uuid", layoutSetPrototype.getUuid());
394 }
395
396 headerElement.addAttribute("type", type);
397
398 if (exportTheme || exportThemeSettings) {
399 headerElement.addAttribute("theme-id", layoutSet.getThemeId());
400 headerElement.addAttribute(
401 "color-scheme-id", layoutSet.getColorSchemeId());
402 }
403
404 if (exportLogo) {
405 Image image = ImageLocalServiceUtil.getImage(layoutSet.getLogoId());
406
407 if ((image != null) && (image.getTextObj() != null)) {
408 String logoPath = ExportImportPathUtil.getRootPath(
409 portletDataContext);
410
411 logoPath += "/logo";
412
413 headerElement.addAttribute("logo-path", logoPath);
414
415 portletDataContext.addZipEntry(logoPath, image.getTextObj());
416 }
417 }
418
419 if (exportLayoutSetSettings) {
420 Element settingsElement = headerElement.addElement("settings");
421
422 settingsElement.addCDATA(layoutSet.getSettings());
423 }
424
425 Element cssElement = headerElement.addElement("css");
426
427 cssElement.addCDATA(layoutSet.getCss());
428
429 Map<String, Object[]> portletIds =
430 new LinkedHashMap<String, Object[]>();
431
432 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
433 groupId, privateLayout);
434
435 List<Portlet> portlets = getDataSiteLevelPortlets(companyId);
436
437 long plid = LayoutConstants.DEFAULT_PLID;
438
439 if (!layouts.isEmpty()) {
440 Layout firstLayout = layouts.get(0);
441
442 plid = firstLayout.getPlid();
443 }
444
445 if (group.isStagingGroup()) {
446 group = group.getLiveGroup();
447 }
448
449 for (Portlet portlet : portlets) {
450 String portletId = portlet.getRootPortletId();
451
452 if (!group.isStagedPortlet(portletId)) {
453 continue;
454 }
455
456 String key = PortletPermissionUtil.getPrimaryKey(0, portletId);
457
458 if (portletIds.get(key) == null) {
459 portletIds.put(
460 key,
461 new Object[] {
462 portletId, plid, groupId, StringPool.BLANK,
463 StringPool.BLANK
464 });
465 }
466 }
467
468 Element missingReferencesElement = rootElement.addElement(
469 "missing-references");
470
471 portletDataContext.setMissingReferencesElement(
472 missingReferencesElement);
473
474 portletDataContext.addDeletionSystemEventStagedModelTypes(
475 new StagedModelType(Layout.class));
476
477 Element layoutsElement = portletDataContext.getExportDataGroupElement(
478 Layout.class);
479
480 String layoutSetPrototypeUuid = layoutSet.getLayoutSetPrototypeUuid();
481
482 if (Validator.isNotNull(layoutSetPrototypeUuid)) {
483 LayoutSetPrototype layoutSetPrototype =
484 LayoutSetPrototypeLocalServiceUtil.
485 getLayoutSetPrototypeByUuidAndCompanyId(
486 layoutSetPrototypeUuid, companyId);
487
488 layoutsElement.addAttribute(
489 "layout-set-prototype-uuid", layoutSetPrototypeUuid);
490
491 layoutsElement.addAttribute(
492 "layout-set-prototype-name",
493 layoutSetPrototype.getName(LocaleUtil.getDefault()));
494 }
495
496 for (Layout layout : layouts) {
497 exportLayout(
498 portletDataContext, portlets, layoutIds, portletIds, layout);
499 }
500
501 long previousScopeGroupId = portletDataContext.getScopeGroupId();
502
503 Element portletsElement = rootElement.addElement("portlets");
504
505 for (Map.Entry<String, Object[]> portletIdsEntry :
506 portletIds.entrySet()) {
507
508 Object[] portletObjects = portletIdsEntry.getValue();
509
510 String portletId = null;
511 plid = LayoutConstants.DEFAULT_PLID;
512 long scopeGroupId = 0;
513 String scopeType = StringPool.BLANK;
514 String scopeLayoutUuid = null;
515
516 if (portletObjects.length == 4) {
517 portletId = (String)portletIdsEntry.getValue()[0];
518 plid = (Long)portletIdsEntry.getValue()[1];
519 scopeGroupId = (Long)portletIdsEntry.getValue()[2];
520 scopeLayoutUuid = (String)portletIdsEntry.getValue()[3];
521 }
522 else {
523 portletId = (String)portletIdsEntry.getValue()[0];
524 plid = (Long)portletIdsEntry.getValue()[1];
525 scopeGroupId = (Long)portletIdsEntry.getValue()[2];
526 scopeType = (String)portletIdsEntry.getValue()[3];
527 scopeLayoutUuid = (String)portletIdsEntry.getValue()[4];
528 }
529
530 Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
531
532 if (layout == null) {
533 if (!group.isCompany() &&
534 (plid <= LayoutConstants.DEFAULT_PLID)) {
535
536 continue;
537 }
538
539 if (_log.isWarnEnabled()) {
540 _log.warn(
541 "Assuming global scope because no layout was found");
542 }
543
544 layout = new LayoutImpl();
545
546 layout.setGroupId(groupId);
547 layout.setCompanyId(companyId);
548 }
549
550 portletDataContext.setPlid(plid);
551 portletDataContext.setOldPlid(plid);
552 portletDataContext.setScopeGroupId(scopeGroupId);
553 portletDataContext.setScopeType(scopeType);
554 portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
555
556 boolean[] exportPortletControls = getExportPortletControls(
557 companyId, portletId, parameterMap, type);
558
559 _portletExporter.exportPortlet(
560 portletDataContext, layoutCache, portletId, layout,
561 portletsElement, defaultUserId, exportPermissions,
562 exportPortletControls[0], exportPortletControls[1],
563 exportPortletControls[2], exportPortletControls[3]);
564 }
565
566 portletDataContext.setScopeGroupId(previousScopeGroupId);
567
568 exportAssetCategories(
569 portletDataContext, exportPortletDataAll, exportCategories,
570 group.isCompany());
571
572 _portletExporter.exportAssetLinks(portletDataContext);
573 _portletExporter.exportAssetTags(portletDataContext);
574 _portletExporter.exportComments(portletDataContext);
575 _portletExporter.exportExpandoTables(portletDataContext);
576 _portletExporter.exportLocks(portletDataContext);
577
578 _deletionSystemEventExporter.exportDeletionSystemEvents(
579 portletDataContext);
580
581 if (exportPermissions) {
582 _permissionExporter.exportPortletDataPermissions(
583 portletDataContext);
584 }
585
586 _portletExporter.exportRatingsEntries(portletDataContext, rootElement);
587
588 if (exportTheme && !portletDataContext.isPerformDirectBinaryImport()) {
589 exportTheme(layoutSet, zipWriter);
590 }
591
592 ExportImportHelperUtil.writeManifestSummary(
593 document, portletDataContext.getManifestSummary());
594
595 if (_log.isInfoEnabled()) {
596 if (stopWatch != null) {
597 _log.info(
598 "Exporting layouts takes " + stopWatch.getTime() + " ms");
599 }
600 else {
601 _log.info("Exporting layouts is finished");
602 }
603 }
604
605 portletDataContext.addZipEntry(
606 "/manifest.xml", document.formattedString());
607
608 try {
609 return zipWriter.getFile();
610 }
611 finally {
612 if (updateLastPublishDate) {
613 updateLastPublishDate(layoutSet, lastPublishDate);
614 }
615 }
616 }
617
618 protected void exportAssetCategories(
619 PortletDataContext portletDataContext, boolean exportPortletDataAll,
620 boolean exportCategories, boolean companyGroup)
621 throws Exception {
622
623 Document document = SAXReaderUtil.createDocument();
624
625 Element rootElement = document.addElement("categories-hierarchy");
626
627 if (exportPortletDataAll || exportCategories || companyGroup) {
628 if (_log.isDebugEnabled()) {
629 _log.debug("Export categories");
630 }
631
632 Element assetVocabulariesElement = rootElement.addElement(
633 "vocabularies");
634
635 List<AssetVocabulary> assetVocabularies =
636 AssetVocabularyLocalServiceUtil.getGroupVocabularies(
637 portletDataContext.getGroupId());
638
639 for (AssetVocabulary assetVocabulary : assetVocabularies) {
640 _portletExporter.exportAssetVocabulary(
641 portletDataContext, assetVocabulariesElement,
642 assetVocabulary);
643 }
644
645 Element categoriesElement = rootElement.addElement("categories");
646
647 List<AssetCategory> assetCategories =
648 AssetCategoryUtil.findByGroupId(
649 portletDataContext.getGroupId());
650
651 for (AssetCategory assetCategory : assetCategories) {
652 _portletExporter.exportAssetCategory(
653 portletDataContext, assetVocabulariesElement,
654 categoriesElement, assetCategory);
655 }
656 }
657
658 _portletExporter.exportAssetCategories(portletDataContext, rootElement);
659
660 portletDataContext.addZipEntry(
661 ExportImportPathUtil.getRootPath(portletDataContext) +
662 "/categories-hierarchy.xml",
663 document.formattedString());
664 }
665
666 protected void exportLayout(
667 PortletDataContext portletDataContext, List<Portlet> portlets,
668 long[] layoutIds, Map<String, Object[]> portletIds, Layout layout)
669 throws Exception {
670
671 if (!ArrayUtil.contains(layoutIds, layout.getLayoutId()) &&
672 (layoutIds != null) && (layoutIds.length > 0)) {
673
674 Element layoutElement = portletDataContext.getExportDataElement(
675 layout);
676
677 layoutElement.addAttribute("action", Constants.SKIP);
678
679 return;
680 }
681
682 StagedModelDataHandlerUtil.exportStagedModel(
683 portletDataContext, layout);
684
685 if (!layout.isSupportsEmbeddedPortlets()) {
686
687
688
689 return;
690 }
691
692 if (layout.isTypePortlet()) {
693 for (Portlet portlet : portlets) {
694 if (portlet.isScopeable() && layout.hasScopeGroup()) {
695 String key = PortletPermissionUtil.getPrimaryKey(
696 layout.getPlid(), portlet.getPortletId());
697
698 Group scopeGroup = layout.getScopeGroup();
699
700 portletIds.put(
701 key,
702 new Object[] {
703 portlet.getPortletId(), layout.getPlid(),
704 scopeGroup.getGroupId(), StringPool.BLANK,
705 layout.getUuid()
706 });
707 }
708 }
709 }
710
711 LayoutTypePortlet layoutTypePortlet =
712 (LayoutTypePortlet)layout.getLayoutType();
713
714
715
716
717
718 for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
719 String portletId = portlet.getPortletId();
720
721 javax.portlet.PortletPreferences jxPortletPreferences =
722 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
723 layout, portletId);
724
725 String scopeType = GetterUtil.getString(
726 jxPortletPreferences.getValue("lfrScopeType", null));
727 String scopeLayoutUuid = GetterUtil.getString(
728 jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
729
730 long scopeGroupId = portletDataContext.getScopeGroupId();
731
732 if (Validator.isNotNull(scopeType)) {
733 Group scopeGroup = null;
734
735 if (scopeType.equals("company")) {
736 scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
737 layout.getCompanyId());
738 }
739 else if (scopeType.equals("layout")) {
740 Layout scopeLayout = null;
741
742 scopeLayout =
743 LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
744 scopeLayoutUuid, portletDataContext.getGroupId(),
745 portletDataContext.isPrivateLayout());
746
747 if (scopeLayout == null) {
748 continue;
749 }
750
751 scopeGroup = scopeLayout.getScopeGroup();
752 }
753 else {
754 throw new IllegalArgumentException(
755 "Scope type " + scopeType + " is invalid");
756 }
757
758 if (scopeGroup != null) {
759 scopeGroupId = scopeGroup.getGroupId();
760 }
761 }
762
763 String key = PortletPermissionUtil.getPrimaryKey(
764 layout.getPlid(), portletId);
765
766 portletIds.put(
767 key,
768 new Object[] {
769 portletId, layout.getPlid(), scopeGroupId, scopeType,
770 scopeLayoutUuid
771 }
772 );
773 }
774 }
775
776 protected void exportTheme(LayoutSet layoutSet, ZipWriter zipWriter)
777 throws Exception {
778
779 Theme theme = layoutSet.getTheme();
780
781 String lookAndFeelXML = ContentUtil.get(
782 "com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl");
783
784 lookAndFeelXML = StringUtil.replace(
785 lookAndFeelXML,
786 new String[] {
787 "[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]"
788 },
789 new String[] {
790 theme.getTemplateExtension(), theme.getVirtualPath()
791 }
792 );
793
794 String servletContextName = theme.getServletContextName();
795
796 ServletContext servletContext = ServletContextPool.get(
797 servletContextName);
798
799 if (servletContext == null) {
800 if (_log.isWarnEnabled()) {
801 _log.warn(
802 "Servlet context not found for theme " +
803 theme.getThemeId());
804 }
805
806 return;
807 }
808
809 File themeZip = new File(zipWriter.getPath() + "/theme.zip");
810
811 ZipWriter themeZipWriter = ZipWriterFactoryUtil.getZipWriter(themeZip);
812
813 themeZipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML);
814
815 File cssPath = null;
816 File imagesPath = null;
817 File javaScriptPath = null;
818 File templatesPath = null;
819
820 if (!theme.isLoadFromServletContext()) {
821 ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(
822 servletContextName);
823
824 if (themeLoader == null) {
825 _log.error(
826 servletContextName + " does not map to a theme loader");
827 }
828 else {
829 File file = themeLoader.getFileStorage();
830
831 String realPath =
832 file.getPath() + StringPool.SLASH + theme.getName();
833
834 cssPath = new File(realPath + "/css");
835 imagesPath = new File(realPath + "/images");
836 javaScriptPath = new File(realPath + "/javascript");
837 templatesPath = new File(realPath + "/templates");
838 }
839 }
840 else {
841 cssPath = new File(servletContext.getRealPath(theme.getCssPath()));
842 imagesPath = new File(
843 servletContext.getRealPath(theme.getImagesPath()));
844 javaScriptPath = new File(
845 servletContext.getRealPath(theme.getJavaScriptPath()));
846 templatesPath = new File(
847 servletContext.getRealPath(theme.getTemplatesPath()));
848 }
849
850 exportThemeFiles("css", cssPath, themeZipWriter);
851 exportThemeFiles("images", imagesPath, themeZipWriter);
852 exportThemeFiles("javascript", javaScriptPath, themeZipWriter);
853 exportThemeFiles("templates", templatesPath, themeZipWriter);
854 }
855
856 protected void exportThemeFiles(String path, File dir, ZipWriter zipWriter)
857 throws Exception {
858
859 if ((dir == null) || !dir.exists()) {
860 return;
861 }
862
863 File[] files = dir.listFiles();
864
865 for (File file : files) {
866 if (file.isDirectory()) {
867 exportThemeFiles(
868 path + StringPool.SLASH + file.getName(), file, zipWriter);
869 }
870 else {
871 zipWriter.addEntry(
872 path + StringPool.SLASH + file.getName(),
873 FileUtil.getBytes(file));
874 }
875 }
876 }
877
878 protected boolean[] getExportPortletControls(
879 long companyId, String portletId,
880 Map<String, String[]> parameterMap, String type)
881 throws Exception {
882
883 boolean exportPortletConfiguration = MapUtil.getBoolean(
884 parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION);
885 boolean exportPortletConfigurationAll = MapUtil.getBoolean(
886 parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL);
887 boolean exportPortletData = MapUtil.getBoolean(
888 parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
889 boolean exportPortletDataAll = MapUtil.getBoolean(
890 parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
891
892 if (_log.isDebugEnabled()) {
893 _log.debug("Export portlet data " + exportPortletData);
894 _log.debug("Export all portlet data " + exportPortletDataAll);
895 _log.debug(
896 "Export portlet configuration " + exportPortletConfiguration);
897 }
898
899 boolean exportCurPortletData = exportPortletData;
900
901 String rootPortletId =
902 ExportImportHelperUtil.getExportableRootPortletId(
903 companyId, portletId);
904
905 if (exportPortletDataAll) {
906 exportCurPortletData = true;
907 }
908 else if (rootPortletId != null) {
909
910
911
912
913 exportCurPortletData =
914 exportPortletData &&
915 MapUtil.getBoolean(
916 parameterMap,
917 PortletDataHandlerKeys.PORTLET_DATA +
918 StringPool.UNDERLINE + rootPortletId);
919 }
920
921 boolean exportCurPortletArchivedSetups = exportPortletConfiguration;
922 boolean exportCurPortletSetup = exportPortletConfiguration;
923 boolean exportCurPortletUserPreferences = exportPortletConfiguration;
924
925 if (exportPortletConfigurationAll ||
926 (exportPortletConfiguration && type.equals("layout-prototype"))) {
927
928 exportCurPortletArchivedSetups =
929 MapUtil.getBoolean(
930 parameterMap,
931 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS_ALL);
932 exportCurPortletSetup =
933 MapUtil.getBoolean(
934 parameterMap, PortletDataHandlerKeys.PORTLET_SETUP_ALL);
935 exportCurPortletUserPreferences =
936 MapUtil.getBoolean(
937 parameterMap,
938 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES_ALL);
939 }
940 else if (rootPortletId != null) {
941 boolean exportCurPortletConfiguration =
942 exportPortletConfiguration &&
943 MapUtil.getBoolean(
944 parameterMap,
945 PortletDataHandlerKeys.PORTLET_CONFIGURATION +
946 StringPool.UNDERLINE + rootPortletId);
947
948 exportCurPortletArchivedSetups =
949 exportCurPortletConfiguration &&
950 MapUtil.getBoolean(
951 parameterMap,
952 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS +
953 StringPool.UNDERLINE + rootPortletId);
954 exportCurPortletSetup =
955 exportCurPortletConfiguration &&
956 MapUtil.getBoolean(
957 parameterMap,
958 PortletDataHandlerKeys.PORTLET_SETUP +
959 StringPool.UNDERLINE + rootPortletId);
960 exportCurPortletUserPreferences =
961 exportCurPortletConfiguration &&
962 MapUtil.getBoolean(
963 parameterMap,
964 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES +
965 StringPool.UNDERLINE + rootPortletId);
966 }
967
968 return new boolean[] {
969 exportCurPortletArchivedSetups, exportCurPortletData,
970 exportCurPortletSetup, exportCurPortletUserPreferences};
971 }
972
973 protected String getLayoutIconPath(
974 PortletDataContext portletDataContext, Layout layout, Image image) {
975
976 StringBundler sb = new StringBundler(5);
977
978 sb.append(
979 ExportImportPathUtil.getLayoutPath(
980 portletDataContext, layout.getPlid()));
981 sb.append("/icons/");
982 sb.append(image.getImageId());
983 sb.append(StringPool.PERIOD);
984 sb.append(image.getType());
985
986 return sb.toString();
987 }
988
989 protected String getLayoutSetPrototype(
990 PortletDataContext portletDataContext, String layoutSetPrototypeUuid) {
991
992 StringBundler sb = new StringBundler(3);
993
994 sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
995 sb.append("/layout-set-prototype/");
996 sb.append(layoutSetPrototypeUuid);
997
998 return sb.toString();
999 }
1000
1001 private static Log _log = LogFactoryUtil.getLog(LayoutExporter.class);
1002
1003 private DeletionSystemEventExporter _deletionSystemEventExporter =
1004 new DeletionSystemEventExporter();
1005 private PermissionExporter _permissionExporter = new PermissionExporter();
1006 private PortletExporter _portletExporter = new PortletExporter();
1007
1008 }