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