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