001
014
015 package com.liferay.portal.lar;
016
017 import com.liferay.portal.LayoutImportException;
018 import com.liferay.portal.NoSuchPortletPreferencesException;
019 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
020 import com.liferay.portal.kernel.exception.PortalException;
021 import com.liferay.portal.kernel.exception.SystemException;
022 import com.liferay.portal.kernel.language.LanguageUtil;
023 import com.liferay.portal.kernel.lar.ExportImportDateUtil;
024 import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
025 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
026 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
027 import com.liferay.portal.kernel.lar.ManifestSummary;
028 import com.liferay.portal.kernel.lar.PortletDataContext;
029 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
030 import com.liferay.portal.kernel.lar.PortletDataException;
031 import com.liferay.portal.kernel.lar.PortletDataHandler;
032 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
033 import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
034 import com.liferay.portal.kernel.log.Log;
035 import com.liferay.portal.kernel.log.LogFactoryUtil;
036 import com.liferay.portal.kernel.util.CharPool;
037 import com.liferay.portal.kernel.util.DateRange;
038 import com.liferay.portal.kernel.util.GetterUtil;
039 import com.liferay.portal.kernel.util.MapUtil;
040 import com.liferay.portal.kernel.util.ReleaseInfo;
041 import com.liferay.portal.kernel.util.StringBundler;
042 import com.liferay.portal.kernel.util.StringPool;
043 import com.liferay.portal.kernel.util.StringUtil;
044 import com.liferay.portal.kernel.util.Time;
045 import com.liferay.portal.kernel.util.UnicodeProperties;
046 import com.liferay.portal.kernel.util.Validator;
047 import com.liferay.portal.kernel.xml.Document;
048 import com.liferay.portal.kernel.xml.Element;
049 import com.liferay.portal.kernel.xml.Node;
050 import com.liferay.portal.kernel.xml.SAXReaderUtil;
051 import com.liferay.portal.kernel.zip.ZipWriter;
052 import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
053 import com.liferay.portal.model.Group;
054 import com.liferay.portal.model.Layout;
055 import com.liferay.portal.model.LayoutConstants;
056 import com.liferay.portal.model.LayoutTypePortlet;
057 import com.liferay.portal.model.Lock;
058 import com.liferay.portal.model.Portlet;
059 import com.liferay.portal.model.PortletConstants;
060 import com.liferay.portal.model.PortletItem;
061 import com.liferay.portal.model.PortletPreferences;
062 import com.liferay.portal.model.User;
063 import com.liferay.portal.service.GroupLocalServiceUtil;
064 import com.liferay.portal.service.LayoutLocalServiceUtil;
065 import com.liferay.portal.service.PortletItemLocalServiceUtil;
066 import com.liferay.portal.service.PortletLocalServiceUtil;
067 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
068 import com.liferay.portal.service.ServiceContext;
069 import com.liferay.portal.service.ServiceContextThreadLocal;
070 import com.liferay.portal.service.UserLocalServiceUtil;
071 import com.liferay.portal.util.PortalUtil;
072 import com.liferay.portal.util.PortletKeys;
073 import com.liferay.portlet.PortletPreferencesFactoryUtil;
074 import com.liferay.portlet.asset.model.AssetEntry;
075 import com.liferay.portlet.asset.model.AssetLink;
076 import com.liferay.portlet.asset.model.AssetTag;
077 import com.liferay.portlet.asset.model.AssetTagProperty;
078 import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
079 import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
080 import com.liferay.portlet.asset.service.AssetTagPropertyLocalServiceUtil;
081 import com.liferay.portlet.expando.model.ExpandoColumn;
082 import com.liferay.util.xml.DocUtil;
083
084 import java.io.File;
085 import java.io.IOException;
086
087 import java.util.Date;
088 import java.util.List;
089 import java.util.Map;
090 import java.util.Map.Entry;
091
092 import org.apache.commons.lang.time.StopWatch;
093
094
105 public class PortletExporter {
106
107 public static PortletExporter getInstance() {
108 return _instance;
109 }
110
111 public void exportPortletData(
112 PortletDataContext portletDataContext, Portlet portlet,
113 Layout layout,
114 javax.portlet.PortletPreferences jxPortletPreferences,
115 Element parentElement)
116 throws Exception {
117
118 if (portlet == null) {
119 return;
120 }
121
122 PortletDataHandler portletDataHandler =
123 portlet.getPortletDataHandlerInstance();
124
125 if ((portletDataHandler == null) ||
126 portletDataHandler.isDataPortletInstanceLevel()) {
127
128 return;
129 }
130
131 String portletId = portlet.getPortletId();
132
133 Group liveGroup = layout.getGroup();
134
135 if (liveGroup.isStagingGroup()) {
136 liveGroup = liveGroup.getLiveGroup();
137 }
138
139 boolean staged = liveGroup.isStagedPortlet(portlet.getRootPortletId());
140
141 if (!staged && ExportImportThreadLocal.isLayoutExportInProcess()) {
142 if (_log.isDebugEnabled()) {
143 _log.debug(
144 "Not exporting data for " + portletId +
145 " because it is configured not to be staged");
146 }
147
148 return;
149 }
150
151 if (_log.isDebugEnabled()) {
152 _log.debug("Exporting data for " + portletId);
153 }
154
155 StringBundler sb = new StringBundler(4);
156
157 sb.append(
158 ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
159 sb.append(StringPool.SLASH);
160
161 if (portlet.isPreferencesUniquePerLayout()) {
162 sb.append(layout.getPlid());
163 }
164 else {
165 sb.append(portletDataContext.getScopeGroupId());
166 }
167
168 sb.append("/portlet-data.xml");
169
170 String path = sb.toString();
171
172 if (portletDataContext.isPathProcessed(path)) {
173 return;
174 }
175
176 Date originalStartDate = portletDataContext.getStartDate();
177
178 Date startDate = originalStartDate;
179
180 String range = MapUtil.getString(
181 portletDataContext.getParameterMap(), "range");
182
183 if (range.equals(ExportImportDateUtil.RANGE_FROM_LAST_PUBLISH_DATE)) {
184 Date lastPublishDate = ExportImportDateUtil.getLastPublishDate(
185 jxPortletPreferences);
186
187 if (lastPublishDate == null) {
188 startDate = null;
189 }
190 else if (lastPublishDate.before(startDate)) {
191 startDate = lastPublishDate;
192 }
193 }
194
195 portletDataContext.setStartDate(startDate);
196
197 long groupId = portletDataContext.getGroupId();
198
199 portletDataContext.setGroupId(portletDataContext.getScopeGroupId());
200
201 portletDataContext.clearScopedPrimaryKeys();
202
203 String data = null;
204
205 try {
206 data = portletDataHandler.exportData(
207 portletDataContext, portletId, jxPortletPreferences);
208 }
209 catch (PortletDataException pde) {
210 throw pde;
211 }
212 catch (Exception e) {
213 throw new SystemException(e);
214 }
215 finally {
216 portletDataContext.setGroupId(groupId);
217 portletDataContext.setStartDate(originalStartDate);
218 }
219
220 if (Validator.isNull(data)) {
221 if (_log.isDebugEnabled()) {
222 _log.debug(
223 "Not exporting data for " + portletId +
224 " because null data was returned");
225 }
226
227 return;
228 }
229
230 Element portletDataElement = parentElement.addElement("portlet-data");
231
232 portletDataElement.addAttribute("path", path);
233
234 portletDataContext.addZipEntry(path, data);
235
236 boolean updateLastPublishDate = MapUtil.getBoolean(
237 portletDataContext.getParameterMap(),
238 PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
239
240 if (updateLastPublishDate) {
241 DateRange adjustedDateRange = new DateRange(
242 startDate, portletDataContext.getEndDate());
243
244 ExportImportDateUtil.updateLastPublishDate(
245 portletId, jxPortletPreferences, adjustedDateRange,
246 portletDataContext.getEndDate());
247 }
248 }
249
250 public File exportPortletInfoAsFile(
251 long plid, long groupId, String portletId,
252 Map<String, String[]> parameterMap, Date startDate, Date endDate)
253 throws Exception {
254
255 try {
256 ExportImportThreadLocal.setPortletExportInProcess(true);
257
258 return doExportPortletInfoAsFile(
259 plid, groupId, portletId, parameterMap, startDate, endDate);
260 }
261 finally {
262 ExportImportThreadLocal.setPortletExportInProcess(false);
263 }
264 }
265
266 protected File doExportPortletInfoAsFile(
267 long plid, long groupId, String portletId,
268 Map<String, String[]> parameterMap, Date startDate, Date endDate)
269 throws Exception {
270
271 boolean exportPermissions = MapUtil.getBoolean(
272 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
273
274 if (_log.isDebugEnabled()) {
275 _log.debug("Export permissions " + exportPermissions);
276 }
277
278 StopWatch stopWatch = new StopWatch();
279
280 stopWatch.start();
281
282 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
283
284 if (!layout.isTypeControlPanel() && !layout.isTypePanel() &&
285 !layout.isTypePortlet()) {
286
287 throw new LayoutImportException(
288 "Layout type " + layout.getType() + " is not valid");
289 }
290
291 ServiceContext serviceContext =
292 ServiceContextThreadLocal.getServiceContext();
293
294 if (serviceContext == null) {
295 serviceContext = new ServiceContext();
296
297 serviceContext.setCompanyId(layout.getCompanyId());
298 serviceContext.setSignedIn(false);
299
300 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
301 layout.getCompanyId());
302
303 serviceContext.setUserId(defaultUserId);
304
305 ServiceContextThreadLocal.pushServiceContext(serviceContext);
306 }
307
308 long layoutSetBranchId = MapUtil.getLong(
309 parameterMap, "layoutSetBranchId");
310
311 serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);
312
313 ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
314
315 long scopeGroupId = groupId;
316
317 javax.portlet.PortletPreferences jxPortletPreferences =
318 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
319 layout, portletId);
320
321 String scopeType = GetterUtil.getString(
322 jxPortletPreferences.getValue("lfrScopeType", null));
323 String scopeLayoutUuid = GetterUtil.getString(
324 jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
325
326 if (Validator.isNotNull(scopeType)) {
327 Group scopeGroup = null;
328
329 if (scopeType.equals("company")) {
330 scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
331 layout.getCompanyId());
332 }
333 else if (Validator.isNotNull(scopeLayoutUuid)) {
334 scopeGroup = layout.getScopeGroup();
335 }
336
337 if (scopeGroup != null) {
338 scopeGroupId = scopeGroup.getGroupId();
339 }
340 }
341
342 PortletDataContext portletDataContext =
343 PortletDataContextFactoryUtil.createExportPortletDataContext(
344 layout.getCompanyId(), scopeGroupId, parameterMap, startDate,
345 endDate, zipWriter);
346
347 portletDataContext.setPortetDataContextListener(
348 new PortletDataContextListenerImpl(portletDataContext));
349
350 portletDataContext.setPlid(plid);
351 portletDataContext.setOldPlid(plid);
352 portletDataContext.setScopeType(scopeType);
353 portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
354
355 Document document = SAXReaderUtil.createDocument();
356
357 Element rootElement = document.addElement("root");
358
359 portletDataContext.setExportDataRootElement(rootElement);
360
361 Element headerElement = rootElement.addElement("header");
362
363 headerElement.addAttribute(
364 "available-locales",
365 StringUtil.merge(
366 LanguageUtil.getAvailableLocales(
367 PortalUtil.getSiteGroupId(
368 portletDataContext.getScopeGroupId()))));
369 headerElement.addAttribute(
370 "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
371 headerElement.addAttribute("export-date", Time.getRFC822());
372
373 if (portletDataContext.hasDateRange()) {
374 headerElement.addAttribute(
375 "start-date",
376 String.valueOf(portletDataContext.getStartDate()));
377 headerElement.addAttribute(
378 "end-date", String.valueOf(portletDataContext.getEndDate()));
379 }
380
381 headerElement.addAttribute("type", "portlet");
382 headerElement.addAttribute(
383 "company-id", String.valueOf(portletDataContext.getCompanyId()));
384 headerElement.addAttribute(
385 "company-group-id",
386 String.valueOf(portletDataContext.getCompanyGroupId()));
387 headerElement.addAttribute("group-id", String.valueOf(scopeGroupId));
388 headerElement.addAttribute(
389 "user-personal-site-group-id",
390 String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
391 headerElement.addAttribute(
392 "private-layout", String.valueOf(layout.isPrivateLayout()));
393 headerElement.addAttribute(
394 "root-portlet-id", PortletConstants.getRootPortletId(portletId));
395
396 Element missingReferencesElement = rootElement.addElement(
397 "missing-references");
398
399 portletDataContext.setMissingReferencesElement(
400 missingReferencesElement);
401
402 Map<String, Boolean> exportPortletControlsMap =
403 ExportImportHelperUtil.getExportPortletControlsMap(
404 layout.getCompanyId(), portletId, parameterMap);
405
406 exportPortlet(
407 portletDataContext, portletId, layout, rootElement,
408 exportPermissions,
409 exportPortletControlsMap.get(
410 PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
411 exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_DATA),
412 exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP),
413 exportPortletControlsMap.get(
414 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
415 exportService(
416 portletDataContext, portletId, rootElement,
417 exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP));
418
419 exportAssetLinks(portletDataContext);
420 exportAssetTags(portletDataContext);
421 exportExpandoTables(portletDataContext);
422 exportLocks(portletDataContext);
423
424 _deletionSystemEventExporter.exportDeletionSystemEvents(
425 portletDataContext);
426
427 if (exportPermissions) {
428 _permissionExporter.exportPortletDataPermissions(
429 portletDataContext);
430 }
431
432 ExportImportHelperUtil.writeManifestSummary(
433 document, portletDataContext.getManifestSummary());
434
435 if (_log.isInfoEnabled()) {
436 _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
437 }
438
439 try {
440 portletDataContext.addZipEntry(
441 "/manifest.xml", document.formattedString());
442 }
443 catch (IOException ioe) {
444 throw new SystemException(ioe);
445 }
446
447 return zipWriter.getFile();
448 }
449
450 protected void exportAssetLinks(PortletDataContext portletDataContext)
451 throws Exception {
452
453 Document document = SAXReaderUtil.createDocument();
454
455 Element rootElement = document.addElement("links");
456
457 Map<String, List<AssetLink>> assetLinksMap =
458 portletDataContext.getAssetLinksMap();
459
460 for (Entry<String, List<AssetLink>> entry : assetLinksMap.entrySet()) {
461 String[] assetLinkNameParts = StringUtil.split(
462 entry.getKey(), CharPool.POUND);
463
464 List<AssetLink> assetLinks = entry.getValue();
465
466 String sourceAssetEntryUuid = assetLinkNameParts[0];
467
468 Element assetElement = rootElement.addElement("asset-link-group");
469
470 assetElement.addAttribute("source-uuid", sourceAssetEntryUuid);
471
472 for (AssetLink assetLink : assetLinks) {
473 String path = getAssetLinkPath(
474 portletDataContext, assetLink.getLinkId());
475
476 if (!portletDataContext.isPathNotProcessed(path)) {
477 return;
478 }
479
480 Element assetLinkElement = assetElement.addElement(
481 "asset-link");
482
483 assetLinkElement.addAttribute("path", path);
484
485 AssetEntry targetAssetEntry =
486 AssetEntryLocalServiceUtil.fetchAssetEntry(
487 assetLink.getEntryId2());
488
489 assetLinkElement.addAttribute(
490 "target-uuid", targetAssetEntry.getClassUuid());
491
492 portletDataContext.addZipEntry(path, assetLink);
493 }
494 }
495
496 portletDataContext.addZipEntry(
497 ExportImportPathUtil.getRootPath(portletDataContext) + "/links.xml",
498 document.formattedString());
499 }
500
501 protected void exportAssetTag(
502 PortletDataContext portletDataContext, AssetTag assetTag,
503 Element assetTagsElement)
504 throws PortalException {
505
506 String path = getAssetTagPath(portletDataContext, assetTag.getTagId());
507
508 if (!portletDataContext.isPathNotProcessed(path)) {
509 return;
510 }
511
512 Element assetTagElement = assetTagsElement.addElement("tag");
513
514 assetTagElement.addAttribute("path", path);
515
516 assetTag.setUserUuid(assetTag.getUserUuid());
517
518 portletDataContext.addZipEntry(path, assetTag);
519
520 List<AssetTagProperty> assetTagProperties =
521 AssetTagPropertyLocalServiceUtil.getTagProperties(
522 assetTag.getTagId());
523
524 for (AssetTagProperty assetTagProperty : assetTagProperties) {
525 Element propertyElement = assetTagElement.addElement("property");
526
527 propertyElement.addAttribute("key", assetTagProperty.getKey());
528 propertyElement.addAttribute("value", assetTagProperty.getValue());
529 }
530
531 portletDataContext.addPermissions(AssetTag.class, assetTag.getTagId());
532 }
533
534 protected void exportAssetTags(PortletDataContext portletDataContext)
535 throws Exception {
536
537 Document document = SAXReaderUtil.createDocument();
538
539 Element rootElement = document.addElement("tags");
540
541 Map<String, String[]> assetTagNamesMap =
542 portletDataContext.getAssetTagNamesMap();
543
544 if (assetTagNamesMap.isEmpty()) {
545 return;
546 }
547
548 for (Map.Entry<String, String[]> entry : assetTagNamesMap.entrySet()) {
549 String[] assetTagNameParts = StringUtil.split(
550 entry.getKey(), CharPool.POUND);
551
552 String className = assetTagNameParts[0];
553 String classPK = assetTagNameParts[1];
554
555 Element assetElement = rootElement.addElement("asset");
556
557 assetElement.addAttribute("class-name", className);
558 assetElement.addAttribute("class-pk", classPK);
559 assetElement.addAttribute(
560 "tags", StringUtil.merge(entry.getValue()));
561
562 List<AssetTag> assetTags = AssetTagLocalServiceUtil.getTags(
563 className, GetterUtil.getLong(classPK));
564
565 for (AssetTag assetTag : assetTags) {
566 exportAssetTag(portletDataContext, assetTag, rootElement);
567 }
568 }
569
570 portletDataContext.addZipEntry(
571 ExportImportPathUtil.getRootPath(portletDataContext) + "/tags.xml",
572 document.formattedString());
573 }
574
575 protected void exportExpandoTables(PortletDataContext portletDataContext)
576 throws Exception {
577
578 Document document = SAXReaderUtil.createDocument();
579
580 Element rootElement = document.addElement("expando-tables");
581
582 Map<String, List<ExpandoColumn>> expandoColumnsMap =
583 portletDataContext.getExpandoColumns();
584
585 for (Map.Entry<String, List<ExpandoColumn>> entry :
586 expandoColumnsMap.entrySet()) {
587
588 String className = entry.getKey();
589
590 Element expandoTableElement = rootElement.addElement(
591 "expando-table");
592
593 expandoTableElement.addAttribute("class-name", className);
594
595 List<ExpandoColumn> expandoColumns = entry.getValue();
596
597 for (ExpandoColumn expandoColumn : expandoColumns) {
598 Element expandoColumnElement = expandoTableElement.addElement(
599 "expando-column");
600
601 expandoColumnElement.addAttribute(
602 "column-id", String.valueOf(expandoColumn.getColumnId()));
603 expandoColumnElement.addAttribute(
604 "name", expandoColumn.getName());
605 expandoColumnElement.addAttribute(
606 "type", String.valueOf(expandoColumn.getType()));
607
608 DocUtil.add(
609 expandoColumnElement, "default-data",
610 expandoColumn.getDefaultData());
611
612 Element typeSettingsElement = expandoColumnElement.addElement(
613 "type-settings");
614
615 UnicodeProperties typeSettingsProperties =
616 expandoColumn.getTypeSettingsProperties();
617
618 typeSettingsElement.addCDATA(typeSettingsProperties.toString());
619 }
620 }
621
622 portletDataContext.addZipEntry(
623 ExportImportPathUtil.getRootPath(portletDataContext) +
624 "/expando-tables.xml",
625 document.formattedString());
626 }
627
628 protected void exportLocks(PortletDataContext portletDataContext)
629 throws Exception {
630
631 Document document = SAXReaderUtil.createDocument();
632
633 Element rootElement = document.addElement("locks");
634
635 Map<String, Lock> locksMap = portletDataContext.getLocks();
636
637 for (Map.Entry<String, Lock> entry : locksMap.entrySet()) {
638 Lock lock = entry.getValue();
639
640 String entryKey = entry.getKey();
641
642 int pos = entryKey.indexOf(CharPool.POUND);
643
644 String className = entryKey.substring(0, pos);
645 String key = entryKey.substring(pos + 1);
646
647 String path = getLockPath(portletDataContext, className, key, lock);
648
649 Element assetElement = rootElement.addElement("asset");
650
651 assetElement.addAttribute("path", path);
652 assetElement.addAttribute("class-name", className);
653 assetElement.addAttribute("key", key);
654
655 if (portletDataContext.isPathNotProcessed(path)) {
656 portletDataContext.addZipEntry(path, lock);
657 }
658 }
659
660 portletDataContext.addZipEntry(
661 ExportImportPathUtil.getRootPath(portletDataContext) + "/locks.xml",
662 document.formattedString());
663 }
664
665 protected void exportPortlet(
666 PortletDataContext portletDataContext, String portletId,
667 Layout layout, Element parentElement, boolean exportPermissions,
668 boolean exportPortletArchivedSetups, boolean exportPortletData,
669 boolean exportPortletSetup, boolean exportPortletUserPreferences)
670 throws Exception {
671
672 long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
673 long layoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
674
675 if (layout != null) {
676 plid = layout.getPlid();
677 layoutId = layout.getLayoutId();
678 }
679
680 Portlet portlet = PortletLocalServiceUtil.getPortletById(
681 portletDataContext.getCompanyId(), portletId);
682
683 if (portlet == null) {
684 if (_log.isDebugEnabled()) {
685 _log.debug(
686 "Do not export portlet " + portletId +
687 " because the portlet does not exist");
688 }
689
690 return;
691 }
692
693 if (!portlet.isInstanceable() &&
694 !portlet.isPreferencesUniquePerLayout() &&
695 portletDataContext.hasNotUniquePerLayout(portletId)) {
696
697 return;
698 }
699
700 if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
701 PortletDataContext clonedPortletDataContext =
702 PortletDataContextFactoryUtil.clonePortletDataContext(
703 portletDataContext);
704
705 ManifestSummary manifestSummary =
706 clonedPortletDataContext.getManifestSummary();
707
708 manifestSummary.resetCounters();
709
710 PortletDataHandler portletDataHandler =
711 portlet.getPortletDataHandlerInstance();
712
713 portletDataHandler.prepareManifestSummary(clonedPortletDataContext);
714
715 PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
716 "portlet", portletId, manifestSummary);
717 }
718
719 Document document = SAXReaderUtil.createDocument();
720
721 Element portletElement = document.addElement("portlet");
722
723 portletElement.addAttribute("portlet-id", portletId);
724 portletElement.addAttribute(
725 "root-portlet-id", PortletConstants.getRootPortletId(portletId));
726 portletElement.addAttribute("old-plid", String.valueOf(plid));
727 portletElement.addAttribute(
728 "scope-group-id",
729 String.valueOf(portletDataContext.getScopeGroupId()));
730 portletElement.addAttribute(
731 "scope-layout-type", portletDataContext.getScopeType());
732 portletElement.addAttribute(
733 "scope-layout-uuid", portletDataContext.getScopeLayoutUuid());
734 portletElement.addAttribute(
735 "private-layout", String.valueOf(layout.isPrivateLayout()));
736
737
738
739 if (exportPortletData) {
740 javax.portlet.PortletPreferences jxPortletPreferences =
741 PortletPreferencesFactoryUtil.getStrictPortletSetup(
742 layout, portletId);
743
744 if (!portlet.isPreferencesUniquePerLayout()) {
745 StringBundler sb = new StringBundler(5);
746
747 sb.append(portletId);
748 sb.append(StringPool.AT);
749 sb.append(portletDataContext.getScopeType());
750 sb.append(StringPool.AT);
751 sb.append(portletDataContext.getScopeLayoutUuid());
752
753 String dataKey = sb.toString();
754
755 if (!portletDataContext.hasNotUniquePerLayout(dataKey)) {
756 portletDataContext.putNotUniquePerLayout(dataKey);
757
758 exportPortletData(
759 portletDataContext, portlet, layout,
760 jxPortletPreferences, portletElement);
761 }
762 }
763 else {
764 exportPortletData(
765 portletDataContext, portlet, layout, jxPortletPreferences,
766 portletElement);
767 }
768 }
769
770
771
772 if (exportPortletSetup) {
773
774
775
776 exportPortletPreferences(
777 portletDataContext, portletDataContext.getCompanyId(),
778 PortletKeys.PREFS_OWNER_TYPE_COMPANY, false, layout, plid,
779 portlet.getRootPortletId(), portletElement);
780
781
782
783 exportPortletPreferences(
784 portletDataContext, portletDataContext.getScopeGroupId(),
785 PortletKeys.PREFS_OWNER_TYPE_GROUP, false, layout,
786 PortletKeys.PREFS_PLID_SHARED, portlet.getRootPortletId(),
787 portletElement);
788
789
790
791 exportPortletPreferences(
792 portletDataContext, PortletKeys.PREFS_OWNER_ID_DEFAULT,
793 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, plid,
794 portletId, portletElement);
795 }
796
797
798
799 if (exportPortletUserPreferences) {
800 List<PortletPreferences> portletPreferencesList =
801 PortletPreferencesLocalServiceUtil.getPortletPreferences(
802 PortletKeys.PREFS_OWNER_TYPE_USER, plid, portletId);
803
804 for (PortletPreferences portletPreferences :
805 portletPreferencesList) {
806
807 boolean defaultUser = false;
808
809 if (portletPreferences.getOwnerId() ==
810 PortletKeys.PREFS_OWNER_ID_DEFAULT) {
811
812 defaultUser = true;
813 }
814
815 exportPortletPreferences(
816 portletDataContext, portletPreferences.getOwnerId(),
817 PortletKeys.PREFS_OWNER_TYPE_USER, defaultUser, layout,
818 plid, portletId, portletElement);
819 }
820
821 try {
822 PortletPreferences groupPortletPreferences =
823 PortletPreferencesLocalServiceUtil.getPortletPreferences(
824 portletDataContext.getScopeGroupId(),
825 PortletKeys.PREFS_OWNER_TYPE_GROUP,
826 PortletKeys.PREFS_PLID_SHARED,
827 portlet.getRootPortletId());
828
829 exportPortletPreference(
830 portletDataContext, portletDataContext.getScopeGroupId(),
831 PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
832 groupPortletPreferences, portlet.getRootPortletId(),
833 PortletKeys.PREFS_PLID_SHARED, portletElement);
834 }
835 catch (NoSuchPortletPreferencesException nsppe) {
836 }
837 }
838
839
840
841 if (exportPortletArchivedSetups) {
842 String rootPortletId = PortletConstants.getRootPortletId(portletId);
843
844 List<PortletItem> portletItems =
845 PortletItemLocalServiceUtil.getPortletItems(
846 portletDataContext.getGroupId(), rootPortletId,
847 PortletPreferences.class.getName());
848
849 for (PortletItem portletItem : portletItems) {
850 exportPortletPreferences(
851 portletDataContext, portletItem.getPortletItemId(),
852 PortletKeys.PREFS_OWNER_TYPE_ARCHIVED, false, null, plid,
853 portletItem.getPortletId(), portletElement);
854 }
855 }
856
857
858
859 if (exportPermissions) {
860 _permissionExporter.exportPortletPermissions(
861 portletDataContext, portletId, layout, portletElement);
862 }
863
864
865
866 StringBundler pathSB = new StringBundler(4);
867
868 pathSB.append(
869 ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
870 pathSB.append(StringPool.SLASH);
871 pathSB.append(plid);
872 pathSB.append("/portlet.xml");
873
874 String path = pathSB.toString();
875
876 Element element = parentElement.addElement("portlet");
877
878 element.addAttribute("portlet-id", portletId);
879 element.addAttribute("layout-id", String.valueOf(layoutId));
880 element.addAttribute("path", path);
881 element.addAttribute("portlet-data", String.valueOf(exportPortletData));
882
883 StringBundler configurationOptionsSB = new StringBundler(6);
884
885 if (exportPortletSetup) {
886 configurationOptionsSB.append("setup");
887 configurationOptionsSB.append(StringPool.COMMA);
888 }
889
890 if (exportPortletArchivedSetups) {
891 configurationOptionsSB.append("archived-setups");
892 configurationOptionsSB.append(StringPool.COMMA);
893 }
894
895 if (exportPortletUserPreferences) {
896 configurationOptionsSB.append("user-preferences");
897 configurationOptionsSB.append(StringPool.COMMA);
898 }
899
900 if (configurationOptionsSB.index() > 0) {
901 configurationOptionsSB.setIndex(configurationOptionsSB.index() -1);
902 }
903
904 element.addAttribute(
905 "portlet-configuration", configurationOptionsSB.toString());
906
907 if (portletDataContext.isPathNotProcessed(path)) {
908 try {
909 portletDataContext.addZipEntry(
910 path, document.formattedString());
911 }
912 catch (IOException ioe) {
913 if (_log.isWarnEnabled()) {
914 _log.warn(ioe.getMessage());
915 }
916 }
917
918 portletDataContext.addPrimaryKey(String.class, path);
919 }
920 }
921
922 protected void exportPortletPreference(
923 PortletDataContext portletDataContext, long ownerId, int ownerType,
924 boolean defaultUser, PortletPreferences portletPreferences,
925 String portletId, long plid, Element parentElement)
926 throws Exception {
927
928 String preferencesXML = portletPreferences.getPreferences();
929
930 if (Validator.isNull(preferencesXML)) {
931 preferencesXML = PortletConstants.DEFAULT_PREFERENCES;
932 }
933
934 javax.portlet.PortletPreferences jxPortletPreferences =
935 PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML);
936
937 Portlet portlet = PortletLocalServiceUtil.getPortletById(
938 portletDataContext.getCompanyId(), portletId);
939
940 Element portletPreferencesElement = parentElement.addElement(
941 "portlet-preferences");
942
943 if ((portlet != null) &&
944 (portlet.getPortletDataHandlerInstance() != null)) {
945
946 Element exportDataRootElement =
947 portletDataContext.getExportDataRootElement();
948
949 try {
950 portletDataContext.clearScopedPrimaryKeys();
951
952 Element preferenceDataElement =
953 portletPreferencesElement.addElement("preference-data");
954
955 portletDataContext.setExportDataRootElement(
956 preferenceDataElement);
957
958 PortletDataHandler portletDataHandler =
959 portlet.getPortletDataHandlerInstance();
960
961 jxPortletPreferences =
962 portletDataHandler.processExportPortletPreferences(
963 portletDataContext, portletId, jxPortletPreferences);
964 }
965 finally {
966 portletDataContext.setExportDataRootElement(
967 exportDataRootElement);
968 }
969 }
970
971 Document document = SAXReaderUtil.read(
972 PortletPreferencesFactoryUtil.toXML(jxPortletPreferences));
973
974 Element rootElement = document.getRootElement();
975
976 rootElement.addAttribute("owner-id", String.valueOf(ownerId));
977 rootElement.addAttribute("owner-type", String.valueOf(ownerType));
978 rootElement.addAttribute("default-user", String.valueOf(defaultUser));
979 rootElement.addAttribute("plid", String.valueOf(plid));
980 rootElement.addAttribute("portlet-id", portletId);
981
982 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
983 PortletItem portletItem =
984 PortletItemLocalServiceUtil.getPortletItem(ownerId);
985
986 rootElement.addAttribute(
987 "archive-user-uuid", portletItem.getUserUuid());
988 rootElement.addAttribute("archive-name", portletItem.getName());
989 }
990 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
991 User user = UserLocalServiceUtil.fetchUserById(ownerId);
992
993 if (user == null) {
994 return;
995 }
996
997 rootElement.addAttribute("user-uuid", user.getUserUuid());
998 }
999
1000 List<Node> nodes = document.selectNodes(
1001 "/portlet-preferences/preference[name/text() = " +
1002 "'last-publish-date']");
1003
1004 for (Node node : nodes) {
1005 document.remove(node);
1006 }
1007
1008 String path = ExportImportPathUtil.getPortletPreferencesPath(
1009 portletDataContext, portletId, ownerId, ownerType, plid);
1010
1011 portletPreferencesElement.addAttribute("path", path);
1012
1013 if (portletDataContext.isPathNotProcessed(path)) {
1014 portletDataContext.addZipEntry(
1015 path, document.formattedString(StringPool.TAB, false, false));
1016 }
1017 }
1018
1019 protected void exportPortletPreferences(
1020 PortletDataContext portletDataContext, long ownerId, int ownerType,
1021 boolean defaultUser, Layout layout, long plid, String portletId,
1022 Element parentElement)
1023 throws Exception {
1024
1025 PortletPreferences portletPreferences = null;
1026
1027 try {
1028 portletPreferences = getPortletPreferences(
1029 ownerId, ownerType, plid, portletId);
1030 }
1031 catch (NoSuchPortletPreferencesException nsppe) {
1032 return;
1033 }
1034
1035 LayoutTypePortlet layoutTypePortlet = null;
1036
1037 if (layout != null) {
1038 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
1039 }
1040
1041 if ((layoutTypePortlet == null) ||
1042 layoutTypePortlet.hasPortletId(portletId)) {
1043
1044 exportPortletPreference(
1045 portletDataContext, ownerId, ownerType, defaultUser,
1046 portletPreferences, portletId, plid, parentElement);
1047 }
1048 }
1049
1050 protected void exportService(
1051 PortletDataContext portletDataContext, String portletId,
1052 Element rootElement, boolean exportServiceSetup)
1053 throws Exception {
1054
1055 if (!exportServiceSetup) {
1056 return;
1057 }
1058
1059 Portlet portlet = PortletLocalServiceUtil.getPortletById(portletId);
1060
1061 PortletDataHandler portletDataHandler =
1062 portlet.getPortletDataHandlerInstance();
1063
1064 String serviceName = portletDataHandler.getServiceName();
1065
1066 if (Validator.isNotNull(serviceName)) {
1067
1068
1069
1070 exportServicePortletPreferences(
1071 portletDataContext, portletDataContext.getCompanyId(),
1072 PortletKeys.PREFS_OWNER_TYPE_COMPANY, serviceName, rootElement);
1073
1074
1075
1076 exportServicePortletPreferences(
1077 portletDataContext, portletDataContext.getScopeGroupId(),
1078 PortletKeys.PREFS_OWNER_TYPE_GROUP, serviceName, rootElement);
1079 }
1080 }
1081
1082 protected void exportServicePortletPreference(
1083 PortletDataContext portletDataContext, long ownerId, int ownerType,
1084 PortletPreferences portletPreferences, String serviceName,
1085 Element parentElement)
1086 throws Exception {
1087
1088 String path = ExportImportPathUtil.getServicePortletPreferencesPath(
1089 portletDataContext, serviceName, ownerId, ownerType);
1090
1091 if (portletDataContext.isPathProcessed(path)) {
1092 return;
1093 }
1094
1095 String preferencesXML = portletPreferences.getPreferences();
1096
1097 if (Validator.isNull(preferencesXML)) {
1098 preferencesXML = PortletConstants.DEFAULT_PREFERENCES;
1099 }
1100
1101 javax.portlet.PortletPreferences jxPortletPreferences =
1102 PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML);
1103
1104 Element serviceElement = parentElement.addElement("service");
1105
1106 serviceElement.addAttribute("service-name", serviceName);
1107
1108 Document document = SAXReaderUtil.read(
1109 PortletPreferencesFactoryUtil.toXML(jxPortletPreferences));
1110
1111 Element rootElement = document.getRootElement();
1112
1113 rootElement.addAttribute("owner-id", String.valueOf(ownerId));
1114 rootElement.addAttribute("owner-type", String.valueOf(ownerType));
1115 rootElement.addAttribute("default-user", String.valueOf(false));
1116 rootElement.addAttribute("service-name", serviceName);
1117
1118 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1119 PortletItem portletItem =
1120 PortletItemLocalServiceUtil.getPortletItem(ownerId);
1121
1122 rootElement.addAttribute(
1123 "archive-user-uuid", portletItem.getUserUuid());
1124 rootElement.addAttribute("archive-name", portletItem.getName());
1125 }
1126 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1127 User user = UserLocalServiceUtil.fetchUserById(ownerId);
1128
1129 if (user == null) {
1130 return;
1131 }
1132
1133 rootElement.addAttribute("user-uuid", user.getUserUuid());
1134 }
1135
1136 List<Node> nodes = document.selectNodes(
1137 "/portlet-preferences/preference[name/text() = " +
1138 "'last-publish-date']");
1139
1140 for (Node node : nodes) {
1141 document.remove(node);
1142 }
1143
1144 serviceElement.addAttribute("path", path);
1145
1146 portletDataContext.addZipEntry(path, document.formattedString());
1147 }
1148
1149 protected void exportServicePortletPreferences(
1150 PortletDataContext portletDataContext, long ownerId, int ownerType,
1151 String serviceName, Element parentElement)
1152 throws Exception {
1153
1154 PortletPreferences portletPreferences = null;
1155
1156 try {
1157 portletPreferences = getPortletPreferences(
1158 ownerId, ownerType, LayoutConstants.DEFAULT_PLID, serviceName);
1159 }
1160 catch (NoSuchPortletPreferencesException nsppe) {
1161 return;
1162 }
1163
1164 exportServicePortletPreference(
1165 portletDataContext, ownerId, ownerType, portletPreferences,
1166 serviceName, parentElement);
1167 }
1168
1169 protected String getAssetLinkPath(
1170 PortletDataContext portletDataContext, long assetLinkId) {
1171
1172 StringBundler sb = new StringBundler(4);
1173
1174 sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1175 sb.append("/links/");
1176 sb.append(assetLinkId);
1177 sb.append(".xml");
1178
1179 return sb.toString();
1180 }
1181
1182 protected String getAssetTagPath(
1183 PortletDataContext portletDataContext, long assetCategoryId) {
1184
1185 StringBundler sb = new StringBundler(4);
1186
1187 sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1188 sb.append("/tags/");
1189 sb.append(assetCategoryId);
1190 sb.append(".xml");
1191
1192 return sb.toString();
1193 }
1194
1195 protected String getLockPath(
1196 PortletDataContext portletDataContext, String className, String key,
1197 Lock lock) {
1198
1199 StringBundler sb = new StringBundler(8);
1200
1201 sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1202 sb.append("/locks/");
1203 sb.append(PortalUtil.getClassNameId(className));
1204 sb.append(CharPool.FORWARD_SLASH);
1205 sb.append(key);
1206 sb.append(CharPool.FORWARD_SLASH);
1207 sb.append(lock.getLockId());
1208 sb.append(".xml");
1209
1210 return sb.toString();
1211 }
1212
1213 protected PortletPreferences getPortletPreferences(
1214 long ownerId, int ownerType, long plid, String portletId)
1215 throws PortalException {
1216
1217 PortletPreferences portletPreferences = null;
1218
1219 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) ||
1220 (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
1221 (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP)) {
1222
1223 portletPreferences =
1224 PortletPreferencesLocalServiceUtil.getPortletPreferences(
1225 ownerId, ownerType, LayoutConstants.DEFAULT_PLID,
1226 portletId);
1227 }
1228 else {
1229 portletPreferences =
1230 PortletPreferencesLocalServiceUtil.getPortletPreferences(
1231 ownerId, ownerType, plid, portletId);
1232 }
1233
1234 return portletPreferences;
1235 }
1236
1237 private PortletExporter() {
1238 }
1239
1240 private static final Log _log = LogFactoryUtil.getLog(
1241 PortletExporter.class);
1242
1243 private static final PortletExporter _instance = new PortletExporter();
1244
1245 private final DeletionSystemEventExporter _deletionSystemEventExporter =
1246 DeletionSystemEventExporter.getInstance();
1247 private final PermissionExporter _permissionExporter =
1248 PermissionExporter.getInstance();
1249
1250 }