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