1
22
23 package com.liferay.portal.lar;
24
25 import com.liferay.portal.LayoutImportException;
26 import com.liferay.portal.NoSuchPortletPreferencesException;
27 import com.liferay.portal.PortalException;
28 import com.liferay.portal.SystemException;
29 import com.liferay.portal.kernel.util.CharPool;
30 import com.liferay.portal.kernel.util.PortletClassInvoker;
31 import com.liferay.portal.kernel.util.ReleaseInfo;
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.model.Group;
41 import com.liferay.portal.model.GroupConstants;
42 import com.liferay.portal.model.Layout;
43 import com.liferay.portal.model.LayoutConstants;
44 import com.liferay.portal.model.LayoutTypePortlet;
45 import com.liferay.portal.model.Permission;
46 import com.liferay.portal.model.Portlet;
47 import com.liferay.portal.model.PortletConstants;
48 import com.liferay.portal.model.PortletItem;
49 import com.liferay.portal.model.PortletPreferences;
50 import com.liferay.portal.model.ResourceConstants;
51 import com.liferay.portal.model.Role;
52 import com.liferay.portal.model.User;
53 import com.liferay.portal.security.permission.ResourceActionsUtil;
54 import com.liferay.portal.service.GroupLocalServiceUtil;
55 import com.liferay.portal.service.LayoutLocalServiceUtil;
56 import com.liferay.portal.service.PermissionLocalServiceUtil;
57 import com.liferay.portal.service.PortletItemLocalServiceUtil;
58 import com.liferay.portal.service.PortletLocalServiceUtil;
59 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
60 import com.liferay.portal.service.RoleLocalServiceUtil;
61 import com.liferay.portal.service.UserLocalServiceUtil;
62 import com.liferay.portal.service.permission.PortletPermissionUtil;
63 import com.liferay.portal.util.PortalUtil;
64 import com.liferay.portal.util.PortletKeys;
65 import com.liferay.portlet.PortletPreferencesFactoryUtil;
66 import com.liferay.portlet.messageboards.model.MBMessage;
67 import com.liferay.portlet.ratings.model.RatingsEntry;
68 import com.liferay.util.MapUtil;
69
70 import java.io.IOException;
71
72 import java.util.Date;
73 import java.util.HashSet;
74 import java.util.Iterator;
75 import java.util.List;
76 import java.util.Map;
77 import java.util.Set;
78
79 import org.apache.commons.lang.time.StopWatch;
80 import org.apache.commons.logging.Log;
81 import org.apache.commons.logging.LogFactory;
82
83
94 public class PortletExporter {
95
96 public byte[] exportPortletInfo(
97 long plid, String portletId, Map<String, String[]> parameterMap,
98 Date startDate, Date endDate)
99 throws PortalException, SystemException {
100
101 boolean exportPermissions = MapUtil.getBoolean(
102 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
103 boolean exportPortletArchivedSetups = MapUtil.getBoolean(
104 parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
105 boolean exportPortletData = true;
106 boolean exportPortletSetup = MapUtil.getBoolean(
107 parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
108 boolean exportPortletUserPreferences = MapUtil.getBoolean(
109 parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
110 boolean exportUserPermissions = MapUtil.getBoolean(
111 parameterMap, PortletDataHandlerKeys.USER_PERMISSIONS);
112
113 if (_log.isDebugEnabled()) {
114 _log.debug("Export permissions " + exportPermissions);
115 _log.debug(
116 "Export portlet archived setups " +
117 exportPortletArchivedSetups);
118 _log.debug("Export portlet data " + exportPortletData);
119 _log.debug("Export portlet setup " + exportPortletSetup);
120 _log.debug(
121 "Export portlet user preferences " +
122 exportPortletUserPreferences);
123 _log.debug("Export user permissions " + exportUserPermissions);
124 }
125
126 StopWatch stopWatch = null;
127
128 if (_log.isInfoEnabled()) {
129 stopWatch = new StopWatch();
130
131 stopWatch.start();
132 }
133
134 LayoutCache layoutCache = new LayoutCache();
135
136 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
137
138 if (!layout.getType().equals(LayoutConstants.TYPE_PORTLET)) {
139 throw new LayoutImportException(
140 "Layout type " + layout.getType() + " is not valid");
141 }
142
143 LayoutTypePortlet layoutTypePortlet =
144 (LayoutTypePortlet)layout.getLayoutType();
145
146 if (!layoutTypePortlet.hasPortletId(portletId)) {
147 throw new LayoutImportException(
148 "The specified layout does not have portlet " + portletId);
149 }
150
151 long companyId = layout.getCompanyId();
152 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
153
154 ZipWriter zipWriter = new ZipWriter();
155
156 PortletDataContext context = new PortletDataContextImpl(
157 companyId, layout.getGroupId(), parameterMap, new HashSet<String>(),
158 startDate, endDate, zipWriter);
159
160 context.setPlid(plid);
161 context.setOldPlid(plid);
162
163
165 Document doc = SAXReaderUtil.createDocument();
166
167 Element root = doc.addElement("root");
168
169 Element header = root.addElement("header");
170
171 header.addAttribute(
172 "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
173 header.addAttribute("export-date", Time.getRFC822());
174
175 if (context.hasDateRange()) {
176 header.addAttribute(
177 "start-date", String.valueOf(context.getStartDate()));
178 header.addAttribute(
179 "end-date", String.valueOf(context.getEndDate()));
180 }
181
182 header.addAttribute("type", "portlet");
183 header.addAttribute("group-id", String.valueOf(layout.getGroupId()));
184 header.addAttribute(
185 "private-layout", String.valueOf(layout.isPrivateLayout()));
186 header.addAttribute(
187 "root-portlet-id", PortletConstants.getRootPortletId(portletId));
188
189
191 exportPortlet(
192 context, layoutCache, portletId, layout, root, defaultUserId,
193 exportPermissions, exportPortletArchivedSetups, exportPortletData,
194 exportPortletSetup, exportPortletUserPreferences,
195 exportUserPermissions);
196
197
199 exportComments(context, root);
200
201
203 exportRatings(context, root);
204
205
207 exportTags(context, root);
208
209
211 if (_log.isInfoEnabled()) {
212 _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
213 }
214
215
217 try {
218 context.addZipEntry("/manifest.xml", doc.formattedString());
219
220 return zipWriter.finish();
221 }
222 catch (IOException ioe) {
223 throw new SystemException(ioe);
224 }
225 }
226
227 protected void exportComments(PortletDataContext context, Element parentEl)
228 throws SystemException {
229
230 try {
231 Document doc = SAXReaderUtil.createDocument();
232
233 Element root = doc.addElement("comments");
234
235 Map<String, List<MBMessage>> commentsMap = context.getComments();
236
237 for (Map.Entry<String, List<MBMessage>> entry :
238 commentsMap.entrySet()) {
239
240 String[] comment = entry.getKey().split(StringPool.POUND);
241
242 String path = getCommentsPath(context, comment[0], comment[1]);
243
244 Element asset = root.addElement("asset");
245 asset.addAttribute("path", path);
246 asset.addAttribute("class-name", comment[0]);
247 asset.addAttribute("class-pk", comment[1]);
248
249 List<MBMessage> messages = entry.getValue();
250
251 for (MBMessage message : messages) {
252 path = getCommentsPath(
253 context, comment[0], comment[1], message);
254
255 context.addZipEntry(path, message);
256 }
257 }
258
259 context.addZipEntry(
260 context.getRootPath() + "/comments.xml", doc.formattedString());
261 }
262 catch (IOException ioe) {
263 throw new SystemException(ioe);
264 }
265 }
266
267 protected Element exportGroupPermissions(
268 long companyId, long groupId, String resourceName,
269 String resourcePrimKey, Element parentEl, String elName)
270 throws SystemException {
271
272 Element el = parentEl.addElement(elName);
273
274 List<Permission> permissions =
275 PermissionLocalServiceUtil.getGroupPermissions(
276 groupId, companyId, resourceName,
277 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
278
279 List<String> actions = ResourceActionsUtil.getActions(permissions);
280
281 for (int i = 0; i < actions.size(); i++) {
282 String action = actions.get(i);
283
284 Element actionKeyEl = el.addElement("action-key");
285
286 actionKeyEl.addText(action);
287 }
288
289 return el;
290 }
291
292 protected void exportGroupRoles(
293 LayoutCache layoutCache, long companyId, long groupId,
294 String resourceName, String entityName, Element parentEl)
295 throws SystemException {
296
297 List<Role> roles = layoutCache.getGroupRoles(groupId);
298
299 Element groupEl = exportRoles(
300 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
301 String.valueOf(groupId), parentEl, entityName + "-roles", roles);
302
303 if (groupEl.elements().isEmpty()) {
304 parentEl.remove(groupEl);
305 }
306 }
307
308 protected void exportInheritedPermissions(
309 LayoutCache layoutCache, long companyId, String resourceName,
310 String resourcePrimKey, Element parentEl, String entityName)
311 throws SystemException {
312
313 Element entityPermissionsEl = SAXReaderUtil.createElement(
314 entityName + "-permissions");
315
316 Map<String, Long> entityMap = layoutCache.getEntityMap(
317 companyId, entityName);
318
319 Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
320
321 while (itr.hasNext()) {
322 Map.Entry<String, Long> entry = itr.next();
323
324 String name = entry.getKey().toString();
325
326 long entityGroupId = entry.getValue();
327
328 Element entityEl = exportGroupPermissions(
329 companyId, entityGroupId, resourceName, resourcePrimKey,
330 entityPermissionsEl, entityName + "-actions");
331
332 if (entityEl.elements().isEmpty()) {
333 entityPermissionsEl.remove(entityEl);
334 }
335 else {
336 entityEl.addAttribute("name", name);
337 }
338 }
339
340 if (!entityPermissionsEl.elements().isEmpty()) {
341 parentEl.add(entityPermissionsEl);
342 }
343 }
344
345 protected void exportInheritedRoles(
346 LayoutCache layoutCache, long companyId, long groupId,
347 String resourceName, String entityName, Element parentEl)
348 throws SystemException {
349
350 Element entityRolesEl = SAXReaderUtil.createElement(
351 entityName + "-roles");
352
353 Map<String, Long> entityMap = layoutCache.getEntityMap(
354 companyId, entityName);
355
356 Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
357
358 while (itr.hasNext()) {
359 Map.Entry<String, Long> entry = itr.next();
360
361 String name = entry.getKey().toString();
362
363 long entityGroupId = entry.getValue();
364
365 List<Role> entityRoles = layoutCache.getGroupRoles(entityGroupId);
366
367 Element entityEl = exportRoles(
368 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
369 String.valueOf(groupId), entityRolesEl, entityName,
370 entityRoles);
371
372 if (entityEl.elements().isEmpty()) {
373 entityRolesEl.remove(entityEl);
374 }
375 else {
376 entityEl.addAttribute("name", name);
377 }
378 }
379
380 if (!entityRolesEl.elements().isEmpty()) {
381 parentEl.add(entityRolesEl);
382 }
383 }
384
385 protected void exportPortlet(
386 PortletDataContext context, LayoutCache layoutCache,
387 String portletId, Layout layout, Element parentEl,
388 long defaultUserId, boolean exportPermissions,
389 boolean exportPortletArchivedSetups, boolean exportPortletData,
390 boolean exportPortletSetup, boolean exportPortletUserPreferences,
391 boolean exportUserPermissions)
392 throws PortalException, SystemException {
393
394 long companyId = context.getCompanyId();
395 long groupId = context.getGroupId();
396
397 Portlet portlet = PortletLocalServiceUtil.getPortletById(
398 context.getCompanyId(), portletId);
399
400 if (portlet == null) {
401 if (_log.isDebugEnabled()) {
402 _log.debug(
403 "Do not export portlet " + portletId +
404 " because the portlet does not exist");
405 }
406
407 return;
408 }
409
410 if ((!portlet.isInstanceable()) &&
411 (!portlet.isPreferencesUniquePerLayout()) &&
412 (_notUniquePerLayout.contains(portletId))) {
413
414 return;
415 }
416
417 Document doc = SAXReaderUtil.createDocument();
418
419 Element portletEl = doc.addElement("portlet");
420
421 portletEl.addAttribute("portlet-id", portletId);
422 portletEl.addAttribute(
423 "root-portlet-id", PortletConstants.getRootPortletId(portletId));
424 portletEl.addAttribute("old-plid", String.valueOf(layout.getPlid()));
425
426
428 javax.portlet.PortletPreferences jxPrefs =
429 PortletPreferencesFactoryUtil.getPortletSetup(
430 layout, portletId, StringPool.BLANK);
431
432 if (exportPortletData) {
433 if (!portlet.isPreferencesUniquePerLayout()) {
434 if (!_notUniquePerLayout.contains(portletId)) {
435 _notUniquePerLayout.add(portletId);
436
437 exportPortletData(
438 context, portlet, layout, jxPrefs, portletEl);
439 }
440 }
441 else {
442 exportPortletData(context, portlet, layout, jxPrefs, portletEl);
443 }
444 }
445
446
448 if (exportPortletSetup) {
449 exportPortletPreferences(
450 context, PortletKeys.PREFS_OWNER_ID_DEFAULT,
451 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, portletId,
452 portletEl);
453
454 exportPortletPreferences(
455 context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
456 layout, portletId, portletEl);
457
458 exportPortletPreferences(
459 context, companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY, false,
460 layout, portletId, portletEl);
461 }
462
463
465 if (exportPortletUserPreferences) {
466 exportPortletPreferences(
467 context, defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
468 true, layout, portletId, portletEl);
469
470 try {
471 PortletPreferences groupPortletPreferences =
472 PortletPreferencesLocalServiceUtil.getPortletPreferences(
473 groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
474 PortletKeys.PREFS_PLID_SHARED, portletId);
475
476 exportPortletPreference(
477 context, groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
478 groupPortletPreferences, portletId,
479 PortletKeys.PREFS_PLID_SHARED, portletEl);
480 }
481 catch (NoSuchPortletPreferencesException nsppe) {
482 }
483 }
484
485
487 if (exportPortletArchivedSetups) {
488 String rootPortletId = PortletConstants.getRootPortletId(portletId);
489
490 List<PortletItem> portletItems =
491 PortletItemLocalServiceUtil.getPortletItems(
492 groupId, rootPortletId, PortletPreferences.class.getName());
493
494 for (PortletItem portletItem: portletItems) {
495 long ownerId = portletItem.getPortletItemId();
496 int ownerType = PortletKeys.PREFS_OWNER_TYPE_ARCHIVED;
497
498 exportPortletPreferences(
499 context, ownerId, ownerType, false, null,
500 portletItem.getPortletId(), portletEl);
501 }
502 }
503
504 Group guestGroup = GroupLocalServiceUtil.getGroup(
505 companyId, GroupConstants.GUEST);
506
507
509 if (exportPermissions) {
510 Element permissionsEl = portletEl.addElement("permissions");
511
512 exportPortletPermissions(
513 layoutCache, companyId, groupId, guestGroup, layout.getPlid(),
514 portletId, permissionsEl, exportUserPermissions);
515
516 Element rolesEl = portletEl.addElement("roles");
517
518 exportPortletRoles(
519 layoutCache, companyId, groupId, portletId, rolesEl);
520 }
521
522
524 StringBuilder sb = new StringBuilder();
525
526 sb.append(context.getPortletPath(portletId));
527
528 if (portlet.isPreferencesUniquePerLayout()) {
529 sb.append(StringPool.SLASH);
530 sb.append(layout.getPlid());
531 }
532
533 sb.append("/portlet.xml");
534
535 Element el = parentEl.addElement("portlet");
536
537 el.addAttribute("portlet-id", portletId);
538 el.addAttribute(
539 "layout-id", String.valueOf(layout.getLayoutId()));
540 el.addAttribute("path", sb.toString());
541
542 try {
543 context.addZipEntry(sb.toString(), doc.formattedString());
544 }
545 catch (IOException ioe) {
546 if (_log.isWarnEnabled()) {
547 _log.warn(ioe.getMessage());
548 }
549 }
550 }
551
552 protected void exportPortletData(
553 PortletDataContext context, Portlet portlet, Layout layout,
554 javax.portlet.PortletPreferences portletPreferences,
555 Element parentEl)
556 throws SystemException {
557
558 String portletDataHandlerClass =
559 portlet.getPortletDataHandlerClass();
560
561 if (Validator.isNull(portletDataHandlerClass)) {
562 return;
563 }
564
565 String portletId = portlet.getPortletId();
566
567 if (_log.isDebugEnabled()) {
568 _log.debug("Exporting data for " + portletId);
569 }
570
571 Map<String, String[]> parameterMap = context.getParameterMap();
572
573 boolean exportData = false;
574
575 if (MapUtil.getBoolean(
576 parameterMap,
577 PortletDataHandlerKeys.PORTLET_DATA + "_" +
578 portlet.getRootPortletId()) ||
579 MapUtil.getBoolean(
580 parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
581
582 exportData = true;
583 }
584
585 if (!exportData) {
586 if (_log.isDebugEnabled()) {
587 _log.debug(
588 "Not exporting data for " + portletId +
589 " because it was not selected by the user");
590 }
591
592 return;
593 }
594
595 String data = null;
596
597 try {
598 data = (String)PortletClassInvoker.invoke(
599 portletId, portletDataHandlerClass, "exportData", context,
600 portletId, portletPreferences);
601 }
602 catch (Exception e) {
603 throw new SystemException(e);
604 }
605
606 if (data == null) {
607 if (_log.isDebugEnabled()) {
608 _log.debug(
609 "Not exporting data for " + portletId +
610 " because null data was returned");
611 }
612
613 return;
614 }
615
616 StringBuilder sb = new StringBuilder();
617
618 sb.append(context.getPortletPath(portletId));
619
620 if (portlet.isPreferencesUniquePerLayout()) {
621 sb.append(StringPool.SLASH);
622 sb.append(layout.getPlid());
623 }
624
625 sb.append("/portlet-data.xml");
626
627 Element portletDataEl = parentEl.addElement("portlet-data");
628
629 portletDataEl.addAttribute("path", sb.toString());
630
631 context.addZipEntry(sb.toString(), data);
632 }
633
634 protected void exportPortletPermissions(
635 LayoutCache layoutCache, long companyId, long groupId,
636 Group guestGroup, long plid, String portletId,
637 Element permissionsEl, boolean exportUserPermissions)
638 throws SystemException {
639
640 String resourceName = PortletConstants.getRootPortletId(portletId);
641 String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
642 plid, portletId);
643
644 exportGroupPermissions(
645 companyId, groupId, resourceName, resourcePrimKey, permissionsEl,
646 "community-actions");
647
648 if (groupId != guestGroup.getGroupId()) {
649 exportGroupPermissions(
650 companyId, guestGroup.getGroupId(), resourceName,
651 resourcePrimKey, permissionsEl, "guest-actions");
652 }
653
654 if (exportUserPermissions) {
655 exportUserPermissions(
656 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
657 permissionsEl);
658 }
659
660 exportInheritedPermissions(
661 layoutCache, companyId, resourceName, resourcePrimKey,
662 permissionsEl, "organization");
663
664 exportInheritedPermissions(
665 layoutCache, companyId, resourceName, resourcePrimKey,
666 permissionsEl, "location");
667
668 exportInheritedPermissions(
669 layoutCache, companyId, resourceName, resourcePrimKey,
670 permissionsEl, "user-group");
671 }
672
673 protected void exportPortletPreference(
674 PortletDataContext context, long ownerId, int ownerType,
675 boolean defaultUser, PortletPreferences portletPreferences,
676 String portletId, long plid, Element parentEl)
677 throws SystemException {
678
679 try {
680 Document prefsDoc = SAXReaderUtil.read(
681 portletPreferences.getPreferences());
682
683 Element root = prefsDoc.getRootElement();
684
685 root.addAttribute("owner-id", String.valueOf(ownerId));
686 root.addAttribute("owner-type", String.valueOf(ownerType));
687 root.addAttribute("default-user", String.valueOf(defaultUser));
688 root.addAttribute("plid", String.valueOf(plid));
689 root.addAttribute("portlet-id", portletId);
690
691 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
692 PortletItem portletItem =
693 PortletItemLocalServiceUtil.getPortletItem(ownerId);
694
695 User user = UserLocalServiceUtil.getUserById(
696 portletItem.getUserId());
697
698 root.addAttribute("archive-user-uuid", user.getUuid());
699 root.addAttribute("archive-name", portletItem.getName());
700 }
701
702 String path = getPortletPreferencesPath(
703 context, portletId, ownerId, ownerType, plid);
704
705 parentEl.addElement(
706 "portlet-preferences").addAttribute("path", path);
707
708 if (context.isPathNotProcessed(path)) {
709 context.addZipEntry(path, prefsDoc.formattedString());
710 }
711 }
712 catch (Exception e) {
713 throw new SystemException(e);
714 }
715 }
716
717 protected void exportPortletPreferences(
718 PortletDataContext context, long ownerId, int ownerType,
719 boolean defaultUser, Layout layout, String portletId,
720 Element parentEl)
721 throws PortalException, SystemException {
722
723 PortletPreferences portletPreferences = null;
724
725 long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
726
727 if (layout != null) {
728 plid = layout.getPlid();
729 }
730
731 if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
732 (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
733 (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
734
735 plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
736 }
737
738 try {
739 portletPreferences =
740 PortletPreferencesLocalServiceUtil.getPortletPreferences(
741 ownerId, ownerType, plid, portletId);
742
743 LayoutTypePortlet layoutTypePortlet = null;
744
745 if (layout != null) {
746 layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
747 }
748
749 if ((layoutTypePortlet == null) ||
750 (layoutTypePortlet.hasPortletId(portletId))) {
751
752 exportPortletPreference(
753 context, ownerId, ownerType, defaultUser,
754 portletPreferences, portletId, plid, parentEl);
755 }
756 }
757 catch (NoSuchPortletPreferencesException nsppe) {
758 }
759 }
760
761 protected void exportPortletRoles(
762 LayoutCache layoutCache, long companyId, long groupId,
763 String portletId, Element rolesEl)
764 throws SystemException {
765
766 String resourceName = PortletConstants.getRootPortletId(
767 portletId);
768
769 Element portletEl = rolesEl.addElement("portlet");
770
771 portletEl.addAttribute("portlet-id", portletId);
772
773 exportGroupRoles(
774 layoutCache, companyId, groupId, resourceName, "community",
775 portletEl);
776
777 exportUserRoles(
778 layoutCache, companyId, groupId, resourceName, portletEl);
779
780 exportInheritedRoles(
781 layoutCache, companyId, groupId, resourceName, "organization",
782 portletEl);
783
784 exportInheritedRoles(
785 layoutCache, companyId, groupId, resourceName, "location",
786 portletEl);
787
788 exportInheritedRoles(
789 layoutCache, companyId, groupId, resourceName, "user-group",
790 portletEl);
791
792 if (portletEl.elements().isEmpty()) {
793 rolesEl.remove(portletEl);
794 }
795 }
796
797 protected void exportRatings(PortletDataContext context, Element parentEl)
798 throws SystemException {
799
800 try {
801 Document doc = SAXReaderUtil.createDocument();
802
803 Element root = doc.addElement("ratings");
804
805 Map<String, List<RatingsEntry>> ratingsEntriesMap =
806 context.getRatingsEntries();
807
808 for (Map.Entry<String, List<RatingsEntry>> entry :
809 ratingsEntriesMap.entrySet()) {
810
811 String[] ratingsEntry = entry.getKey().split(StringPool.POUND);
812
813 String ratingPath = getRatingsPath(
814 context, ratingsEntry[0], ratingsEntry[1]);
815
816 Element asset = root.addElement("asset");
817
818 asset.addAttribute("path", ratingPath);
819 asset.addAttribute("class-name", ratingsEntry[0]);
820 asset.addAttribute("class-pk", ratingsEntry[1]);
821
822 List<RatingsEntry> ratingsEntries = entry.getValue();
823
824 for (RatingsEntry rating : ratingsEntries) {
825 ratingPath = getRatingsPath(
826 context, ratingsEntry[0], ratingsEntry[1], rating);
827
828 context.addZipEntry(ratingPath, rating);
829 }
830 }
831
832 context.addZipEntry(
833 context.getRootPath() + "/ratings.xml", doc.formattedString());
834 }
835 catch (Exception e) {
836 throw new SystemException(e);
837 }
838 }
839
840 protected Element exportRoles(
841 long companyId, String resourceName, int scope,
842 String resourcePrimKey, Element parentEl, String elName,
843 List<Role> roles)
844 throws SystemException {
845
846 Element el = parentEl.addElement(elName);
847
848 Map<String, List<String>> resourceRoles =
849 RoleLocalServiceUtil.getResourceRoles(
850 companyId, resourceName, scope, resourcePrimKey);
851
852 Iterator<Map.Entry<String, List<String>>> itr =
853 resourceRoles.entrySet().iterator();
854
855 while (itr.hasNext()) {
856 Map.Entry<String, List<String>> entry = itr.next();
857
858 String roleName = entry.getKey().toString();
859
860 if (hasRole(roles, roleName)) {
861 Element roleEl = el.addElement("role");
862
863 roleEl.addAttribute("name", roleName);
864
865 List<String> actions = entry.getValue();
866
867 for (int i = 0; i < actions.size(); i++) {
868 String action = actions.get(i);
869
870 Element actionKeyEl = roleEl.addElement("action-key");
871
872 actionKeyEl.addText(action);
873 actionKeyEl.addAttribute("scope", String.valueOf(scope));
874 }
875 }
876 }
877
878 return el;
879 }
880
881 protected void exportTags(PortletDataContext context, Element parentEl)
882 throws SystemException {
883
884 try {
885 Document doc = SAXReaderUtil.createDocument();
886
887 Element root = doc.addElement("tags");
888
889 Map<String, String[]> tagsEntries = context.getTagsEntries();
890
891 for (Map.Entry<String, String[]> entry : tagsEntries.entrySet()) {
892 String[] tagsEntry = entry.getKey().split(StringPool.POUND);
893
894 Element asset = root.addElement("asset");
895
896 asset.addAttribute("class-name", tagsEntry[0]);
897 asset.addAttribute("class-pk", tagsEntry[1]);
898 asset.addAttribute(
899 "entries", StringUtil.merge(entry.getValue()));
900 }
901
902 context.addZipEntry(
903 context.getRootPath() + "/tags.xml", doc.formattedString());
904 }
905 catch (Exception e) {
906 throw new SystemException(e);
907 }
908 }
909
910 protected void exportUserPermissions(
911 LayoutCache layoutCache, long companyId, long groupId,
912 String resourceName, String resourcePrimKey, Element parentEl)
913 throws SystemException {
914
915 StopWatch stopWatch = null;
916
917 if (_log.isDebugEnabled()) {
918 stopWatch = new StopWatch();
919
920 stopWatch.start();
921 }
922
923 Element userPermissionsEl = SAXReaderUtil.createElement(
924 "user-permissions");
925
926 List<User> users = layoutCache.getGroupUsers(groupId);
927
928 for (User user : users) {
929 String emailAddress = user.getEmailAddress();
930
931 Element userActionsEl = SAXReaderUtil.createElement("user-actions");
932
933 List<Permission> permissions =
934 PermissionLocalServiceUtil.getUserPermissions(
935 user.getUserId(), companyId, resourceName,
936 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
937
938 List<String> actions = ResourceActionsUtil.getActions(permissions);
939
940 for (String action : actions) {
941 Element actionKeyEl = userActionsEl.addElement("action-key");
942
943 actionKeyEl.addText(action);
944 }
945
946 if (!userActionsEl.elements().isEmpty()) {
947 userActionsEl.addAttribute("email-address", emailAddress);
948 userPermissionsEl.add(userActionsEl);
949 }
950 }
951
952 if (!userPermissionsEl.elements().isEmpty()) {
953 parentEl.add(userPermissionsEl);
954 }
955
956 if (_log.isDebugEnabled()) {
957 _log.debug(
958 "Export user permissions for {" + resourceName + ", " +
959 resourcePrimKey + "} with " + users.size() +
960 " users takes " + stopWatch.getTime() + " ms");
961 }
962 }
963
964 protected void exportUserRoles(
965 LayoutCache layoutCache, long companyId, long groupId,
966 String resourceName, Element parentEl)
967 throws SystemException {
968
969 Element userRolesEl = SAXReaderUtil.createElement("user-roles");
970
971 List<User> users = layoutCache.getGroupUsers(groupId);
972
973 for (User user : users) {
974 long userId = user.getUserId();
975 String emailAddress = user.getEmailAddress();
976
977 List<Role> userRoles = layoutCache.getUserRoles(userId);
978
979 Element userEl = exportRoles(
980 companyId, resourceName, ResourceConstants.SCOPE_GROUP,
981 String.valueOf(groupId), userRolesEl, "user", userRoles);
982
983 if (userEl.elements().isEmpty()) {
984 userRolesEl.remove(userEl);
985 }
986 else {
987 userEl.addAttribute("email-address", emailAddress);
988 }
989 }
990
991 if (!userRolesEl.elements().isEmpty()) {
992 parentEl.add(userRolesEl);
993 }
994 }
995
996 protected String getCommentsPath(
997 PortletDataContext context, String className, String classPK) {
998
999 StringBuilder sb = new StringBuilder();
1000
1001 sb.append(context.getRootPath());
1002 sb.append("/comments/");
1003 sb.append(PortalUtil.getClassNameId(className));
1004 sb.append(CharPool.FORWARD_SLASH);
1005 sb.append(classPK);
1006 sb.append(CharPool.FORWARD_SLASH);
1007
1008 return sb.toString();
1009 }
1010
1011 protected String getCommentsPath(
1012 PortletDataContext context, String className, String classPK,
1013 MBMessage message) {
1014
1015 StringBuilder sb = new StringBuilder();
1016
1017 sb.append(context.getRootPath());
1018 sb.append("/comments/");
1019 sb.append(PortalUtil.getClassNameId(className));
1020 sb.append(CharPool.FORWARD_SLASH);
1021 sb.append(classPK);
1022 sb.append(CharPool.FORWARD_SLASH);
1023 sb.append(message.getMessageId());
1024 sb.append(".xml");
1025
1026 return sb.toString();
1027 }
1028
1029 protected String getPortletDataPath(
1030 PortletDataContext context, String portletId) {
1031
1032 return context.getPortletPath(portletId) + "/portlet-data.xml";
1033 }
1034
1035 protected String getPortletPreferencesPath(
1036 PortletDataContext context, String portletId, long ownerId,
1037 int ownerType, long plid) {
1038
1039 StringBuilder sb = new StringBuilder();
1040
1041 sb.append(context.getPortletPath(portletId));
1042 sb.append("/preferences/");
1043
1044 if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
1045 sb.append("company/");
1046 }
1047 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1048 sb.append("group/");
1049 }
1050 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
1051 sb.append("layout/");
1052 }
1053 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1054 sb.append("user/");
1055 }
1056 else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1057 sb.append("archived/");
1058 }
1059
1060 sb.append(ownerId);
1061 sb.append(CharPool.FORWARD_SLASH);
1062 sb.append(plid);
1063 sb.append(CharPool.FORWARD_SLASH);
1064 sb.append("portlet-preferences.xml");
1065
1066 return sb.toString();
1067 }
1068
1069 protected String getRatingsPath(
1070 PortletDataContext context, String className, String classPK) {
1071
1072 StringBuilder sb = new StringBuilder();
1073
1074 sb.append(context.getRootPath());
1075 sb.append("/ratings/");
1076 sb.append(PortalUtil.getClassNameId(className));
1077 sb.append(CharPool.FORWARD_SLASH);
1078 sb.append(classPK);
1079 sb.append(CharPool.FORWARD_SLASH);
1080
1081 return sb.toString();
1082 }
1083
1084 protected String getRatingsPath(
1085 PortletDataContext context, String className, String classPK,
1086 RatingsEntry rating) {
1087
1088 StringBuilder sb = new StringBuilder();
1089
1090 sb.append(context.getRootPath());
1091 sb.append("/ratings/");
1092 sb.append(PortalUtil.getClassNameId(className));
1093 sb.append(CharPool.FORWARD_SLASH);
1094 sb.append(classPK);
1095 sb.append(CharPool.FORWARD_SLASH);
1096 sb.append(rating.getEntryId());
1097 sb.append(".xml");
1098
1099 return sb.toString();
1100 }
1101
1102 protected boolean hasRole(List<Role> roles, String roleName) {
1103 if ((roles == null) || (roles.size() == 0)) {
1104 return false;
1105 }
1106
1107 for (Role role : roles) {
1108 if (role.getName().equals(roleName)) {
1109 return true;
1110 }
1111 }
1112
1113 return false;
1114 }
1115
1116 private static Log _log = LogFactory.getLog(PortletExporter.class);
1117
1118 private Set<String> _notUniquePerLayout = new HashSet<String>();
1119
1120}