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