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