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