1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
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  /**
98   * <a href="LayoutImporter.java.html"><b><i>View Source</i></b></a>
99   *
100  * @author Brian Wing Shun Chan
101  * @author Joel Kozikowski
102  * @author Charles May
103  * @author Raymond Augé
104  * @author Jorge Ferrer
105  * @author Bruno Farache
106  * @author Wesley Gong
107  */
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         // Zip
188 
189         Element root = null;
190         InputStream themeZip = null;
191 
192         // Manifest
193 
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         // Build compatibility
210 
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         // Type compatibility
225 
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         // Import GroupId
234 
235         long importGroupId = GetterUtil.getLong(
236             header.attributeValue("group-id"));
237 
238         context.setImportGroupId(importGroupId);
239 
240         // Look and feel
241 
242         if (importTheme) {
243             themeZip = context.getZipEntryAsInputStream("theme.zip");
244         }
245 
246         // Look and feel
247 
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         // Read comments, ratings, and tags to make them available to the data
282         // handlers through the context
283 
284         _portletImporter.readComments(context, root);
285         _portletImporter.readRatings(context, root);
286         _portletImporter.readTags(context, root);
287 
288         // Layouts
289 
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             // Layout permissions
512 
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         // Delete portlet data
542 
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         // Import portlets
563 
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             // The order of the import is important. You must always import
597             // the portlet preferences first, then the portlet data, then
598             // the portlet permissions. The import of the portlet data
599             // assumes that portlet preferences already exist.
600 
601             // Portlet preferences
602 
603             _portletImporter.importPortletPreferences(
604                 context, layoutSet.getCompanyId(), layout.getGroupId(),
605                 layout.getPlid(), null, portletEl, importPortletSetup,
606                 importPortletArchivedSetups, importPortletUserPreferences);
607 
608             // Portlet data
609 
610             Element portletDataEl = portletEl.element("portlet-data");
611 
612             if (importPortletData && portletDataEl != null) {
613                 _portletImporter.importPortletData(
614                     context, portletId, plid, portletDataEl);
615             }
616 
617             // Portlet permissions
618 
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             // Archived setups
654 
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                 // Portlet roles
663 
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             // Layout roles
680 
681             if (importPermissions) {
682                 importLayoutRoles(layoutCache, companyId, groupId, rolesEl);
683             }
684         }
685 
686         // Delete missing layouts
687 
688         if (deleteMissingLayouts) {
689             deleteMissingLayouts(
690                 groupId, privateLayout, newLayoutIds, previousLayouts);
691         }
692 
693         // Page count
694 
695         LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
696 
697         if (_log.isInfoEnabled()) {
698             _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
699         }
700 
701         // Article layout type
702 
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         // Layouts
731 
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         // Layout set
749 
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            // Add portlets in non-existent column to the first column
1509
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}