1
14
15 package com.liferay.portal.lar;
16
17 import com.liferay.counter.service.CounterLocalServiceUtil;
18 import com.liferay.portal.LARFileException;
19 import com.liferay.portal.LARTypeException;
20 import com.liferay.portal.LayoutImportException;
21 import com.liferay.portal.NoSuchLayoutException;
22 import com.liferay.portal.PortalException;
23 import com.liferay.portal.SystemException;
24 import com.liferay.portal.kernel.cluster.ClusterLinkUtil;
25 import com.liferay.portal.kernel.cluster.Priority;
26 import com.liferay.portal.kernel.log.Log;
27 import com.liferay.portal.kernel.log.LogFactoryUtil;
28 import com.liferay.portal.kernel.messaging.Message;
29 import com.liferay.portal.kernel.util.ArrayUtil;
30 import com.liferay.portal.kernel.util.FileUtil;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.LocaleUtil;
33 import com.liferay.portal.kernel.util.MapUtil;
34 import com.liferay.portal.kernel.util.MethodWrapper;
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.UnicodeProperties;
40 import com.liferay.portal.kernel.util.Validator;
41 import com.liferay.portal.kernel.xml.Document;
42 import com.liferay.portal.kernel.xml.DocumentException;
43 import com.liferay.portal.kernel.xml.Element;
44 import com.liferay.portal.kernel.xml.SAXReaderUtil;
45 import com.liferay.portal.kernel.zip.ZipReader;
46 import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
47 import com.liferay.portal.model.Group;
48 import com.liferay.portal.model.GroupConstants;
49 import com.liferay.portal.model.Layout;
50 import com.liferay.portal.model.LayoutConstants;
51 import com.liferay.portal.model.LayoutSet;
52 import com.liferay.portal.model.LayoutTemplate;
53 import com.liferay.portal.model.LayoutTypePortlet;
54 import com.liferay.portal.model.Portlet;
55 import com.liferay.portal.model.PortletConstants;
56 import com.liferay.portal.model.Resource;
57 import com.liferay.portal.model.ResourceConstants;
58 import com.liferay.portal.model.Role;
59 import com.liferay.portal.model.User;
60 import com.liferay.portal.model.impl.ColorSchemeImpl;
61 import com.liferay.portal.model.impl.LayoutTypePortletImpl;
62 import com.liferay.portal.service.GroupLocalServiceUtil;
63 import com.liferay.portal.service.ImageLocalServiceUtil;
64 import com.liferay.portal.service.LayoutLocalServiceUtil;
65 import com.liferay.portal.service.LayoutSetLocalServiceUtil;
66 import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
67 import com.liferay.portal.service.PermissionLocalServiceUtil;
68 import com.liferay.portal.service.PortletLocalServiceUtil;
69 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
70 import com.liferay.portal.service.RoleLocalServiceUtil;
71 import com.liferay.portal.service.permission.PortletPermissionUtil;
72 import com.liferay.portal.service.persistence.LayoutUtil;
73 import com.liferay.portal.service.persistence.UserUtil;
74 import com.liferay.portal.theme.ThemeLoader;
75 import com.liferay.portal.theme.ThemeLoaderFactory;
76 import com.liferay.portal.util.PortalUtil;
77 import com.liferay.portal.util.PortletKeys;
78 import com.liferay.portal.util.PropsValues;
79 import com.liferay.portlet.journal.model.JournalArticle;
80 import com.liferay.util.LocalizationUtil;
81
82 import java.io.File;
83 import java.io.IOException;
84 import java.io.InputStream;
85
86 import java.util.ArrayList;
87 import java.util.Date;
88 import java.util.HashSet;
89 import java.util.Iterator;
90 import java.util.List;
91 import java.util.Locale;
92 import java.util.Map;
93 import java.util.Set;
94
95 import org.apache.commons.lang.time.StopWatch;
96
97
108 public class LayoutImporter {
109
110 public void importLayouts(
111 long userId, long groupId, boolean privateLayout,
112 Map<String, String[]> parameterMap, File file)
113 throws PortalException, SystemException {
114
115 boolean deleteMissingLayouts = MapUtil.getBoolean(
116 parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
117 Boolean.TRUE.booleanValue());
118 boolean deletePortletData = MapUtil.getBoolean(
119 parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
120 boolean importPermissions = MapUtil.getBoolean(
121 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
122 boolean importUserPermissions = MapUtil.getBoolean(
123 parameterMap, PortletDataHandlerKeys.PERMISSIONS);
124 boolean importPortletData = MapUtil.getBoolean(
125 parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
126 boolean importPortletSetup = MapUtil.getBoolean(
127 parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
128 boolean importPortletArchivedSetups = MapUtil.getBoolean(
129 parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
130 boolean importPortletUserPreferences = MapUtil.getBoolean(
131 parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
132 boolean importTheme = MapUtil.getBoolean(
133 parameterMap, PortletDataHandlerKeys.THEME);
134 String layoutsImportMode = MapUtil.getString(
135 parameterMap, PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
136 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_ID);
137 String portletsMergeMode = MapUtil.getString(
138 parameterMap, PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
139 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE);
140 String userIdStrategy = MapUtil.getString(
141 parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
142
143 if (_log.isDebugEnabled()) {
144 _log.debug("Delete portlet data " + deletePortletData);
145 _log.debug("Import permissions " + importPermissions);
146 _log.debug("Import user permissions " + importUserPermissions);
147 _log.debug("Import portlet data " + importPortletData);
148 _log.debug("Import portlet setup " + importPortletSetup);
149 _log.debug(
150 "Import portlet archived setups " +
151 importPortletArchivedSetups);
152 _log.debug(
153 "Import portlet user preferences " +
154 importPortletUserPreferences);
155 _log.debug("Import theme " + importTheme);
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 LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
169 groupId, privateLayout);
170
171 long companyId = layoutSet.getCompanyId();
172
173 User user = UserUtil.findByPrimaryKey(userId);
174
175 UserIdStrategy strategy = _portletImporter.getUserIdStrategy(
176 user, userIdStrategy);
177
178 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(file);
179
180 PortletDataContext context = new PortletDataContextImpl(
181 companyId, groupId, parameterMap, new HashSet<String>(), strategy,
182 zipReader);
183
184 Group guestGroup = GroupLocalServiceUtil.getGroup(
185 companyId, GroupConstants.GUEST);
186
187
189 Element root = null;
190 InputStream themeZip = null;
191
192
194 String xml = context.getZipEntryAsString("/manifest.xml");
195
196 if (xml == null) {
197 throw new LARFileException("manifest.xml not found in the LAR");
198 }
199
200 try {
201 Document doc = SAXReaderUtil.read(xml);
202
203 root = doc.getRootElement();
204 }
205 catch (Exception e) {
206 throw new LARFileException(e);
207 }
208
209
211 Element header = root.element("header");
212
213 int buildNumber = ReleaseInfo.getBuildNumber();
214
215 int importBuildNumber = GetterUtil.getInteger(
216 header.attributeValue("build-number"));
217
218 if (buildNumber != importBuildNumber) {
219 throw new LayoutImportException(
220 "LAR build number " + importBuildNumber + " does not match " +
221 "portal build number " + buildNumber);
222 }
223
224
226 String larType = header.attributeValue("type");
227
228 if (!larType.equals("layout-set")) {
229 throw new LARTypeException(
230 "Invalid type of LAR file (" + larType + ")");
231 }
232
233
235 long importGroupId = GetterUtil.getLong(
236 header.attributeValue("group-id"));
237
238 context.setImportGroupId(importGroupId);
239
240
242 if (importTheme) {
243 themeZip = context.getZipEntryAsInputStream("theme.zip");
244 }
245
246
248 String themeId = header.attributeValue("theme-id");
249 String colorSchemeId = header.attributeValue("color-scheme-id");
250
251 boolean useThemeZip = false;
252
253 if (themeZip != null) {
254 try {
255 String importThemeId = importTheme(layoutSet, themeZip);
256
257 if (importThemeId != null) {
258 themeId = importThemeId;
259 colorSchemeId =
260 ColorSchemeImpl.getDefaultRegularColorSchemeId();
261
262 useThemeZip = true;
263 }
264
265 if (_log.isDebugEnabled()) {
266 _log.debug(
267 "Importing theme takes " + stopWatch.getTime() + " ms");
268 }
269 }
270 catch (Exception e) {
271 throw new SystemException(e);
272 }
273 }
274
275 boolean wapTheme = false;
276
277 LayoutSetLocalServiceUtil.updateLookAndFeel(
278 groupId, privateLayout, themeId, colorSchemeId, StringPool.BLANK,
279 wapTheme);
280
281
284 _portletImporter.readComments(context, root);
285 _portletImporter.readRatings(context, root);
286 _portletImporter.readTags(context, root);
287
288
290 List<Layout> previousLayouts = LayoutUtil.findByG_P(
291 groupId, privateLayout);
292
293 List<Layout> newLayouts = new ArrayList<Layout>();
294
295 Set<Long> newLayoutIds = new HashSet<Long>();
296
297 Map<Long, Long> newLayoutIdPlidMap =
298 (Map<Long, Long>)context.getNewPrimaryKeysMap(Layout.class);
299
300 List<Element> layoutEls = root.element("layouts").elements("layout");
301
302 if (_log.isDebugEnabled()) {
303 if (layoutEls.size() > 0) {
304 _log.debug("Importing layouts");
305 }
306 }
307
308 for (Element layoutRefEl : layoutEls) {
309 long layoutId = GetterUtil.getInteger(
310 layoutRefEl.attributeValue("layout-id"));
311
312 long oldLayoutId = layoutId;
313
314 boolean deleteLayout = GetterUtil.getBoolean(
315 layoutRefEl.attributeValue("delete"));
316
317 if (deleteLayout) {
318 try {
319 LayoutLocalServiceUtil.deleteLayout(
320 context.getGroupId(), privateLayout, oldLayoutId);
321 }
322 catch (NoSuchLayoutException nsle) {
323 _log.warn(
324 "Error deleting layout for {" + importGroupId + ", " +
325 privateLayout + ", " + oldLayoutId + "}");
326 }
327
328 continue;
329 }
330
331 String layoutPath = layoutRefEl.attributeValue("path");
332
333 Element layoutEl = null;
334
335 try {
336 Document layoutDoc = SAXReaderUtil.read(
337 context.getZipEntryAsString(layoutPath));
338
339 layoutEl = layoutDoc.getRootElement();
340 }
341 catch (DocumentException de) {
342 throw new SystemException(de);
343 }
344
345 long parentLayoutId = GetterUtil.getInteger(
346 layoutEl.elementText("parent-layout-id"));
347
348 if (_log.isDebugEnabled()) {
349 _log.debug(
350 "Importing layout with layout id " + layoutId +
351 " and parent layout id " + parentLayoutId);
352 }
353
354 long oldPlid = GetterUtil.getInteger(
355 layoutEl.attributeValue("old-plid"));
356
357 String name = layoutEl.elementText("name");
358 String title = layoutEl.elementText("title");
359 String description = layoutEl.elementText("description");
360 String type = layoutEl.elementText("type");
361 String typeSettings = layoutEl.elementText("type-settings");
362 boolean hidden = GetterUtil.getBoolean(
363 layoutEl.elementText("hidden"));
364 String friendlyURL = layoutEl.elementText("friendly-url");
365 boolean iconImage = GetterUtil.getBoolean(
366 layoutEl.elementText("icon-image"));
367
368 byte[] iconBytes = null;
369
370 if (iconImage) {
371 String path = layoutEl.elementText("icon-image-path");
372
373 iconBytes = context.getZipEntryAsByteArray(path);
374 }
375
376 if (useThemeZip) {
377 themeId = StringPool.BLANK;
378 colorSchemeId = StringPool.BLANK;
379 }
380 else {
381 themeId = layoutEl.elementText("theme-id");
382 colorSchemeId = layoutEl.elementText("color-scheme-id");
383 }
384
385 String wapThemeId = layoutEl.elementText("wap-theme-id");
386 String wapColorSchemeId = layoutEl.elementText(
387 "wap-color-scheme-id");
388 String css = layoutEl.elementText("css");
389 int priority = GetterUtil.getInteger(
390 layoutEl.elementText("priority"));
391
392 Layout layout = null;
393
394 if (layoutsImportMode.equals(
395 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_ADD_AS_NEW)) {
396
397 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
398 groupId, privateLayout);
399 friendlyURL = StringPool.SLASH + layoutId;
400 }
401 else if (layoutsImportMode.equals(
402 PortletDataHandlerKeys.
403 LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME)) {
404
405 Locale locale = LocaleUtil.getDefault();
406
407 String localizedName = LocalizationUtil.getLocalization(
408 name, LocaleUtil.toLanguageId(locale));
409
410 for (Layout curLayout : previousLayouts) {
411 if (curLayout.getName(locale).equals(localizedName)) {
412 layout = curLayout;
413
414 break;
415 }
416 }
417
418 if (layout == null) {
419 layoutId = LayoutLocalServiceUtil.getNextLayoutId(
420 groupId, privateLayout);
421 }
422 }
423 else {
424 layout = LayoutUtil.fetchByG_P_L(
425 groupId, privateLayout, layoutId);
426 }
427
428 if (_log.isDebugEnabled()) {
429 if (layout == null) {
430 _log.debug(
431 "Layout with {groupId=" + groupId + ",privateLayout=" +
432 privateLayout + ",layoutId=" + layoutId +
433 "} does not exist");
434 }
435 else {
436 _log.debug(
437 "Layout with {groupId=" + groupId + ",privateLayout=" +
438 privateLayout + ",layoutId=" + layoutId +
439 "} exists");
440 }
441 }
442
443 if (layout == null) {
444 long plid = CounterLocalServiceUtil.increment();
445
446 layout = LayoutUtil.create(plid);
447
448 layout.setGroupId(groupId);
449 layout.setPrivateLayout(privateLayout);
450 layout.setLayoutId(layoutId);
451 }
452
453 layout.setCompanyId(user.getCompanyId());
454 layout.setParentLayoutId(parentLayoutId);
455 layout.setName(name);
456 layout.setTitle(title);
457 layout.setDescription(description);
458 layout.setType(type);
459
460 if (layout.getType().equals(LayoutConstants.TYPE_PORTLET) &&
461 Validator.isNotNull(layout.getTypeSettings()) &&
462 !portletsMergeMode.equals(
463 PortletDataHandlerKeys.
464 PORTLETS_MERGE_MODE_REPLACE)) {
465 mergePortlets(layout, typeSettings, portletsMergeMode);
466 }
467 else {
468 layout.setTypeSettings(typeSettings);
469 }
470
471 layout.setHidden(hidden);
472 layout.setFriendlyURL(friendlyURL);
473
474 if (iconImage) {
475 layout.setIconImage(iconImage);
476
477 if (layout.isNew()) {
478 long iconImageId = CounterLocalServiceUtil.increment();
479
480 layout.setIconImageId(iconImageId);
481 }
482 }
483
484 layout.setThemeId(themeId);
485 layout.setColorSchemeId(colorSchemeId);
486 layout.setWapThemeId(wapThemeId);
487 layout.setWapColorSchemeId(wapColorSchemeId);
488 layout.setCss(css);
489 layout.setPriority(priority);
490
491 fixTypeSettings(layout);
492
493 LayoutUtil.update(layout, false);
494
495 if ((iconBytes != null) && (iconBytes.length > 0)) {
496 ImageLocalServiceUtil.updateImage(
497 layout.getIconImageId(), iconBytes);
498 }
499
500 context.setPlid(layout.getPlid());
501 context.setOldPlid(oldPlid);
502
503 newLayoutIdPlidMap.put(oldLayoutId, layout.getPlid());
504
505 newLayoutIds.add(layoutId);
506
507 newLayouts.add(layout);
508
509 Element permissionsEl = layoutEl.element("permissions");
510
511
513 if (importPermissions && (permissionsEl != null)) {
514 String resourceName = Layout.class.getName();
515 String resourcePrimKey = String.valueOf(layout.getPlid());
516
517 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
518 importLayoutPermissions_5(
519 layoutCache, companyId, groupId, userId, resourceName,
520 resourcePrimKey, permissionsEl);
521 }
522 else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
523 importLayoutPermissions_6(
524 layoutCache, companyId, groupId, userId, resourceName,
525 resourcePrimKey, permissionsEl);
526 }
527 else {
528 importLayoutPermissions_4(
529 layoutCache, companyId, groupId, guestGroup, layout,
530 resourceName, resourcePrimKey, permissionsEl,
531 importUserPermissions);
532 }
533 }
534
535 _portletImporter.importPortletData(
536 context, PortletKeys.LAYOUT_CONFIGURATION, null, layoutEl);
537 }
538
539 List<Element> portletEls = root.element("portlets").elements("portlet");
540
541
543 if (deletePortletData) {
544 if (_log.isDebugEnabled()) {
545 if (portletEls.size() > 0) {
546 _log.debug("Deleting portlet data");
547 }
548 }
549
550 for (Element portletRefEl : portletEls) {
551 String portletId = portletRefEl.attributeValue("portlet-id");
552 long layoutId = GetterUtil.getLong(
553 portletRefEl.attributeValue("layout-id"));
554 long plid = newLayoutIdPlidMap.get(layoutId);
555
556 context.setPlid(plid);
557
558 _portletImporter.deletePortletData(context, portletId, plid);
559 }
560 }
561
562
564 if (_log.isDebugEnabled()) {
565 if (portletEls.size() > 0) {
566 _log.debug("Importing portlets");
567 }
568 }
569
570 for (Element portletRefEl : portletEls) {
571 String portletPath = portletRefEl.attributeValue("path");
572 String portletId = portletRefEl.attributeValue("portlet-id");
573 long layoutId = GetterUtil.getLong(
574 portletRefEl.attributeValue("layout-id"));
575 long plid = newLayoutIdPlidMap.get(layoutId);
576 long oldPlid = GetterUtil.getLong(
577 portletRefEl.attributeValue("old-plid"));
578
579 Layout layout = LayoutUtil.findByPrimaryKey(plid);
580
581 context.setPlid(plid);
582 context.setOldPlid(oldPlid);
583
584 Element portletEl = null;
585
586 try {
587 Document portletDoc = SAXReaderUtil.read(
588 context.getZipEntryAsString(portletPath));
589
590 portletEl = portletDoc.getRootElement();
591 }
592 catch (DocumentException de) {
593 throw new SystemException(de);
594 }
595
596
601
603 _portletImporter.importPortletPreferences(
604 context, layoutSet.getCompanyId(), layout.getGroupId(),
605 layout.getPlid(), null, portletEl, importPortletSetup,
606 importPortletArchivedSetups, importPortletUserPreferences);
607
608
610 Element portletDataEl = portletEl.element("portlet-data");
611
612 if (importPortletData && portletDataEl != null) {
613 _portletImporter.importPortletData(
614 context, portletId, plid, portletDataEl);
615 }
616
617
619 Element permissionsEl = portletEl.element("permissions");
620
621 if (importPermissions && (permissionsEl != null)) {
622 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
623 String resourceName = PortletConstants.getRootPortletId(
624 portletId);
625
626 String resourcePrimKey =
627 PortletPermissionUtil.getPrimaryKey(
628 layout.getPlid(), portletId);
629
630 importPortletPermissions_6(
631 layoutCache, companyId, groupId, userId, resourceName,
632 resourcePrimKey, permissionsEl);
633 }
634 else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
635 String resourceName = PortletConstants.getRootPortletId(
636 portletId);
637
638 String resourcePrimKey =
639 PortletPermissionUtil.getPrimaryKey(
640 layout.getPlid(), portletId);
641
642 importPortletPermissions_5(
643 layoutCache, companyId, groupId, userId, resourceName,
644 resourcePrimKey, permissionsEl);
645 }
646 else {
647 importPortletPermissions_4(
648 layoutCache, companyId, groupId, guestGroup, layout,
649 permissionsEl, importUserPermissions);
650 }
651 }
652
653
655 _portletImporter.importPortletPreferences(
656 context, layoutSet.getCompanyId(), groupId, 0, null, portletEl,
657 importPortletSetup, importPortletArchivedSetups,
658 importPortletUserPreferences);
659
660 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) {
661
662
664 Element rolesEl = portletEl.element("roles");
665
666 if (importPermissions && (rolesEl != null)) {
667 importPortletRoles(
668 layoutCache, companyId, groupId, portletEl);
669
670 importPortletRoles(
671 layoutCache, companyId, groupId, portletId, rolesEl);
672 }
673 }
674 }
675
676 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM < 5) {
677 Element rolesEl = root.element("roles");
678
679
681 if (importPermissions) {
682 importLayoutRoles(layoutCache, companyId, groupId, rolesEl);
683 }
684 }
685
686
688 if (deleteMissingLayouts) {
689 deleteMissingLayouts(
690 groupId, privateLayout, newLayoutIds, previousLayouts);
691 }
692
693
695 LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
696
697 if (_log.isInfoEnabled()) {
698 _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
699 }
700
701
703 for (Layout layout : newLayouts) {
704 UnicodeProperties typeSettingsProperties =
705 layout.getTypeSettingsProperties();
706
707 String articleId = typeSettingsProperties.getProperty("article-id");
708
709 if (Validator.isNotNull(articleId)) {
710 Map<String, String> articleIds =
711 (Map<String, String>)context.getNewPrimaryKeysMap(
712 JournalArticle.class);
713
714 typeSettingsProperties.setProperty(
715 "article-id",
716 MapUtil.getString(articleIds, articleId, articleId));
717
718 LayoutUtil.update(layout, false);
719 }
720 }
721
722 zipReader.close();
723 }
724
725 protected void deleteMissingLayouts(
726 long groupId, boolean privateLayout, Set<Long> newLayoutIds,
727 List<Layout> previousLayouts)
728 throws PortalException, SystemException {
729
730
732 if (_log.isDebugEnabled()) {
733 if (newLayoutIds.size() > 0) {
734 _log.debug("Delete missing layouts");
735 }
736 }
737
738 for (Layout layout : previousLayouts) {
739 if (!newLayoutIds.contains(layout.getLayoutId())) {
740 try {
741 LayoutLocalServiceUtil.deleteLayout(layout, false);
742 }
743 catch (NoSuchLayoutException nsle) {
744 }
745 }
746 }
747
748
750 LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
751 }
752
753 protected void fixTypeSettings(Layout layout) {
754 if (!layout.getType().equals(LayoutConstants.TYPE_URL)) {
755 return;
756 }
757
758 UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
759
760 String url = GetterUtil.getString(typeSettings.getProperty("url"));
761
762 String friendlyURLPrivateGroupPath =
763 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
764 String friendlyURLPrivateUserPath =
765 PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
766 String friendlyURLPublicPath =
767 PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
768
769 if (!url.startsWith(friendlyURLPrivateGroupPath) &&
770 !url.startsWith(friendlyURLPrivateUserPath) &&
771 !url.startsWith(friendlyURLPublicPath)) {
772
773 return;
774 }
775
776 int x = url.indexOf(StringPool.SLASH, 1);
777
778 if (x == -1) {
779 return;
780 }
781
782 int y = url.indexOf(StringPool.SLASH, x + 1);
783
784 if (y == -1) {
785 return;
786 }
787
788 String friendlyURL = url.substring(x, y);
789
790 if (!friendlyURL.equals(LayoutExporter.SAME_GROUP_FRIENDLY_URL)) {
791 return;
792 }
793
794 typeSettings.setProperty(
795 "url",
796 url.substring(0, x) + layout.getGroup().getFriendlyURL() +
797 url.substring(y));
798 }
799
800 protected List<String> getActions(Element el) {
801 List<String> actions = new ArrayList<String>();
802
803 Iterator<Element> itr = el.elements("action-key").iterator();
804
805 while (itr.hasNext()) {
806 Element actionEl = itr.next();
807
808 actions.add(actionEl.getText());
809 }
810
811 return actions;
812 }
813
814 protected void importGroupPermissions(
815 LayoutCache layoutCache, long companyId, long groupId,
816 String resourceName, String resourcePrimKey, Element parentEl,
817 String elName, boolean portletActions)
818 throws PortalException, SystemException {
819
820 Element actionEl = parentEl.element(elName);
821
822 if (actionEl == null) {
823 return;
824 }
825
826 List<String> actions = getActions(actionEl);
827
828 Resource resource = layoutCache.getResource(
829 companyId, groupId, resourceName,
830 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
831 portletActions);
832
833 PermissionLocalServiceUtil.setGroupPermissions(
834 groupId, actions.toArray(new String[actions.size()]),
835 resource.getResourceId());
836 }
837
838 protected void importGroupRoles(
839 LayoutCache layoutCache, long companyId, long groupId,
840 String resourceName, String entityName,
841 Element parentEl)
842 throws PortalException, SystemException {
843
844 Element entityRolesEl = parentEl.element(entityName + "-roles");
845
846 if (entityRolesEl == null) {
847 return;
848 }
849
850 importRolePermissions(
851 layoutCache, companyId, resourceName, ResourceConstants.SCOPE_GROUP,
852 String.valueOf(groupId), entityRolesEl, true);
853 }
854
855 protected void importInheritedPermissions(
856 LayoutCache layoutCache, long companyId, String resourceName,
857 String resourcePrimKey, Element permissionsEl, String entityName,
858 boolean portletActions)
859 throws PortalException, SystemException {
860
861 Element entityPermissionsEl = permissionsEl.element(
862 entityName + "-permissions");
863
864 if (entityPermissionsEl == null) {
865 return;
866 }
867
868 List<Element> actionsEls = entityPermissionsEl.elements(
869 entityName + "-actions");
870
871 for (int i = 0; i < actionsEls.size(); i++) {
872 Element actionEl = actionsEls.get(i);
873
874 String name = actionEl.attributeValue("name");
875
876 long entityGroupId = layoutCache.getEntityGroupId(
877 companyId, entityName, name);
878
879 if (entityGroupId == 0) {
880 _log.warn(
881 "Ignore inherited permissions for entity " + entityName +
882 " with name " + name);
883 }
884 else {
885 Element parentEl = SAXReaderUtil.createElement("parent");
886
887 parentEl.add(actionEl.createCopy());
888
889 importGroupPermissions(
890 layoutCache, companyId, entityGroupId, resourceName,
891 resourcePrimKey, parentEl, entityName + "-actions",
892 portletActions);
893 }
894 }
895 }
896
897 protected void importInheritedRoles(
898 LayoutCache layoutCache, long companyId, long groupId,
899 String resourceName, String entityName, Element parentEl)
900 throws PortalException, SystemException {
901
902 Element entityRolesEl = parentEl.element(entityName + "-roles");
903
904 if (entityRolesEl == null) {
905 return;
906 }
907
908 List<Element> entityEls = entityRolesEl.elements(entityName);
909
910 for (int i = 0; i < entityEls.size(); i++) {
911 Element entityEl = entityEls.get(i);
912
913 String name = entityEl.attributeValue("name");
914
915 long entityGroupId = layoutCache.getEntityGroupId(
916 companyId, entityName, name);
917
918 if (entityGroupId == 0) {
919 _log.warn(
920 "Ignore inherited roles for entity " + entityName +
921 " with name " + name);
922 }
923 else {
924 importRolePermissions(
925 layoutCache, companyId, resourceName,
926 ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
927 entityEl, false);
928 }
929 }
930 }
931
932 protected void importLayoutPermissions_4(
933 LayoutCache layoutCache, long companyId, long groupId,
934 Group guestGroup, Layout layout, String resourceName,
935 String resourcePrimKey, Element permissionsEl,
936 boolean importUserPermissions)
937 throws PortalException, SystemException {
938
939 importGroupPermissions(
940 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
941 permissionsEl, "community-actions", false);
942
943 if (groupId != guestGroup.getGroupId()) {
944 importGroupPermissions(
945 layoutCache, companyId, guestGroup.getGroupId(), resourceName,
946 resourcePrimKey, permissionsEl, "guest-actions", false);
947 }
948
949 if (importUserPermissions) {
950 importUserPermissions(
951 layoutCache, companyId, groupId, resourceName, resourcePrimKey,
952 permissionsEl, false);
953 }
954
955 importInheritedPermissions(
956 layoutCache, companyId, resourceName, resourcePrimKey,
957 permissionsEl, "organization", false);
958
959 importInheritedPermissions(
960 layoutCache, companyId, resourceName, resourcePrimKey,
961 permissionsEl, "location", false);
962
963 importInheritedPermissions(
964 layoutCache, companyId, resourceName, resourcePrimKey,
965 permissionsEl, "user-group", false);
966 }
967
968 protected void importLayoutPermissions_5(
969 LayoutCache layoutCache, long companyId, long groupId, long userId,
970 String resourceName, String resourcePrimKey, Element permissionsEl)
971 throws PortalException, SystemException {
972
973 boolean portletActions = false;
974
975 Resource resource = layoutCache.getResource(
976 companyId, groupId, resourceName,
977 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
978 portletActions);
979
980 importPermissions_5(
981 layoutCache, companyId, userId, resource.getResourceId(),
982 permissionsEl);
983 }
984
985 protected void importLayoutPermissions_6(
986 LayoutCache layoutCache, long companyId, long groupId, long userId,
987 String resourceName, String resourcePrimKey, Element permissionsEl)
988 throws PortalException, SystemException {
989
990 boolean portletActions = false;
991
992 importPermissions_6(
993 layoutCache, companyId, groupId, userId, resourceName,
994 resourcePrimKey, permissionsEl, portletActions);
995 }
996
997 protected void importLayoutRoles(
998 LayoutCache layoutCache, long companyId, long groupId,
999 Element rolesEl)
1000 throws PortalException, SystemException {
1001
1002 String resourceName = Layout.class.getName();
1003
1004 importGroupRoles(
1005 layoutCache, companyId, groupId, resourceName, "community",
1006 rolesEl);
1007
1008 importUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
1009
1010 importInheritedRoles(
1011 layoutCache, companyId, groupId, resourceName, "organization",
1012 rolesEl);
1013
1014 importInheritedRoles(
1015 layoutCache, companyId, groupId, resourceName, "location", rolesEl);
1016
1017 importInheritedRoles(
1018 layoutCache, companyId, groupId, resourceName, "user-group",
1019 rolesEl);
1020 }
1021
1022 protected void importPermissions_5(
1023 LayoutCache layoutCache, long companyId, long userId,
1024 long resourceId, Element permissionsEl)
1025 throws PortalException, SystemException {
1026
1027 List<Element> roleEls = permissionsEl.elements("role");
1028
1029 for (Element roleEl : roleEls) {
1030 String name = roleEl.attributeValue("name");
1031
1032 Role role = layoutCache.getRole(companyId, name);
1033
1034 if (role == null) {
1035 String description = roleEl.attributeValue("description");
1036 int type = Integer.valueOf(roleEl.attributeValue("type"));
1037
1038 role = RoleLocalServiceUtil.addRole(
1039 userId, companyId, name, description, type);
1040 }
1041
1042 List<String> actions = getActions(roleEl);
1043
1044 PermissionLocalServiceUtil.setRolePermissions(
1045 role.getRoleId(), actions.toArray(new String[actions.size()]),
1046 resourceId);
1047 }
1048 }
1049
1050 protected void importPermissions_6(
1051 LayoutCache layoutCache, long companyId, long groupId, long userId,
1052 String resourceName, String resourcePrimKey, Element permissionsEl,
1053 boolean portletActions)
1054 throws PortalException, SystemException {
1055
1056 List<Element> roleEls = permissionsEl.elements("role");
1057
1058 for (Element roleEl : roleEls) {
1059 String name = roleEl.attributeValue("name");
1060
1061 Role role = layoutCache.getRole(companyId, name);
1062
1063 if (role == null) {
1064 String description = roleEl.attributeValue("description");
1065 int type = Integer.valueOf(roleEl.attributeValue("type"));
1066
1067 role = RoleLocalServiceUtil.addRole(
1068 userId, companyId, name, description, type);
1069 }
1070
1071 List<String> actions = getActions(roleEl);
1072
1073 ResourcePermissionLocalServiceUtil.setResourcePermissions(
1074 companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
1075 resourcePrimKey, role.getRoleId(),
1076 actions.toArray(new String[actions.size()]));
1077 }
1078 }
1079
1080 protected void importPortletPermissions_4(
1081 LayoutCache layoutCache, long companyId, long groupId,
1082 Group guestGroup, Layout layout, Element permissionsEl,
1083 boolean importUserPermissions)
1084 throws PortalException, SystemException {
1085
1086 Iterator<Element> itr = permissionsEl.elements("portlet").iterator();
1087
1088 while (itr.hasNext()) {
1089 Element portletEl = itr.next();
1090
1091 String portletId = portletEl.attributeValue("portlet-id");
1092
1093 String resourceName = PortletConstants.getRootPortletId(portletId);
1094 String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
1095 layout.getPlid(), portletId);
1096
1097 Portlet portlet = PortletLocalServiceUtil.getPortletById(
1098 companyId, resourceName);
1099
1100 if (portlet == null) {
1101 if (_log.isDebugEnabled()) {
1102 _log.debug(
1103 "Do not import portlet permissions for " + portletId +
1104 " because the portlet does not exist");
1105 }
1106 }
1107 else {
1108 importGroupPermissions(
1109 layoutCache, companyId, groupId, resourceName,
1110 resourcePrimKey, portletEl, "community-actions", true);
1111
1112 if (groupId != guestGroup.getGroupId()) {
1113 importGroupPermissions(
1114 layoutCache, companyId, guestGroup.getGroupId(),
1115 resourceName, resourcePrimKey, portletEl,
1116 "guest-actions", true);
1117 }
1118
1119 if (importUserPermissions) {
1120 importUserPermissions(
1121 layoutCache, companyId, groupId, resourceName,
1122 resourcePrimKey, portletEl, true);
1123 }
1124
1125 importInheritedPermissions(
1126 layoutCache, companyId, resourceName, resourcePrimKey,
1127 portletEl, "organization", true);
1128
1129 importInheritedPermissions(
1130 layoutCache, companyId, resourceName, resourcePrimKey,
1131 portletEl, "location", true);
1132
1133 importInheritedPermissions(
1134 layoutCache, companyId, resourceName, resourcePrimKey,
1135 portletEl, "user-group", true);
1136 }
1137 }
1138 }
1139
1140 protected void importPortletPermissions_5(
1141 LayoutCache layoutCache, long companyId, long groupId, long userId,
1142 String resourceName, String resourcePrimKey, Element permissionsEl)
1143 throws PortalException, SystemException {
1144
1145 boolean portletActions = true;
1146
1147 Resource resource = layoutCache.getResource(
1148 companyId, groupId, resourceName,
1149 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
1150 portletActions);
1151
1152 importPermissions_5(
1153 layoutCache, companyId, userId, resource.getResourceId(),
1154 permissionsEl);
1155 }
1156
1157 protected void importPortletPermissions_6(
1158 LayoutCache layoutCache, long companyId, long groupId, long userId,
1159 String resourceName, String resourcePrimKey, Element permissionsEl)
1160 throws PortalException, SystemException {
1161
1162 boolean portletActions = true;
1163
1164 importPermissions_6(
1165 layoutCache, companyId, groupId, userId, resourceName,
1166 resourcePrimKey, permissionsEl, portletActions);
1167 }
1168
1169 protected void importPortletRoles(
1170 LayoutCache layoutCache, long companyId, long groupId,
1171 String portletId, Element rolesEl)
1172 throws PortalException, SystemException {
1173
1174 String resourceName = PortletConstants.getRootPortletId(portletId);
1175
1176 Portlet portlet = PortletLocalServiceUtil.getPortletById(
1177 companyId, resourceName);
1178
1179 if (portlet == null) {
1180 if (_log.isDebugEnabled()) {
1181 _log.debug(
1182 "Do not import portlet roles for " + portletId +
1183 " because the portlet does not exist");
1184 }
1185 }
1186 else {
1187 importGroupRoles(
1188 layoutCache, companyId, groupId, resourceName, "community",
1189 rolesEl);
1190
1191 importUserRoles(
1192 layoutCache, companyId, groupId, resourceName, rolesEl);
1193
1194 importInheritedRoles(
1195 layoutCache, companyId, groupId, resourceName,
1196 "organization", rolesEl);
1197
1198 importInheritedRoles(
1199 layoutCache, companyId, groupId, resourceName, "location",
1200 rolesEl);
1201
1202 importInheritedRoles(
1203 layoutCache, companyId, groupId, resourceName, "user-group",
1204 rolesEl);
1205 }
1206 }
1207
1208 protected void importPortletRoles(
1209 LayoutCache layoutCache, long companyId, long groupId,
1210 Element rolesEl)
1211 throws PortalException, SystemException {
1212
1213 Iterator<Element> itr = rolesEl.elements("portlet").iterator();
1214
1215 while (itr.hasNext()) {
1216 Element portletEl = itr.next();
1217
1218 String portletId = portletEl.attributeValue("portlet-id");
1219
1220 String resourceName = PortletConstants.getRootPortletId(portletId);
1221
1222 Portlet portlet = PortletLocalServiceUtil.getPortletById(
1223 companyId, resourceName);
1224
1225 if (portlet == null) {
1226 if (_log.isDebugEnabled()) {
1227 _log.debug(
1228 "Do not import portlet roles for " + portletId +
1229 " because the portlet does not exist");
1230 }
1231 }
1232 else {
1233 importGroupRoles(
1234 layoutCache, companyId, groupId, resourceName, "community",
1235 portletEl);
1236
1237 importUserRoles(
1238 layoutCache, companyId, groupId, resourceName, portletEl);
1239
1240 importInheritedRoles(
1241 layoutCache, companyId, groupId, resourceName,
1242 "organization", portletEl);
1243
1244 importInheritedRoles(
1245 layoutCache, companyId, groupId, resourceName, "location",
1246 portletEl);
1247
1248 importInheritedRoles(
1249 layoutCache, companyId, groupId, resourceName, "user-group",
1250 portletEl);
1251 }
1252 }
1253 }
1254
1255 protected void importRolePermissions(
1256 LayoutCache layoutCache, long companyId, String resourceName,
1257 int scope, String resourcePrimKey, Element parentEl,
1258 boolean communityRole)
1259 throws PortalException, SystemException {
1260
1261 List<Element> roleEls = parentEl.elements("role");
1262
1263 for (int i = 0; i < roleEls.size(); i++) {
1264 Element roleEl = roleEls.get(i);
1265
1266 String roleName = roleEl.attributeValue("name");
1267
1268 Role role = layoutCache.getRole(companyId, roleName);
1269
1270 if (role == null) {
1271 _log.warn(
1272 "Ignoring permissions for role with name " + roleName);
1273 }
1274 else {
1275 List<String> actions = getActions(roleEl);
1276
1277 PermissionLocalServiceUtil.setRolePermissions(
1278 role.getRoleId(), companyId, resourceName, scope,
1279 resourcePrimKey,
1280 actions.toArray(new String[actions.size()]));
1281
1282 if (communityRole) {
1283 long[] groupIds = {GetterUtil.getLong(resourcePrimKey)};
1284
1285 GroupLocalServiceUtil.addRoleGroups(
1286 role.getRoleId(), groupIds);
1287 }
1288 }
1289 }
1290 }
1291
1292 protected String importTheme(LayoutSet layoutSet, InputStream themeZip)
1293 throws IOException {
1294
1295 ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
1296
1297 if (themeLoader == null) {
1298 _log.error("No theme loaders are deployed");
1299
1300 return null;
1301 }
1302
1303 ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(themeZip);
1304
1305 String lookAndFeelXML = zipReader.getEntryAsString(
1306 "liferay-look-and-feel.xml");
1307
1308 String themeId = String.valueOf(layoutSet.getGroupId());
1309
1310 if (layoutSet.isPrivateLayout()) {
1311 themeId += "-private";
1312 }
1313 else {
1314 themeId += "-public";
1315 }
1316
1317 if (PropsValues.THEME_LOADER_NEW_THEME_ID_ON_IMPORT) {
1318 Date now = new Date();
1319
1320 themeId += "-" + Time.getShortTimestamp(now);
1321 }
1322
1323 String themeName = themeId;
1324
1325 lookAndFeelXML = StringUtil.replace(
1326 lookAndFeelXML,
1327 new String[] {
1328 "[$GROUP_ID$]", "[$THEME_ID$]", "[$THEME_NAME$]"
1329 },
1330 new String[] {
1331 String.valueOf(layoutSet.getGroupId()), themeId, themeName
1332 }
1333 );
1334
1335 FileUtil.deltree(
1336 themeLoader.getFileStorage() + StringPool.SLASH + themeId);
1337
1338 List<String> zipEntries = zipReader.getEntries();
1339
1340 for (String zipEntry : zipEntries) {
1341 String key = zipEntry;
1342
1343 if (key.contains(StringPool.SLASH)) {
1344 key = key.substring(key.lastIndexOf(StringPool.SLASH));
1345 }
1346
1347 if (key.equals("liferay-look-and-feel.xml")) {
1348 FileUtil.write(
1349 themeLoader.getFileStorage() + StringPool.SLASH + themeId +
1350 StringPool.SLASH + key,
1351 lookAndFeelXML.getBytes());
1352 }
1353 else {
1354 InputStream is = zipReader.getEntryAsInputStream(zipEntry);
1355
1356 FileUtil.write(
1357 themeLoader.getFileStorage() + StringPool.SLASH + themeId +
1358 StringPool.SLASH + key,
1359 is);
1360 }
1361 }
1362
1363 themeLoader.loadThemes();
1364
1365 MethodWrapper methodWrapper = new MethodWrapper(
1366 ThemeLoaderFactory.class.getName(), "loadThemes");
1367
1368 Message message = new Message();
1369 message.setPayload(methodWrapper);
1370
1371 ClusterLinkUtil.sendMulticastMessage(message, Priority.LEVEL5);
1372
1373 themeId +=
1374 PortletConstants.WAR_SEPARATOR +
1375 themeLoader.getServletContextName();
1376
1377 return PortalUtil.getJsSafePortletId(themeId);
1378 }
1379
1380 protected void importUserPermissions(
1381 LayoutCache layoutCache, long companyId, long groupId,
1382 String resourceName, String resourcePrimKey, Element parentEl,
1383 boolean portletActions)
1384 throws PortalException, SystemException {
1385
1386 Element userPermissionsEl = parentEl.element("user-permissions");
1387
1388 if (userPermissionsEl == null) {
1389 return;
1390 }
1391
1392 List<Element> userActionsEls = userPermissionsEl.elements(
1393 "user-actions");
1394
1395 for (int i = 0; i < userActionsEls.size(); i++) {
1396 Element userActionsEl = userActionsEls.get(i);
1397
1398 String emailAddress = userActionsEl.attributeValue("email-address");
1399
1400 User user = layoutCache.getUser(companyId, groupId, emailAddress);
1401
1402 if (user == null) {
1403 if (_log.isWarnEnabled()) {
1404 _log.warn(
1405 "Ignoring permissions for user with email address " +
1406 emailAddress);
1407 }
1408 }
1409 else {
1410 List<String> actions = getActions(userActionsEl);
1411
1412 Resource resource = layoutCache.getResource(
1413 companyId, groupId, resourceName,
1414 ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
1415 portletActions);
1416
1417 PermissionLocalServiceUtil.setUserPermissions(
1418 user.getUserId(),
1419 actions.toArray(new String[actions.size()]),
1420 resource.getResourceId());
1421 }
1422 }
1423 }
1424
1425 protected void importUserRoles(
1426 LayoutCache layoutCache, long companyId, long groupId,
1427 String resourceName, Element parentEl)
1428 throws PortalException, SystemException {
1429
1430 Element userRolesEl = parentEl.element("user-roles");
1431
1432 if (userRolesEl == null) {
1433 return;
1434 }
1435
1436 List<Element> userEls = userRolesEl.elements("user");
1437
1438 for (int i = 0; i < userEls.size(); i++) {
1439 Element userEl = userEls.get(i);
1440
1441 String emailAddress = userEl.attributeValue("email-address");
1442
1443 User user = layoutCache.getUser(companyId, groupId, emailAddress);
1444
1445 if (user == null) {
1446 if (_log.isWarnEnabled()) {
1447 _log.warn(
1448 "Ignoring roles for user with email address " +
1449 emailAddress);
1450 }
1451 }
1452 else {
1453 importRolePermissions(
1454 layoutCache, companyId, resourceName,
1455 ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
1456 userEl, false);
1457 }
1458 }
1459 }
1460
1461 protected void mergePortlets(
1462 Layout layout, String newTypeSettings, String portletsMergeMode) {
1463
1464 try {
1465 UnicodeProperties previousProps =
1466 layout.getTypeSettingsProperties();
1467 LayoutTypePortlet previousLayoutType =
1468 (LayoutTypePortlet)layout.getLayoutType();
1469 List<String> previousColumns =
1470 previousLayoutType.getLayoutTemplate().getColumns();
1471
1472 UnicodeProperties newProps = new UnicodeProperties(true);
1473
1474 newProps.load(newTypeSettings);
1475
1476 String layoutTemplateId = newProps.getProperty(
1477 LayoutTypePortletImpl.LAYOUT_TEMPLATE_ID);
1478
1479 LayoutTemplate newLayoutTemplate =
1480 LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1481 layoutTemplateId, false, null);
1482
1483 String[] lostPortletIds = new String[0];
1484
1485 for (String columnId : newLayoutTemplate.getColumns()) {
1486 String columnValue =
1487 newProps.getProperty(columnId);
1488
1489 String[] portletIds = StringUtil.split(columnValue);
1490
1491 if (!previousColumns.contains(columnId)) {
1492 lostPortletIds = ArrayUtil.append(
1493 lostPortletIds, portletIds);
1494 }
1495 else {
1496
1497 String[] previousPortletIds = StringUtil.split(
1498 previousProps.getProperty(columnId));
1499
1500 portletIds = appendPortletIds(
1501 previousPortletIds, portletIds, portletsMergeMode);
1502
1503 previousProps.setProperty(
1504 columnId, StringUtil.merge(portletIds));
1505 }
1506 }
1507
1508
1510 String columnId = previousColumns.get(0);
1511
1512 String[] portletIds = StringUtil.split(
1513 previousProps.getProperty(columnId));
1514
1515 appendPortletIds(portletIds, lostPortletIds, portletsMergeMode);
1516
1517 previousProps.setProperty(
1518 columnId, StringUtil.merge(portletIds));
1519
1520 layout.setTypeSettings(previousProps.toString());
1521
1522 }
1523 catch (IOException e) {
1524 layout.setTypeSettings(newTypeSettings);
1525 }
1526 }
1527
1528 protected String[] appendPortletIds(
1529 String[] portletIds, String[] newPortletIds,
1530 String portletsMergeMode) {
1531
1532 for (String portletId : newPortletIds) {
1533 if (ArrayUtil.contains(portletIds, portletId)) {
1534 continue;
1535 }
1536
1537 if (portletsMergeMode.equals(
1538 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM)) {
1539 portletIds = ArrayUtil.append(
1540 portletIds, portletId);
1541 }
1542 else {
1543 portletIds = ArrayUtil.append(
1544 new String[] {portletId}, portletIds);
1545 }
1546 }
1547
1548 return portletIds;
1549 }
1550
1551 private static Log _log = LogFactoryUtil.getLog(LayoutImporter.class);
1552
1553 private PortletImporter _portletImporter = new PortletImporter();
1554
1555}