1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
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.PortalException;
20  import com.liferay.portal.SystemException;
21  import com.liferay.portal.kernel.log.Log;
22  import com.liferay.portal.kernel.log.LogFactoryUtil;
23  import com.liferay.portal.kernel.util.CharPool;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.MapUtil;
27  import com.liferay.portal.kernel.util.ReleaseInfo;
28  import com.liferay.portal.kernel.util.StringBundler;
29  import com.liferay.portal.kernel.util.StringPool;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Time;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.kernel.xml.Document;
34  import com.liferay.portal.kernel.xml.Element;
35  import com.liferay.portal.kernel.xml.SAXReaderUtil;
36  import com.liferay.portal.kernel.zip.ZipWriter;
37  import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
38  import com.liferay.portal.model.Group;
39  import com.liferay.portal.model.Layout;
40  import com.liferay.portal.model.LayoutTypePortlet;
41  import com.liferay.portal.model.Portlet;
42  import com.liferay.portal.model.PortletConstants;
43  import com.liferay.portal.model.PortletItem;
44  import com.liferay.portal.model.PortletPreferences;
45  import com.liferay.portal.model.User;
46  import com.liferay.portal.service.LayoutLocalServiceUtil;
47  import com.liferay.portal.service.PortletItemLocalServiceUtil;
48  import com.liferay.portal.service.PortletLocalServiceUtil;
49  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
50  import com.liferay.portal.service.UserLocalServiceUtil;
51  import com.liferay.portal.util.PortalUtil;
52  import com.liferay.portal.util.PortletKeys;
53  import com.liferay.portlet.PortletPreferencesFactoryUtil;
54  import com.liferay.portlet.messageboards.model.MBMessage;
55  import com.liferay.portlet.ratings.model.RatingsEntry;
56  
57  import java.io.File;
58  import java.io.IOException;
59  
60  import java.util.Date;
61  import java.util.HashSet;
62  import java.util.List;
63  import java.util.Map;
64  import java.util.Set;
65  
66  import org.apache.commons.lang.time.StopWatch;
67  
68  /**
69   * <a href="PortletExporter.java.html"><b><i>View Source</i></b></a>
70   *
71   * @author Brian Wing Shun Chan
72   * @author Joel Kozikowski
73   * @author Charles May
74   * @author Raymond Augé
75   * @author Jorge Ferrer
76   * @author Bruno Farache
77   * @author Zsigmond Rab
78   * @author Douglas Wong
79   */
80  public class PortletExporter {
81  
82      public byte[] exportPortletInfo(
83              long plid, long groupId, String portletId,
84              Map<String, String[]> parameterMap, Date startDate, Date endDate)
85          throws PortalException, SystemException {
86  
87          File file = exportPortletInfoAsFile(
88              plid, groupId, portletId, parameterMap, startDate, endDate);
89  
90          try {
91              return FileUtil.getBytes(file);
92          }
93          catch (IOException ioe) {
94              throw new SystemException(ioe);
95          }
96          finally {
97              file.delete();
98          }
99      }
100 
101     public File exportPortletInfoAsFile(
102             long plid, long groupId, String portletId,
103             Map<String, String[]> parameterMap, Date startDate, Date endDate)
104         throws PortalException, SystemException {
105 
106         boolean exportPermissions = MapUtil.getBoolean(
107             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
108         boolean exportPortletArchivedSetups = MapUtil.getBoolean(
109             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
110         boolean exportPortletData = MapUtil.getBoolean(
111             parameterMap, PortletDataHandlerKeys.PORTLET_DATA + "_" +
112             PortletConstants.getRootPortletId(portletId));
113         boolean exportPortletDataAll = MapUtil.getBoolean(
114             parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
115         boolean exportPortletSetup = MapUtil.getBoolean(
116             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
117         boolean exportPortletUserPreferences = MapUtil.getBoolean(
118             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
119         boolean exportUserPermissions = MapUtil.getBoolean(
120             parameterMap, PortletDataHandlerKeys.USER_PERMISSIONS);
121 
122         if (_log.isDebugEnabled()) {
123             _log.debug("Export permissions " + exportPermissions);
124             _log.debug(
125                 "Export portlet archived setups " +
126                     exportPortletArchivedSetups);
127             _log.debug("Export portlet data " + exportPortletData);
128             _log.debug("Export all portlet data " + exportPortletDataAll);
129             _log.debug("Export portlet setup " + exportPortletSetup);
130             _log.debug(
131                 "Export portlet user preferences " +
132                     exportPortletUserPreferences);
133             _log.debug("Export user permissions " + exportUserPermissions);
134         }
135 
136         if (exportPortletDataAll) {
137             exportPortletData = true;
138         }
139 
140         StopWatch stopWatch = null;
141 
142         if (_log.isInfoEnabled()) {
143             stopWatch = new StopWatch();
144 
145             stopWatch.start();
146         }
147 
148         LayoutCache layoutCache = new LayoutCache();
149 
150         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
151 
152         if (!layout.isTypeControlPanel() && !layout.isTypePanel() &&
153             !layout.isTypePortlet()) {
154 
155             throw new LayoutImportException(
156                 "Layout type " + layout.getType() + " is not valid");
157         }
158 
159         long companyId = layout.getCompanyId();
160         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
161 
162         ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
163 
164         long scopeGroupId = groupId;
165 
166         javax.portlet.PortletPreferences jxPreferences =
167             PortletPreferencesFactoryUtil.getLayoutPortletSetup(
168                 layout, portletId);
169 
170         long scopeLayoutId = GetterUtil.getLong(
171             jxPreferences.getValue("lfr-scope-layout-id", null));
172 
173         if (scopeLayoutId != 0) {
174             Group scopeGroup = layout.getScopeGroup();
175 
176             if (scopeGroup != null) {
177                 scopeGroupId = scopeGroup.getGroupId();
178             }
179         }
180 
181         PortletDataContext context = new PortletDataContextImpl(
182             companyId, scopeGroupId, parameterMap, new HashSet<String>(),
183             startDate, endDate, zipWriter);
184 
185         context.setPlid(plid);
186         context.setOldPlid(plid);
187         context.setScopeLayoutId(scopeLayoutId);
188 
189         // Build compatibility
190 
191         Document doc = SAXReaderUtil.createDocument();
192 
193         Element root = doc.addElement("root");
194 
195         Element header = root.addElement("header");
196 
197         header.addAttribute(
198             "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
199         header.addAttribute("export-date", Time.getRFC822());
200 
201         if (context.hasDateRange()) {
202             header.addAttribute(
203                 "start-date", String.valueOf(context.getStartDate()));
204             header.addAttribute(
205                 "end-date", String.valueOf(context.getEndDate()));
206         }
207 
208         header.addAttribute("type", "portlet");
209         header.addAttribute("group-id", String.valueOf(scopeGroupId));
210         header.addAttribute(
211             "private-layout", String.valueOf(layout.isPrivateLayout()));
212         header.addAttribute(
213             "root-portlet-id", PortletConstants.getRootPortletId(portletId));
214 
215         // Portlet
216 
217         exportPortlet(
218             context, layoutCache, portletId, layout, root, defaultUserId,
219             exportPermissions, exportPortletArchivedSetups, exportPortletData,
220             exportPortletSetup, exportPortletUserPreferences,
221             exportUserPermissions);
222 
223         // Categories
224 
225         exportCategories(context, root);
226 
227         // Comments
228 
229         exportComments(context, root);
230 
231         // Portlet data permissions
232 
233         if (exportPermissions) {
234             _permissionExporter.exportPortletDataPermissions(context);
235         }
236 
237         // Ratings
238 
239         exportRatings(context, root);
240 
241         // Tags
242 
243         exportTags(context, root);
244 
245         // Log
246 
247         if (_log.isInfoEnabled()) {
248             _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
249         }
250 
251         // Zip
252 
253         try {
254             context.addZipEntry("/manifest.xml", doc.formattedString());
255         }
256         catch (IOException ioe) {
257             throw new SystemException(ioe);
258         }
259 
260         return zipWriter.getFile();
261     }
262 
263     protected void exportCategories(
264             PortletDataContext context, Element parentEl)
265         throws SystemException {
266 
267         try {
268             Document doc = SAXReaderUtil.createDocument();
269 
270             Element root = doc.addElement("categories");
271 
272             Set<Map.Entry<String, String[]>> categoriesEntries =
273                 context.getTagsCategories().entrySet();
274 
275             for (Map.Entry<String, String[]> entry : categoriesEntries) {
276                 String[] categoryEntry = entry.getKey().split(StringPool.POUND);
277 
278                 Element asset = root.addElement("asset");
279 
280                 asset.addAttribute("class-name", categoryEntry[0]);
281                 asset.addAttribute("class-pk", categoryEntry[1]);
282                 asset.addAttribute(
283                     "entries", StringUtil.merge(entry.getValue()));
284             }
285 
286             context.addZipEntry(
287                 context.getRootPath() + "/categories.xml",
288                 doc.formattedString());
289         }
290         catch (Exception e) {
291             throw new SystemException(e);
292         }
293     }
294 
295     protected void exportComments(PortletDataContext context, Element parentEl)
296         throws SystemException {
297 
298         try {
299             Document doc = SAXReaderUtil.createDocument();
300 
301             Element root = doc.addElement("comments");
302 
303             Map<String, List<MBMessage>> commentsMap = context.getComments();
304 
305             for (Map.Entry<String, List<MBMessage>> entry :
306                     commentsMap.entrySet()) {
307 
308                 String[] comment = entry.getKey().split(StringPool.POUND);
309 
310                 String path = getCommentsPath(context, comment[0], comment[1]);
311 
312                 Element asset = root.addElement("asset");
313 
314                 asset.addAttribute("path", path);
315                 asset.addAttribute("class-name", comment[0]);
316                 asset.addAttribute("class-pk", comment[1]);
317 
318                 List<MBMessage> messages = entry.getValue();
319 
320                 for (MBMessage message : messages) {
321                     path = getCommentsPath(
322                         context, comment[0], comment[1], message);
323 
324                     if (context.isPathNotProcessed(path)) {
325                         context.addZipEntry(path, message);
326                     }
327                 }
328             }
329 
330             context.addZipEntry(
331                 context.getRootPath() + "/comments.xml", doc.formattedString());
332         }
333         catch (IOException ioe) {
334             throw new SystemException(ioe);
335         }
336     }
337 
338     protected void exportPortlet(
339             PortletDataContext context, LayoutCache layoutCache,
340             String portletId, Layout layout, Element parentEl,
341             long defaultUserId, boolean exportPermissions,
342             boolean exportPortletArchivedSetups, boolean exportPortletData,
343             boolean exportPortletSetup, boolean exportPortletUserPreferences,
344             boolean exportUserPermissions)
345         throws PortalException, SystemException {
346 
347         long companyId = context.getCompanyId();
348         long groupId = context.getGroupId();
349 
350         Portlet portlet = PortletLocalServiceUtil.getPortletById(
351             context.getCompanyId(), portletId);
352 
353         if (portlet == null) {
354             if (_log.isDebugEnabled()) {
355                 _log.debug(
356                     "Do not export portlet " + portletId +
357                         " because the portlet does not exist");
358             }
359 
360             return;
361         }
362 
363         if ((!portlet.isInstanceable()) &&
364             (!portlet.isPreferencesUniquePerLayout()) &&
365             (context.hasNotUniquePerLayout(portletId))) {
366 
367             return;
368         }
369 
370         Document doc = SAXReaderUtil.createDocument();
371 
372         Element portletEl = doc.addElement("portlet");
373 
374         portletEl.addAttribute("portlet-id", portletId);
375         portletEl.addAttribute(
376             "root-portlet-id", PortletConstants.getRootPortletId(portletId));
377         portletEl.addAttribute("old-plid", String.valueOf(layout.getPlid()));
378         portletEl.addAttribute(
379             "scope-layout-id", String.valueOf(context.getScopeLayoutId()));
380 
381         // Data
382 
383         javax.portlet.PortletPreferences jxPreferences =
384             PortletPreferencesFactoryUtil.getPortletSetup(
385                 layout, portletId, StringPool.BLANK);
386 
387         if (exportPortletData) {
388             if (!portlet.isPreferencesUniquePerLayout()) {
389                 String dataKey =
390                     portletId + StringPool.AT + context.getScopeLayoutId();
391 
392                 if (!context.hasNotUniquePerLayout(dataKey)) {
393                     context.putNotUniquePerLayout(dataKey);
394 
395                     exportPortletData(
396                         context, portlet, layout, jxPreferences, portletEl);
397                 }
398             }
399             else {
400                 exportPortletData(
401                     context, portlet, layout, jxPreferences, portletEl);
402             }
403         }
404 
405         // Portlet preferences
406 
407         if (exportPortletSetup) {
408             exportPortletPreferences(
409                 context, PortletKeys.PREFS_OWNER_ID_DEFAULT,
410                 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, portletId,
411                 portletEl);
412 
413             exportPortletPreferences(
414                 context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
415                 layout, portletId, portletEl);
416 
417             exportPortletPreferences(
418                 context, companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY, false,
419                 layout, portletId, portletEl);
420         }
421 
422         // Portlet preferences
423 
424         if (exportPortletUserPreferences) {
425             exportPortletPreferences(
426                 context, defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
427                 true, layout, portletId, portletEl);
428 
429             try {
430                 PortletPreferences groupPortletPreferences =
431                     PortletPreferencesLocalServiceUtil.getPortletPreferences(
432                         groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
433                         PortletKeys.PREFS_PLID_SHARED, portletId);
434 
435                 exportPortletPreference(
436                     context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
437                     groupPortletPreferences, portletId,
438                     PortletKeys.PREFS_PLID_SHARED, portletEl);
439             }
440             catch (NoSuchPortletPreferencesException nsppe) {
441             }
442         }
443 
444         // Archived setups
445 
446         if (exportPortletArchivedSetups) {
447             String rootPortletId = PortletConstants.getRootPortletId(portletId);
448 
449             List<PortletItem> portletItems =
450                 PortletItemLocalServiceUtil.getPortletItems(
451                     groupId, rootPortletId, PortletPreferences.class.getName());
452 
453             for (PortletItem portletItem: portletItems) {
454                 long ownerId = portletItem.getPortletItemId();
455                 int ownerType = PortletKeys.PREFS_OWNER_TYPE_ARCHIVED;
456 
457                 exportPortletPreferences(
458                     context, ownerId, ownerType, false, null,
459                     portletItem.getPortletId(), portletEl);
460             }
461         }
462 
463         // Permissions
464 
465         if (exportPermissions) {
466             _permissionExporter.exportPortletPermissions(
467                 context, layoutCache, portletId, layout, portletEl);
468         }
469 
470         // Zip
471 
472         StringBundler sb = new StringBundler(4);
473 
474         sb.append(context.getPortletPath(portletId));
475         sb.append(StringPool.SLASH);
476         sb.append(layout.getPlid());
477         sb.append("/portlet.xml");
478 
479         String path = sb.toString();
480 
481         Element el = parentEl.addElement("portlet");
482 
483         el.addAttribute("portlet-id", portletId);
484         el.addAttribute("layout-id", String.valueOf(layout.getLayoutId()));
485         el.addAttribute("path", path);
486 
487         if (context.isPathNotProcessed(path)) {
488             try {
489                 context.addZipEntry(path, doc.formattedString());
490             }
491             catch (IOException ioe) {
492                 if (_log.isWarnEnabled()) {
493                     _log.warn(ioe.getMessage());
494                 }
495             }
496 
497             context.addPrimaryKey(String.class, path);
498         }
499     }
500 
501     protected void exportPortletData(
502             PortletDataContext context, Portlet portlet, Layout layout,
503             javax.portlet.PortletPreferences portletPreferences,
504             Element parentEl)
505         throws SystemException {
506 
507         PortletDataHandler portletDataHandler =
508             portlet.getPortletDataHandlerInstance();
509 
510         if (portletDataHandler == null) {
511             return;
512         }
513 
514         String portletId = portlet.getPortletId();
515 
516         if (_log.isDebugEnabled()) {
517             _log.debug("Exporting data for " + portletId);
518         }
519 
520         String data = null;
521 
522         long groupId = context.getGroupId();
523 
524         context.setGroupId(context.getScopeGroupId());
525 
526         try {
527             data = portletDataHandler.exportData(
528                 context, portletId, portletPreferences);
529         }
530         catch (Exception e) {
531             throw new SystemException(e);
532         }
533         finally {
534             context.setGroupId(groupId);
535         }
536 
537         if (Validator.isNull(data)) {
538             if (_log.isDebugEnabled()) {
539                 _log.debug(
540                     "Not exporting data for " + portletId +
541                         " because null data was returned");
542             }
543 
544             return;
545         }
546 
547         StringBundler sb = new StringBundler(4);
548 
549         sb.append(context.getPortletPath(portletId));
550 
551         if (portlet.isPreferencesUniquePerLayout()) {
552             sb.append(StringPool.SLASH);
553             sb.append(layout.getPlid());
554         }
555 
556         sb.append("/portlet-data.xml");
557 
558         Element portletDataEl = parentEl.addElement("portlet-data");
559 
560         portletDataEl.addAttribute("path", sb.toString());
561 
562         context.addZipEntry(sb.toString(), data);
563     }
564 
565     protected void exportPortletPreference(
566             PortletDataContext context, long ownerId, int ownerType,
567             boolean defaultUser, PortletPreferences portletPreferences,
568             String portletId, long plid, Element parentEl)
569         throws SystemException {
570 
571         try {
572             Document preferencesDoc = SAXReaderUtil.read(
573                 portletPreferences.getPreferences());
574 
575             Element root = preferencesDoc.getRootElement();
576 
577             root.addAttribute("owner-id", String.valueOf(ownerId));
578             root.addAttribute("owner-type", String.valueOf(ownerType));
579             root.addAttribute("default-user", String.valueOf(defaultUser));
580             root.addAttribute("plid", String.valueOf(plid));
581             root.addAttribute("portlet-id", portletId);
582 
583             if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
584                 PortletItem portletItem =
585                     PortletItemLocalServiceUtil.getPortletItem(ownerId);
586 
587                 User user = UserLocalServiceUtil.getUserById(
588                     portletItem.getUserId());
589 
590                 root.addAttribute("archive-user-uuid", user.getUuid());
591                 root.addAttribute("archive-name", portletItem.getName());
592             }
593 
594             String path = getPortletPreferencesPath(
595                 context, portletId, ownerId, ownerType, plid);
596 
597             parentEl.addElement(
598                 "portlet-preferences").addAttribute("path", path);
599 
600             if (context.isPathNotProcessed(path)) {
601                 context.addZipEntry(path, preferencesDoc.formattedString());
602             }
603         }
604         catch (Exception e) {
605             throw new SystemException(e);
606         }
607     }
608 
609     protected void exportPortletPreferences(
610             PortletDataContext context, long ownerId, int ownerType,
611             boolean defaultUser, Layout layout, String portletId,
612             Element parentEl)
613         throws PortalException, SystemException {
614 
615         PortletPreferences portletPreferences = null;
616 
617         long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
618 
619         if (layout != null) {
620             plid = layout.getPlid();
621         }
622 
623         if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
624             (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
625             (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
626 
627             plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
628         }
629 
630         try {
631             portletPreferences =
632                 PortletPreferencesLocalServiceUtil.getPortletPreferences(
633                     ownerId, ownerType, plid, portletId);
634 
635             LayoutTypePortlet layoutTypePortlet = null;
636 
637             if (layout != null) {
638                 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
639             }
640 
641             if ((layoutTypePortlet == null) ||
642                 (layoutTypePortlet.hasPortletId(portletId))) {
643 
644                 exportPortletPreference(
645                     context, ownerId, ownerType, defaultUser,
646                     portletPreferences, portletId, plid, parentEl);
647             }
648         }
649         catch (NoSuchPortletPreferencesException nsppe) {
650         }
651     }
652 
653     protected void exportRatings(PortletDataContext context, Element parentEl)
654         throws SystemException {
655 
656         try {
657             Document doc = SAXReaderUtil.createDocument();
658 
659             Element root = doc.addElement("ratings");
660 
661             Map<String, List<RatingsEntry>> ratingsEntriesMap =
662                 context.getRatingsEntries();
663 
664             for (Map.Entry<String, List<RatingsEntry>> entry :
665                     ratingsEntriesMap.entrySet()) {
666 
667                 String[] ratingsEntry = entry.getKey().split(StringPool.POUND);
668 
669                 String ratingPath = getRatingsPath(
670                     context, ratingsEntry[0], ratingsEntry[1]);
671 
672                 Element asset = root.addElement("asset");
673 
674                 asset.addAttribute("path", ratingPath);
675                 asset.addAttribute("class-name", ratingsEntry[0]);
676                 asset.addAttribute("class-pk", ratingsEntry[1]);
677 
678                 List<RatingsEntry> ratingsEntries = entry.getValue();
679 
680                 for (RatingsEntry rating : ratingsEntries) {
681                     ratingPath = getRatingsPath(
682                         context, ratingsEntry[0], ratingsEntry[1], rating);
683 
684                     context.addZipEntry(ratingPath, rating);
685                 }
686             }
687 
688             context.addZipEntry(
689                 context.getRootPath() + "/ratings.xml", doc.formattedString());
690         }
691         catch (Exception e) {
692             throw new SystemException(e);
693         }
694     }
695 
696     protected void exportTags(PortletDataContext context, Element parentEl)
697         throws SystemException {
698 
699         try {
700             Document doc = SAXReaderUtil.createDocument();
701 
702             Element root = doc.addElement("tags");
703 
704             Map<String, String[]> tagsEntries = context.getTagsEntries();
705 
706             for (Map.Entry<String, String[]> entry : tagsEntries.entrySet()) {
707                 String[] tagsEntry = entry.getKey().split(StringPool.POUND);
708 
709                 Element asset = root.addElement("asset");
710 
711                 asset.addAttribute("class-name", tagsEntry[0]);
712                 asset.addAttribute("class-pk", tagsEntry[1]);
713                 asset.addAttribute(
714                     "entries", StringUtil.merge(entry.getValue()));
715             }
716 
717             context.addZipEntry(
718                 context.getRootPath() + "/tags.xml", doc.formattedString());
719         }
720         catch (Exception e) {
721             throw new SystemException(e);
722         }
723     }
724 
725     protected String getCommentsPath(
726         PortletDataContext context, String className, String classPK) {
727 
728         StringBundler sb = new StringBundler(6);
729 
730         sb.append(context.getRootPath());
731         sb.append("/comments/");
732         sb.append(PortalUtil.getClassNameId(className));
733         sb.append(CharPool.FORWARD_SLASH);
734         sb.append(classPK);
735         sb.append(CharPool.FORWARD_SLASH);
736 
737         return sb.toString();
738     }
739 
740     protected String getCommentsPath(
741         PortletDataContext context, String className, String classPK,
742         MBMessage message) {
743 
744         StringBundler sb = new StringBundler(8);
745 
746         sb.append(context.getRootPath());
747         sb.append("/comments/");
748         sb.append(PortalUtil.getClassNameId(className));
749         sb.append(CharPool.FORWARD_SLASH);
750         sb.append(classPK);
751         sb.append(CharPool.FORWARD_SLASH);
752         sb.append(message.getMessageId());
753         sb.append(".xml");
754 
755         return sb.toString();
756     }
757 
758     protected String getPortletDataPath(
759         PortletDataContext context, String portletId) {
760 
761         return context.getPortletPath(portletId) + "/portlet-data.xml";
762     }
763 
764     protected String getPortletPreferencesPath(
765         PortletDataContext context, String portletId, long ownerId,
766         int ownerType, long plid) {
767 
768         StringBundler sb = new StringBundler(8);
769 
770         sb.append(context.getPortletPath(portletId));
771         sb.append("/preferences/");
772 
773         if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
774             sb.append("company/");
775         }
776         else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
777             sb.append("group/");
778         }
779         else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
780             sb.append("layout/");
781         }
782         else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
783             sb.append("user/");
784         }
785         else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
786             sb.append("archived/");
787         }
788 
789         sb.append(ownerId);
790         sb.append(CharPool.FORWARD_SLASH);
791         sb.append(plid);
792         sb.append(CharPool.FORWARD_SLASH);
793         sb.append("portlet-preferences.xml");
794 
795         return sb.toString();
796     }
797 
798     protected String getRatingsPath(
799         PortletDataContext context, String className, String classPK) {
800 
801         StringBundler sb = new StringBundler(6);
802 
803         sb.append(context.getRootPath());
804         sb.append("/ratings/");
805         sb.append(PortalUtil.getClassNameId(className));
806         sb.append(CharPool.FORWARD_SLASH);
807         sb.append(classPK);
808         sb.append(CharPool.FORWARD_SLASH);
809 
810         return sb.toString();
811     }
812 
813     protected String getRatingsPath(
814         PortletDataContext context, String className, String classPK,
815         RatingsEntry rating) {
816 
817         StringBundler sb = new StringBundler(8);
818 
819         sb.append(context.getRootPath());
820         sb.append("/ratings/");
821         sb.append(PortalUtil.getClassNameId(className));
822         sb.append(CharPool.FORWARD_SLASH);
823         sb.append(classPK);
824         sb.append(CharPool.FORWARD_SLASH);
825         sb.append(rating.getEntryId());
826         sb.append(".xml");
827 
828         return sb.toString();
829     }
830 
831     private static Log _log = LogFactoryUtil.getLog(PortletExporter.class);
832 
833     private PermissionExporter _permissionExporter = new PermissionExporter();
834 
835 }