1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.service.impl;
24  
25  import com.liferay.counter.service.CounterLocalServiceUtil;
26  import com.liferay.portal.LayoutFriendlyURLException;
27  import com.liferay.portal.LayoutHiddenException;
28  import com.liferay.portal.LayoutImportException;
29  import com.liferay.portal.LayoutNameException;
30  import com.liferay.portal.LayoutParentLayoutIdException;
31  import com.liferay.portal.LayoutTypeException;
32  import com.liferay.portal.NoSuchLayoutException;
33  import com.liferay.portal.NoSuchPortletPreferencesException;
34  import com.liferay.portal.PortalException;
35  import com.liferay.portal.RequiredLayoutException;
36  import com.liferay.portal.SystemException;
37  import com.liferay.portal.comm.CommLink;
38  import com.liferay.portal.kernel.lar.PortletDataContext;
39  import com.liferay.portal.kernel.lar.PortletDataHandler;
40  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
41  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
42  import com.liferay.portal.kernel.util.GetterUtil;
43  import com.liferay.portal.kernel.util.LocaleUtil;
44  import com.liferay.portal.kernel.util.MethodWrapper;
45  import com.liferay.portal.kernel.util.StringPool;
46  import com.liferay.portal.kernel.util.StringUtil;
47  import com.liferay.portal.kernel.util.Validator;
48  import com.liferay.portal.kernel.zip.ZipReader;
49  import com.liferay.portal.kernel.zip.ZipWriter;
50  import com.liferay.portal.model.Group;
51  import com.liferay.portal.model.Layout;
52  import com.liferay.portal.model.LayoutReference;
53  import com.liferay.portal.model.LayoutSet;
54  import com.liferay.portal.model.LayoutTypePortlet;
55  import com.liferay.portal.model.Portlet;
56  import com.liferay.portal.model.PortletPreferences;
57  import com.liferay.portal.model.Resource;
58  import com.liferay.portal.model.Role;
59  import com.liferay.portal.model.Theme;
60  import com.liferay.portal.model.User;
61  import com.liferay.portal.model.impl.ColorSchemeImpl;
62  import com.liferay.portal.model.impl.GroupImpl;
63  import com.liferay.portal.model.impl.LayoutImpl;
64  import com.liferay.portal.model.impl.PortletImpl;
65  import com.liferay.portal.model.impl.ResourceImpl;
66  import com.liferay.portal.security.permission.ResourceActionsUtil;
67  import com.liferay.portal.service.GroupLocalServiceUtil;
68  import com.liferay.portal.service.LayoutSetLocalServiceUtil;
69  import com.liferay.portal.service.PermissionLocalServiceUtil;
70  import com.liferay.portal.service.PortletLocalServiceUtil;
71  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
72  import com.liferay.portal.service.ResourceLocalServiceUtil;
73  import com.liferay.portal.service.RoleLocalServiceUtil;
74  import com.liferay.portal.service.UserLocalServiceUtil;
75  import com.liferay.portal.service.base.LayoutLocalServiceBaseImpl;
76  import com.liferay.portal.service.permission.PortletPermissionUtil;
77  import com.liferay.portal.service.persistence.LayoutFinder;
78  import com.liferay.portal.service.persistence.LayoutUtil;
79  import com.liferay.portal.service.persistence.PortletPreferencesUtil;
80  import com.liferay.portal.service.persistence.ResourceFinder;
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.ContentUtil;
85  import com.liferay.portal.util.PortalUtil;
86  import com.liferay.portal.util.PortletKeys;
87  import com.liferay.portal.util.PropsUtil;
88  import com.liferay.portal.util.ReleaseInfo;
89  import com.liferay.portal.util.comparator.LayoutPriorityComparator;
90  import com.liferay.portal.velocity.VelocityContextPool;
91  import com.liferay.portlet.PortletPreferencesImpl;
92  import com.liferay.portlet.PortletPreferencesSerializer;
93  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
94  import com.liferay.portlet.documentlibrary.model.DLFolder;
95  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
96  import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
97  import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
98  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
99  import com.liferay.portlet.ratings.service.RatingsStatsLocalServiceUtil;
100 import com.liferay.util.CollectionFactory;
101 import com.liferay.util.FileUtil;
102 import com.liferay.util.MapUtil;
103 import com.liferay.util.Time;
104 import com.liferay.util.xml.XMLFormatter;
105 
106 import java.io.ByteArrayInputStream;
107 import java.io.File;
108 import java.io.FileInputStream;
109 import java.io.FileNotFoundException;
110 import java.io.IOException;
111 import java.io.InputStream;
112 import java.io.StringReader;
113 
114 import java.util.ArrayList;
115 import java.util.Collections;
116 import java.util.Date;
117 import java.util.Iterator;
118 import java.util.LinkedHashMap;
119 import java.util.LinkedHashSet;
120 import java.util.List;
121 import java.util.Locale;
122 import java.util.Map;
123 import java.util.Properties;
124 import java.util.Set;
125 
126 import javax.servlet.ServletContext;
127 
128 import org.apache.commons.lang.time.StopWatch;
129 import org.apache.commons.logging.Log;
130 import org.apache.commons.logging.LogFactory;
131 
132 import org.dom4j.Document;
133 import org.dom4j.DocumentHelper;
134 import org.dom4j.Element;
135 import org.dom4j.io.SAXReader;
136 
137 /**
138  * <a href="LayoutLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
139  *
140  * @author Brian Wing Shun Chan
141  * @author Joel Kozikowski
142  * @author Charles May
143  * @author Raymond Aug�
144  *
145  */
146 public class LayoutLocalServiceImpl extends LayoutLocalServiceBaseImpl {
147 
148     public Layout addLayout(
149             long userId, long groupId, boolean privateLayout,
150             long parentLayoutId, String name, String title, String description,
151             String type, boolean hidden, String friendlyURL)
152         throws PortalException, SystemException {
153 
154         return addLayout(
155             userId, groupId, privateLayout, parentLayoutId, name, title,
156             description, type, hidden, friendlyURL,
157             DLFolderImpl.DEFAULT_PARENT_FOLDER_ID);
158     }
159 
160     public Layout addLayout(
161             long userId, long groupId, boolean privateLayout,
162             long parentLayoutId, String name, String title, String description,
163             String type, boolean hidden, String friendlyURL, long dlFolderId)
164         throws PortalException, SystemException {
165 
166         // Layout
167 
168         User user = UserUtil.findByPrimaryKey(userId);
169         long layoutId = getNextLayoutId(groupId, privateLayout);
170         parentLayoutId = getParentLayoutId(
171             groupId, privateLayout, parentLayoutId);
172         friendlyURL = friendlyURL.toLowerCase();
173         int priority = getNextPriority(groupId, privateLayout, parentLayoutId);
174 
175         validate(
176             groupId, privateLayout, layoutId, parentLayoutId, name, type,
177             hidden, friendlyURL);
178 
179         long plid = CounterLocalServiceUtil.increment();
180 
181         Layout layout = LayoutUtil.create(plid);
182 
183         layout.setGroupId(groupId);
184         layout.setCompanyId(user.getCompanyId());
185         layout.setPrivateLayout(privateLayout);
186         layout.setLayoutId(layoutId);
187         layout.setParentLayoutId(parentLayoutId);
188         layout.setName(name, null);
189         layout.setTitle(title, null);
190         layout.setDescription(description);
191         layout.setType(type);
192         layout.setHidden(hidden);
193         layout.setFriendlyURL(friendlyURL);
194         layout.setPriority(priority);
195         layout.setDlFolderId(dlFolderId);
196 
197         LayoutUtil.update(layout);
198 
199         // Resources
200 
201         ResourceLocalServiceUtil.addResources(
202             user.getCompanyId(), groupId, user.getUserId(),
203             Layout.class.getName(), layout.getPlid(), false, true, true);
204 
205         // Layout set
206 
207         LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
208 
209         return layout;
210     }
211 
212     public void deleteLayout(long plid)
213         throws PortalException, SystemException {
214 
215         Layout layout = LayoutUtil.findByPrimaryKey(plid);
216 
217         deleteLayout(layout, true);
218     }
219 
220     public void deleteLayout(long groupId, boolean privateLayout, long layoutId)
221         throws PortalException, SystemException {
222 
223         Layout layout = LayoutUtil.findByG_P_L(
224             groupId, privateLayout, layoutId);
225 
226         deleteLayout(layout, true);
227     }
228 
229     public void deleteLayout(Layout layout, boolean updateLayoutSet)
230         throws PortalException, SystemException {
231 
232         // Child layouts
233 
234         List childLayouts = LayoutUtil.findByG_P_P(
235             layout.getGroupId(), layout.isPrivateLayout(),
236             layout.getLayoutId());
237 
238         for (int i = 0; i < childLayouts.size(); i++) {
239             Layout childLayout = (Layout)childLayouts.get(i);
240 
241             deleteLayout(childLayout, updateLayoutSet);
242         }
243 
244         // Portlet preferences
245 
246         PortletPreferencesLocalServiceUtil.deletePortletPreferences(
247             PortletKeys.PREFS_OWNER_ID_DEFAULT,
248             PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid());
249 
250         // Ratings
251 
252         RatingsStatsLocalServiceUtil.deleteStats(
253             Layout.class.getName(), layout.getPlid());
254 
255         // Message boards
256 
257         MBMessageLocalServiceUtil.deleteDiscussionMessages(
258             Layout.class.getName(), layout.getPlid());
259 
260         // Journal content searches
261 
262         JournalContentSearchLocalServiceUtil.deleteLayoutContentSearches(
263             layout.getGroupId(), layout.isPrivateLayout(),
264             layout.getLayoutId());
265 
266         // Icon
267 
268         ImageLocalUtil.deleteImage(layout.getIconImageId());
269 
270         // Resources
271 
272         String primKey = layout.getPlid() + PortletImpl.LAYOUT_SEPARATOR + "%";
273 
274         Iterator itr = ResourceFinder.findByC_P(
275             layout.getCompanyId(), primKey).iterator();
276 
277         while (itr.hasNext()) {
278             Resource resource = (Resource)itr.next();
279 
280             ResourceLocalServiceUtil.deleteResource(resource);
281         }
282 
283         ResourceLocalServiceUtil.deleteResource(
284             layout.getCompanyId(), Layout.class.getName(),
285             ResourceImpl.SCOPE_INDIVIDUAL, layout.getPlid());
286 
287         // Layout
288 
289         LayoutUtil.remove(layout.getPlid());
290 
291         // Layout set
292 
293         if (updateLayoutSet) {
294             LayoutSetLocalServiceUtil.updatePageCount(
295                 layout.getGroupId(), layout.isPrivateLayout());
296         }
297     }
298 
299     public void deleteLayouts(long groupId, boolean privateLayout)
300         throws PortalException, SystemException {
301 
302         // Layouts
303 
304         List layouts = LayoutUtil.findByG_P_P(
305             groupId, privateLayout, LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
306 
307         Iterator itr = layouts.iterator();
308 
309         while (itr.hasNext()) {
310             Layout layout = (Layout)itr.next();
311 
312             try {
313                 deleteLayout(layout, false);
314             }
315             catch (NoSuchLayoutException nsle) {
316             }
317         }
318 
319         // Layout set
320 
321         LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
322     }
323 
324     public byte[] exportLayouts(
325             long groupId, boolean privateLayout, Map parameterMap)
326         throws PortalException, SystemException {
327 
328         boolean exportPermissions = MapUtil.getBoolean(
329             parameterMap, PortletDataHandlerKeys.EXPORT_PERMISSIONS);
330         boolean exportPortletData = MapUtil.getBoolean(
331             parameterMap, PortletDataHandlerKeys.EXPORT_PORTLET_DATA);
332         boolean exportPortletPreferences = MapUtil.getBoolean(
333             parameterMap, PortletDataHandlerKeys.EXPORT_PORTLET_PREFERENCES);
334         boolean exportTheme = MapUtil.getBoolean(
335             parameterMap, PortletDataHandlerKeys.EXPORT_THEME);
336 
337         if (_log.isDebugEnabled()) {
338             _log.debug("Export permissions " + exportPermissions);
339             _log.debug("Export portlet data " + exportPortletData);
340             _log.debug(
341                 "Export portlet preferences " + exportPortletPreferences);
342             _log.debug("Export theme " + exportTheme);
343         }
344 
345         StopWatch stopWatch = null;
346 
347         if (_log.isInfoEnabled()) {
348             stopWatch = new StopWatch();
349 
350             stopWatch.start();
351         }
352 
353         LayoutCache layoutCache = new LayoutCache();
354 
355         LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
356             groupId, privateLayout);
357 
358         long companyId = layoutSet.getCompanyId();
359         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
360             companyId);
361 
362         ZipWriter zipWriter = new ZipWriter();
363 
364         PortletDataContext context = new PortletDataContext(
365             companyId, groupId, parameterMap, CollectionFactory.getHashSet(),
366             zipWriter);
367 
368         Group guestGroup = GroupLocalServiceUtil.getGroup(
369             companyId, GroupImpl.GUEST);
370 
371         // Build compatibility
372 
373         Document doc = DocumentHelper.createDocument();
374 
375         Element root = doc.addElement("root");
376 
377         Element header = root.addElement("header");
378 
379         header.addAttribute(
380             "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
381         header.addAttribute("group-id", String.valueOf(groupId));
382         header.addAttribute("private-layout", String.valueOf(privateLayout));
383         header.addAttribute("export-date", Time.getRFC822());
384         header.addAttribute("theme-id", layoutSet.getThemeId());
385         header.addAttribute("color-scheme-id", layoutSet.getColorSchemeId());
386 
387         // Layouts
388 
389         Set portletIds = new LinkedHashSet();
390 
391         Iterator itr = getLayouts(groupId, privateLayout).iterator();
392 
393         while (itr.hasNext()) {
394             Layout layout = (Layout)itr.next();
395 
396             Element layoutEl = root.addElement("layout");
397 
398             layoutEl.addAttribute(
399                 "layout-id", String.valueOf(layout.getLayoutId()));
400             layoutEl.addElement("parent-layout-id").addText(
401                 String.valueOf(layout.getParentLayoutId()));
402             layoutEl.addElement("name").addCDATA(layout.getName());
403             layoutEl.addElement("title").addCDATA(layout.getTitle());
404             layoutEl.addElement("type").addText(layout.getType());
405             layoutEl.addElement("type-settings").addCDATA(
406                 layout.getTypeSettings());
407             layoutEl.addElement("hidden").addText(
408                 String.valueOf(layout.getHidden()));
409             layoutEl.addElement("friendly-url").addText(
410                 layout.getFriendlyURL());
411             layoutEl.addElement("theme-id").addText(layout.getThemeId());
412             layoutEl.addElement("color-scheme-id").addText(
413                 layout.getColorSchemeId());
414             layoutEl.addElement("priority").addText(
415                 String.valueOf(layout.getPriority()));
416 
417             Element permissionsEl = layoutEl.addElement("permissions");
418 
419             // Layout permissions
420 
421             if (exportPermissions) {
422                 exportLayoutPermissions(
423                     layoutCache, companyId, groupId, guestGroup, layout,
424                     permissionsEl);
425             }
426 
427             if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
428                 LayoutTypePortlet layoutTypePortlet =
429                     (LayoutTypePortlet)layout.getLayoutType();
430 
431                 // The order of the export is important. You must always export
432                 // the portlet data first, then the portlet preferences, then
433                 // the portlet permissions. The export of the portlet data
434                 // process may modify the portlet preferences, and those changes
435                 // should be included in the exported LAR.
436 
437                 // Portlet data
438 
439                 if (exportPortletData) {
440                     exportPortletData(
441                         context, layout, layoutTypePortlet, layoutEl);
442                 }
443 
444                 // Portlet preferences
445 
446                 if (exportPortletPreferences) {
447                     exportPortletPreferences(
448                         PortletKeys.PREFS_OWNER_ID_DEFAULT,
449                         PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false,
450                         layout.getPlid(), layoutTypePortlet, layoutEl);
451 
452                     if (!layoutSet.isPrivateLayout()) {
453                         exportPortletPreferences(
454                             defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
455                             true, layout.getPlid(), layoutTypePortlet,
456                             layoutEl);
457                     }
458                 }
459 
460                 // Portlet permissions
461 
462                 if (exportPermissions) {
463                     exportPortletPermissions(
464                         layoutCache, companyId, groupId, guestGroup,
465                         layout, layoutTypePortlet, portletIds, permissionsEl);
466                 }
467             }
468         }
469 
470         // Portlet preferences
471 
472         if (exportPortletPreferences) {
473             exportPortletPreferences(
474                 groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
475                 PortletKeys.PREFS_PLID_SHARED, false, root);
476 
477         }
478 
479         Element rolesEl = root.addElement("roles");
480 
481         // Layout roles
482 
483         if (exportPermissions) {
484             exportLayoutRoles(layoutCache, companyId, groupId, rolesEl);
485         }
486 
487         // Portlet roles
488 
489         if (exportPermissions) {
490             exportPortletRoles(
491                 layoutCache, companyId, groupId, portletIds, rolesEl);
492         }
493 
494         // Look and feel
495 
496         byte[] themeZip = null;
497 
498         try {
499             if (exportTheme) {
500                 themeZip = exportTheme(layoutSet);
501             }
502         }
503         catch (IOException ioe) {
504             throw new SystemException(ioe);
505         }
506 
507         // XML
508 
509         if (_log.isInfoEnabled()) {
510             _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms");
511         }
512 
513         // Zip
514 
515         try {
516             zipWriter.addEntry("layouts.xml", XMLFormatter.toString(doc));
517 
518             if (themeZip != null) {
519                 zipWriter.addEntry("theme.zip", themeZip);
520             }
521 
522             return zipWriter.finish();
523         }
524         catch (IOException ioe) {
525             throw new SystemException(ioe);
526         }
527     }
528 
529     public long getDefaultPlid(long groupId, boolean privateLayout)
530         throws SystemException {
531 
532         if (groupId > 0) {
533             List layouts = LayoutUtil.findByG_P(groupId, privateLayout, 0, 1);
534 
535             if (layouts.size() > 0) {
536                 Layout layout = (Layout)layouts.get(0);
537 
538                 return layout.getPlid();
539             }
540         }
541 
542         return LayoutImpl.DEFAULT_PLID;
543     }
544 
545     public Layout getDLFolderLayout(long dlFolderId)
546         throws PortalException, SystemException {
547 
548         return LayoutUtil.findByDLF(dlFolderId);
549     }
550 
551     public Layout getFriendlyURLLayout(
552             long groupId, boolean privateLayout, String friendlyURL)
553         throws PortalException, SystemException {
554 
555         if (Validator.isNull(friendlyURL)) {
556             throw new NoSuchLayoutException();
557         }
558 
559         friendlyURL = friendlyURL.toLowerCase();
560 
561         return LayoutUtil.findByG_P_F(groupId, privateLayout, friendlyURL);
562     }
563 
564     public Layout getLayout(long plid)
565         throws PortalException, SystemException {
566 
567         return LayoutUtil.findByPrimaryKey(plid);
568     }
569 
570     public Layout getLayout(long groupId, boolean privateLayout, long layoutId)
571         throws PortalException, SystemException {
572 
573         return LayoutUtil.findByG_P_L(groupId, privateLayout, layoutId);
574     }
575 
576     public List getLayouts(long groupId, boolean privateLayout)
577         throws SystemException {
578 
579         return LayoutUtil.findByG_P(groupId, privateLayout);
580     }
581 
582     public List getLayouts(
583             long groupId, boolean privateLayout, long parentLayoutId)
584         throws SystemException {
585 
586         return LayoutUtil.findByG_P_P(groupId, privateLayout, parentLayoutId);
587     }
588 
589     public List getLayouts(
590             long groupId, boolean privateLayout, long parentLayoutId, int begin,
591             int end)
592         throws SystemException {
593 
594         return LayoutUtil.findByG_P_P(
595             groupId, privateLayout, parentLayoutId, begin, end);
596     }
597 
598     public LayoutReference[] getLayouts(
599             long companyId, String portletId, String prefsKey,
600             String prefsValue)
601         throws SystemException {
602 
603         List list = LayoutFinder.findByC_P_P(
604             companyId, portletId, prefsKey, prefsValue);
605 
606         return (LayoutReference[])list.toArray(new LayoutReference[0]);
607     }
608 
609     public void importLayouts(
610             long userId, long groupId, boolean privateLayout, Map parameterMap,
611             File file)
612         throws PortalException, SystemException {
613 
614         try {
615             importLayouts(
616                 userId, groupId, privateLayout, parameterMap,
617                 new FileInputStream(file));
618         }
619         catch (FileNotFoundException fnfe) {
620             throw new SystemException(fnfe);
621         }
622     }
623 
624     public void importLayouts(
625             long userId, long groupId, boolean privateLayout, Map parameterMap,
626             InputStream is)
627         throws PortalException, SystemException {
628 
629         boolean importPermissions = MapUtil.getBoolean(
630             parameterMap, PortletDataHandlerKeys.IMPORT_PERMISSIONS);
631         boolean importPortletData = MapUtil.getBoolean(
632             parameterMap, PortletDataHandlerKeys.IMPORT_PORTLET_DATA);
633         boolean importPortletPreferences = MapUtil.getBoolean(
634             parameterMap, PortletDataHandlerKeys.IMPORT_PORTLET_PREFERENCES);
635         boolean importTheme = MapUtil.getBoolean(
636             parameterMap, PortletDataHandlerKeys.IMPORT_THEME);
637 
638         if (_log.isDebugEnabled()) {
639             _log.debug("Import permissions " + importPermissions);
640             _log.debug("Import portlet data " + importPortletData);
641             _log.debug(
642                 "Import portlet preferences " + importPortletPreferences);
643             _log.debug("Import theme " + importTheme);
644         }
645 
646         StopWatch stopWatch = null;
647 
648         if (_log.isInfoEnabled()) {
649             stopWatch = new StopWatch();
650 
651             stopWatch.start();
652         }
653 
654         LayoutCache layoutCache = new LayoutCache();
655 
656         LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
657             groupId, privateLayout);
658 
659         long companyId = layoutSet.getCompanyId();
660 
661         ZipReader zipReader = new ZipReader(is);
662 
663         PortletDataContext context = new PortletDataContext(
664             companyId, groupId, parameterMap, CollectionFactory.getHashSet(),
665             zipReader);
666 
667         Group guestGroup = GroupLocalServiceUtil.getGroup(
668             companyId, GroupImpl.GUEST);
669 
670         // Zip
671 
672         Element root = null;
673         byte[] themeZip = null;
674 
675         try {
676 
677             // XML
678 
679             String xml = zipReader.getEntryAsString("layouts.xml");
680 
681             SAXReader reader = new SAXReader();
682 
683             Document doc = reader.read(new StringReader(xml));
684 
685             root = doc.getRootElement();
686 
687             // Look and feel
688 
689             if (importTheme) {
690                 themeZip = zipReader.getEntryAsByteArray("theme.zip");
691             }
692         }
693         catch (Exception e) {
694             throw new SystemException(e);
695         }
696 
697         // Build compatibility
698 
699         Element header = (Element)root.element("header");
700 
701         int buildNumber = ReleaseInfo.getBuildNumber();
702 
703         int importBuildNumber = GetterUtil.getInteger(
704             header.attributeValue("build-number"));
705 
706         if (buildNumber != importBuildNumber) {
707             throw new LayoutImportException(
708                 "LAR build number " + importBuildNumber + " does not match " +
709                     "portal build number " + buildNumber);
710         }
711 
712         // Look and feel
713 
714         String themeId = header.attributeValue("theme-id");
715         String colorSchemeId = header.attributeValue("color-scheme-id");
716 
717         boolean useThemeZip = false;
718 
719         if (themeZip != null) {
720             try {
721                 String importThemeId = importTheme(layoutSet, themeZip);
722 
723                 if (importThemeId != null) {
724                     themeId = importThemeId;
725                     colorSchemeId =
726                         ColorSchemeImpl.getDefaultRegularColorSchemeId();
727 
728                     useThemeZip = true;
729                 }
730 
731                 if (_log.isDebugEnabled()) {
732                     _log.debug(
733                         "Importing theme takes " + stopWatch.getTime() + " ms");
734                 }
735             }
736             catch (Exception e) {
737                 throw new SystemException(e);
738             }
739         }
740 
741         boolean wapTheme = false;
742 
743         LayoutSetLocalServiceUtil.updateLookAndFeel(
744             groupId, privateLayout, themeId, colorSchemeId, StringPool.BLANK,
745             wapTheme);
746 
747         // Layouts
748 
749         User user = UserUtil.findByPrimaryKey(userId);
750 
751         Set newLayoutIds = CollectionFactory.getHashSet();
752 
753         Iterator itr = root.elements("layout").iterator();
754 
755         if (_log.isDebugEnabled()) {
756             if (itr.hasNext()) {
757                 _log.debug("Importing layouts");
758             }
759         }
760 
761         while (itr.hasNext()) {
762             Element layoutEl = (Element)itr.next();
763 
764             long layoutId = GetterUtil.getInteger(
765                 layoutEl.attributeValue("layout-id"));
766             long parentLayoutId = GetterUtil.getInteger(
767                 layoutEl.elementText("parent-layout-id"));
768 
769             if (_log.isDebugEnabled()) {
770                 _log.debug(
771                     "Importing layout with layout id " + layoutId +
772                         " and parent layout id " + parentLayoutId);
773             }
774 
775             String name = layoutEl.elementText("name");
776             String title = layoutEl.elementText("title");
777             String type = layoutEl.elementText("type");
778             String typeSettings = layoutEl.elementText("type-settings");
779             boolean hidden = GetterUtil.getBoolean(
780                 layoutEl.elementText("hidden"));
781             String friendlyURL = layoutEl.elementText("friendly-url");
782 
783             if (useThemeZip) {
784                 themeId = StringPool.BLANK;
785                 colorSchemeId = StringPool.BLANK;
786             }
787             else {
788                 themeId = layoutEl.elementText("theme-id");
789                 colorSchemeId = layoutEl.elementText("color-scheme-id");
790             }
791 
792             int priority = GetterUtil.getInteger(
793                 layoutEl.elementText("priority"));
794 
795             Layout layout = LayoutUtil.fetchByG_P_L(
796                 groupId, privateLayout, layoutId);
797 
798             if (_log.isDebugEnabled()) {
799                 if (layout == null) {
800                     _log.debug(
801                         "Layout with {groupId=" + groupId + ",privateLayout=" +
802                             privateLayout + ",layoutId=" + layoutId +
803                                 "} does not exist");
804                 }
805                 else {
806                     _log.debug(
807                         "Layout with {groupId=" + groupId + ",privateLayout=" +
808                             privateLayout + ",layoutId=" + layoutId +
809                                 "} exists");
810                 }
811             }
812 
813             if (layout == null) {
814                 long plid = CounterLocalServiceUtil.increment();
815 
816                 layout = LayoutUtil.create(plid);
817 
818                 layout.setGroupId(groupId);
819                 layout.setPrivateLayout(privateLayout);
820                 layout.setLayoutId(layoutId);
821             }
822 
823             layout.setCompanyId(user.getCompanyId());
824             layout.setParentLayoutId(parentLayoutId);
825             layout.setName(name);
826             layout.setTitle(title);
827             layout.setType(type);
828             layout.setTypeSettings(typeSettings);
829             layout.setHidden(hidden);
830             layout.setFriendlyURL(friendlyURL);
831             layout.setThemeId(themeId);
832             layout.setColorSchemeId(colorSchemeId);
833             layout.setPriority(priority);
834 
835             fixTypeSettings(layout);
836 
837             LayoutUtil.update(layout);
838 
839             context.setPlid(layout.getPlid());
840 
841             newLayoutIds.add(new Long(layoutId));
842 
843             Element permissionsEl = layoutEl.element("permissions");
844 
845             // Layout permissions
846 
847             if (importPermissions) {
848                 importLayoutPermissions(
849                     layoutCache, companyId, groupId, guestGroup, layout,
850                     permissionsEl);
851             }
852 
853             // The order of the import is important. You must always import
854             // the portlet preferences first, then the portlet data, then
855             // the portlet permissions. The import of the portlet data
856             // assumes that portlet preferences already exist.
857 
858             // Portlet preferences
859 
860             if (importPortletPreferences) {
861                 importPortletPreferences(layoutSet, layout.getPlid(), layoutEl);
862             }
863 
864             // Portlet data
865 
866             if (importPortletData) {
867                 importPortletData(context, layout, layoutEl);
868             }
869 
870             // Portlet permissions
871 
872             if (importPermissions) {
873                 importPortletPermissions(
874                     layoutCache, companyId, groupId, guestGroup, layout,
875                     permissionsEl);
876             }
877         }
878 
879         // Portlet preferences
880 
881         /*if (importPortletPreferences) {
882             importPortletPreferences(layoutSet, root);
883         }*/
884 
885         Element rolesEl = (Element)root.element("roles");
886 
887         // Layout roles
888 
889         if (importPermissions) {
890             importLayoutRoles(layoutCache, companyId, groupId, rolesEl);
891         }
892 
893         // Portlet roles
894 
895         if (importPermissions) {
896             importPortletRoles(layoutCache, companyId, groupId, rolesEl);
897         }
898 
899         // Delete missing layouts
900 
901         deleteMissingLayouts(groupId, privateLayout, newLayoutIds);
902 
903         // Page count
904 
905         LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
906 
907         if (_log.isInfoEnabled()) {
908             _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
909         }
910     }
911 
912     public void setLayouts(
913             long groupId, boolean privateLayout, long parentLayoutId,
914             long[] layoutIds)
915         throws PortalException, SystemException {
916 
917         if (layoutIds == null) {
918             return;
919         }
920 
921         if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
922             if (layoutIds.length < 1) {
923                 throw new RequiredLayoutException(
924                     RequiredLayoutException.AT_LEAST_ONE);
925             }
926 
927             Layout layout = LayoutUtil.findByG_P_L(
928                 groupId, privateLayout, layoutIds[0]);
929 
930             if (!layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
931                 throw new RequiredLayoutException(
932                     RequiredLayoutException.FIRST_LAYOUT_TYPE);
933             }
934 
935             if (layout.isHidden()) {
936                 throw new RequiredLayoutException(
937                     RequiredLayoutException.FIRST_LAYOUT_HIDDEN);
938             }
939         }
940 
941         Set layoutIdsSet = new LinkedHashSet();
942 
943         for (int i = 0; i < layoutIds.length; i++) {
944             layoutIdsSet.add(new Long(layoutIds[i]));
945         }
946 
947         Set newLayoutIdsSet = CollectionFactory.getHashSet();
948 
949         Iterator itr = LayoutUtil.findByG_P_P(
950             groupId, privateLayout, parentLayoutId).iterator();
951 
952         while (itr.hasNext()) {
953             Layout layout = (Layout)itr.next();
954 
955             Long layoutIdObj = new Long(layout.getLayoutId());
956 
957             if (!layoutIdsSet.contains(layoutIdObj)) {
958                 deleteLayout(layout, true);
959             }
960             else {
961                 newLayoutIdsSet.add(layoutIdObj);
962             }
963         }
964 
965         int priority = 0;
966 
967         itr = layoutIdsSet.iterator();
968 
969         while (itr.hasNext()) {
970             Long layoutIdObj = (Long)itr.next();
971 
972             Layout layout = LayoutUtil.findByG_P_L(
973                 groupId, privateLayout, layoutIdObj.longValue());
974 
975             layout.setPriority(priority++);
976 
977             LayoutUtil.update(layout);
978         }
979 
980         LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
981     }
982 
983     public Layout updateLayout(
984             long groupId, boolean privateLayout, long layoutId,
985             long parentLayoutId, String name, String title, String languageId,
986             String description, String type, boolean hidden, String friendlyURL)
987         throws PortalException, SystemException {
988 
989         return updateLayout(
990             groupId, privateLayout, layoutId, parentLayoutId, name, title,
991             languageId, description, type, hidden, friendlyURL, null, null);
992     }
993 
994     public Layout updateLayout(
995             long groupId, boolean privateLayout, long layoutId,
996             long parentLayoutId, String name, String title, String languageId,
997             String description, String type, boolean hidden, String friendlyURL,
998             Boolean iconImage, byte[] iconBytes)
999         throws PortalException, SystemException {
1000
1001        // Layout
1002
1003        parentLayoutId = getParentLayoutId(
1004            groupId, privateLayout, parentLayoutId);
1005        Locale locale = LocaleUtil.fromLanguageId(languageId);
1006        friendlyURL = friendlyURL.toLowerCase();
1007
1008        validate(
1009            groupId, privateLayout, layoutId, parentLayoutId, name, type,
1010            hidden, friendlyURL);
1011
1012        validateParentLayoutId(
1013            groupId, privateLayout, layoutId, parentLayoutId);
1014
1015        Layout layout = LayoutUtil.findByG_P_L(
1016            groupId, privateLayout, layoutId);
1017
1018        if (parentLayoutId != layout.getParentLayoutId()) {
1019            layout.setPriority(
1020                getNextPriority(groupId, privateLayout, parentLayoutId));
1021        }
1022
1023        layout.setParentLayoutId(parentLayoutId);
1024        layout.setName(name, locale);
1025        layout.setTitle(title, locale);
1026        layout.setDescription(description);
1027        layout.setType(type);
1028        layout.setHidden(hidden);
1029        layout.setFriendlyURL(friendlyURL);
1030
1031        if (iconImage != null) {
1032            layout.setIconImage(iconImage.booleanValue());
1033
1034            if (iconImage.booleanValue()) {
1035                long iconImageId = layout.getIconImageId();
1036
1037                if (iconImageId <= 0) {
1038                    iconImageId = CounterLocalServiceUtil.increment();
1039
1040                    layout.setIconImageId(iconImageId);
1041                }
1042            }
1043        }
1044
1045        LayoutUtil.update(layout);
1046
1047        // Icon
1048
1049        if (iconImage != null) {
1050            if (!iconImage.booleanValue()) {
1051                ImageLocalUtil.deleteImage(layout.getIconImageId());
1052            }
1053            else if ((iconBytes != null) && (iconBytes.length > 0)) {
1054                ImageLocalUtil.updateImage(layout.getIconImageId(), iconBytes);
1055            }
1056        }
1057
1058        try {
1059            if (layout.getDlFolderId() > 0) {
1060                DLFolder folder = DLFolderLocalServiceUtil.getFolder(
1061                    layout.getDlFolderId());
1062
1063                DLFolderLocalServiceUtil.updateFolder(
1064                    folder.getFolderId(), folder.getParentFolderId(), name,
1065                    folder.getDescription());
1066            }
1067        }
1068        catch (NoSuchFolderException nsfe) {
1069        }
1070
1071        return layout;
1072    }
1073
1074    public Layout updateLayout(
1075            long groupId, boolean privateLayout, long layoutId,
1076            String typeSettings)
1077        throws PortalException, SystemException {
1078
1079        Layout layout = LayoutUtil.findByG_P_L(
1080            groupId, privateLayout, layoutId);
1081
1082        layout.setTypeSettings(typeSettings);
1083
1084        LayoutUtil.update(layout);
1085
1086        return layout;
1087    }
1088
1089    public Layout updateLookAndFeel(
1090            long groupId, boolean privateLayout, long layoutId, String themeId,
1091            String colorSchemeId, String css, boolean wapTheme)
1092        throws PortalException, SystemException {
1093
1094        Layout layout = LayoutUtil.findByG_P_L(
1095            groupId, privateLayout, layoutId);
1096
1097        if (wapTheme) {
1098            layout.setWapThemeId(themeId);
1099            layout.setWapColorSchemeId(colorSchemeId);
1100        }
1101        else {
1102            layout.setThemeId(themeId);
1103            layout.setColorSchemeId(colorSchemeId);
1104            layout.setCss(css);
1105        }
1106
1107        LayoutUtil.update(layout);
1108
1109        return layout;
1110    }
1111
1112    public Layout updateName(long plid, String name, String languageId)
1113        throws PortalException, SystemException {
1114
1115        Layout layout = LayoutUtil.findByPrimaryKey(plid);
1116
1117        return updateName(layout, name, languageId);
1118    }
1119
1120    public Layout updateName(
1121            long groupId, boolean privateLayout, long layoutId, String name,
1122            String languageId)
1123        throws PortalException, SystemException {
1124
1125        Layout layout = LayoutUtil.findByG_P_L(
1126            groupId, privateLayout, layoutId);
1127
1128        return updateName(layout, name, languageId);
1129    }
1130
1131    public Layout updateName(Layout layout, String name, String languageId)
1132        throws PortalException, SystemException {
1133
1134        layout.setName(name, LocaleUtil.fromLanguageId(languageId));
1135
1136        LayoutUtil.update(layout);
1137
1138        try {
1139            if (layout.getDlFolderId() > 0) {
1140                DLFolder folder = DLFolderLocalServiceUtil.getFolder(
1141                    layout.getDlFolderId());
1142
1143                DLFolderLocalServiceUtil.updateFolder(
1144                    folder.getFolderId(), folder.getParentFolderId(), name,
1145                    folder.getDescription());
1146            }
1147        }
1148        catch (NoSuchFolderException nsfe) {
1149        }
1150
1151        return layout;
1152    }
1153
1154    public Layout updateParentLayoutId(long plid, long parentPlid)
1155        throws PortalException, SystemException {
1156
1157        Layout layout = LayoutUtil.findByPrimaryKey(plid);
1158
1159        long parentLayoutId = LayoutImpl.DEFAULT_PARENT_LAYOUT_ID;
1160
1161        if (parentPlid > 0) {
1162            try {
1163                Layout parentLayout = LayoutUtil.findByPrimaryKey(parentPlid);
1164
1165                parentLayoutId = parentLayout.getLayoutId();
1166            }
1167            catch (NoSuchLayoutException nsle) {
1168            }
1169        }
1170
1171        parentLayoutId = getParentLayoutId(
1172            layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1173
1174        validateParentLayoutId(
1175            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1176            parentLayoutId);
1177
1178        if (parentLayoutId != layout.getParentLayoutId()) {
1179            int priority = getNextPriority(
1180                layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1181
1182            layout.setPriority(priority);
1183        }
1184
1185        layout.setParentLayoutId(parentLayoutId);
1186
1187        LayoutUtil.update(layout);
1188
1189        return layout;
1190    }
1191
1192    public Layout updateParentLayoutId(
1193            long groupId, boolean privateLayout, long layoutId,
1194            long parentLayoutId)
1195        throws PortalException, SystemException {
1196
1197        parentLayoutId = getParentLayoutId(
1198            groupId, privateLayout, parentLayoutId);
1199
1200        validateParentLayoutId(
1201            groupId, privateLayout, layoutId, parentLayoutId);
1202
1203        Layout layout = LayoutUtil.findByG_P_L(
1204            groupId, privateLayout, layoutId);
1205
1206        if (parentLayoutId != layout.getParentLayoutId()) {
1207            layout.setPriority(
1208                getNextPriority(groupId, privateLayout, parentLayoutId));
1209        }
1210
1211        layout.setParentLayoutId(parentLayoutId);
1212
1213        LayoutUtil.update(layout);
1214
1215        return layout;
1216    }
1217
1218    public Layout updatePriority(long plid, int priority)
1219        throws PortalException, SystemException {
1220
1221        Layout layout = LayoutUtil.findByPrimaryKey(plid);
1222
1223        return updatePriority(layout, priority);
1224    }
1225
1226    public Layout updatePriority(
1227            long groupId, boolean privateLayout, long layoutId, int priority)
1228        throws PortalException, SystemException {
1229
1230        Layout layout = LayoutUtil.findByG_P_L(
1231            groupId, privateLayout, layoutId);
1232
1233        return updatePriority(layout, priority);
1234    }
1235
1236    public Layout updatePriority(Layout layout, int priority)
1237        throws PortalException, SystemException {
1238
1239        if (layout.getPriority() == priority) {
1240            return layout;
1241        }
1242
1243        boolean lessThan = false;
1244
1245        if (layout.getPriority() < priority) {
1246            lessThan = true;
1247        }
1248
1249        layout.setPriority(priority);
1250
1251        LayoutUtil.update(layout);
1252
1253        priority = 0;
1254
1255        List layouts = LayoutUtil.findByG_P_P(
1256            layout.getGroupId(), layout.isPrivateLayout(),
1257            layout.getParentLayoutId());
1258
1259        Collections.sort(
1260            layouts, new LayoutPriorityComparator(layout, lessThan));
1261
1262        Iterator itr = layouts.iterator();
1263
1264        while (itr.hasNext()) {
1265            Layout curLayout = (Layout)itr.next();
1266
1267            curLayout.setPriority(priority++);
1268
1269            LayoutUtil.update(curLayout);
1270
1271            if (curLayout.equals(layout)) {
1272                layout = curLayout;
1273            }
1274        }
1275
1276        return layout;
1277    }
1278
1279    protected void deleteMissingLayouts(
1280            long groupId, boolean privateLayout, Set newLayoutIds)
1281        throws PortalException, SystemException {
1282
1283        // Layouts
1284
1285        if (_log.isDebugEnabled()) {
1286            if (newLayoutIds.size() > 0) {
1287                _log.debug("Delete missing layouts");
1288            }
1289        }
1290
1291        List layouts = LayoutUtil.findByG_P(groupId, privateLayout);
1292
1293        Iterator itr = layouts.iterator();
1294
1295        while (itr.hasNext()) {
1296            Layout layout = (Layout)itr.next();
1297
1298            if (!newLayoutIds.contains(new Long(layout.getLayoutId()))) {
1299                try {
1300                    deleteLayout(layout, false);
1301                }
1302                catch (NoSuchLayoutException nsle) {
1303                }
1304            }
1305        }
1306
1307        // Layout set
1308
1309        LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
1310    }
1311
1312    protected Element exportGroupPermissions(
1313            long companyId, long groupId, String resourceName,
1314            String resourcePrimKey, Element parentEl, String elName)
1315        throws PortalException, SystemException {
1316
1317        Element el = parentEl.addElement(elName);
1318
1319        List permissions = PermissionLocalServiceUtil.getGroupPermissions(
1320            groupId, companyId, resourceName, ResourceImpl.SCOPE_INDIVIDUAL,
1321            resourcePrimKey);
1322
1323        List actions = ResourceActionsUtil.getActions(permissions);
1324
1325        for (int i = 0; i < actions.size(); i++) {
1326            String action = (String)actions.get(i);
1327
1328            Element actionKeyEl = el.addElement("action-key");
1329
1330            actionKeyEl.addText(action);
1331        }
1332
1333        return el;
1334    }
1335
1336    protected void exportGroupRoles(
1337            LayoutCache layoutCache, long companyId, long groupId,
1338            String resourceName, String entityName, Element parentEl)
1339        throws PortalException, SystemException {
1340
1341        List roles = layoutCache.getGroupRoles(groupId);
1342
1343        Element groupEl = exportRoles(
1344            companyId, resourceName, ResourceImpl.SCOPE_GROUP,
1345            String.valueOf(groupId), parentEl, entityName + "-roles", roles);
1346
1347        if (groupEl.elements().isEmpty()) {
1348            parentEl.remove(groupEl);
1349        }
1350    }
1351
1352    protected void exportInheritedPermissions(
1353            LayoutCache layoutCache, long companyId, String resourceName,
1354            String resourcePrimKey, Element parentEl, String entityName)
1355        throws PortalException, SystemException {
1356
1357        Element entityPermissionsEl = DocumentHelper.createElement(
1358            entityName + "-permissions");
1359
1360        Map entityMap = layoutCache.getEntityMap(companyId, entityName);
1361
1362        Iterator itr = entityMap.entrySet().iterator();
1363
1364        while (itr.hasNext()) {
1365            Map.Entry entry = (Map.Entry)itr.next();
1366
1367            String name = entry.getKey().toString();
1368
1369            long entityGroupId = ((Long)entry.getValue()).longValue();
1370
1371            Element entityEl = exportGroupPermissions(
1372                companyId, entityGroupId, resourceName, resourcePrimKey,
1373                entityPermissionsEl, entityName + "-actions");
1374
1375            if (entityEl.elements().isEmpty()) {
1376                entityPermissionsEl.remove(entityEl);
1377            }
1378            else {
1379                entityEl.addAttribute("name", name);
1380            }
1381        }
1382
1383        if (!entityPermissionsEl.elements().isEmpty()) {
1384            parentEl.add(entityPermissionsEl);
1385        }
1386    }
1387
1388    protected void exportInheritedRoles(
1389            LayoutCache layoutCache, long companyId, long groupId,
1390            String resourceName, String entityName, Element parentEl)
1391        throws PortalException, SystemException {
1392
1393        Element entityRolesEl = DocumentHelper.createElement(
1394            entityName + "-roles");
1395
1396        Map entityMap = layoutCache.getEntityMap(companyId, entityName);
1397
1398        Iterator itr = entityMap.entrySet().iterator();
1399
1400        while (itr.hasNext()) {
1401            Map.Entry entry = (Map.Entry)itr.next();
1402
1403            String name = entry.getKey().toString();
1404
1405            long entityGroupId = ((Long)entry.getValue()).longValue();
1406
1407            List entityRoles = layoutCache.getGroupRoles(entityGroupId);
1408
1409            Element entityEl = exportRoles(
1410                companyId, resourceName, ResourceImpl.SCOPE_GROUP,
1411                String.valueOf(groupId), entityRolesEl, entityName,
1412                entityRoles);
1413
1414            if (entityEl.elements().isEmpty()) {
1415                entityRolesEl.remove(entityEl);
1416            }
1417            else {
1418                entityEl.addAttribute("name", name);
1419            }
1420        }
1421
1422        if (!entityRolesEl.elements().isEmpty()) {
1423            parentEl.add(entityRolesEl);
1424        }
1425    }
1426
1427    protected void exportLayoutPermissions(
1428            LayoutCache layoutCache, long companyId, long groupId,
1429            Group guestGroup, Layout layout, Element permissionsEl)
1430        throws PortalException, SystemException {
1431
1432        String resourceName = Layout.class.getName();
1433        String resourcePrimKey = String.valueOf(layout.getPlid());
1434
1435        exportGroupPermissions(
1436            companyId, groupId, resourceName, resourcePrimKey, permissionsEl,
1437            "community-actions");
1438
1439        if (groupId != guestGroup.getGroupId()) {
1440            exportGroupPermissions(
1441                companyId, guestGroup.getGroupId(), resourceName,
1442                resourcePrimKey, permissionsEl, "guest-actions");
1443        }
1444
1445        exportUserPermissions(
1446            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
1447            permissionsEl);
1448
1449        exportInheritedPermissions(
1450            layoutCache, companyId, resourceName, resourcePrimKey,
1451            permissionsEl, "organization");
1452
1453        exportInheritedPermissions(
1454            layoutCache, companyId, resourceName, resourcePrimKey,
1455            permissionsEl, "location");
1456
1457        exportInheritedPermissions(
1458            layoutCache, companyId, resourceName, resourcePrimKey,
1459            permissionsEl, "user-group");
1460    }
1461
1462    protected void exportLayoutRoles(
1463            LayoutCache layoutCache, long companyId, long groupId,
1464            Element rolesEl)
1465        throws PortalException, SystemException {
1466
1467        String resourceName = Layout.class.getName();
1468
1469        exportGroupRoles(
1470            layoutCache, companyId, groupId, resourceName, "community",
1471            rolesEl);
1472
1473        exportUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
1474
1475        exportInheritedRoles(
1476            layoutCache, companyId, groupId, resourceName, "organization",
1477            rolesEl);
1478
1479        exportInheritedRoles(
1480            layoutCache, companyId, groupId, resourceName, "location", rolesEl);
1481
1482        exportInheritedRoles(
1483            layoutCache, companyId, groupId, resourceName, "user-group",
1484            rolesEl);
1485    }
1486
1487    protected void exportPortletData(
1488            PortletDataContext context, Layout layout,
1489            LayoutTypePortlet layoutTypePortlet, Element parentEl)
1490        throws PortalException, SystemException {
1491
1492        Iterator itr =
1493            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1494                layout.getPlid()).iterator();
1495
1496        while (itr.hasNext()) {
1497            PortletPreferences portletPreferences =
1498                (PortletPreferences)itr.next();
1499
1500            javax.portlet.PortletPreferences jxPrefs =
1501                PortletPreferencesLocalServiceUtil.getPreferences(
1502                    layout.getCompanyId(), portletPreferences.getOwnerId(),
1503                    portletPreferences.getOwnerType(),
1504                    portletPreferences.getPlid(),
1505                    portletPreferences.getPortletId());
1506
1507            String portletId = portletPreferences.getPortletId();
1508
1509            if (layoutTypePortlet.hasPortletId(portletId)) {
1510                exportPortletData(context, portletId, jxPrefs, parentEl);
1511            }
1512        }
1513    }
1514
1515    protected void exportPortletData(
1516            PortletDataContext context, String portletId,
1517            javax.portlet.PortletPreferences portletPreferences,
1518            Element parentEl)
1519        throws PortalException, SystemException {
1520
1521        Portlet portlet = PortletLocalServiceUtil.getPortletById(
1522            context.getCompanyId(), portletId);
1523
1524        if (portlet == null) {
1525            if (_log.isDebugEnabled()) {
1526                _log.debug(
1527                    "Do not export portlet data for " + portletId +
1528                        " because the portlet does not exist");
1529            }
1530
1531            return;
1532        }
1533
1534        PortletDataHandler portletDataHandler =
1535            portlet.getPortletDataHandlerInstance();
1536
1537        if (portletDataHandler == null) {
1538            return;
1539        }
1540
1541        if (_log.isDebugEnabled()) {
1542            _log.debug("Exporting data for " + portletId);
1543        }
1544
1545        String data = portletDataHandler.exportData(
1546            context, portletId, portletPreferences);
1547
1548        if (data == null) {
1549            if (_log.isDebugEnabled()) {
1550                _log.debug(
1551                    "Not exporting data for " + portletId +
1552                        " because null data was returned");
1553            }
1554
1555            return;
1556        }
1557
1558        Element el = parentEl.addElement("portlet-data");
1559
1560        el.addAttribute("portlet-id", portletId);
1561        el.addCDATA(data);
1562    }
1563
1564    protected void exportPortletPermissions(
1565            LayoutCache layoutCache, long companyId, long groupId,
1566            Group guestGroup, Layout layout,
1567            LayoutTypePortlet layoutTypePortlet, Set portletIds,
1568            Element permissionsEl)
1569        throws PortalException, SystemException {
1570
1571        Iterator itr = layoutTypePortlet.getPortletIds().iterator();
1572
1573        while (itr.hasNext()) {
1574            String portletId = (String)itr.next();
1575
1576            if (!portletIds.contains(portletId)) {
1577                portletIds.add(portletId);
1578            }
1579
1580            if (layoutTypePortlet.hasPortletId(portletId)) {
1581                String resourceName = PortletImpl.getRootPortletId(portletId);
1582                String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
1583                    layout.getPlid(), portletId);
1584
1585                Element portletEl = permissionsEl.addElement("portlet");
1586
1587                portletEl.addAttribute("portlet-id", portletId);
1588
1589                exportGroupPermissions(
1590                    companyId, groupId, resourceName, resourcePrimKey,
1591                    portletEl, "community-actions");
1592
1593                if (groupId != guestGroup.getGroupId()) {
1594                    exportGroupPermissions(
1595                        companyId, guestGroup.getGroupId(), resourceName,
1596                        resourcePrimKey, portletEl, "guest-actions");
1597                }
1598
1599                exportUserPermissions(
1600                    layoutCache, companyId, groupId, resourceName,
1601                    resourcePrimKey, portletEl);
1602
1603                exportInheritedPermissions(
1604                    layoutCache, companyId, resourceName, resourcePrimKey,
1605                    portletEl, "organization");
1606
1607                exportInheritedPermissions(
1608                    layoutCache, companyId, resourceName, resourcePrimKey,
1609                    portletEl, "location");
1610
1611                exportInheritedPermissions(
1612                    layoutCache, companyId, resourceName, resourcePrimKey,
1613                    portletEl, "user-group");
1614            }
1615        }
1616    }
1617
1618    protected void exportPortletPreferences(
1619            long ownerId, int ownerType, long plid, boolean defaultUser,
1620            Element parentEl)
1621        throws PortalException, SystemException {
1622
1623        exportPortletPreferences(
1624            ownerId, ownerType, defaultUser, plid, null, parentEl);
1625    }
1626
1627    protected void exportPortletPreferences(
1628            long ownerId, int ownerType, boolean defaultUser, long plid,
1629            LayoutTypePortlet layoutTypePortlet, Element parentEl)
1630        throws PortalException, SystemException {
1631
1632        Iterator itr =
1633            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1634                ownerId, ownerType, plid).iterator();
1635
1636        while (itr.hasNext()) {
1637            PortletPreferences portletPreferences =
1638                (PortletPreferences)itr.next();
1639
1640            String portletId = portletPreferences.getPortletId();
1641
1642            if ((layoutTypePortlet == null) ||
1643                (layoutTypePortlet.hasPortletId(portletId))) {
1644
1645                Element el = parentEl.addElement("portlet-preferences");
1646
1647                el.addAttribute("owner-id", String.valueOf(ownerId));
1648                el.addAttribute("owner-type", String.valueOf(ownerType));
1649                el.addAttribute("default-user", String.valueOf(defaultUser));
1650                el.addAttribute("plid", String.valueOf(plid));
1651                el.addAttribute("portlet-id", portletId);
1652                el.addElement("preferences").addCDATA(
1653                    portletPreferences.getPreferences());
1654            }
1655        }
1656    }
1657
1658    protected void exportPortletRoles(
1659            LayoutCache layoutCache, long companyId, long groupId,
1660            Set portletIds, Element rolesEl)
1661        throws PortalException, SystemException {
1662
1663        Iterator itr = portletIds.iterator();
1664
1665        while (itr.hasNext()) {
1666            String portletId = (String)itr.next();
1667
1668            String resourceName = PortletImpl.getRootPortletId(portletId);
1669
1670            Element portletEl = rolesEl.addElement("portlet");
1671
1672            portletEl.addAttribute("portlet-id", portletId);
1673
1674            exportGroupRoles(
1675                layoutCache, companyId, groupId, resourceName, "community",
1676                portletEl);
1677
1678            exportUserRoles(
1679                layoutCache, companyId, groupId, resourceName, portletEl);
1680
1681            exportInheritedRoles(
1682                layoutCache, companyId, groupId, resourceName, "organization",
1683                portletEl);
1684
1685            exportInheritedRoles(
1686                layoutCache, companyId, groupId, resourceName, "location",
1687                portletEl);
1688
1689            exportInheritedRoles(
1690                layoutCache, companyId, groupId, resourceName, "user-group",
1691                portletEl);
1692
1693            if (portletEl.elements().isEmpty()) {
1694                rolesEl.remove(portletEl);
1695            }
1696        }
1697    }
1698
1699    protected Element exportRoles(
1700            long companyId, String resourceName, int scope,
1701            String resourcePrimKey, Element parentEl, String elName,
1702            List roles)
1703        throws PortalException, SystemException {
1704
1705        Element el = parentEl.addElement(elName);
1706
1707        Map resourceRoles = RoleLocalServiceUtil.getResourceRoles(
1708            companyId, resourceName, scope, resourcePrimKey);
1709
1710        Iterator itr = resourceRoles.entrySet().iterator();
1711
1712        while (itr.hasNext()) {
1713            Map.Entry entry = (Map.Entry)itr.next();
1714
1715            String roleName = entry.getKey().toString();
1716
1717            if (hasRole(roles, roleName)) {
1718                Element roleEl = el.addElement("role");
1719
1720                roleEl.addAttribute("name", roleName);
1721
1722                List actions = (List)entry.getValue();
1723
1724                for (int i = 0; i < actions.size(); i++) {
1725                    String action = (String)actions.get(i);
1726
1727                    Element actionKeyEl = roleEl.addElement("action-key");
1728
1729                    actionKeyEl.addText(action);
1730                    actionKeyEl.addAttribute("scope", String.valueOf(scope));
1731                }
1732            }
1733        }
1734
1735        return el;
1736    }
1737
1738    protected byte[] exportTheme(LayoutSet layoutSet)
1739        throws IOException, PortalException, SystemException {
1740
1741        Theme theme = layoutSet.getTheme();
1742
1743        ZipWriter zipWriter = new ZipWriter();
1744
1745        String lookAndFeelXML = ContentUtil.get(
1746            "com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl");
1747
1748        lookAndFeelXML = StringUtil.replace(
1749            lookAndFeelXML,
1750            new String[] {
1751                "[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]"
1752            },
1753            new String[] {
1754                theme.getTemplateExtension(), theme.getVirtualPath()
1755            }
1756        );
1757
1758        zipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML);
1759
1760        String servletContextName = theme.getServletContextName();
1761
1762        ServletContext ctx = VelocityContextPool.get(servletContextName);
1763
1764        if (ctx == null) {
1765            if (_log.isWarnEnabled()) {
1766                _log.warn(
1767                    "Servlet context not found for theme " +
1768                        theme.getThemeId());
1769            }
1770
1771            return null;
1772        }
1773
1774        File cssPath = null;
1775        File imagesPath = null;
1776        File javaScriptPath = null;
1777        File templatesPath = null;
1778
1779        if (!theme.isLoadFromServletContext()) {
1780            ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(
1781                servletContextName);
1782
1783            if (themeLoader == null) {
1784                _log.error(
1785                    servletContextName + " does not map to a theme loader");
1786            }
1787            else {
1788                String realPath =
1789                    themeLoader.getFileStorage().getPath() + "/" +
1790                        theme.getName();
1791
1792                cssPath = new File(realPath + "/css");
1793                imagesPath = new File(realPath + "/images");
1794                javaScriptPath = new File(realPath + "/javascript");
1795                templatesPath = new File(realPath + "/templates");
1796            }
1797        }
1798        else {
1799            cssPath = new File(ctx.getRealPath(theme.getCssPath()));
1800            imagesPath = new File(ctx.getRealPath(theme.getImagesPath()));
1801            javaScriptPath = new File(
1802                ctx.getRealPath(theme.getJavaScriptPath()));
1803            templatesPath = new File(ctx.getRealPath(theme.getTemplatesPath()));
1804        }
1805
1806        exportThemeFiles("css", cssPath, zipWriter);
1807        exportThemeFiles("images", imagesPath, zipWriter);
1808        exportThemeFiles("javascript", javaScriptPath, zipWriter);
1809        exportThemeFiles("templates", templatesPath, zipWriter);
1810
1811        return zipWriter.finish();
1812    }
1813
1814    protected void exportThemeFiles(String path, File dir, ZipWriter zipWriter)
1815        throws IOException {
1816
1817        if ((dir == null) || (!dir.exists())) {
1818            return;
1819        }
1820
1821        File[] files = dir.listFiles();
1822
1823        for (int i = 0; i < files.length; i++) {
1824            File file = files[i];
1825
1826            if (file.isDirectory()) {
1827                exportThemeFiles(path + "/" + file.getName(), file, zipWriter);
1828            }
1829            else {
1830                zipWriter.addEntry(
1831                    path + "/" + file.getName(), FileUtil.getBytes(file));
1832            }
1833        }
1834    }
1835
1836    protected void exportUserPermissions(
1837            LayoutCache layoutCache, long companyId, long groupId,
1838            String resourceName, String resourcePrimKey, Element parentEl)
1839        throws PortalException, SystemException {
1840
1841        Element userPermissionsEl = DocumentHelper.createElement(
1842            "user-permissions");
1843
1844        List users = layoutCache.getGroupUsers(groupId);
1845
1846        for (int i = 0; i < users.size(); i++) {
1847            User user = (User)users.get(i);
1848
1849            String emailAddress = user.getEmailAddress();
1850
1851            Element userActionsEl =
1852                userPermissionsEl.addElement("user-actions");
1853
1854            List permissions = PermissionLocalServiceUtil.getUserPermissions(
1855                user.getUserId(), companyId, resourceName,
1856                ResourceImpl.SCOPE_INDIVIDUAL, resourcePrimKey);
1857
1858            List actions = ResourceActionsUtil.getActions(permissions);
1859
1860            for (int j = 0; j < actions.size(); j++) {
1861                String action = (String)actions.get(j);
1862
1863                Element actionKeyEl = userActionsEl.addElement("action-key");
1864
1865                actionKeyEl.addText(action);
1866            }
1867
1868            if (userActionsEl.elements().isEmpty()) {
1869                userPermissionsEl.remove(userActionsEl);
1870            }
1871            else {
1872                userActionsEl.addAttribute("email-address", emailAddress);
1873            }
1874        }
1875
1876        if (!userPermissionsEl.elements().isEmpty()) {
1877            parentEl.add(userPermissionsEl);
1878        }
1879    }
1880
1881    protected void exportUserRoles(
1882            LayoutCache layoutCache, long companyId, long groupId,
1883            String resourceName, Element parentEl)
1884        throws PortalException, SystemException {
1885
1886        Element userRolesEl = DocumentHelper.createElement("user-roles");
1887
1888        List users = layoutCache.getGroupUsers(groupId);
1889
1890        for (int i = 0; i < users.size(); i++) {
1891            User user = (User)users.get(i);
1892
1893            long userId = user.getUserId();
1894            String emailAddress = user.getEmailAddress();
1895
1896            List userRoles = layoutCache.getUserRoles(userId);
1897
1898            Element userEl = exportRoles(
1899                companyId, resourceName, ResourceImpl.SCOPE_GROUP,
1900                String.valueOf(groupId), userRolesEl, "user", userRoles);
1901
1902            if (userEl.elements().isEmpty()) {
1903                userRolesEl.remove(userEl);
1904            }
1905            else {
1906                userEl.addAttribute("email-address", emailAddress);
1907            }
1908        }
1909
1910        if (!userRolesEl.elements().isEmpty()) {
1911            parentEl.add(userRolesEl);
1912        }
1913    }
1914
1915    protected void fixTypeSettings(Layout layout) {
1916        if (layout.getType().equals(LayoutImpl.TYPE_URL)) {
1917            Properties typeSettings = layout.getTypeSettingsProperties();
1918
1919            String url = GetterUtil.getString(typeSettings.getProperty("url"));
1920
1921            String friendlyURLPrivateGroupPath = PropsUtil.get(
1922                PropsUtil.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING);
1923            String friendlyURLPrivateUserPath = PropsUtil.get(
1924                PropsUtil.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING);
1925            String friendlyURLPublicPath = PropsUtil.get(
1926                PropsUtil.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING);
1927
1928            if (url.startsWith(friendlyURLPrivateGroupPath) ||
1929                url.startsWith(friendlyURLPrivateUserPath) ||
1930                url.startsWith(friendlyURLPublicPath)) {
1931
1932                int x = url.indexOf(StringPool.SLASH, 1);
1933
1934                if (x > 0) {
1935                    int y = url.indexOf(StringPool.SLASH, x + 1);
1936
1937                    if (y > x) {
1938                        String fixedUrl = url.substring(0, x) +
1939
1940                        layout.getGroup().getFriendlyURL() +
1941
1942                        url.substring(y);
1943
1944                        typeSettings.setProperty("url", fixedUrl);
1945                    }
1946                }
1947            }
1948        }
1949    }
1950
1951    protected List getActions(Element el) {
1952        List actions = new ArrayList();
1953
1954        Iterator itr = el.elements("action-key").iterator();
1955
1956        while (itr.hasNext()) {
1957            Element actionEl = (Element)itr.next();
1958
1959            actions.add(actionEl.getText());
1960        }
1961
1962        return actions;
1963    }
1964
1965    protected long getNextLayoutId(long groupId, boolean privateLayout)
1966        throws SystemException {
1967
1968        long layoutId = 0;
1969
1970        List layouts = LayoutUtil.findByG_P(groupId, privateLayout);
1971
1972        for (int i = 0; i < layouts.size(); i++) {
1973            Layout curLayout = (Layout)layouts.get(i);
1974
1975            long curLayoutId = curLayout.getLayoutId();
1976
1977            if (curLayoutId > layoutId) {
1978                layoutId = curLayoutId;
1979            }
1980        }
1981
1982        return ++layoutId;
1983    }
1984
1985    protected int getNextPriority(
1986            long groupId, boolean privateLayout, long parentLayoutId)
1987        throws SystemException {
1988
1989        List layouts = LayoutUtil.findByG_P_P(
1990            groupId, privateLayout, parentLayoutId);
1991
1992        if (layouts.size() == 0) {
1993            return 0;
1994        }
1995
1996        Layout layout = (Layout)layouts.get(layouts.size() - 1);
1997
1998        return layout.getPriority() + 1;
1999    }
2000
2001    protected long getParentLayoutId(
2002            long groupId, boolean privateLayout, long parentLayoutId)
2003        throws PortalException, SystemException {
2004
2005        if (parentLayoutId != LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
2006
2007            // Ensure parent layout exists
2008
2009            try {
2010                LayoutUtil.findByG_P_L(groupId, privateLayout, parentLayoutId);
2011            }
2012            catch (NoSuchLayoutException nsfe) {
2013                parentLayoutId = LayoutImpl.DEFAULT_PARENT_LAYOUT_ID;
2014            }
2015        }
2016
2017        return parentLayoutId;
2018    }
2019
2020    protected boolean hasRole(List roles, String roleName) {
2021        if ((roles == null) || (roles.size() == 0)) {
2022            return false;
2023        }
2024
2025        for (int i = 0; i < roles.size(); i++) {
2026            Role role = (Role)roles.get(i);
2027
2028            if (role.getName().equals(roleName)) {
2029                return true;
2030            }
2031        }
2032
2033        return false;
2034    }
2035
2036    protected void importGroupPermissions(
2037            LayoutCache layoutCache, long companyId, long groupId,
2038            String resourceName, String resourcePrimKey, Element parentEl,
2039            String elName, boolean portletActions)
2040        throws PortalException, SystemException {
2041
2042        Element actionEl = parentEl.element(elName);
2043
2044        if (actionEl == null) {
2045            return;
2046        }
2047
2048        List actions = getActions(actionEl);
2049
2050        Resource resource = layoutCache.getResource(
2051            companyId, groupId, resourceName, ResourceImpl.SCOPE_INDIVIDUAL,
2052            resourcePrimKey, portletActions);
2053
2054        PermissionLocalServiceUtil.setGroupPermissions(
2055            groupId, (String[])actions.toArray(new String[0]),
2056            resource.getResourceId());
2057    }
2058
2059    protected void importGroupRoles(
2060            LayoutCache layoutCache, long companyId, long groupId,
2061            String resourceName, String entityName,
2062            Element parentEl)
2063        throws PortalException, SystemException {
2064
2065        Element entityRolesEl = parentEl.element(entityName + "-roles");
2066
2067        if (entityRolesEl == null) {
2068            return;
2069        }
2070
2071        importRolePermissions(
2072            layoutCache, companyId, resourceName, ResourceImpl.SCOPE_GROUP,
2073            String.valueOf(groupId), entityRolesEl, true);
2074    }
2075
2076    protected void importInheritedPermissions(
2077            LayoutCache layoutCache, long companyId, String resourceName,
2078            String resourcePrimKey, Element permissionsEl, String entityName,
2079            boolean portletActions)
2080        throws PortalException, SystemException {
2081
2082        Element entityPermissionsEl = permissionsEl.element(
2083            entityName + "-permissions");
2084
2085        if (entityPermissionsEl == null) {
2086            return;
2087        }
2088
2089        List actionsEls = entityPermissionsEl.elements(
2090            entityName + "-actions");
2091
2092        for (int i = 0; i < actionsEls.size(); i++) {
2093            Element actionEl = (Element)actionsEls.get(i);
2094
2095            String name = actionEl.attributeValue("name");
2096
2097            long entityGroupId = layoutCache.getEntityGroupId(
2098                companyId, entityName, name);
2099
2100            if (entityGroupId == 0) {
2101                _log.warn(
2102                    "Ignore inherited permissions for entity " + entityName +
2103                        " with name " + name);
2104            }
2105            else {
2106                Element parentEl = DocumentHelper.createElement("parent");
2107
2108                parentEl.add(actionEl.createCopy());
2109
2110                importGroupPermissions(
2111                    layoutCache, companyId, entityGroupId, resourceName,
2112                    resourcePrimKey, parentEl, entityName + "-actions",
2113                    portletActions);
2114            }
2115        }
2116    }
2117
2118    protected void importInheritedRoles(
2119            LayoutCache layoutCache, long companyId, long groupId,
2120            String resourceName, String entityName, Element parentEl)
2121        throws PortalException, SystemException {
2122
2123        Element entityRolesEl = parentEl.element(entityName + "-roles");
2124
2125        if (entityRolesEl == null) {
2126            return;
2127        }
2128
2129        List entityEls = entityRolesEl.elements(entityName);
2130
2131        for (int i = 0; i < entityEls.size(); i++) {
2132            Element entityEl = (Element)entityEls.get(i);
2133
2134            String name = entityEl.attributeValue("name");
2135
2136            long entityGroupId = layoutCache.getEntityGroupId(
2137                companyId, entityName, name);
2138
2139            if (entityGroupId == 0) {
2140                _log.warn(
2141                    "Ignore inherited roles for entity " + entityName +
2142                        " with name " + name);
2143            }
2144            else {
2145                importRolePermissions(
2146                    layoutCache, companyId, resourceName,
2147                    ResourceImpl.SCOPE_GROUP, String.valueOf(groupId), entityEl,
2148                    false);
2149            }
2150        }
2151    }
2152
2153    protected void importLayoutPermissions(
2154            LayoutCache layoutCache, long companyId, long groupId,
2155            Group guestGroup, Layout layout, Element permissionsEl)
2156        throws PortalException, SystemException {
2157
2158        String resourceName = Layout.class.getName();
2159        String resourcePrimKey = String.valueOf(layout.getPlid());
2160
2161        importGroupPermissions(
2162            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
2163            permissionsEl, "community-actions", false);
2164
2165        if (groupId != guestGroup.getGroupId()) {
2166            importGroupPermissions(
2167                layoutCache, companyId, guestGroup.getGroupId(), resourceName,
2168                resourcePrimKey, permissionsEl, "guest-actions", false);
2169        }
2170
2171        importUserPermissions(
2172            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
2173            permissionsEl, false);
2174
2175        importInheritedPermissions(
2176            layoutCache, companyId, resourceName, resourcePrimKey,
2177            permissionsEl, "organization", false);
2178
2179        importInheritedPermissions(
2180            layoutCache, companyId, resourceName, resourcePrimKey,
2181            permissionsEl, "location", false);
2182
2183        importInheritedPermissions(
2184            layoutCache, companyId, resourceName, resourcePrimKey,
2185            permissionsEl, "user-group", false);
2186    }
2187
2188    protected void importLayoutRoles(
2189            LayoutCache layoutCache, long companyId, long groupId,
2190            Element rolesEl)
2191        throws PortalException, SystemException {
2192
2193        String resourceName = Layout.class.getName();
2194
2195        importGroupRoles(
2196            layoutCache, companyId, groupId, resourceName, "community",
2197            rolesEl);
2198
2199        importUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
2200
2201        importInheritedRoles(
2202            layoutCache, companyId, groupId, resourceName, "organization",
2203            rolesEl);
2204
2205        importInheritedRoles(
2206            layoutCache, companyId, groupId, resourceName, "location", rolesEl);
2207
2208        importInheritedRoles(
2209            layoutCache, companyId, groupId, resourceName, "user-group",
2210            rolesEl);
2211    }
2212
2213    protected void importPortletData(
2214            PortletDataContext context, Layout layout, Element parentEl)
2215        throws PortalException, SystemException {
2216
2217        Iterator itr = parentEl.elements("portlet-data").iterator();
2218
2219        while (itr.hasNext()) {
2220            Element el = (Element)itr.next();
2221
2222            String portletId = el.attributeValue("portlet-id");
2223
2224            try {
2225                PortletPreferences portletPreferences =
2226                    PortletPreferencesUtil.findByO_O_P_P(
2227                        PortletKeys.PREFS_OWNER_ID_DEFAULT,
2228                        PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid(),
2229                        portletId);
2230
2231                String preferences = importPortletData(
2232                    context, portletId, portletPreferences, el);
2233
2234                if (preferences != null) {
2235                    portletPreferences.setPreferences(preferences);
2236
2237                    PortletPreferencesUtil.update(portletPreferences);
2238                }
2239            }
2240            catch (NoSuchPortletPreferencesException nsppe) {
2241            }
2242        }
2243    }
2244
2245    protected String importPortletData(
2246            PortletDataContext context, String portletId,
2247            PortletPreferences portletPreferences, Element parentEl)
2248        throws PortalException, SystemException {
2249
2250        Portlet portlet = PortletLocalServiceUtil.getPortletById(
2251            context.getCompanyId(), portletId);
2252
2253        if (portlet == null) {
2254            if (_log.isDebugEnabled()) {
2255                _log.debug(
2256                    "Do not import portlet data for " + portletId +
2257                        " because the portlet does not exist");
2258            }
2259
2260            return null;
2261        }
2262
2263        PortletDataHandler portletDataHandler =
2264            portlet.getPortletDataHandlerInstance();
2265
2266        if (portlet == null) {
2267            if (_log.isDebugEnabled()) {
2268                _log.debug(
2269                    "Do not import portlet data for " + portletId +
2270                        " because the portlet does not have a " +
2271                            "PortletDataHandler");
2272            }
2273
2274            return null;
2275        }
2276
2277        if (_log.isDebugEnabled()) {
2278            _log.debug("Importing data for " + portletId);
2279        }
2280
2281        PortletPreferencesImpl prefsImpl =
2282            (PortletPreferencesImpl)PortletPreferencesSerializer.fromDefaultXML(
2283                portletPreferences.getPreferences());
2284
2285        prefsImpl = (PortletPreferencesImpl)portletDataHandler.importData(
2286            context, portletId, prefsImpl, parentEl.getText());
2287
2288        if (prefsImpl == null) {
2289            return null;
2290        }
2291
2292        return PortletPreferencesSerializer.toXML(prefsImpl);
2293    }
2294
2295    protected void importPortletPermissions(
2296            LayoutCache layoutCache, long companyId, long groupId,
2297            Group guestGroup, Layout layout, Element permissionsEl)
2298        throws PortalException, SystemException {
2299
2300        Iterator itr = permissionsEl.elements("portlet").iterator();
2301
2302        while (itr.hasNext()) {
2303            Element portletEl = (Element)itr.next();
2304
2305            String portletId = portletEl.attributeValue("portlet-id");
2306
2307            String resourceName = PortletImpl.getRootPortletId(portletId);
2308            String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
2309                layout.getPlid(), portletId);
2310
2311            Portlet portlet = PortletLocalServiceUtil.getPortletById(
2312                companyId, resourceName);
2313
2314            if (portlet == null) {
2315                if (_log.isDebugEnabled()) {
2316                    _log.debug(
2317                        "Do not import portlet permissions for " + portletId +
2318                            " because the portlet does not exist");
2319                }
2320            }
2321            else {
2322                importGroupPermissions(
2323                    layoutCache, companyId, groupId, resourceName,
2324                    resourcePrimKey, portletEl, "community-actions", true);
2325
2326                if (groupId != guestGroup.getGroupId()) {
2327                    importGroupPermissions(
2328                        layoutCache, companyId, guestGroup.getGroupId(),
2329                        resourceName, resourcePrimKey, portletEl,
2330                        "guest-actions", true);
2331                }
2332
2333                importUserPermissions(
2334                    layoutCache, companyId, groupId, resourceName,
2335                    resourcePrimKey, portletEl, true);
2336
2337                importInheritedPermissions(
2338                    layoutCache, companyId, resourceName, resourcePrimKey,
2339                    portletEl, "organization", true);
2340
2341                importInheritedPermissions(
2342                    layoutCache, companyId, resourceName, resourcePrimKey,
2343                    portletEl, "location", true);
2344
2345                importInheritedPermissions(
2346                    layoutCache, companyId, resourceName, resourcePrimKey,
2347                    portletEl, "user-group", true);
2348            }
2349        }
2350    }
2351
2352    protected void importPortletPreferences(
2353            LayoutSet layoutSet, long plid, Element parentEl)
2354        throws PortalException, SystemException {
2355
2356        long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
2357            layoutSet.getCompanyId());
2358
2359        Iterator itr = parentEl.elements("portlet-preferences").iterator();
2360
2361        while (itr.hasNext()) {
2362            Element el = (Element)itr.next();
2363
2364            long ownerId = GetterUtil.getLong(el.attributeValue("owner-id"));
2365            int ownerType = GetterUtil.getInteger(
2366                el.attributeValue("owner-type"));
2367            boolean defaultUser = GetterUtil.getBoolean(
2368                el.attributeValue("default-user"));
2369            //long plid = GetterUtil.getLong(el.attributeValue("plid"));
2370            String portletId = el.attributeValue("portlet-id");
2371            String preferences = el.elementText("preferences");
2372
2373            if (defaultUser) {
2374                ownerId = defaultUserId;
2375            }
2376
2377            try {
2378                PortletPreferencesLocalServiceUtil.deletePortletPreferences(
2379                    ownerId, ownerType, plid, portletId);
2380            }
2381            catch (NoSuchPortletPreferencesException nsppe) {
2382            }
2383
2384            long portletPreferencesId = CounterLocalServiceUtil.increment();
2385
2386            PortletPreferences portletPreferences =
2387                PortletPreferencesUtil.create(portletPreferencesId);
2388
2389            portletPreferences.setOwnerId(ownerId);
2390            portletPreferences.setOwnerType(ownerType);
2391            portletPreferences.setPlid(plid);
2392            portletPreferences.setPortletId(portletId);
2393
2394            portletPreferences.setPreferences(preferences);
2395
2396            PortletPreferencesUtil.update(portletPreferences);
2397        }
2398    }
2399
2400    protected void importPortletRoles(
2401            LayoutCache layoutCache, long companyId, long groupId,
2402            Element rolesEl)
2403        throws PortalException, SystemException {
2404
2405        Iterator itr = rolesEl.elements("portlet").iterator();
2406
2407        while (itr.hasNext()) {
2408            Element portletEl = (Element)itr.next();
2409
2410            String portletId = portletEl.attributeValue("portlet-id");
2411
2412            String resourceName = PortletImpl.getRootPortletId(portletId);
2413
2414            Portlet portlet = PortletLocalServiceUtil.getPortletById(
2415                companyId, resourceName);
2416
2417            if (portlet == null) {
2418                if (_log.isDebugEnabled()) {
2419                    _log.debug(
2420                        "Do not import portlet roles for " + portletId +
2421                            " because the portlet does not exist");
2422                }
2423            }
2424            else {
2425                importGroupRoles(
2426                    layoutCache, companyId, groupId, resourceName, "community",
2427                    portletEl);
2428
2429                importUserRoles(
2430                    layoutCache, companyId, groupId, resourceName, portletEl);
2431
2432                importInheritedRoles(
2433                    layoutCache, companyId, groupId, resourceName,
2434                    "organization", portletEl);
2435
2436                importInheritedRoles(
2437                    layoutCache, companyId, groupId, resourceName, "location",
2438                    portletEl);
2439
2440                importInheritedRoles(
2441                    layoutCache, companyId, groupId, resourceName, "user-group",
2442                    portletEl);
2443            }
2444        }
2445    }
2446
2447    protected void importRolePermissions(
2448            LayoutCache layoutCache, long companyId, String resourceName,
2449            int scope, String resourcePrimKey, Element parentEl,
2450            boolean communityRole)
2451        throws PortalException, SystemException {
2452
2453        List roleEls = parentEl.elements("role");
2454
2455        for (int i = 0; i < roleEls.size(); i++) {
2456            Element roleEl = (Element)roleEls.get(i);
2457
2458            String roleName = roleEl.attributeValue("name");
2459
2460            Role role = layoutCache.getRole(companyId, roleName);
2461
2462            if (role == null) {
2463                _log.warn(
2464                    "Ignoring permissions for role with name " + roleName);
2465            }
2466            else {
2467                List actions = getActions(roleEl);
2468
2469                PermissionLocalServiceUtil.setRolePermissions(
2470                    role.getRoleId(), companyId, resourceName, scope,
2471                    resourcePrimKey, (String[])actions.toArray(new String[0]));
2472
2473                if (communityRole) {
2474                    long[] groupIds = {GetterUtil.getLong(resourcePrimKey)};
2475
2476                    GroupLocalServiceUtil.addRoleGroups(
2477                        role.getRoleId(), groupIds);
2478                }
2479            }
2480        }
2481    }
2482
2483    protected String importTheme(LayoutSet layoutSet, byte[] themeZip)
2484        throws IOException {
2485
2486        ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
2487
2488        if (themeLoader == null) {
2489            _log.error("No theme loaders are deployed");
2490
2491            return null;
2492        }
2493
2494        ZipReader zipReader = new ZipReader(new ByteArrayInputStream(themeZip));
2495
2496        Map entries = zipReader.getEntries();
2497
2498        String lookAndFeelXML = new String(
2499            (byte[])entries.get("liferay-look-and-feel.xml"));
2500
2501        Date now = new Date();
2502
2503        String themeId =
2504            layoutSet.getGroupId() + "-" + Time.getShortTimestamp(now);
2505        String themeName = themeId;
2506
2507        lookAndFeelXML = StringUtil.replace(
2508            lookAndFeelXML,
2509            new String[] {
2510                "[$GROUP_ID$]", "[$THEME_ID$]", "[$THEME_NAME$]"
2511            },
2512            new String[] {
2513                String.valueOf(layoutSet.getGroupId()), themeId, themeName
2514            }
2515        );
2516
2517        Iterator itr = entries.entrySet().iterator();
2518
2519        while (itr.hasNext()) {
2520            Map.Entry entry = (Map.Entry)itr.next();
2521
2522            String key = (String)entry.getKey();
2523            byte[] value = (byte[])entry.getValue();
2524
2525            if (key.equals("liferay-look-and-feel.xml")) {
2526                value = lookAndFeelXML.getBytes();
2527            }
2528
2529            FileUtil.write(
2530                themeLoader.getFileStorage() + "/" + themeId + "/" + key,
2531                value);
2532        }
2533
2534        themeLoader.loadThemes();
2535
2536        CommLink commLink = CommLink.getInstance();
2537
2538        MethodWrapper methodWrapper = new MethodWrapper(
2539            ThemeLoaderFactory.class.getName(), "loadThemes");
2540
2541        commLink.send(methodWrapper);
2542
2543        themeId +=
2544            PortletImpl.WAR_SEPARATOR + themeLoader.getServletContextName();
2545
2546        return PortalUtil.getJsSafePortletId(themeId);
2547    }
2548
2549    protected void importUserPermissions(
2550            LayoutCache layoutCache, long companyId, long groupId,
2551            String resourceName, String resourcePrimKey, Element parentEl,
2552            boolean portletActions)
2553        throws PortalException, SystemException {
2554
2555        Element userPermissionsEl = parentEl.element("user-permissions");
2556
2557        if (userPermissionsEl == null) {
2558            return;
2559        }
2560
2561        List userActionsEls = userPermissionsEl.elements("user-actions");
2562
2563        for (int i = 0; i < userActionsEls.size(); i++) {
2564            Element userActionsEl = (Element)userActionsEls.get(i);
2565
2566            String emailAddress = userActionsEl.attributeValue("email-address");
2567
2568            User user = layoutCache.getUser(companyId, groupId, emailAddress);
2569
2570            if (user == null) {
2571                if (_log.isWarnEnabled()) {
2572                    _log.warn(
2573                        "Ignoring permissions for user with email address " +
2574                            emailAddress);
2575                }
2576            }
2577            else {
2578                List actions = getActions(userActionsEl);
2579
2580                Resource resource = layoutCache.getResource(
2581                    companyId, groupId, resourceName,
2582                    ResourceImpl.SCOPE_INDIVIDUAL, resourcePrimKey,
2583                    portletActions);
2584
2585                PermissionLocalServiceUtil.setUserPermissions(
2586                    user.getUserId(), (String[])actions.toArray(new String[0]),
2587                    resource.getResourceId());
2588            }
2589        }
2590    }
2591
2592    protected void importUserRoles(
2593            LayoutCache layoutCache, long companyId, long groupId,
2594            String resourceName, Element parentEl)
2595        throws PortalException, SystemException {
2596
2597        Element userRolesEl = parentEl.element("user-roles");
2598
2599        if (userRolesEl == null) {
2600            return;
2601        }
2602
2603        LinkedHashMap params = new LinkedHashMap();
2604
2605        params.put("usersGroups", new Long(groupId));
2606
2607        List userEls = userRolesEl.elements("user");
2608
2609        for (int i = 0; i < userEls.size(); i++) {
2610            Element userEl = (Element)userEls.get(i);
2611
2612            String emailAddress = userEl.attributeValue("email-address");
2613
2614            User user = layoutCache.getUser(companyId, groupId, emailAddress);
2615
2616            if (user == null) {
2617                if (_log.isWarnEnabled()) {
2618                    _log.warn(
2619                        "Ignoring roles for user with email address " +
2620                            emailAddress);
2621                }
2622            }
2623            else {
2624                importRolePermissions(
2625                    layoutCache, companyId, resourceName,
2626                    ResourceImpl.SCOPE_GROUP, String.valueOf(groupId), userEl,
2627                    false);
2628            }
2629        }
2630    }
2631
2632    protected boolean isDescendant(Layout layout, long layoutId)
2633        throws PortalException, SystemException {
2634
2635        if (layout.getLayoutId() == layoutId) {
2636            return true;
2637        }
2638        else {
2639            Iterator itr = layout.getChildren().iterator();
2640
2641            while (itr.hasNext()) {
2642                Layout childLayout = (Layout)itr.next();
2643
2644                if (isDescendant(childLayout, layoutId)) {
2645                    return true;
2646                }
2647            }
2648
2649            return false;
2650        }
2651    }
2652
2653    protected void validate(
2654            long groupId, boolean privateLayout, long layoutId,
2655            long parentLayoutId, String name, String type, boolean hidden,
2656            String friendlyURL)
2657        throws PortalException, SystemException {
2658
2659        friendlyURL = friendlyURL.toLowerCase();
2660
2661        boolean firstLayout = false;
2662
2663        if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
2664            List layouts = LayoutUtil.findByG_P_P(
2665                groupId, privateLayout, parentLayoutId, 0, 1);
2666
2667            if (layouts.size() == 0) {
2668                firstLayout = true;
2669            }
2670            else {
2671                long firstLayoutId = ((Layout)layouts.get(0)).getLayoutId();
2672
2673                if (firstLayoutId == layoutId) {
2674                    firstLayout = true;
2675                }
2676            }
2677        }
2678
2679        if (firstLayout) {
2680            validateFirstLayout(type, hidden);
2681        }
2682
2683        if (Validator.isNull(name)) {
2684            throw new LayoutNameException();
2685        }
2686
2687        if (!PortalUtil.isLayoutParentable(type)) {
2688            if (LayoutUtil.countByG_P_P(groupId, privateLayout, layoutId) > 0) {
2689                throw new LayoutTypeException(
2690                    LayoutTypeException.NOT_PARENTABLE);
2691            }
2692        }
2693
2694        if (Validator.isNotNull(friendlyURL)) {
2695            int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
2696
2697            if (exceptionType != -1) {
2698                throw new LayoutFriendlyURLException(exceptionType);
2699            }
2700
2701            try {
2702                Layout layout = LayoutUtil.findByG_P_F(
2703                    groupId, privateLayout, friendlyURL);
2704
2705                if (layout.getLayoutId() != layoutId) {
2706                    throw new LayoutFriendlyURLException(
2707                        LayoutFriendlyURLException.DUPLICATE);
2708                }
2709            }
2710            catch (NoSuchLayoutException nsle) {
2711            }
2712
2713            LayoutImpl.validateFriendlyURLKeyword(friendlyURL);
2714
2715            List friendlyURLMappers =
2716                PortletLocalServiceUtil.getFriendlyURLMappers();
2717
2718            Iterator itr = friendlyURLMappers.iterator();
2719
2720            while (itr.hasNext()) {
2721                FriendlyURLMapper friendlyURLMapper =
2722                    (FriendlyURLMapper)itr.next();
2723
2724                if (friendlyURL.indexOf(friendlyURLMapper.getMapping()) != -1) {
2725                    LayoutFriendlyURLException lfurle =
2726                        new LayoutFriendlyURLException(
2727                            LayoutFriendlyURLException.KEYWORD_CONFLICT);
2728
2729                    lfurle.setKeywordConflict(friendlyURLMapper.getMapping());
2730
2731                    throw lfurle;
2732                }
2733            }
2734
2735        }
2736    }
2737
2738    protected void validateFirstLayout(String type, boolean hidden)
2739        throws PortalException {
2740
2741        if (!type.equals(LayoutImpl.TYPE_PORTLET)) {
2742            throw new LayoutTypeException(LayoutTypeException.FIRST_LAYOUT);
2743        }
2744
2745        if (hidden) {
2746            throw new LayoutHiddenException();
2747        }
2748    }
2749
2750    protected void validateParentLayoutId(
2751            long groupId, boolean privateLayout, long layoutId,
2752            long parentLayoutId)
2753        throws PortalException, SystemException {
2754
2755        Layout layout = LayoutUtil.findByG_P_L(
2756            groupId, privateLayout, layoutId);
2757
2758        if (parentLayoutId != layout.getParentLayoutId()) {
2759
2760            // Layouts can always be moved to the root level
2761
2762            if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
2763                return;
2764            }
2765
2766            // Layout cannot become a child of a layout that is not parentable
2767
2768            Layout parentLayout = LayoutUtil.findByG_P_L(
2769                groupId, privateLayout, parentLayoutId);
2770
2771            if (!PortalUtil.isLayoutParentable(parentLayout)) {
2772                throw new LayoutParentLayoutIdException(
2773                    LayoutParentLayoutIdException.NOT_PARENTABLE);
2774            }
2775
2776            // Layout cannot become descendant of itself
2777
2778            if (isDescendant(layout, parentLayoutId)) {
2779                throw new LayoutParentLayoutIdException(
2780                    LayoutParentLayoutIdException.SELF_DESCENDANT);
2781            }
2782
2783            // If layout is moved, the new first layout must be valid
2784
2785            if (layout.getParentLayoutId() ==
2786                    LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
2787
2788                List layouts = LayoutUtil.findByG_P_P(
2789                    groupId, privateLayout,
2790                    LayoutImpl.DEFAULT_PARENT_LAYOUT_ID, 0, 2);
2791
2792                // You can only reach this point if there are more than two
2793                // layouts at the root level because of the descendant check
2794
2795                long firstLayoutId = ((Layout)layouts.get(0)).getLayoutId();
2796
2797                if (firstLayoutId == layoutId) {
2798                    Layout secondLayout = (Layout)layouts.get(1);
2799
2800                    try {
2801                        validateFirstLayout(
2802                            secondLayout.getType(), secondLayout.getHidden());
2803                    }
2804                    catch (LayoutHiddenException lhe) {
2805                        throw new LayoutParentLayoutIdException(
2806                            LayoutParentLayoutIdException.FIRST_LAYOUT_HIDDEN);
2807                    }
2808                    catch (LayoutTypeException lte) {
2809                        throw new LayoutParentLayoutIdException(
2810                            LayoutParentLayoutIdException.FIRST_LAYOUT_TYPE);
2811                    }
2812                }
2813            }
2814        }
2815    }
2816
2817    private static Log _log = LogFactory.getLog(LayoutLocalServiceImpl.class);
2818
2819}