1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.lar;
16  
17  import com.liferay.portal.LayoutImportException;
18  import com.liferay.portal.NoSuchPortletPreferencesException;
19  import com.liferay.portal.kernel.exception.PortalException;
20  import com.liferay.portal.kernel.exception.SystemException;
21  import com.liferay.portal.kernel.lar.PortletDataContext;
22  import com.liferay.portal.kernel.lar.PortletDataHandler;
23  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
24  import com.liferay.portal.kernel.log.Log;
25  import com.liferay.portal.kernel.log.LogFactoryUtil;
26  import com.liferay.portal.kernel.util.CharPool;
27  import com.liferay.portal.kernel.util.FileUtil;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.kernel.util.MapUtil;
30  import com.liferay.portal.kernel.util.ReleaseInfo;
31  import com.liferay.portal.kernel.util.StringBundler;
32  import com.liferay.portal.kernel.util.StringPool;
33  import com.liferay.portal.kernel.util.StringUtil;
34  import com.liferay.portal.kernel.util.Time;
35  import com.liferay.portal.kernel.util.Validator;
36  import com.liferay.portal.kernel.xml.Document;
37  import com.liferay.portal.kernel.xml.Element;
38  import com.liferay.portal.kernel.xml.SAXReaderUtil;
39  import com.liferay.portal.kernel.zip.ZipWriter;
40  import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
41  import com.liferay.portal.model.Group;
42  import com.liferay.portal.model.Layout;
43  import com.liferay.portal.model.LayoutTypePortlet;
44  import com.liferay.portal.model.Lock;
45  import com.liferay.portal.model.Portlet;
46  import com.liferay.portal.model.PortletConstants;
47  import com.liferay.portal.model.PortletItem;
48  import com.liferay.portal.model.PortletPreferences;
49  import com.liferay.portal.model.User;
50  import com.liferay.portal.service.LayoutLocalServiceUtil;
51  import com.liferay.portal.service.PortletItemLocalServiceUtil;
52  import com.liferay.portal.service.PortletLocalServiceUtil;
53  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
54  import com.liferay.portal.service.UserLocalServiceUtil;
55  import com.liferay.portal.util.PortalUtil;
56  import com.liferay.portal.util.PortletKeys;
57  import com.liferay.portlet.PortletPreferencesFactoryUtil;
58  import com.liferay.portlet.asset.model.AssetCategory;
59  import com.liferay.portlet.asset.model.AssetCategoryConstants;
60  import com.liferay.portlet.asset.model.AssetCategoryProperty;
61  import com.liferay.portlet.asset.model.AssetVocabulary;
62  import com.liferay.portlet.asset.service.AssetCategoryPropertyLocalServiceUtil;
63  import com.liferay.portlet.asset.service.AssetCategoryServiceUtil;
64  import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
65  import com.liferay.portlet.asset.service.persistence.AssetVocabularyUtil;
66  import com.liferay.portlet.messageboards.model.MBMessage;
67  import com.liferay.portlet.ratings.model.RatingsEntry;
68  
69  import java.io.File;
70  import java.io.IOException;
71  
72  import java.util.Date;
73  import java.util.HashSet;
74  import java.util.List;
75  import java.util.Map;
76  
77  import org.apache.commons.lang.time.StopWatch;
78  
79  /**
80   * <a href="PortletExporter.java.html"><b><i>View Source</i></b></a>
81   *
82   * @author Brian Wing Shun Chan
83   * @author Joel Kozikowski
84   * @author Charles May
85   * @author Raymond Augé
86   * @author Jorge Ferrer
87   * @author Bruno Farache
88   * @author Zsigmond Rab
89   * @author Douglas Wong
90   */
91  public class PortletExporter {
92  
93      public byte[] exportPortletInfo(
94              long plid, long groupId, String portletId,
95              Map<String, String[]> parameterMap, Date startDate, Date endDate)
96          throws PortalException, SystemException {
97  
98          File file = exportPortletInfoAsFile(
99              plid, groupId, portletId, parameterMap, startDate, endDate);
100 
101         try {
102             return FileUtil.getBytes(file);
103         }
104         catch (IOException ioe) {
105             throw new SystemException(ioe);
106         }
107         finally {
108             file.delete();
109         }
110     }
111 
112     public File exportPortletInfoAsFile(
113             long plid, long groupId, String portletId,
114             Map<String, String[]> parameterMap, Date startDate, Date endDate)
115         throws PortalException, SystemException {
116 
117         boolean exportCategories = MapUtil.getBoolean(
118             parameterMap, PortletDataHandlerKeys.CATEGORIES);
119         boolean exportPermissions = MapUtil.getBoolean(
120             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
121         boolean exportPortletArchivedSetups = MapUtil.getBoolean(
122             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
123         boolean exportPortletData = MapUtil.getBoolean(
124             parameterMap, PortletDataHandlerKeys.PORTLET_DATA + "_" +
125             PortletConstants.getRootPortletId(portletId));
126         boolean exportPortletDataAll = MapUtil.getBoolean(
127             parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
128         boolean exportPortletSetup = MapUtil.getBoolean(
129             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
130         boolean exportPortletUserPreferences = MapUtil.getBoolean(
131             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
132         boolean exportUserPermissions = MapUtil.getBoolean(
133             parameterMap, PortletDataHandlerKeys.USER_PERMISSIONS);
134 
135         if (_log.isDebugEnabled()) {
136             _log.debug("Export categories " + exportCategories);
137             _log.debug("Export permissions " + exportPermissions);
138             _log.debug(
139                 "Export portlet archived setups " +
140                     exportPortletArchivedSetups);
141             _log.debug("Export portlet data " + exportPortletData);
142             _log.debug("Export all portlet data " + exportPortletDataAll);
143             _log.debug("Export portlet setup " + exportPortletSetup);
144             _log.debug(
145                 "Export portlet user preferences " +
146                     exportPortletUserPreferences);
147             _log.debug("Export user permissions " + exportUserPermissions);
148         }
149 
150         if (exportPortletDataAll) {
151             exportPortletData = true;
152         }
153 
154         StopWatch stopWatch = null;
155 
156         if (_log.isInfoEnabled()) {
157             stopWatch = new StopWatch();
158 
159             stopWatch.start();
160         }
161 
162         LayoutCache layoutCache = new LayoutCache();
163 
164         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
165 
166         if (!layout.isTypeControlPanel() && !layout.isTypePanel() &&
167             !layout.isTypePortlet()) {
168 
169             throw new LayoutImportException(
170                 "Layout type " + layout.getType() + " is not valid");
171         }
172 
173         long companyId = layout.getCompanyId();
174         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
175 
176         ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
177 
178         long scopeGroupId = groupId;
179 
180         javax.portlet.PortletPreferences jxPreferences =
181             PortletPreferencesFactoryUtil.getLayoutPortletSetup(
182                 layout, portletId);
183 
184         long scopeLayoutId = GetterUtil.getLong(
185             jxPreferences.getValue("lfr-scope-layout-id", null));
186 
187         if (scopeLayoutId != 0) {
188             Group scopeGroup = layout.getScopeGroup();
189 
190             if (scopeGroup != null) {
191                 scopeGroupId = scopeGroup.getGroupId();
192             }
193         }
194 
195         PortletDataContext context = new PortletDataContextImpl(
196             companyId, scopeGroupId, parameterMap, new HashSet<String>(),
197             startDate, endDate, zipWriter);
198 
199         context.setPortetDataContextListener(
200             new PortletDataContextListenerImpl(context));
201 
202         context.setPlid(plid);
203         context.setOldPlid(plid);
204         context.setScopeLayoutId(scopeLayoutId);
205 
206         // Build compatibility
207 
208         Document doc = SAXReaderUtil.createDocument();
209 
210         Element root = doc.addElement("root");
211 
212         Element header = root.addElement("header");
213 
214         header.addAttribute(
215             "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
216         header.addAttribute("export-date", Time.getRFC822());
217 
218         if (context.hasDateRange()) {
219             header.addAttribute(
220                 "start-date", String.valueOf(context.getStartDate()));
221             header.addAttribute(
222                 "end-date", String.valueOf(context.getEndDate()));
223         }
224 
225         header.addAttribute("type", "portlet");
226         header.addAttribute("group-id", String.valueOf(scopeGroupId));
227         header.addAttribute(
228             "private-layout", String.valueOf(layout.isPrivateLayout()));
229         header.addAttribute(
230             "root-portlet-id", PortletConstants.getRootPortletId(portletId));
231 
232         // Portlet
233 
234         exportPortlet(
235             context, layoutCache, portletId, layout, root, defaultUserId,
236             exportPermissions, exportPortletArchivedSetups, exportPortletData,
237             exportPortletSetup, exportPortletUserPreferences,
238             exportUserPermissions);
239 
240         // Categories
241 
242         if (exportCategories) {
243             exportCategories(context);
244         }
245 
246         // Comments
247 
248         exportComments(context, root);
249 
250         // Locks
251 
252         exportLocks(context, root);
253 
254         // Portlet data permissions
255 
256         if (exportPermissions) {
257             _permissionExporter.exportPortletDataPermissions(context);
258         }
259 
260         // Ratings
261 
262         exportRatings(context, root);
263 
264         // Tags
265 
266         exportTags(context, root);
267 
268         // Log
269 
270         if (_log.isInfoEnabled()) {
271             _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
272         }
273 
274         // Zip
275 
276         try {
277             context.addZipEntry("/manifest.xml", doc.formattedString());
278         }
279         catch (IOException ioe) {
280             throw new SystemException(ioe);
281         }
282 
283         return zipWriter.getFile();
284     }
285 
286     protected void exportCategories(PortletDataContext context)
287         throws SystemException {
288 
289         try {
290             Document doc = SAXReaderUtil.createDocument();
291 
292             Element root = doc.addElement("categories-hierarchy");
293 
294             exportCategories(context, root);
295 
296             context.addZipEntry(
297                 context.getRootPath() + "/categories-hierarchy.xml",
298                 doc.formattedString());
299         }
300         catch (Exception e) {
301             throw new SystemException(e);
302         }
303     }
304 
305     protected void exportCategories(PortletDataContext context, Element root)
306         throws SystemException {
307 
308         try {
309             Element vocabulariesEl = root.element("vocabularies");
310 
311             if (vocabulariesEl == null) {
312                 vocabulariesEl = root.addElement("vocabularies");
313             }
314 
315             Element assetsEl = root.addElement("assets");
316 
317             Element categoriesEl = root.addElement("categories");
318 
319             Map<String, String[]> assetCategoryUuidsMap =
320                 context.getAssetCategoryUuidsMap();
321 
322             for (Map.Entry<String, String[]> entry :
323                     assetCategoryUuidsMap.entrySet()) {
324 
325                 String[] categoryEntry = entry.getKey().split(StringPool.POUND);
326 
327                 String className = categoryEntry[0];
328                 long classPK = GetterUtil.getLong(categoryEntry[1]);
329 
330                 Element asset = assetsEl.addElement("asset");
331 
332                 asset.addAttribute("class-name", className);
333                 asset.addAttribute("class-pk", String.valueOf(classPK));
334                 asset.addAttribute(
335                     "category-uuids", StringUtil.merge(entry.getValue()));
336 
337                 List<AssetCategory> assetCategories =
338                     AssetCategoryServiceUtil.getCategories(className, classPK);
339 
340                 for (AssetCategory assestCategory : assetCategories) {
341                     exportCategory(
342                         context, vocabulariesEl, categoriesEl, assestCategory);
343                 }
344             }
345         }
346         catch (Exception e) {
347             throw new SystemException(e);
348         }
349     }
350 
351     protected void exportCategory(
352             PortletDataContext context, Element vocabulariesEl,
353             Element categoryEls, long assetCategoryId)
354         throws Exception {
355 
356         AssetCategory assetCategory = AssetCategoryUtil.fetchByPrimaryKey(
357             assetCategoryId);
358 
359         if (assetCategory != null) {
360             exportCategory(context, vocabulariesEl, categoryEls, assetCategory);
361         }
362     }
363 
364     protected void exportCategory(
365             PortletDataContext context, Element vocabulariesEl,
366             Element categoriesEl, AssetCategory assetCategory)
367         throws Exception {
368 
369         exportVocabulary(
370             context, vocabulariesEl, assetCategory.getVocabularyId());
371 
372         if (assetCategory.getParentCategoryId() !=
373                 AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
374 
375             exportCategory(
376                 context, vocabulariesEl, categoriesEl,
377                 assetCategory.getParentCategoryId());
378         }
379 
380         String path = getCategoryPath(context, assetCategory.getCategoryId());
381 
382         if (!context.isPathNotProcessed(path)) {
383             return;
384         }
385 
386         Element categoryEl = categoriesEl.addElement("category");
387 
388         categoryEl.addAttribute("path", path);
389 
390         assetCategory.setUserUuid(assetCategory.getUserUuid());
391 
392         context.addZipEntry(path, assetCategory);
393 
394         List<AssetCategoryProperty> assetCategoryProperties =
395             AssetCategoryPropertyLocalServiceUtil.getCategoryProperties(
396                 assetCategory.getCategoryId());
397 
398         for (AssetCategoryProperty assetCategoryProperty :
399                 assetCategoryProperties) {
400 
401             Element propertyEl = categoryEl.addElement("property");
402 
403             propertyEl.addAttribute(
404                 "userUuid", assetCategoryProperty.getUserUuid());
405             propertyEl.addAttribute("key", assetCategoryProperty.getKey());
406             propertyEl.addAttribute("value", assetCategoryProperty.getValue());
407         }
408 
409         context.addPermissions(
410             AssetCategory.class, assetCategory.getCategoryId());
411     }
412 
413     protected void exportComments(PortletDataContext context, Element parentEl)
414         throws SystemException {
415 
416         try {
417             Document doc = SAXReaderUtil.createDocument();
418 
419             Element root = doc.addElement("comments");
420 
421             Map<String, List<MBMessage>> commentsMap = context.getComments();
422 
423             for (Map.Entry<String, List<MBMessage>> entry :
424                     commentsMap.entrySet()) {
425 
426                 String[] comment = entry.getKey().split(StringPool.POUND);
427 
428                 String path = getCommentsPath(context, comment[0], comment[1]);
429 
430                 Element asset = root.addElement("asset");
431 
432                 asset.addAttribute("path", path);
433                 asset.addAttribute("class-name", comment[0]);
434                 asset.addAttribute("class-pk", comment[1]);
435 
436                 List<MBMessage> messages = entry.getValue();
437 
438                 for (MBMessage message : messages) {
439                     path = getCommentsPath(
440                         context, comment[0], comment[1], message);
441 
442                     if (context.isPathNotProcessed(path)) {
443                         context.addZipEntry(path, message);
444                     }
445                 }
446             }
447 
448             context.addZipEntry(
449                 context.getRootPath() + "/comments.xml", doc.formattedString());
450         }
451         catch (IOException ioe) {
452             throw new SystemException(ioe);
453         }
454     }
455 
456     protected void exportLocks(PortletDataContext context, Element parentEl)
457         throws SystemException {
458 
459         try {
460             Document doc = SAXReaderUtil.createDocument();
461 
462             Element root = doc.addElement("locks");
463 
464             Map<String, Lock> locksMap = context.getLocks();
465 
466             for (Map.Entry<String, Lock> entry : locksMap.entrySet()) {
467                 Lock lock = entry.getValue();
468 
469                 String entryKey = entry.getKey();
470 
471                 int index = entryKey.indexOf(StringPool.POUND);
472 
473                 String className = entryKey.substring(0, index);
474                 String key = entryKey.substring(index + 1);
475                 String path = getLocksPath(context, className, key, lock);
476 
477                 Element asset = root.addElement("asset");
478 
479                 asset.addAttribute("class-name", className);
480                 asset.addAttribute("key", key);
481                 asset.addAttribute("path", path);
482 
483                 if (context.isPathNotProcessed(path)) {
484                     context.addZipEntry(path, lock);
485                 }
486             }
487 
488             context.addZipEntry(
489                 context.getRootPath() + "/locks.xml", doc.formattedString());
490         }
491         catch (IOException ioe) {
492             throw new SystemException(ioe);
493         }
494     }
495 
496     protected void exportPortlet(
497             PortletDataContext context, LayoutCache layoutCache,
498             String portletId, Layout layout, Element parentEl,
499             long defaultUserId, boolean exportPermissions,
500             boolean exportPortletArchivedSetups, boolean exportPortletData,
501             boolean exportPortletSetup, boolean exportPortletUserPreferences,
502             boolean exportUserPermissions)
503         throws PortalException, SystemException {
504 
505         long companyId = context.getCompanyId();
506         long groupId = context.getGroupId();
507 
508         Portlet portlet = PortletLocalServiceUtil.getPortletById(
509             context.getCompanyId(), portletId);
510 
511         if (portlet == null) {
512             if (_log.isDebugEnabled()) {
513                 _log.debug(
514                     "Do not export portlet " + portletId +
515                         " because the portlet does not exist");
516             }
517 
518             return;
519         }
520 
521         if ((!portlet.isInstanceable()) &&
522             (!portlet.isPreferencesUniquePerLayout()) &&
523             (context.hasNotUniquePerLayout(portletId))) {
524 
525             return;
526         }
527 
528         Document doc = SAXReaderUtil.createDocument();
529 
530         Element portletEl = doc.addElement("portlet");
531 
532         portletEl.addAttribute("portlet-id", portletId);
533         portletEl.addAttribute(
534             "root-portlet-id", PortletConstants.getRootPortletId(portletId));
535         portletEl.addAttribute("old-plid", String.valueOf(layout.getPlid()));
536         portletEl.addAttribute(
537             "scope-layout-id", String.valueOf(context.getScopeLayoutId()));
538 
539         // Data
540 
541         javax.portlet.PortletPreferences jxPreferences =
542             PortletPreferencesFactoryUtil.getPortletSetup(
543                 layout, portletId, StringPool.BLANK);
544 
545         if (exportPortletData) {
546             if (!portlet.isPreferencesUniquePerLayout()) {
547                 String dataKey =
548                     portletId + StringPool.AT + context.getScopeLayoutId();
549 
550                 if (!context.hasNotUniquePerLayout(dataKey)) {
551                     context.putNotUniquePerLayout(dataKey);
552 
553                     exportPortletData(
554                         context, portlet, layout, jxPreferences, portletEl);
555                 }
556             }
557             else {
558                 exportPortletData(
559                     context, portlet, layout, jxPreferences, portletEl);
560             }
561         }
562 
563         // Portlet preferences
564 
565         if (exportPortletSetup) {
566             exportPortletPreferences(
567                 context, PortletKeys.PREFS_OWNER_ID_DEFAULT,
568                 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, portletId,
569                 portletEl);
570 
571             exportPortletPreferences(
572                 context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
573                 layout, portletId, portletEl);
574 
575             exportPortletPreferences(
576                 context, companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY, false,
577                 layout, portletId, portletEl);
578         }
579 
580         // Portlet preferences
581 
582         if (exportPortletUserPreferences) {
583             exportPortletPreferences(
584                 context, defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
585                 true, layout, portletId, portletEl);
586 
587             try {
588                 PortletPreferences groupPortletPreferences =
589                     PortletPreferencesLocalServiceUtil.getPortletPreferences(
590                         groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
591                         PortletKeys.PREFS_PLID_SHARED, portletId);
592 
593                 exportPortletPreference(
594                     context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
595                     groupPortletPreferences, portletId,
596                     PortletKeys.PREFS_PLID_SHARED, portletEl);
597             }
598             catch (NoSuchPortletPreferencesException nsppe) {
599             }
600         }
601 
602         // Archived setups
603 
604         if (exportPortletArchivedSetups) {
605             String rootPortletId = PortletConstants.getRootPortletId(portletId);
606 
607             List<PortletItem> portletItems =
608                 PortletItemLocalServiceUtil.getPortletItems(
609                     groupId, rootPortletId, PortletPreferences.class.getName());
610 
611             for (PortletItem portletItem: portletItems) {
612                 long ownerId = portletItem.getPortletItemId();
613                 int ownerType = PortletKeys.PREFS_OWNER_TYPE_ARCHIVED;
614 
615                 exportPortletPreferences(
616                     context, ownerId, ownerType, false, null,
617                     portletItem.getPortletId(), portletEl);
618             }
619         }
620 
621         // Permissions
622 
623         if (exportPermissions) {
624             _permissionExporter.exportPortletPermissions(
625                 context, layoutCache, portletId, layout, portletEl);
626         }
627 
628         // Zip
629 
630         StringBundler sb = new StringBundler(4);
631 
632         sb.append(context.getPortletPath(portletId));
633         sb.append(StringPool.SLASH);
634         sb.append(layout.getPlid());
635         sb.append("/portlet.xml");
636 
637         String path = sb.toString();
638 
639         Element el = parentEl.addElement("portlet");
640 
641         el.addAttribute("portlet-id", portletId);
642         el.addAttribute("layout-id", String.valueOf(layout.getLayoutId()));
643         el.addAttribute("path", path);
644 
645         if (context.isPathNotProcessed(path)) {
646             try {
647                 context.addZipEntry(path, doc.formattedString());
648             }
649             catch (IOException ioe) {
650                 if (_log.isWarnEnabled()) {
651                     _log.warn(ioe.getMessage());
652                 }
653             }
654 
655             context.addPrimaryKey(String.class, path);
656         }
657     }
658 
659     protected void exportPortletData(
660             PortletDataContext context, Portlet portlet, Layout layout,
661             javax.portlet.PortletPreferences portletPreferences,
662             Element parentEl)
663         throws SystemException {
664 
665         PortletDataHandler portletDataHandler =
666             portlet.getPortletDataHandlerInstance();
667 
668         if (portletDataHandler == null) {
669             return;
670         }
671 
672         String portletId = portlet.getPortletId();
673 
674         if (_log.isDebugEnabled()) {
675             _log.debug("Exporting data for " + portletId);
676         }
677 
678         String data = null;
679 
680         long groupId = context.getGroupId();
681 
682         context.setGroupId(context.getScopeGroupId());
683 
684         try {
685             data = portletDataHandler.exportData(
686                 context, portletId, portletPreferences);
687         }
688         catch (Exception e) {
689             throw new SystemException(e);
690         }
691         finally {
692             context.setGroupId(groupId);
693         }
694 
695         if (Validator.isNull(data)) {
696             if (_log.isDebugEnabled()) {
697                 _log.debug(
698                     "Not exporting data for " + portletId +
699                         " because null data was returned");
700             }
701 
702             return;
703         }
704 
705         StringBundler sb = new StringBundler(4);
706 
707         sb.append(context.getPortletPath(portletId));
708 
709         if (portlet.isPreferencesUniquePerLayout()) {
710             sb.append(StringPool.SLASH);
711             sb.append(layout.getPlid());
712         }
713 
714         sb.append("/portlet-data.xml");
715 
716         Element portletDataEl = parentEl.addElement("portlet-data");
717 
718         portletDataEl.addAttribute("path", sb.toString());
719 
720         context.addZipEntry(sb.toString(), data);
721     }
722 
723     protected void exportPortletPreference(
724             PortletDataContext context, long ownerId, int ownerType,
725             boolean defaultUser, PortletPreferences portletPreferences,
726             String portletId, long plid, Element parentEl)
727         throws SystemException {
728 
729         try {
730             Document preferencesDoc = SAXReaderUtil.read(
731                 portletPreferences.getPreferences());
732 
733             Element root = preferencesDoc.getRootElement();
734 
735             root.addAttribute("owner-id", String.valueOf(ownerId));
736             root.addAttribute("owner-type", String.valueOf(ownerType));
737             root.addAttribute("default-user", String.valueOf(defaultUser));
738             root.addAttribute("plid", String.valueOf(plid));
739             root.addAttribute("portlet-id", portletId);
740 
741             if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
742                 PortletItem portletItem =
743                     PortletItemLocalServiceUtil.getPortletItem(ownerId);
744 
745                 User user = UserLocalServiceUtil.getUserById(
746                     portletItem.getUserId());
747 
748                 root.addAttribute("archive-user-uuid", user.getUuid());
749                 root.addAttribute("archive-name", portletItem.getName());
750             }
751 
752             String path = getPortletPreferencesPath(
753                 context, portletId, ownerId, ownerType, plid);
754 
755             parentEl.addElement(
756                 "portlet-preferences").addAttribute("path", path);
757 
758             if (context.isPathNotProcessed(path)) {
759                 context.addZipEntry(path, preferencesDoc.formattedString());
760             }
761         }
762         catch (Exception e) {
763             throw new SystemException(e);
764         }
765     }
766 
767     protected void exportPortletPreferences(
768             PortletDataContext context, long ownerId, int ownerType,
769             boolean defaultUser, Layout layout, String portletId,
770             Element parentEl)
771         throws PortalException, SystemException {
772 
773         PortletPreferences portletPreferences = null;
774 
775         long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
776 
777         if (layout != null) {
778             plid = layout.getPlid();
779         }
780 
781         if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
782             (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
783             (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
784 
785             plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
786         }
787 
788         try {
789             portletPreferences =
790                 PortletPreferencesLocalServiceUtil.getPortletPreferences(
791                     ownerId, ownerType, plid, portletId);
792 
793             LayoutTypePortlet layoutTypePortlet = null;
794 
795             if (layout != null) {
796                 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
797             }
798 
799             if ((layoutTypePortlet == null) ||
800                 (layoutTypePortlet.hasPortletId(portletId))) {
801 
802                 exportPortletPreference(
803                     context, ownerId, ownerType, defaultUser,
804                     portletPreferences, portletId, plid, parentEl);
805             }
806         }
807         catch (NoSuchPortletPreferencesException nsppe) {
808         }
809     }
810 
811     protected void exportRatings(PortletDataContext context, Element parentEl)
812         throws SystemException {
813 
814         try {
815             Document doc = SAXReaderUtil.createDocument();
816 
817             Element root = doc.addElement("ratings");
818 
819             Map<String, List<RatingsEntry>> ratingsEntriesMap =
820                 context.getRatingsEntries();
821 
822             for (Map.Entry<String, List<RatingsEntry>> entry :
823                     ratingsEntriesMap.entrySet()) {
824 
825                 String[] ratingsEntry = entry.getKey().split(StringPool.POUND);
826 
827                 String ratingPath = getRatingsPath(
828                     context, ratingsEntry[0], ratingsEntry[1]);
829 
830                 Element asset = root.addElement("asset");
831 
832                 asset.addAttribute("path", ratingPath);
833                 asset.addAttribute("class-name", ratingsEntry[0]);
834                 asset.addAttribute("class-pk", ratingsEntry[1]);
835 
836                 List<RatingsEntry> ratingsEntries = entry.getValue();
837 
838                 for (RatingsEntry rating : ratingsEntries) {
839                     ratingPath = getRatingsPath(
840                         context, ratingsEntry[0], ratingsEntry[1], rating);
841 
842                     context.addZipEntry(ratingPath, rating);
843                 }
844             }
845 
846             context.addZipEntry(
847                 context.getRootPath() + "/ratings.xml", doc.formattedString());
848         }
849         catch (Exception e) {
850             throw new SystemException(e);
851         }
852     }
853 
854     protected void exportTags(PortletDataContext context, Element parentEl)
855         throws SystemException {
856 
857         try {
858             Document doc = SAXReaderUtil.createDocument();
859 
860             Element root = doc.addElement("tags");
861 
862             Map<String, String[]> assetTagNamesMap =
863                 context.getAssetTagNamesMap();
864 
865             for (Map.Entry<String, String[]> entry :
866                     assetTagNamesMap.entrySet()) {
867 
868                 String[] tagsEntry = entry.getKey().split(StringPool.POUND);
869 
870                 Element asset = root.addElement("asset");
871 
872                 asset.addAttribute("class-name", tagsEntry[0]);
873                 asset.addAttribute("class-pk", tagsEntry[1]);
874                 asset.addAttribute("tags", StringUtil.merge(entry.getValue()));
875             }
876 
877             context.addZipEntry(
878                 context.getRootPath() + "/tags.xml", doc.formattedString());
879         }
880         catch (Exception e) {
881             throw new SystemException(e);
882         }
883     }
884 
885     protected void exportVocabulary(
886             PortletDataContext context, Element vocabulariesEl,
887             long assetVocabularyId)
888         throws Exception {
889 
890         AssetVocabulary assetVocabulary = AssetVocabularyUtil.findByPrimaryKey(
891             assetVocabularyId);
892 
893         exportVocabulary(context, vocabulariesEl, assetVocabulary);
894     }
895 
896     protected void exportVocabulary(
897             PortletDataContext context, Element vocabulariesEl,
898             AssetVocabulary assetVocabulary)
899         throws Exception {
900 
901         String path = getVocabulariesPath(
902             context, assetVocabulary.getVocabularyId());
903 
904         if (!context.isPathNotProcessed(path)) {
905             return;
906         }
907 
908         Element vocabularyEl = vocabulariesEl.addElement("vocabulary");
909 
910         vocabularyEl.addAttribute("path", path);
911 
912         assetVocabulary.setUserUuid(assetVocabulary.getUserUuid());
913 
914         context.addZipEntry(path, assetVocabulary);
915 
916         context.addPermissions(
917             AssetVocabulary.class, assetVocabulary.getVocabularyId());
918     }
919 
920     protected String getCategoryPath(
921         PortletDataContext context, long assetCategoryId) {
922 
923         StringBundler sb = new StringBundler(6);
924 
925         sb.append(context.getRootPath());
926         sb.append("/categories/");
927         sb.append(assetCategoryId);
928         sb.append(".xml");
929 
930         return sb.toString();
931     }
932 
933     protected String getCommentsPath(
934         PortletDataContext context, String className, String classPK) {
935 
936         StringBundler sb = new StringBundler(6);
937 
938         sb.append(context.getRootPath());
939         sb.append("/comments/");
940         sb.append(PortalUtil.getClassNameId(className));
941         sb.append(CharPool.FORWARD_SLASH);
942         sb.append(classPK);
943         sb.append(CharPool.FORWARD_SLASH);
944 
945         return sb.toString();
946     }
947 
948     protected String getCommentsPath(
949         PortletDataContext context, String className, String classPK,
950         MBMessage message) {
951 
952         StringBundler sb = new StringBundler(8);
953 
954         sb.append(context.getRootPath());
955         sb.append("/comments/");
956         sb.append(PortalUtil.getClassNameId(className));
957         sb.append(CharPool.FORWARD_SLASH);
958         sb.append(classPK);
959         sb.append(CharPool.FORWARD_SLASH);
960         sb.append(message.getMessageId());
961         sb.append(".xml");
962 
963         return sb.toString();
964     }
965 
966     protected String getLocksPath(
967         PortletDataContext context, String className, String key, Lock lock) {
968 
969         StringBundler sb = new StringBundler(8);
970 
971         sb.append(context.getRootPath());
972         sb.append("/locks/");
973         sb.append(PortalUtil.getClassNameId(className));
974         sb.append(CharPool.FORWARD_SLASH);
975         sb.append(key);
976         sb.append(CharPool.FORWARD_SLASH);
977         sb.append(lock.getLockId());
978         sb.append(".xml");
979 
980         return sb.toString();
981     }
982 
983     protected String getPortletDataPath(
984         PortletDataContext context, String portletId) {
985 
986         return context.getPortletPath(portletId) + "/portlet-data.xml";
987     }
988 
989     protected String getPortletPreferencesPath(
990         PortletDataContext context, String portletId, long ownerId,
991         int ownerType, long plid) {
992 
993         StringBundler sb = new StringBundler(8);
994 
995         sb.append(context.getPortletPath(portletId));
996         sb.append("/preferences/");
997 
998         if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
999             sb.append("company/");
1000        }
1001        else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1002            sb.append("group/");
1003        }
1004        else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
1005            sb.append("layout/");
1006        }
1007        else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1008            sb.append("user/");
1009        }
1010        else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1011            sb.append("archived/");
1012        }
1013
1014        sb.append(ownerId);
1015        sb.append(CharPool.FORWARD_SLASH);
1016        sb.append(plid);
1017        sb.append(CharPool.FORWARD_SLASH);
1018        sb.append("portlet-preferences.xml");
1019
1020        return sb.toString();
1021    }
1022
1023    protected String getRatingsPath(
1024        PortletDataContext context, String className, String classPK) {
1025
1026        StringBundler sb = new StringBundler(6);
1027
1028        sb.append(context.getRootPath());
1029        sb.append("/ratings/");
1030        sb.append(PortalUtil.getClassNameId(className));
1031        sb.append(CharPool.FORWARD_SLASH);
1032        sb.append(classPK);
1033        sb.append(CharPool.FORWARD_SLASH);
1034
1035        return sb.toString();
1036    }
1037
1038    protected String getRatingsPath(
1039        PortletDataContext context, String className, String classPK,
1040        RatingsEntry ratingsEntry) {
1041
1042        StringBundler sb = new StringBundler(8);
1043
1044        sb.append(context.getRootPath());
1045        sb.append("/ratings/");
1046        sb.append(PortalUtil.getClassNameId(className));
1047        sb.append(CharPool.FORWARD_SLASH);
1048        sb.append(classPK);
1049        sb.append(CharPool.FORWARD_SLASH);
1050        sb.append(ratingsEntry.getEntryId());
1051        sb.append(".xml");
1052
1053        return sb.toString();
1054    }
1055
1056    protected String getVocabulariesPath(
1057        PortletDataContext context, long assetVocabularyId) {
1058
1059        StringBundler sb = new StringBundler(8);
1060
1061        sb.append(context.getRootPath());
1062        sb.append("/vocabularies/");
1063        sb.append(assetVocabularyId);
1064        sb.append(".xml");
1065
1066        return sb.toString();
1067    }
1068
1069    private static Log _log = LogFactoryUtil.getLog(PortletExporter.class);
1070
1071    private PermissionExporter _permissionExporter = new PermissionExporter();
1072
1073}