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