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