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