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