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