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