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