1   /**
2    * Copyright (c) 2000-2008 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.portal.LayoutFriendlyURLException;
26  import com.liferay.portal.LayoutHiddenException;
27  import com.liferay.portal.LayoutImportException;
28  import com.liferay.portal.LayoutParentLayoutIdException;
29  import com.liferay.portal.LayoutTypeException;
30  import com.liferay.portal.NoSuchLayoutException;
31  import com.liferay.portal.NoSuchPortletPreferencesException;
32  import com.liferay.portal.PortalException;
33  import com.liferay.portal.RequiredLayoutException;
34  import com.liferay.portal.SystemException;
35  import com.liferay.portal.comm.CommLink;
36  import com.liferay.portal.kernel.language.LanguageUtil;
37  import com.liferay.portal.kernel.lar.PortletDataContext;
38  import com.liferay.portal.kernel.lar.PortletDataHandler;
39  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
40  import com.liferay.portal.kernel.lar.UserIdStrategy;
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.ReleaseInfo;
46  import com.liferay.portal.kernel.util.StringPool;
47  import com.liferay.portal.kernel.util.StringUtil;
48  import com.liferay.portal.kernel.util.Validator;
49  import com.liferay.portal.kernel.zip.ZipReader;
50  import com.liferay.portal.kernel.zip.ZipWriter;
51  import com.liferay.portal.lar.AlwaysCurrentUserIdStrategy;
52  import com.liferay.portal.lar.CurrentUserIdStrategy;
53  import com.liferay.portal.lar.PortletDataContextImpl;
54  import com.liferay.portal.model.Group;
55  import com.liferay.portal.model.Layout;
56  import com.liferay.portal.model.LayoutReference;
57  import com.liferay.portal.model.LayoutSet;
58  import com.liferay.portal.model.LayoutTypePortlet;
59  import com.liferay.portal.model.Permission;
60  import com.liferay.portal.model.Portlet;
61  import com.liferay.portal.model.PortletItem;
62  import com.liferay.portal.model.PortletPreferences;
63  import com.liferay.portal.model.Resource;
64  import com.liferay.portal.model.ResourceConstants;
65  import com.liferay.portal.model.Role;
66  import com.liferay.portal.model.Theme;
67  import com.liferay.portal.model.User;
68  import com.liferay.portal.model.impl.ColorSchemeImpl;
69  import com.liferay.portal.model.impl.GroupImpl;
70  import com.liferay.portal.model.impl.LayoutImpl;
71  import com.liferay.portal.model.impl.PortletImpl;
72  import com.liferay.portal.security.permission.ResourceActionsUtil;
73  import com.liferay.portal.service.LayoutLocalServiceUtil;
74  import com.liferay.portal.service.base.LayoutLocalServiceBaseImpl;
75  import com.liferay.portal.service.permission.PortletPermissionUtil;
76  import com.liferay.portal.theme.ThemeLoader;
77  import com.liferay.portal.theme.ThemeLoaderFactory;
78  import com.liferay.portal.util.ContentUtil;
79  import com.liferay.portal.util.DocumentUtil;
80  import com.liferay.portal.util.PortalUtil;
81  import com.liferay.portal.util.PortletKeys;
82  import com.liferay.portal.util.PropsValues;
83  import com.liferay.portal.util.comparator.LayoutPriorityComparator;
84  import com.liferay.portal.velocity.VelocityContextPool;
85  import com.liferay.portlet.PortletPreferencesImpl;
86  import com.liferay.portlet.PortletPreferencesSerializer;
87  import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
88  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
89  import com.liferay.portlet.documentlibrary.model.DLFolder;
90  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
91  import com.liferay.util.FileUtil;
92  import com.liferay.util.MapUtil;
93  import com.liferay.util.Normalizer;
94  import com.liferay.util.Time;
95  import com.liferay.util.xml.XMLFormatter;
96  
97  import com.thoughtworks.xstream.XStream;
98  
99  import java.io.ByteArrayInputStream;
100 import java.io.File;
101 import java.io.FileInputStream;
102 import java.io.FileNotFoundException;
103 import java.io.IOException;
104 import java.io.InputStream;
105 import java.io.StringReader;
106 
107 import java.util.ArrayList;
108 import java.util.Collections;
109 import java.util.Date;
110 import java.util.HashMap;
111 import java.util.HashSet;
112 import java.util.Iterator;
113 import java.util.LinkedHashSet;
114 import java.util.List;
115 import java.util.Locale;
116 import java.util.Map;
117 import java.util.Properties;
118 import java.util.Set;
119 
120 import javax.servlet.ServletContext;
121 
122 import org.apache.commons.lang.time.StopWatch;
123 import org.apache.commons.logging.Log;
124 import org.apache.commons.logging.LogFactory;
125 
126 import org.dom4j.Document;
127 import org.dom4j.DocumentHelper;
128 import org.dom4j.Element;
129 import org.dom4j.io.SAXReader;
130 
131 /**
132  * <a href="LayoutLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
133  *
134  * @author Brian Wing Shun Chan
135  * @author Joel Kozikowski
136  * @author Charles May
137  * @author Raymond Aug�
138  * @author Jorge Ferrer
139  * @author Bruno Farache
140  *
141  */
142 public class LayoutLocalServiceImpl extends LayoutLocalServiceBaseImpl {
143 
144     public Layout addLayout(
145             long userId, long groupId, boolean privateLayout,
146             long parentLayoutId, String name, String title, String description,
147             String type, boolean hidden, String friendlyURL)
148         throws PortalException, SystemException {
149 
150         Map<Locale, String> localeNamesMap = new HashMap<Locale, String>();
151 
152         Locale defaultLocale = LocaleUtil.getDefault();
153 
154         localeNamesMap.put(defaultLocale, name);
155 
156         return addLayout(
157             userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
158             new HashMap<Locale, String>(), description, type, hidden,
159             friendlyURL);
160     }
161 
162     public Layout addLayout(
163             long userId, long groupId, boolean privateLayout,
164             long parentLayoutId, Map<Locale, String> localeNamesMap,
165             Map<Locale, String> localeTitlesMap, String description,
166             String type, boolean hidden, String friendlyURL)
167         throws PortalException, SystemException {
168 
169         return addLayout(
170             userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
171             localeTitlesMap, description, type, hidden, friendlyURL,
172             DLFolderImpl.DEFAULT_PARENT_FOLDER_ID);
173     }
174 
175     public Layout addLayout(
176             long userId, long groupId, boolean privateLayout,
177             long parentLayoutId, String name, String title, String description,
178             String type, boolean hidden, String friendlyURL, long dlFolderId)
179         throws PortalException, SystemException {
180 
181         Map<Locale, String> localeNamesMap = new HashMap<Locale, String>();
182 
183         Locale defaultLocale = LocaleUtil.getDefault();
184 
185         localeNamesMap.put(defaultLocale, name);
186 
187         return addLayout(
188             userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
189             new HashMap<Locale, String>(), description, type, hidden,
190             friendlyURL, dlFolderId);
191     }
192 
193     public Layout addLayout(
194             long userId, long groupId, boolean privateLayout,
195             long parentLayoutId, Map<Locale, String> localeNamesMap,
196             Map<Locale, String> localeTitlesMap, String description,
197             String type, boolean hidden, String friendlyURL, long dlFolderId)
198         throws PortalException, SystemException {
199 
200         // Layout
201 
202         User user = userPersistence.findByPrimaryKey(userId);
203         long layoutId = getNextLayoutId(groupId, privateLayout);
204         parentLayoutId = getParentLayoutId(
205             groupId, privateLayout, parentLayoutId);
206         friendlyURL = getFriendlyURL(layoutId, friendlyURL);
207         int priority = getNextPriority(groupId, privateLayout, parentLayoutId);
208 
209         validate(
210             groupId, privateLayout, layoutId, parentLayoutId, type, hidden,
211             friendlyURL);
212 
213         long plid = counterLocalService.increment();
214 
215         Layout layout = layoutPersistence.create(plid);
216 
217         layout.setGroupId(groupId);
218         layout.setCompanyId(user.getCompanyId());
219         layout.setPrivateLayout(privateLayout);
220         layout.setLayoutId(layoutId);
221         layout.setParentLayoutId(parentLayoutId);
222         layout.setDescription(description);
223         layout.setType(type);
224         layout.setHidden(hidden);
225         layout.setFriendlyURL(friendlyURL);
226         layout.setPriority(priority);
227         layout.setDlFolderId(dlFolderId);
228 
229         setLocalizedAttributes(layout, localeNamesMap, localeTitlesMap);
230 
231         layoutPersistence.update(layout, false);
232 
233         // Resources
234 
235         resourceLocalService.addResources(
236             user.getCompanyId(), groupId, user.getUserId(),
237             Layout.class.getName(), layout.getPlid(), false, true, true);
238 
239         // Layout set
240 
241         layoutSetLocalService.updatePageCount(groupId, privateLayout);
242 
243         return layout;
244     }
245 
246     public void deleteLayout(long plid)
247         throws PortalException, SystemException {
248 
249         Layout layout = layoutPersistence.findByPrimaryKey(plid);
250 
251         deleteLayout(layout, true);
252     }
253 
254     public void deleteLayout(long groupId, boolean privateLayout, long layoutId)
255         throws PortalException, SystemException {
256 
257         Layout layout = layoutPersistence.findByG_P_L(
258             groupId, privateLayout, layoutId);
259 
260         deleteLayout(layout, true);
261     }
262 
263     public void deleteLayout(Layout layout, boolean updateLayoutSet)
264         throws PortalException, SystemException {
265 
266         // Child layouts
267 
268         List<Layout> childLayouts = layoutPersistence.findByG_P_P(
269             layout.getGroupId(), layout.isPrivateLayout(),
270             layout.getLayoutId());
271 
272         for (Layout childLayout : childLayouts) {
273             deleteLayout(childLayout, updateLayoutSet);
274         }
275 
276         // Portlet preferences
277 
278         portletPreferencesLocalService.deletePortletPreferences(
279             PortletKeys.PREFS_OWNER_ID_DEFAULT,
280             PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid());
281 
282         // Tasks
283 
284         tasksProposalLocalService.deleteProposal(
285             Layout.class.getName(), String.valueOf(layout.getPlid()));
286 
287         // Ratings
288 
289         ratingsStatsLocalService.deleteStats(
290             Layout.class.getName(), layout.getPlid());
291 
292         // Message boards
293 
294         mbMessageLocalService.deleteDiscussionMessages(
295             Layout.class.getName(), layout.getPlid());
296 
297         // Journal content searches
298 
299         journalContentSearchLocalService.deleteLayoutContentSearches(
300             layout.getGroupId(), layout.isPrivateLayout(),
301             layout.getLayoutId());
302 
303         // Icon
304 
305         ImageLocalUtil.deleteImage(layout.getIconImageId());
306 
307         // Resources
308 
309         String primKey = layout.getPlid() + PortletImpl.LAYOUT_SEPARATOR + "%";
310 
311         List<Resource> resources = resourceFinder.findByC_P(
312             layout.getCompanyId(), primKey);
313 
314         for (Resource resource : resources) {
315             resourceLocalService.deleteResource(resource);
316         }
317 
318         resourceLocalService.deleteResource(
319             layout.getCompanyId(), Layout.class.getName(),
320             ResourceConstants.SCOPE_INDIVIDUAL, layout.getPlid());
321 
322         // Layout
323 
324         layoutPersistence.remove(layout.getPlid());
325 
326         // Layout set
327 
328         if (updateLayoutSet) {
329             layoutSetLocalService.updatePageCount(
330                 layout.getGroupId(), layout.isPrivateLayout());
331         }
332     }
333 
334     public void deleteLayouts(long groupId, boolean privateLayout)
335         throws PortalException, SystemException {
336 
337         // Layouts
338 
339         List<Layout> layouts = layoutPersistence.findByG_P_P(
340             groupId, privateLayout, LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
341 
342         for (Layout layout : layouts) {
343             try {
344                 deleteLayout(layout, false);
345             }
346             catch (NoSuchLayoutException nsle) {
347             }
348         }
349 
350         // Layout set
351 
352         layoutSetLocalService.updatePageCount(groupId, privateLayout);
353     }
354 
355     public byte[] exportLayouts(
356             long groupId, boolean privateLayout,
357             Map<String, String[]> parameterMap)
358         throws PortalException, SystemException {
359 
360         return exportLayouts(groupId, privateLayout, null, parameterMap);
361     }
362 
363     public byte[] exportLayouts(
364             long groupId, boolean privateLayout, long[] layoutIds,
365             Map<String, String[]> parameterMap)
366         throws PortalException, SystemException {
367 
368         boolean exportPermissions = MapUtil.getBoolean(
369             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
370         boolean exportUserPermissions = MapUtil.getBoolean(
371             parameterMap, PortletDataHandlerKeys.USER_PERMISSIONS);
372         boolean exportPortletData = MapUtil.getBoolean(
373             parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
374         boolean exportPortletSetup = MapUtil.getBoolean(
375             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
376         boolean exportPortletArchivedSetups = MapUtil.getBoolean(
377             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
378         boolean exportPortletUserPreferences = MapUtil.getBoolean(
379             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
380         boolean exportTheme = MapUtil.getBoolean(
381             parameterMap, PortletDataHandlerKeys.THEME);
382 
383         if (_log.isDebugEnabled()) {
384             _log.debug("Export permissions " + exportPermissions);
385             _log.debug("Export user permissions " + exportUserPermissions);
386             _log.debug("Export portlet data " + exportPortletData);
387             _log.debug("Export portlet setup " + exportPortletSetup);
388             _log.debug(
389                 "Export portlet archived setups " +
390                     exportPortletArchivedSetups);
391             _log.debug(
392                 "Export portlet user preferences " +
393                     exportPortletUserPreferences);
394             _log.debug("Export theme " + exportTheme);
395         }
396 
397         StopWatch stopWatch = null;
398 
399         if (_log.isInfoEnabled()) {
400             stopWatch = new StopWatch();
401 
402             stopWatch.start();
403         }
404 
405         LayoutCache layoutCache = new LayoutCache();
406 
407         LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
408             groupId, privateLayout);
409 
410         long companyId = layoutSet.getCompanyId();
411         long defaultUserId = userLocalService.getDefaultUserId(companyId);
412 
413         ZipWriter zipWriter = new ZipWriter();
414 
415         PortletDataContext context = new PortletDataContextImpl(
416             companyId, groupId, parameterMap, new HashSet(), zipWriter);
417 
418         Group guestGroup = groupLocalService.getGroup(
419             companyId, GroupImpl.GUEST);
420 
421         // Build compatibility
422 
423         Document doc = DocumentHelper.createDocument();
424 
425         Element root = doc.addElement("root");
426 
427         Element header = root.addElement("header");
428 
429         header.addAttribute(
430             "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
431         header.addAttribute("group-id", String.valueOf(groupId));
432         header.addAttribute("private-layout", String.valueOf(privateLayout));
433         header.addAttribute("export-date", Time.getRFC822());
434         header.addAttribute("theme-id", layoutSet.getThemeId());
435         header.addAttribute("color-scheme-id", layoutSet.getColorSchemeId());
436         header.addAttribute("type", "layouts");
437 
438         // Layouts
439 
440         Set<String> portletIds = new LinkedHashSet<String>();
441 
442         List<Layout> layouts = null;
443 
444         if ((layoutIds == null) || (layoutIds.length == 0)) {
445             layouts = getLayouts(groupId, privateLayout);
446         }
447         else {
448             layouts = getLayouts(groupId, privateLayout, layoutIds);
449         }
450 
451         for (Layout layout : layouts) {
452             context.setPlid(layout.getPlid());
453 
454             Element layoutEl = root.addElement("layout");
455 
456             layoutEl.addAttribute(
457                 "layout-id", String.valueOf(layout.getLayoutId()));
458             layoutEl.addElement("parent-layout-id").addText(
459                 String.valueOf(layout.getParentLayoutId()));
460             layoutEl.addElement("name").addCDATA(layout.getName());
461             layoutEl.addElement("title").addCDATA(layout.getTitle());
462             layoutEl.addElement("type").addText(layout.getType());
463             layoutEl.addElement("type-settings").addCDATA(
464                 layout.getTypeSettings());
465             layoutEl.addElement("hidden").addText(
466                 String.valueOf(layout.getHidden()));
467             layoutEl.addElement("friendly-url").addText(
468                 layout.getFriendlyURL());
469             layoutEl.addElement("theme-id").addText(layout.getThemeId());
470             layoutEl.addElement("color-scheme-id").addText(
471                 layout.getColorSchemeId());
472             layoutEl.addElement("priority").addText(
473                 String.valueOf(layout.getPriority()));
474 
475             Element permissionsEl = layoutEl.addElement("permissions");
476 
477             // Layout permissions
478 
479             if (exportPermissions) {
480                 exportLayoutPermissions(
481                     layoutCache, companyId, groupId, guestGroup, layout,
482                     permissionsEl, exportUserPermissions);
483             }
484 
485             if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
486                 LayoutTypePortlet layoutTypePortlet =
487                     (LayoutTypePortlet)layout.getLayoutType();
488 
489                 // The order of the export is important. You must always export
490                 // the portlet data first, then the portlet preferences, then
491                 // the portlet permissions. The export of the portlet data
492                 // process may modify the portlet preferences, and those changes
493                 // should be included in the exported LAR.
494 
495                 // Portlet data
496 
497                 if (exportPortletData) {
498                     exportPortletData(
499                         context, layout, layoutTypePortlet, layoutEl);
500                 }
501 
502                 // Portlet preferences
503 
504                 if (exportPortletSetup) {
505                     exportPortletPreferences(
506                         PortletKeys.PREFS_OWNER_ID_DEFAULT,
507                         PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false,
508                         layout.getPlid(), layoutTypePortlet, layoutEl);
509 
510                     exportPortletPreferences(
511                         layout.getGroupId(),
512                         PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
513                         layout.getPlid(), layoutTypePortlet, layoutEl);
514 
515                     exportPortletPreferences(
516                         layout.getCompanyId(),
517                         PortletKeys.PREFS_OWNER_TYPE_COMPANY, false,
518                         layout.getPlid(), layoutTypePortlet, layoutEl);
519                 }
520 
521                 if (exportPortletUserPreferences) {
522                     exportPortletPreferences(
523                         defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
524                         true, layout.getPlid(), layoutTypePortlet,
525                         layoutEl);
526                 }
527 
528                 // Portlet permissions
529 
530                 if (exportPermissions) {
531                     exportPortletPermissions(
532                         layoutCache, companyId, groupId, guestGroup,
533                         layout, layoutTypePortlet, portletIds, permissionsEl,
534                         exportUserPermissions);
535                 }
536             }
537         }
538 
539         // Portlet preferences
540 
541         if (exportPortletUserPreferences) {
542             exportPortletPreferences(
543                 groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
544                 PortletKeys.PREFS_PLID_SHARED, false, root);
545 
546         }
547 
548         // Archived setups
549 
550         if (exportPortletArchivedSetups) {
551             List<PortletItem> portletItems =
552                 portletItemLocalService.getPortletItems(
553                     groupId, PortletPreferences.class.getName());
554 
555             for (PortletItem portletItem: portletItems) {
556                 long ownerId = portletItem.getPortletItemId();
557                 int ownerType = PortletKeys.PREFS_OWNER_TYPE_ARCHIVED;
558 
559                 exportPortletPreferences(
560                     ownerId, ownerType, false, null, portletItem.getPortletId(),
561                     root);
562             }
563         }
564 
565         Element rolesEl = root.addElement("roles");
566 
567         // Layout roles
568 
569         if (exportPermissions) {
570             exportLayoutRoles(layoutCache, companyId, groupId, rolesEl);
571         }
572 
573         // Portlet roles
574 
575         if (exportPermissions) {
576             exportPortletRoles(
577                 layoutCache, companyId, groupId, portletIds, rolesEl);
578         }
579 
580         // Comments
581 
582         exportComments(context, root);
583 
584         // Ratings
585 
586         exportRatings(context, root);
587 
588         // Tags
589 
590         exportTags(context, root);
591 
592         // Look and feel
593 
594         byte[] themeZip = null;
595 
596         try {
597             if (exportTheme) {
598                 themeZip = exportTheme(layoutSet);
599             }
600         }
601         catch (IOException ioe) {
602             throw new SystemException(ioe);
603         }
604 
605         // XML
606 
607         if (_log.isInfoEnabled()) {
608             _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms");
609         }
610 
611         // Zip
612 
613         try {
614             zipWriter.addEntry("layouts.xml", XMLFormatter.toString(doc));
615 
616             if (themeZip != null) {
617                 zipWriter.addEntry("theme.zip", themeZip);
618             }
619 
620             return zipWriter.finish();
621         }
622         catch (IOException ioe) {
623             throw new SystemException(ioe);
624         }
625     }
626 
627     public byte[] exportPortletInfo(
628             long plid, String portletId, Map<String, String[]> parameterMap)
629         throws PortalException, SystemException {
630 
631         boolean exportPortletSetup = MapUtil.getBoolean(
632             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
633         boolean exportPortletArchivedSetups = MapUtil.getBoolean(
634             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
635         boolean exportPortletUserPreferences = MapUtil.getBoolean(
636             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
637 
638         StopWatch stopWatch = null;
639 
640         if (_log.isInfoEnabled()) {
641             stopWatch = new StopWatch();
642 
643             stopWatch.start();
644         }
645 
646         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
647 
648         if (!layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
649             throw new LayoutImportException(
650                 "Layout type " + layout.getType() + " is not valid");
651         }
652 
653         LayoutTypePortlet layoutTypePortlet =
654             (LayoutTypePortlet)layout.getLayoutType();
655 
656         if (!layoutTypePortlet.hasPortletId(portletId)) {
657             throw new LayoutImportException(
658                 "The specified layout does not have portlet " + portletId);
659         }
660 
661         long companyId = layout.getCompanyId();
662         long defaultUserId = userLocalService.getDefaultUserId(companyId);
663 
664         ZipWriter zipWriter = new ZipWriter();
665 
666         PortletDataContext context = new PortletDataContextImpl(
667             companyId, layout.getGroupId(), parameterMap, new HashSet(),
668             zipWriter);
669 
670         context.setPlid(plid);
671 
672         // Build compatibility
673 
674         Document doc = DocumentHelper.createDocument();
675 
676         Element root = doc.addElement("root");
677 
678         Element header = root.addElement("header");
679 
680         header.addAttribute(
681             "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
682         header.addAttribute("group-id", String.valueOf(layout.getGroupId()));
683         header.addAttribute("export-date", Time.getRFC822());
684         header.addAttribute("type", "portlet");
685 
686         // Data
687 
688         PortletPreferences portletPreferences =
689             portletPreferencesLocalService.getPortletPreferences(plid).get(0);
690 
691         javax.portlet.PortletPreferences jxPrefs =
692             portletPreferencesLocalService.getPreferences(
693                 layout.getCompanyId(), portletPreferences.getOwnerId(),
694                 portletPreferences.getOwnerType(), plid, portletId);
695 
696         exportPortletData(context, portletId, jxPrefs, root);
697 
698         // Comments
699 
700         exportComments(context, root);
701 
702         // Ratings
703 
704         exportRatings(context, root);
705 
706         // Tags
707 
708         exportTags(context, root);
709 
710         // Portlet preferences
711 
712         if (exportPortletSetup) {
713             exportPortletPreferences(
714                 PortletKeys.PREFS_OWNER_ID_DEFAULT,
715                 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, portletId,
716                 root);
717 
718             exportPortletPreferences(
719                 layout.getGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
720                 layout, portletId, root);
721 
722             exportPortletPreferences(
723                 layout.getCompanyId(), PortletKeys.PREFS_OWNER_TYPE_COMPANY,
724                 false, layout, portletId, root);
725         }
726 
727         if (exportPortletArchivedSetups) {
728             String rootPortletId = PortletImpl.getRootPortletId(portletId);
729 
730             List<PortletItem> portletItems =
731                 portletItemLocalService.getPortletItems(
732                     layout.getGroupId(), rootPortletId,
733                     PortletPreferences.class.getName());
734 
735             for (PortletItem portletItem: portletItems) {
736                 long ownerId = portletItem.getPortletItemId();
737                 int ownerType = PortletKeys.PREFS_OWNER_TYPE_ARCHIVED;
738 
739                 exportPortletPreferences(
740                     ownerId, ownerType, false, null, portletItem.getPortletId(),
741                     root);
742             }
743         }
744 
745         if (exportPortletUserPreferences) {
746             exportPortletPreferences(
747                 defaultUserId, PortletKeys.PREFS_OWNER_TYPE_USER,
748                 true, layout, portletId, root);
749         }
750 
751         // XML
752 
753         if (_log.isInfoEnabled()) {
754             _log.info(
755                 "Exporting portlet info takes " + stopWatch.getTime() + " ms");
756         }
757 
758         // Zip
759 
760         try {
761             zipWriter.addEntry("portlet.xml", XMLFormatter.toString(doc));
762 
763             return zipWriter.finish();
764         }
765         catch (IOException ioe) {
766             throw new SystemException(ioe);
767         }
768     }
769 
770     public long getDefaultPlid(long groupId) throws SystemException {
771         if (groupId > 0) {
772             List<Layout> layouts = layoutPersistence.findByGroupId(
773                 groupId, 0, 1);
774 
775             if (layouts.size() > 0) {
776                 Layout layout = layouts.get(0);
777 
778                 return layout.getPlid();
779             }
780         }
781 
782         return LayoutImpl.DEFAULT_PLID;
783     }
784 
785     public long getDefaultPlid(long groupId, boolean privateLayout)
786         throws SystemException {
787 
788         if (groupId > 0) {
789             List<Layout> layouts = layoutPersistence.findByG_P(
790                 groupId, privateLayout, 0, 1);
791 
792             if (layouts.size() > 0) {
793                 Layout layout = layouts.get(0);
794 
795                 return layout.getPlid();
796             }
797         }
798 
799         return LayoutImpl.DEFAULT_PLID;
800     }
801 
802     public long getDefaultPlid(
803             long groupId, boolean privateLayout, String portletId)
804         throws SystemException {
805 
806         if (groupId > 0) {
807             List<Layout> layouts = layoutPersistence.findByG_P(
808                 groupId, privateLayout);
809 
810             for (Layout layout : layouts) {
811                 if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
812                     LayoutTypePortlet layoutTypePortlet =
813                         (LayoutTypePortlet)layout.getLayoutType();
814 
815                     if (layoutTypePortlet.hasPortletId(portletId)) {
816                         return layout.getPlid();
817                     }
818                 }
819             }
820         }
821 
822         return LayoutImpl.DEFAULT_PLID;
823     }
824 
825     public Layout getDLFolderLayout(long dlFolderId)
826         throws PortalException, SystemException {
827 
828         return layoutPersistence.findByDLFolderId(dlFolderId);
829     }
830 
831     public Layout getFriendlyURLLayout(
832             long groupId, boolean privateLayout, String friendlyURL)
833         throws PortalException, SystemException {
834 
835         if (Validator.isNull(friendlyURL)) {
836             throw new NoSuchLayoutException();
837         }
838 
839         friendlyURL = getFriendlyURL(friendlyURL);
840 
841         return layoutPersistence.findByG_P_F(
842             groupId, privateLayout, friendlyURL);
843     }
844 
845     public Layout getLayout(long plid)
846         throws PortalException, SystemException {
847 
848         return layoutPersistence.findByPrimaryKey(plid);
849     }
850 
851     public Layout getLayout(long groupId, boolean privateLayout, long layoutId)
852         throws PortalException, SystemException {
853 
854         return layoutPersistence.findByG_P_L(groupId, privateLayout, layoutId);
855     }
856 
857     public Layout getLayoutByIconImageId(long iconImageId)
858         throws PortalException, SystemException {
859 
860         return layoutPersistence.findByIconImageId(iconImageId);
861     }
862 
863     public List<Layout> getLayouts(long groupId, boolean privateLayout)
864         throws SystemException {
865 
866         return layoutPersistence.findByG_P(groupId, privateLayout);
867     }
868 
869     public List<Layout> getLayouts(
870             long groupId, boolean privateLayout, long parentLayoutId)
871         throws SystemException {
872 
873         return layoutPersistence.findByG_P_P(
874             groupId, privateLayout, parentLayoutId);
875     }
876 
877     public List<Layout> getLayouts(
878             long groupId, boolean privateLayout, long parentLayoutId, int begin,
879             int end)
880         throws SystemException {
881 
882         return layoutPersistence.findByG_P_P(
883             groupId, privateLayout, parentLayoutId, begin, end);
884     }
885 
886     public List<Layout> getLayouts(
887             long groupId, boolean privateLayout, long[] layoutIds)
888         throws PortalException, SystemException {
889 
890         List<Layout> layouts = new ArrayList<Layout>();
891 
892         for (long layoutId : layoutIds) {
893             Layout layout = getLayout(groupId, privateLayout, layoutId);
894 
895             layouts.add(layout);
896         }
897 
898         return layouts;
899     }
900 
901     public LayoutReference[] getLayouts(
902             long companyId, String portletId, String prefsKey,
903             String prefsValue)
904         throws SystemException {
905 
906         List<LayoutReference> layoutReferences = layoutFinder.findByC_P_P(
907             companyId, portletId, prefsKey, prefsValue);
908 
909         return layoutReferences.toArray(
910             new LayoutReference[layoutReferences.size()]);
911     }
912 
913     public List<Layout> getNullFriendlyURLLayouts() throws SystemException {
914         return layoutFinder.findByNullFriendlyURL();
915     }
916 
917     public void importLayouts(
918             long userId, long groupId, boolean privateLayout,
919             Map<String, String[]> parameterMap, File file)
920         throws PortalException, SystemException {
921 
922         try {
923             importLayouts(
924                 userId, groupId, privateLayout, parameterMap,
925                 new FileInputStream(file));
926         }
927         catch (FileNotFoundException fnfe) {
928             throw new SystemException(fnfe);
929         }
930     }
931 
932     public void importLayouts(
933             long userId, long groupId, boolean privateLayout,
934             Map<String, String[]> parameterMap, InputStream is)
935         throws PortalException, SystemException {
936 
937         boolean deleteMissingLayouts = MapUtil.getBoolean(
938             parameterMap, PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
939             Boolean.TRUE.booleanValue());
940         boolean deletePortletData = MapUtil.getBoolean(
941             parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
942         boolean importPermissions = MapUtil.getBoolean(
943             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
944         boolean importUserPermissions = MapUtil.getBoolean(
945             parameterMap, PortletDataHandlerKeys.PERMISSIONS);
946         boolean importPortletData = MapUtil.getBoolean(
947             parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
948         boolean importPortletSetup = MapUtil.getBoolean(
949             parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
950         boolean importPortletArchivedSetups = MapUtil.getBoolean(
951             parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
952         boolean importPortletUserPreferences = MapUtil.getBoolean(
953             parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
954         boolean importTheme = MapUtil.getBoolean(
955             parameterMap, PortletDataHandlerKeys.THEME);
956         String userIdStrategy = MapUtil.getString(
957             parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
958 
959         if (_log.isDebugEnabled()) {
960             _log.debug("Delete portlet data " + deletePortletData);
961             _log.debug("Import permissions " + importPermissions);
962             _log.debug("Import user permissions " + importUserPermissions);
963             _log.debug("Import portlet data " + importPortletData);
964             _log.debug("Import portlet setup " + importPortletSetup);
965             _log.debug(
966                 "Import portlet archived setups " +
967                     importPortletArchivedSetups);
968             _log.debug(
969                 "Import portlet user preferences " +
970                     importPortletUserPreferences);
971             _log.debug("Import theme " + importTheme);
972         }
973 
974         StopWatch stopWatch = null;
975 
976         if (_log.isInfoEnabled()) {
977             stopWatch = new StopWatch();
978 
979             stopWatch.start();
980         }
981 
982         LayoutCache layoutCache = new LayoutCache();
983 
984         LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
985             groupId, privateLayout);
986 
987         long companyId = layoutSet.getCompanyId();
988 
989         User user = userPersistence.findByPrimaryKey(userId);
990 
991         UserIdStrategy strategy = getUserIdStrategy(user, userIdStrategy);
992 
993         ZipReader zipReader = new ZipReader(is);
994 
995         PortletDataContext context = new PortletDataContextImpl(
996             companyId, groupId, parameterMap, new HashSet(), strategy,
997             zipReader);
998 
999         Group guestGroup = groupLocalService.getGroup(
1000            companyId, GroupImpl.GUEST);
1001
1002        // Zip
1003
1004        Element root = null;
1005        byte[] themeZip = null;
1006
1007        try {
1008
1009            // XML
1010
1011            String xml = zipReader.getEntryAsString("layouts.xml");
1012
1013            SAXReader reader = new SAXReader();
1014
1015            Document doc = reader.read(new StringReader(xml));
1016
1017            root = doc.getRootElement();
1018
1019            // Look and feel
1020
1021            if (importTheme) {
1022                themeZip = zipReader.getEntryAsByteArray("theme.zip");
1023            }
1024        }
1025        catch (Exception e) {
1026            throw new SystemException(e);
1027        }
1028
1029        // Build compatibility
1030
1031        Element header = root.element("header");
1032
1033        int buildNumber = ReleaseInfo.getBuildNumber();
1034
1035        int importBuildNumber = GetterUtil.getInteger(
1036            header.attributeValue("build-number"));
1037
1038        if (buildNumber != importBuildNumber) {
1039            throw new LayoutImportException(
1040                "LAR build number " + importBuildNumber + " does not match " +
1041                    "portal build number " + buildNumber);
1042        }
1043
1044        // Look and feel
1045
1046        String themeId = header.attributeValue("theme-id");
1047        String colorSchemeId = header.attributeValue("color-scheme-id");
1048
1049        boolean useThemeZip = false;
1050
1051        if (themeZip != null) {
1052            try {
1053                String importThemeId = importTheme(layoutSet, themeZip);
1054
1055                if (importThemeId != null) {
1056                    themeId = importThemeId;
1057                    colorSchemeId =
1058                        ColorSchemeImpl.getDefaultRegularColorSchemeId();
1059
1060                    useThemeZip = true;
1061                }
1062
1063                if (_log.isDebugEnabled()) {
1064                    _log.debug(
1065                        "Importing theme takes " + stopWatch.getTime() + " ms");
1066                }
1067            }
1068            catch (Exception e) {
1069                throw new SystemException(e);
1070            }
1071        }
1072
1073        boolean wapTheme = false;
1074
1075        layoutSetLocalService.updateLookAndFeel(
1076            groupId, privateLayout, themeId, colorSchemeId, StringPool.BLANK,
1077            wapTheme);
1078
1079        // Read comments, ratings, and tags to make them available to the data
1080        // handlers through the context
1081
1082        readComments(context, root);
1083        readRatings(context, root);
1084        readTags(context, root);
1085
1086        // Layouts
1087
1088        Set<Long> newLayoutIds = new HashSet<Long>();
1089
1090        Iterator<Element> itr = root.elements("layout").iterator();
1091
1092        if (_log.isDebugEnabled()) {
1093            if (itr.hasNext()) {
1094                _log.debug("Importing layouts");
1095            }
1096        }
1097
1098        while (itr.hasNext()) {
1099            Element layoutEl = itr.next();
1100
1101            long layoutId = GetterUtil.getInteger(
1102                layoutEl.attributeValue("layout-id"));
1103            long parentLayoutId = GetterUtil.getInteger(
1104                layoutEl.elementText("parent-layout-id"));
1105
1106            if (_log.isDebugEnabled()) {
1107                _log.debug(
1108                    "Importing layout with layout id " + layoutId +
1109                        " and parent layout id " + parentLayoutId);
1110            }
1111
1112            String name = layoutEl.elementText("name");
1113            String title = layoutEl.elementText("title");
1114            String type = layoutEl.elementText("type");
1115            String typeSettings = layoutEl.elementText("type-settings");
1116            boolean hidden = GetterUtil.getBoolean(
1117                layoutEl.elementText("hidden"));
1118            String friendlyURL = layoutEl.elementText("friendly-url");
1119
1120            if (useThemeZip) {
1121                themeId = StringPool.BLANK;
1122                colorSchemeId = StringPool.BLANK;
1123            }
1124            else {
1125                themeId = layoutEl.elementText("theme-id");
1126                colorSchemeId = layoutEl.elementText("color-scheme-id");
1127            }
1128
1129            int priority = GetterUtil.getInteger(
1130                layoutEl.elementText("priority"));
1131
1132            Layout layout = layoutPersistence.fetchByG_P_L(
1133                groupId, privateLayout, layoutId);
1134
1135            if (_log.isDebugEnabled()) {
1136                if (layout == null) {
1137                    _log.debug(
1138                        "Layout with {groupId=" + groupId + ",privateLayout=" +
1139                            privateLayout + ",layoutId=" + layoutId +
1140                                "} does not exist");
1141                }
1142                else {
1143                    _log.debug(
1144                        "Layout with {groupId=" + groupId + ",privateLayout=" +
1145                            privateLayout + ",layoutId=" + layoutId +
1146                                "} exists");
1147                }
1148            }
1149
1150            if (layout == null) {
1151                long plid = counterLocalService.increment();
1152
1153                layout = layoutPersistence.create(plid);
1154
1155                layout.setGroupId(groupId);
1156                layout.setPrivateLayout(privateLayout);
1157                layout.setLayoutId(layoutId);
1158            }
1159
1160            layout.setCompanyId(user.getCompanyId());
1161            layout.setParentLayoutId(parentLayoutId);
1162            layout.setName(name);
1163            layout.setTitle(title);
1164            layout.setType(type);
1165            layout.setTypeSettings(typeSettings);
1166            layout.setHidden(hidden);
1167            layout.setFriendlyURL(friendlyURL);
1168            layout.setThemeId(themeId);
1169            layout.setColorSchemeId(colorSchemeId);
1170            layout.setPriority(priority);
1171
1172            fixTypeSettings(layout);
1173
1174            layoutPersistence.update(layout, false);
1175
1176            context.setPlid(layout.getPlid());
1177
1178            newLayoutIds.add(layoutId);
1179
1180            Element permissionsEl = layoutEl.element("permissions");
1181
1182            // Layout permissions
1183
1184            if (importPermissions) {
1185                importLayoutPermissions(
1186                    layoutCache, companyId, groupId, guestGroup, layout,
1187                    permissionsEl, importUserPermissions);
1188            }
1189
1190            // The order of the import is important. You must always import
1191            // the portlet preferences first, then the portlet data, then
1192            // the portlet permissions. The import of the portlet data
1193            // assumes that portlet preferences already exist.
1194
1195            // Delete portlet data
1196
1197            if (deletePortletData) {
1198                deletePortletData(context, layout, layoutEl);
1199            }
1200
1201            // Portlet preferences
1202
1203            importPortletPreferences(
1204                context, layoutSet.getCompanyId(), layout.getGroupId(),
1205                layout.getPlid(), layoutEl, importPortletSetup,
1206                importPortletArchivedSetups, importPortletUserPreferences);
1207
1208            // Portlet data
1209
1210            if (importPortletData) {
1211                importPortletData(context, layout, layoutEl);
1212            }
1213
1214            // Portlet permissions
1215
1216            if (importPermissions) {
1217                importPortletPermissions(
1218                    layoutCache, companyId, groupId, guestGroup, layout,
1219                    permissionsEl, importUserPermissions);
1220            }
1221        }
1222
1223        // Archived setups
1224
1225        importPortletPreferences(
1226            context, layoutSet.getCompanyId(), groupId, 0, root,
1227            importPortletSetup, importPortletArchivedSetups,
1228            importPortletUserPreferences);
1229
1230        Element rolesEl = root.element("roles");
1231
1232        // Layout roles
1233
1234        if (importPermissions) {
1235            importLayoutRoles(layoutCache, companyId, groupId, rolesEl);
1236        }
1237
1238        // Portlet roles
1239
1240        if (importPermissions) {
1241            importPortletRoles(layoutCache, companyId, groupId, rolesEl);
1242        }
1243
1244        // Delete missing layouts
1245
1246        if (deleteMissingLayouts) {
1247            deleteMissingLayouts(groupId, privateLayout, newLayoutIds);
1248        }
1249
1250        // Page count
1251
1252        layoutSetLocalService.updatePageCount(groupId, privateLayout);
1253
1254        if (_log.isInfoEnabled()) {
1255            _log.info("Importing layouts takes " + stopWatch.getTime() + " ms");
1256        }
1257    }
1258
1259    public void importPortletInfo(
1260            long userId, long plid, String portletId,
1261            Map<String, String[]> parameterMap, File file)
1262        throws PortalException, SystemException {
1263
1264        try {
1265            importPortletInfo(
1266                userId, plid, portletId, parameterMap,
1267                new FileInputStream(file));
1268        }
1269        catch (FileNotFoundException fnfe) {
1270            throw new SystemException(fnfe);
1271        }
1272    }
1273
1274    public void importPortletInfo(
1275            long userId, long plid, String portletId,
1276            Map<String, String[]> parameterMap, InputStream is)
1277        throws PortalException, SystemException {
1278
1279        boolean deletePortletData = MapUtil.getBoolean(
1280            parameterMap, PortletDataHandlerKeys.DELETE_PORTLET_DATA);
1281        boolean importPortletData = MapUtil.getBoolean(
1282            parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
1283        boolean importPortletArchivedSetups = MapUtil.getBoolean(
1284            parameterMap, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS);
1285        boolean importPortletSetup = MapUtil.getBoolean(
1286            parameterMap, PortletDataHandlerKeys.PORTLET_SETUP);
1287        boolean importUserPreferences = MapUtil.getBoolean(
1288            parameterMap, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES);
1289        String userIdStrategy = MapUtil.getString(
1290            parameterMap, PortletDataHandlerKeys.USER_ID_STRATEGY);
1291
1292        StopWatch stopWatch = null;
1293
1294        if (_log.isInfoEnabled()) {
1295            stopWatch = new StopWatch();
1296
1297            stopWatch.start();
1298        }
1299
1300        Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1301
1302        long companyId = layout.getCompanyId();
1303
1304        User user = userPersistence.findByPrimaryKey(userId);
1305
1306        UserIdStrategy strategy = getUserIdStrategy(user, userIdStrategy);
1307
1308        ZipReader zipReader = new ZipReader(is);
1309
1310        PortletDataContext context = new PortletDataContextImpl(
1311            companyId, layout.getGroupId(), parameterMap, new HashSet(),
1312            strategy, zipReader);
1313
1314        context.setPlid(plid);
1315
1316        // Zip
1317
1318        Element root = null;
1319
1320        try {
1321
1322            // XML
1323
1324            String xml = zipReader.getEntryAsString("portlet.xml");
1325
1326            SAXReader reader = new SAXReader();
1327
1328            Document doc = reader.read(new StringReader(xml));
1329
1330            root = doc.getRootElement();
1331        }
1332        catch (Exception e) {
1333            throw new SystemException(e);
1334        }
1335
1336        // Build compatibility
1337
1338        Element header = root.element("header");
1339
1340        int buildNumber = ReleaseInfo.getBuildNumber();
1341
1342        int importBuildNumber = GetterUtil.getInteger(
1343            header.attributeValue("build-number"));
1344
1345        if (buildNumber != importBuildNumber) {
1346            throw new LayoutImportException(
1347                "LAR build number " + importBuildNumber + " does not match " +
1348                    "portal build number " + buildNumber);
1349        }
1350
1351        String type = header.attributeValue("type");
1352
1353        if (!type.equals("portlet")) {
1354            throw new LayoutImportException(
1355                "Invalid type of LAR file (" + type + ")");
1356        }
1357
1358        // Read comments, ratings, and tags to make them available to the data
1359        // handlers through the context
1360
1361        readComments(context, root);
1362        readRatings(context, root);
1363        readTags(context, root);
1364
1365        // Delete portlet data
1366
1367        if (_log.isDebugEnabled()) {
1368            _log.debug("Deleting portlet data");
1369        }
1370
1371        if (deletePortletData) {
1372            deletePortletData(context, layout, root);
1373        }
1374
1375        // Portlet preferences
1376
1377        importPortletPreferences(
1378            context, layout.getCompanyId(), layout.getGroupId(), plid, root,
1379            importPortletSetup, importPortletArchivedSetups,
1380            importUserPreferences);
1381
1382        // Portlet data
1383
1384        if (_log.isDebugEnabled()) {
1385            _log.debug("Importing portlet data");
1386        }
1387
1388        if (importPortletData) {
1389            importPortletData(context, layout, root);
1390        }
1391
1392        if (_log.isInfoEnabled()) {
1393            _log.info(
1394                "Importing portlet data takes " + stopWatch.getTime() + " ms");
1395        }
1396    }
1397
1398    public void setLayouts(
1399            long groupId, boolean privateLayout, long parentLayoutId,
1400            long[] layoutIds)
1401        throws PortalException, SystemException {
1402
1403        if (layoutIds == null) {
1404            return;
1405        }
1406
1407        if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
1408            if (layoutIds.length < 1) {
1409                throw new RequiredLayoutException(
1410                    RequiredLayoutException.AT_LEAST_ONE);
1411            }
1412
1413            Layout layout = layoutPersistence.findByG_P_L(
1414                groupId, privateLayout, layoutIds[0]);
1415
1416            if (!layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
1417                throw new RequiredLayoutException(
1418                    RequiredLayoutException.FIRST_LAYOUT_TYPE);
1419            }
1420
1421            if (layout.isHidden()) {
1422                throw new RequiredLayoutException(
1423                    RequiredLayoutException.FIRST_LAYOUT_HIDDEN);
1424            }
1425        }
1426
1427        Set<Long> layoutIdsSet = new LinkedHashSet<Long>();
1428
1429        for (int i = 0; i < layoutIds.length; i++) {
1430            layoutIdsSet.add(layoutIds[i]);
1431        }
1432
1433        Set<Long> newLayoutIdsSet = new HashSet<Long>();
1434
1435        List<Layout> layouts = layoutPersistence.findByG_P_P(
1436            groupId, privateLayout, parentLayoutId);
1437
1438        for (Layout layout : layouts) {
1439            if (!layoutIdsSet.contains(layout.getLayoutId())) {
1440                deleteLayout(layout, true);
1441            }
1442            else {
1443                newLayoutIdsSet.add(layout.getLayoutId());
1444            }
1445        }
1446
1447        int priority = 0;
1448
1449        for (long layoutId : layoutIdsSet) {
1450            Layout layout = layoutPersistence.findByG_P_L(
1451                groupId, privateLayout, layoutId);
1452
1453            layout.setPriority(priority++);
1454
1455            layoutPersistence.update(layout, false);
1456        }
1457
1458        layoutSetLocalService.updatePageCount(groupId, privateLayout);
1459    }
1460
1461    public Layout updateFriendlyURL(long plid, String friendlyURL)
1462        throws PortalException, SystemException {
1463
1464        Layout layout = layoutPersistence.findByPrimaryKey(plid);
1465
1466        friendlyURL = getFriendlyURL(layout.getLayoutId(), friendlyURL);
1467
1468        validateFriendlyURL(
1469            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1470            friendlyURL);
1471
1472        layout.setFriendlyURL(friendlyURL);
1473
1474        layoutPersistence.update(layout, false);
1475
1476        return layout;
1477    }
1478
1479    public Layout updateLayout(
1480            long groupId, boolean privateLayout, long layoutId,
1481            long parentLayoutId, Map<Locale, String> localeNamesMap,
1482            Map<Locale, String> localeTitlesMap, String description,
1483            String type, boolean hidden, String friendlyURL)
1484        throws PortalException, SystemException {
1485
1486        return updateLayout(
1487            groupId, privateLayout, layoutId, parentLayoutId, localeNamesMap,
1488            localeTitlesMap, description, type, hidden, friendlyURL, null,
1489            null);
1490    }
1491
1492    public Layout updateLayout(
1493            long groupId, boolean privateLayout, long layoutId,
1494            long parentLayoutId, Map<Locale, String> localeNamesMap,
1495            Map<Locale, String> localeTitlesMap, String description,
1496            String type, boolean hidden, String friendlyURL, Boolean iconImage,
1497            byte[] iconBytes)
1498        throws PortalException, SystemException {
1499
1500        // Layout
1501
1502        parentLayoutId = getParentLayoutId(
1503            groupId, privateLayout, parentLayoutId);
1504        friendlyURL = getFriendlyURL(layoutId, friendlyURL);
1505
1506        validate(
1507            groupId, privateLayout, layoutId, parentLayoutId, type, hidden,
1508            friendlyURL);
1509
1510        validateParentLayoutId(
1511            groupId, privateLayout, layoutId, parentLayoutId);
1512
1513        Layout layout = layoutPersistence.findByG_P_L(
1514            groupId, privateLayout, layoutId);
1515
1516        if (parentLayoutId != layout.getParentLayoutId()) {
1517            layout.setPriority(
1518                getNextPriority(groupId, privateLayout, parentLayoutId));
1519        }
1520
1521        layout.setParentLayoutId(parentLayoutId);
1522        layout.setDescription(description);
1523        layout.setType(type);
1524        layout.setHidden(hidden);
1525        layout.setFriendlyURL(friendlyURL);
1526
1527        setLocalizedAttributes(layout, localeNamesMap, localeTitlesMap);
1528
1529        if (iconImage != null) {
1530            layout.setIconImage(iconImage.booleanValue());
1531
1532            if (iconImage.booleanValue()) {
1533                long iconImageId = layout.getIconImageId();
1534
1535                if (iconImageId <= 0) {
1536                    iconImageId = counterLocalService.increment();
1537
1538                    layout.setIconImageId(iconImageId);
1539                }
1540            }
1541        }
1542
1543        layoutPersistence.update(layout, false);
1544
1545        // Icon
1546
1547        if (iconImage != null) {
1548            if (!iconImage.booleanValue()) {
1549                ImageLocalUtil.deleteImage(layout.getIconImageId());
1550            }
1551            else if ((iconBytes != null) && (iconBytes.length > 0)) {
1552                ImageLocalUtil.updateImage(layout.getIconImageId(), iconBytes);
1553            }
1554        }
1555
1556        try {
1557            if (layout.getDlFolderId() > 0) {
1558                DLFolder folder = dlFolderLocalService.getFolder(
1559                    layout.getDlFolderId());
1560
1561                String name = layout.getName(LocaleUtil.getDefault());
1562
1563                if (!name.equals(folder.getName())) {
1564                    dlFolderLocalService.updateFolder(
1565                        folder.getFolderId(), folder.getParentFolderId(), name,
1566                        folder.getDescription());
1567                }
1568            }
1569        }
1570        catch (DuplicateFolderNameException dfne) {
1571            if (_log.isDebugEnabled()) {
1572                _log.debug(dfne);
1573            }
1574        }
1575        catch (NoSuchFolderException nsfe) {
1576        }
1577
1578        return layout;
1579    }
1580
1581    public Layout updateLayout(
1582            long groupId, boolean privateLayout, long layoutId,
1583            String typeSettings)
1584        throws PortalException, SystemException {
1585
1586        Layout layout = layoutPersistence.findByG_P_L(
1587            groupId, privateLayout, layoutId);
1588
1589        layout.setTypeSettings(typeSettings);
1590
1591        layoutPersistence.update(layout, false);
1592
1593        return layout;
1594    }
1595
1596    public Layout updateLookAndFeel(
1597            long groupId, boolean privateLayout, long layoutId, String themeId,
1598            String colorSchemeId, String css, boolean wapTheme)
1599        throws PortalException, SystemException {
1600
1601        Layout layout = layoutPersistence.findByG_P_L(
1602            groupId, privateLayout, layoutId);
1603
1604        if (wapTheme) {
1605            layout.setWapThemeId(themeId);
1606            layout.setWapColorSchemeId(colorSchemeId);
1607        }
1608        else {
1609            layout.setThemeId(themeId);
1610            layout.setColorSchemeId(colorSchemeId);
1611            layout.setCss(css);
1612        }
1613
1614        layoutPersistence.update(layout, false);
1615
1616        return layout;
1617    }
1618
1619    public Layout updateName(long plid, String name, String languageId)
1620        throws PortalException, SystemException {
1621
1622        Layout layout = layoutPersistence.findByPrimaryKey(plid);
1623
1624        return updateName(layout, name, languageId);
1625    }
1626
1627    public Layout updateName(
1628            long groupId, boolean privateLayout, long layoutId, String name,
1629            String languageId)
1630        throws PortalException, SystemException {
1631
1632        Layout layout = layoutPersistence.findByG_P_L(
1633            groupId, privateLayout, layoutId);
1634
1635        return updateName(layout, name, languageId);
1636    }
1637
1638    public Layout updateName(Layout layout, String name, String languageId)
1639        throws PortalException, SystemException {
1640
1641        layout.setName(name, LocaleUtil.fromLanguageId(languageId));
1642
1643        layoutPersistence.update(layout, false);
1644
1645        try {
1646            if (layout.getDlFolderId() > 0) {
1647                DLFolder folder = dlFolderLocalService.getFolder(
1648                    layout.getDlFolderId());
1649
1650                dlFolderLocalService.updateFolder(
1651                    folder.getFolderId(), folder.getParentFolderId(),
1652                    layout.getName(LocaleUtil.getDefault()),
1653                    folder.getDescription());
1654            }
1655        }
1656        catch (NoSuchFolderException nsfe) {
1657        }
1658
1659        return layout;
1660    }
1661
1662    public Layout updateParentLayoutId(long plid, long parentPlid)
1663        throws PortalException, SystemException {
1664
1665        Layout layout = layoutPersistence.findByPrimaryKey(plid);
1666
1667        long parentLayoutId = LayoutImpl.DEFAULT_PARENT_LAYOUT_ID;
1668
1669        if (parentPlid > 0) {
1670            try {
1671                Layout parentLayout = layoutPersistence.findByPrimaryKey(
1672                    parentPlid);
1673
1674                parentLayoutId = parentLayout.getLayoutId();
1675            }
1676            catch (NoSuchLayoutException nsle) {
1677            }
1678        }
1679
1680        parentLayoutId = getParentLayoutId(
1681            layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1682
1683        validateParentLayoutId(
1684            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1685            parentLayoutId);
1686
1687        if (parentLayoutId != layout.getParentLayoutId()) {
1688            int priority = getNextPriority(
1689                layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1690
1691            layout.setPriority(priority);
1692        }
1693
1694        layout.setParentLayoutId(parentLayoutId);
1695
1696        layoutPersistence.update(layout, false);
1697
1698        return layout;
1699    }
1700
1701    public Layout updateParentLayoutId(
1702            long groupId, boolean privateLayout, long layoutId,
1703            long parentLayoutId)
1704        throws PortalException, SystemException {
1705
1706        parentLayoutId = getParentLayoutId(
1707            groupId, privateLayout, parentLayoutId);
1708
1709        validateParentLayoutId(
1710            groupId, privateLayout, layoutId, parentLayoutId);
1711
1712        Layout layout = layoutPersistence.findByG_P_L(
1713            groupId, privateLayout, layoutId);
1714
1715        if (parentLayoutId != layout.getParentLayoutId()) {
1716            layout.setPriority(
1717                getNextPriority(groupId, privateLayout, parentLayoutId));
1718        }
1719
1720        layout.setParentLayoutId(parentLayoutId);
1721
1722        layoutPersistence.update(layout, false);
1723
1724        return layout;
1725    }
1726
1727    public Layout updatePriority(long plid, int priority)
1728        throws PortalException, SystemException {
1729
1730        Layout layout = layoutPersistence.findByPrimaryKey(plid);
1731
1732        return updatePriority(layout, priority);
1733    }
1734
1735    public Layout updatePriority(
1736            long groupId, boolean privateLayout, long layoutId, int priority)
1737        throws PortalException, SystemException {
1738
1739        Layout layout = layoutPersistence.findByG_P_L(
1740            groupId, privateLayout, layoutId);
1741
1742        return updatePriority(layout, priority);
1743    }
1744
1745    public Layout updatePriority(Layout layout, int priority)
1746        throws PortalException, SystemException {
1747
1748        if (layout.getPriority() == priority) {
1749            return layout;
1750        }
1751
1752        boolean lessThan = false;
1753
1754        if (layout.getPriority() < priority) {
1755            lessThan = true;
1756        }
1757
1758        layout.setPriority(priority);
1759
1760        layoutPersistence.update(layout, false);
1761
1762        priority = 0;
1763
1764        List<Layout> layouts = layoutPersistence.findByG_P_P(
1765            layout.getGroupId(), layout.isPrivateLayout(),
1766            layout.getParentLayoutId());
1767
1768        Collections.sort(
1769            layouts, new LayoutPriorityComparator(layout, lessThan));
1770
1771        for (Layout curLayout : layouts) {
1772            curLayout.setPriority(priority++);
1773
1774            layoutPersistence.update(curLayout, false);
1775
1776            if (curLayout.equals(layout)) {
1777                layout = curLayout;
1778            }
1779        }
1780
1781        return layout;
1782    }
1783
1784    protected void deleteMissingLayouts(
1785            long groupId, boolean privateLayout, Set<Long> newLayoutIds)
1786        throws PortalException, SystemException {
1787
1788        // Layouts
1789
1790        if (_log.isDebugEnabled()) {
1791            if (newLayoutIds.size() > 0) {
1792                _log.debug("Delete missing layouts");
1793            }
1794        }
1795
1796        List<Layout> layouts = layoutPersistence.findByG_P(
1797            groupId, privateLayout);
1798
1799        for (Layout layout : layouts) {
1800            if (!newLayoutIds.contains(layout.getLayoutId())) {
1801                try {
1802                    deleteLayout(layout, false);
1803                }
1804                catch (NoSuchLayoutException nsle) {
1805                }
1806            }
1807        }
1808
1809        // Layout set
1810
1811        layoutSetLocalService.updatePageCount(groupId, privateLayout);
1812    }
1813
1814    protected void deletePortletData(
1815            PortletDataContext context, Layout layout, Element parentEl)
1816        throws PortalException, SystemException {
1817
1818        Iterator<Element> itr = parentEl.elements("portlet-data").iterator();
1819
1820        while (itr.hasNext()) {
1821            Element el = itr.next();
1822
1823            String portletId = el.attributeValue("portlet-id");
1824
1825            try {
1826                PortletPreferences portletPreferences =
1827                    portletPreferencesPersistence.findByO_O_P_P(
1828                        PortletKeys.PREFS_OWNER_ID_DEFAULT,
1829                        PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid(),
1830                        portletId);
1831
1832                String preferences = deletePortletData(
1833                    context, portletId, portletPreferences, el);
1834
1835                if (preferences != null) {
1836                    portletPreferences.setPreferences(preferences);
1837
1838                    portletPreferencesPersistence.update(
1839                        portletPreferences, false);
1840                }
1841            }
1842            catch (NoSuchPortletPreferencesException nsppe) {
1843            }
1844        }
1845    }
1846
1847    protected String deletePortletData(
1848            PortletDataContext context, String portletId,
1849            PortletPreferences portletPreferences, Element parentEl)
1850        throws PortalException, SystemException {
1851
1852        Portlet portlet = portletLocalService.getPortletById(
1853            context.getCompanyId(), portletId);
1854
1855        if (portlet == null) {
1856            if (_log.isDebugEnabled()) {
1857                _log.debug(
1858                    "Do not delete portlet data for " + portletId +
1859                        " because the portlet does not exist");
1860            }
1861
1862            return null;
1863        }
1864
1865        PortletDataHandler portletDataHandler =
1866            portlet.getPortletDataHandlerInstance();
1867
1868        if (portletDataHandler == null) {
1869            if (_log.isDebugEnabled()) {
1870                _log.debug(
1871                    "Do not delete portlet data for " + portletId +
1872                        " because the portlet does not have a " +
1873                            "PortletDataHandler");
1874            }
1875
1876            return null;
1877        }
1878
1879        if (_log.isDebugEnabled()) {
1880            _log.debug("Deleting data for " + portletId);
1881        }
1882
1883        PortletPreferencesImpl prefsImpl =
1884            (PortletPreferencesImpl)PortletPreferencesSerializer.fromDefaultXML(
1885                portletPreferences.getPreferences());
1886
1887        prefsImpl = (PortletPreferencesImpl)portletDataHandler.deleteData(
1888            context, portletId, prefsImpl);
1889
1890        if (prefsImpl == null) {
1891            return null;
1892        }
1893
1894        return PortletPreferencesSerializer.toXML(prefsImpl);
1895    }
1896
1897    protected void exportComments(PortletDataContext context, Element root)
1898        throws SystemException {
1899
1900        try {
1901            XStream xStream = new XStream();
1902
1903            Map commentsMap = context.getComments();
1904
1905            Iterator<String> itr = commentsMap.keySet().iterator();
1906
1907            while (itr.hasNext()) {
1908                String key = itr.next();
1909
1910                String[] comment = key.split(StringPool.POUND);
1911
1912                Element el = root.addElement("comments");
1913
1914                el.addAttribute("class-name", comment[0]);
1915                el.addAttribute("class-pk", comment[1]);
1916
1917                List messages = (List)commentsMap.get(key);
1918
1919                String xml = xStream.toXML(messages);
1920
1921                Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
1922
1923                el.content().add(tempDoc.getRootElement().createCopy());
1924            }
1925        }
1926        catch (Exception e) {
1927            throw new SystemException(e);
1928        }
1929    }
1930
1931    protected Element exportGroupPermissions(
1932            long companyId, long groupId, String resourceName,
1933            String resourcePrimKey, Element parentEl, String elName)
1934        throws PortalException, SystemException {
1935
1936        Element el = parentEl.addElement(elName);
1937
1938        List<Permission> permissions =
1939            permissionLocalService.getGroupPermissions(
1940                groupId, companyId, resourceName,
1941                ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
1942
1943        List<String> actions = ResourceActionsUtil.getActions(permissions);
1944
1945        for (int i = 0; i < actions.size(); i++) {
1946            String action = actions.get(i);
1947
1948            Element actionKeyEl = el.addElement("action-key");
1949
1950            actionKeyEl.addText(action);
1951        }
1952
1953        return el;
1954    }
1955
1956    protected void exportGroupRoles(
1957            LayoutCache layoutCache, long companyId, long groupId,
1958            String resourceName, String entityName, Element parentEl)
1959        throws PortalException, SystemException {
1960
1961        List<Role> roles = layoutCache.getGroupRoles(groupId);
1962
1963        Element groupEl = exportRoles(
1964            companyId, resourceName, ResourceConstants.SCOPE_GROUP,
1965            String.valueOf(groupId), parentEl, entityName + "-roles", roles);
1966
1967        if (groupEl.elements().isEmpty()) {
1968            parentEl.remove(groupEl);
1969        }
1970    }
1971
1972    protected void exportInheritedPermissions(
1973            LayoutCache layoutCache, long companyId, String resourceName,
1974            String resourcePrimKey, Element parentEl, String entityName)
1975        throws PortalException, SystemException {
1976
1977        Element entityPermissionsEl = DocumentHelper.createElement(
1978            entityName + "-permissions");
1979
1980        Map<String, Long> entityMap = layoutCache.getEntityMap(
1981            companyId, entityName);
1982
1983        Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
1984
1985        while (itr.hasNext()) {
1986            Map.Entry<String, Long> entry = itr.next();
1987
1988            String name = entry.getKey().toString();
1989
1990            long entityGroupId = entry.getValue();
1991
1992            Element entityEl = exportGroupPermissions(
1993                companyId, entityGroupId, resourceName, resourcePrimKey,
1994                entityPermissionsEl, entityName + "-actions");
1995
1996            if (entityEl.elements().isEmpty()) {
1997                entityPermissionsEl.remove(entityEl);
1998            }
1999            else {
2000                entityEl.addAttribute("name", name);
2001            }
2002        }
2003
2004        if (!entityPermissionsEl.elements().isEmpty()) {
2005            parentEl.add(entityPermissionsEl);
2006        }
2007    }
2008
2009    protected void exportInheritedRoles(
2010            LayoutCache layoutCache, long companyId, long groupId,
2011            String resourceName, String entityName, Element parentEl)
2012        throws PortalException, SystemException {
2013
2014        Element entityRolesEl = DocumentHelper.createElement(
2015            entityName + "-roles");
2016
2017        Map<String, Long> entityMap = layoutCache.getEntityMap(
2018            companyId, entityName);
2019
2020        Iterator<Map.Entry<String, Long>> itr = entityMap.entrySet().iterator();
2021
2022        while (itr.hasNext()) {
2023            Map.Entry<String, Long> entry = itr.next();
2024
2025            String name = entry.getKey().toString();
2026
2027            long entityGroupId = entry.getValue();
2028
2029            List<Role> entityRoles = layoutCache.getGroupRoles(entityGroupId);
2030
2031            Element entityEl = exportRoles(
2032                companyId, resourceName, ResourceConstants.SCOPE_GROUP,
2033                String.valueOf(groupId), entityRolesEl, entityName,
2034                entityRoles);
2035
2036            if (entityEl.elements().isEmpty()) {
2037                entityRolesEl.remove(entityEl);
2038            }
2039            else {
2040                entityEl.addAttribute("name", name);
2041            }
2042        }
2043
2044        if (!entityRolesEl.elements().isEmpty()) {
2045            parentEl.add(entityRolesEl);
2046        }
2047    }
2048
2049    protected void exportLayoutPermissions(
2050            LayoutCache layoutCache, long companyId, long groupId,
2051            Group guestGroup, Layout layout, Element permissionsEl,
2052            boolean exportUserPermissions)
2053        throws PortalException, SystemException {
2054
2055        String resourceName = Layout.class.getName();
2056        String resourcePrimKey = String.valueOf(layout.getPlid());
2057
2058        exportGroupPermissions(
2059            companyId, groupId, resourceName, resourcePrimKey, permissionsEl,
2060            "community-actions");
2061
2062        if (groupId != guestGroup.getGroupId()) {
2063            exportGroupPermissions(
2064                companyId, guestGroup.getGroupId(), resourceName,
2065                resourcePrimKey, permissionsEl, "guest-actions");
2066        }
2067
2068        if (exportUserPermissions) {
2069            exportUserPermissions(
2070                layoutCache, companyId, groupId, resourceName, resourcePrimKey,
2071                permissionsEl);
2072        }
2073
2074        exportInheritedPermissions(
2075            layoutCache, companyId, resourceName, resourcePrimKey,
2076            permissionsEl, "organization");
2077
2078        exportInheritedPermissions(
2079            layoutCache, companyId, resourceName, resourcePrimKey,
2080            permissionsEl, "location");
2081
2082        exportInheritedPermissions(
2083            layoutCache, companyId, resourceName, resourcePrimKey,
2084            permissionsEl, "user-group");
2085    }
2086
2087    protected void exportLayoutRoles(
2088            LayoutCache layoutCache, long companyId, long groupId,
2089            Element rolesEl)
2090        throws PortalException, SystemException {
2091
2092        String resourceName = Layout.class.getName();
2093
2094        exportGroupRoles(
2095            layoutCache, companyId, groupId, resourceName, "community",
2096            rolesEl);
2097
2098        exportUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
2099
2100        exportInheritedRoles(
2101            layoutCache, companyId, groupId, resourceName, "organization",
2102            rolesEl);
2103
2104        exportInheritedRoles(
2105            layoutCache, companyId, groupId, resourceName, "location", rolesEl);
2106
2107        exportInheritedRoles(
2108            layoutCache, companyId, groupId, resourceName, "user-group",
2109            rolesEl);
2110    }
2111
2112    protected void exportPortletData(
2113            PortletDataContext context, Layout layout,
2114            LayoutTypePortlet layoutTypePortlet, Element parentEl)
2115        throws PortalException, SystemException {
2116
2117        Iterator<PortletPreferences> itr =
2118            portletPreferencesLocalService.getPortletPreferences(
2119                layout.getPlid()).iterator();
2120
2121        while (itr.hasNext()) {
2122            PortletPreferences portletPreferences = itr.next();
2123
2124            javax.portlet.PortletPreferences jxPrefs =
2125                portletPreferencesLocalService.getPreferences(
2126                    layout.getCompanyId(), portletPreferences.getOwnerId(),
2127                    portletPreferences.getOwnerType(),
2128                    portletPreferences.getPlid(),
2129                    portletPreferences.getPortletId());
2130
2131            String portletId = portletPreferences.getPortletId();
2132
2133            if (layoutTypePortlet.hasPortletId(portletId)) {
2134                exportPortletData(context, portletId, jxPrefs, parentEl);
2135            }
2136        }
2137    }
2138
2139    protected void exportPortletData(
2140            PortletDataContext context, String portletId,
2141            javax.portlet.PortletPreferences portletPreferences,
2142            Element parentEl)
2143        throws PortalException, SystemException {
2144
2145        Portlet portlet = portletLocalService.getPortletById(
2146            context.getCompanyId(), portletId);
2147
2148        if (portlet == null) {
2149            if (_log.isDebugEnabled()) {
2150                _log.debug(
2151                    "Do not export portlet data for " + portletId +
2152                        " because the portlet does not exist");
2153            }
2154
2155            return;
2156        }
2157
2158        PortletDataHandler portletDataHandler =
2159            portlet.getPortletDataHandlerInstance();
2160
2161        if (portletDataHandler == null) {
2162            return;
2163        }
2164
2165        if (_log.isDebugEnabled()) {
2166            _log.debug("Exporting data for " + portletId);
2167        }
2168
2169        Map parameterMap = context.getParameterMap();
2170
2171        boolean exportData = false;
2172
2173        if (MapUtil.getBoolean(
2174                parameterMap,
2175                PortletDataHandlerKeys.PORTLET_DATA + "_" + portletId) ||
2176            MapUtil.getBoolean(
2177                parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
2178
2179            exportData = true;
2180        }
2181
2182        if (!exportData) {
2183            if (_log.isDebugEnabled()) {
2184                _log.debug(
2185                    "Not exporting data for " + portletId +
2186                        " because it was not selected by the user");
2187            }
2188
2189            return;
2190        }
2191
2192        String data = portletDataHandler.exportData(
2193            context, portletId, portletPreferences);
2194
2195        if (data == null) {
2196            if (_log.isDebugEnabled()) {
2197                _log.debug(
2198                    "Not exporting data for " + portletId +
2199                        " because null data was returned");
2200            }
2201
2202            return;
2203        }
2204
2205        Element el = parentEl.addElement("portlet-data");
2206
2207        el.addAttribute("portlet-id", portletId);
2208        el.addCDATA(data);
2209    }
2210
2211    protected void exportPortletPermissions(
2212            LayoutCache layoutCache, long companyId, long groupId,
2213            Group guestGroup, Layout layout,
2214            LayoutTypePortlet layoutTypePortlet, Set<String> portletIds,
2215            Element permissionsEl, boolean exportUserPermissions)
2216        throws PortalException, SystemException {
2217
2218        for (String portletId : layoutTypePortlet.getPortletIds()) {
2219            if (!portletIds.contains(portletId)) {
2220                portletIds.add(portletId);
2221            }
2222
2223            if (layoutTypePortlet.hasPortletId(portletId)) {
2224                String resourceName = PortletImpl.getRootPortletId(portletId);
2225                String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
2226                    layout.getPlid(), portletId);
2227
2228                Element portletEl = permissionsEl.addElement("portlet");
2229
2230                portletEl.addAttribute("portlet-id", portletId);
2231
2232                exportGroupPermissions(
2233                    companyId, groupId, resourceName, resourcePrimKey,
2234                    portletEl, "community-actions");
2235
2236                if (groupId != guestGroup.getGroupId()) {
2237                    exportGroupPermissions(
2238                        companyId, guestGroup.getGroupId(), resourceName,
2239                        resourcePrimKey, portletEl, "guest-actions");
2240                }
2241
2242                if (exportUserPermissions) {
2243                    exportUserPermissions(
2244                        layoutCache, companyId, groupId, resourceName,
2245                        resourcePrimKey, portletEl);
2246                }
2247
2248                exportInheritedPermissions(
2249                    layoutCache, companyId, resourceName, resourcePrimKey,
2250                    portletEl, "organization");
2251
2252                exportInheritedPermissions(
2253                    layoutCache, companyId, resourceName, resourcePrimKey,
2254                    portletEl, "location");
2255
2256                exportInheritedPermissions(
2257                    layoutCache, companyId, resourceName, resourcePrimKey,
2258                    portletEl, "user-group");
2259            }
2260        }
2261    }
2262
2263    protected void exportPortletPreferences(
2264            long ownerId, int ownerType, long plid, boolean defaultUser,
2265            Element parentEl)
2266        throws PortalException, SystemException {
2267
2268        exportPortletPreferences(
2269            ownerId, ownerType, defaultUser, plid, null, parentEl);
2270    }
2271
2272    protected void exportPortletPreferences(
2273            long ownerId, int ownerType, boolean defaultUser, long plid,
2274            LayoutTypePortlet layoutTypePortlet, Element parentEl)
2275        throws PortalException, SystemException {
2276
2277        Iterator<PortletPreferences> itr =
2278            portletPreferencesLocalService.getPortletPreferences(
2279                ownerId, ownerType, plid).iterator();
2280
2281        while (itr.hasNext()) {
2282            PortletPreferences portletPreferences = itr.next();
2283
2284            String portletId = portletPreferences.getPortletId();
2285
2286            if ((layoutTypePortlet == null) ||
2287                (layoutTypePortlet.hasPortletId(portletId))) {
2288
2289                Element el = parentEl.addElement("portlet-preferences");
2290
2291                el.addAttribute("owner-id", String.valueOf(ownerId));
2292                el.addAttribute("owner-type", String.valueOf(ownerType));
2293                el.addAttribute("default-user", String.valueOf(defaultUser));
2294                el.addAttribute("plid", String.valueOf(plid));
2295                el.addAttribute("portlet-id", portletId);
2296                el.addElement("preferences").addCDATA(
2297                    portletPreferences.getPreferences());
2298
2299                if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
2300                    PortletItem portletItem =
2301                        portletItemLocalService.getPortletItem(ownerId);
2302
2303                    User user = userLocalService.getUserById(
2304                        portletItem.getUserId());
2305
2306                    el.addAttribute("archive-user-uuid", user.getUuid());
2307                    el.addAttribute("archive-name", portletItem.getName());
2308                }
2309            }
2310        }
2311    }
2312
2313    protected void exportPortletPreferences(
2314            long ownerId, int ownerType, boolean defaultUser, Layout layout,
2315            String portletId, Element parentEl)
2316        throws PortalException, SystemException {
2317
2318        PortletPreferences portletPreferences = null;
2319
2320        long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
2321
2322        if (layout != null) {
2323            plid = layout.getPlid();
2324        }
2325
2326        if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
2327            (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
2328            (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
2329
2330            plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
2331        }
2332
2333        try {
2334            portletPreferences =
2335                portletPreferencesLocalService.getPortletPreferences(
2336                    ownerId, ownerType, plid, portletId);
2337
2338            LayoutTypePortlet layoutTypePortlet = null;
2339
2340            if (layout != null) {
2341                layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
2342            }
2343
2344            if ((layoutTypePortlet == null) ||
2345                (layoutTypePortlet.hasPortletId(portletId))) {
2346
2347                Element el = parentEl.addElement("portlet-preferences");
2348
2349                el.addAttribute("owner-id", String.valueOf(ownerId));
2350                el.addAttribute("owner-type", String.valueOf(ownerType));
2351                el.addAttribute("default-user", String.valueOf(defaultUser));
2352                el.addAttribute("plid", String.valueOf(plid));
2353                el.addAttribute("portlet-id", portletId);
2354
2355                if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
2356                    PortletItem portletItem =
2357                        portletItemLocalService.getPortletItem(ownerId);
2358
2359                    User user = userLocalService.getUserById(
2360                        portletItem.getUserId());
2361
2362                    el.addAttribute("archive-user-uuid", user.getUuid());
2363                    el.addAttribute("archive-name", portletItem.getName());
2364                }
2365
2366                el.addElement("preferences").addCDATA(
2367                    portletPreferences.getPreferences());
2368            }
2369        }
2370        catch (NoSuchPortletPreferencesException nsppe) {
2371        }
2372    }
2373
2374    protected void exportPortletRoles(
2375            LayoutCache layoutCache, long companyId, long groupId,
2376            Set<String> portletIds, Element rolesEl)
2377        throws PortalException, SystemException {
2378
2379        for (String portletId : portletIds) {
2380            String resourceName = PortletImpl.getRootPortletId(portletId);
2381
2382            Element portletEl = rolesEl.addElement("portlet");
2383
2384            portletEl.addAttribute("portlet-id", portletId);
2385
2386            exportGroupRoles(
2387                layoutCache, companyId, groupId, resourceName, "community",
2388                portletEl);
2389
2390            exportUserRoles(
2391                layoutCache, companyId, groupId, resourceName, portletEl);
2392
2393            exportInheritedRoles(
2394                layoutCache, companyId, groupId, resourceName, "organization",
2395                portletEl);
2396
2397            exportInheritedRoles(
2398                layoutCache, companyId, groupId, resourceName, "location",
2399                portletEl);
2400
2401            exportInheritedRoles(
2402                layoutCache, companyId, groupId, resourceName, "user-group",
2403                portletEl);
2404
2405            if (portletEl.elements().isEmpty()) {
2406                rolesEl.remove(portletEl);
2407            }
2408        }
2409    }
2410
2411    protected Element exportRoles(
2412            long companyId, String resourceName, int scope,
2413            String resourcePrimKey, Element parentEl, String elName,
2414            List<Role> roles)
2415        throws PortalException, SystemException {
2416
2417        Element el = parentEl.addElement(elName);
2418
2419        Map<String, List<String>> resourceRoles =
2420            roleLocalService.getResourceRoles(
2421                companyId, resourceName, scope, resourcePrimKey);
2422
2423        Iterator<Map.Entry<String, List<String>>> itr =
2424            resourceRoles.entrySet().iterator();
2425
2426        while (itr.hasNext()) {
2427            Map.Entry<String, List<String>> entry = itr.next();
2428
2429            String roleName = entry.getKey().toString();
2430
2431            if (hasRole(roles, roleName)) {
2432                Element roleEl = el.addElement("role");
2433
2434                roleEl.addAttribute("name", roleName);
2435
2436                List<String> actions = entry.getValue();
2437
2438                for (int i = 0; i < actions.size(); i++) {
2439                    String action = actions.get(i);
2440
2441                    Element actionKeyEl = roleEl.addElement("action-key");
2442
2443                    actionKeyEl.addText(action);
2444                    actionKeyEl.addAttribute("scope", String.valueOf(scope));
2445                }
2446            }
2447        }
2448
2449        return el;
2450    }
2451
2452    protected void exportRatings(PortletDataContext context, Element root)
2453        throws SystemException {
2454
2455        try {
2456            XStream xStream = new XStream();
2457
2458            Map ratingsEntriesMap = context.getRatingsEntries();
2459
2460            Iterator<String> itr = ratingsEntriesMap.keySet().iterator();
2461
2462            while (itr.hasNext()) {
2463                String key = itr.next();
2464
2465                String[] ratingsEntry = key.split(StringPool.POUND);
2466
2467                Element el = root.addElement("ratings");
2468
2469                el.addAttribute("class-name", ratingsEntry[0]);
2470                el.addAttribute("class-pk", ratingsEntry[1]);
2471
2472                List ratingsEntries = (List)ratingsEntriesMap.get(key);
2473
2474                String xml = xStream.toXML(ratingsEntries);
2475
2476                Document tempDoc = DocumentUtil.readDocumentFromXML(xml);
2477
2478                el.content().add(tempDoc.getRootElement().createCopy());
2479            }
2480        }
2481        catch (Exception e) {
2482            throw new SystemException(e);
2483        }
2484    }
2485
2486    protected void exportTags(PortletDataContext context, Element root) {
2487        Map<String, String[]> tagsEntries = context.getTagsEntries();
2488
2489        Iterator<String> itr = tagsEntries.keySet().iterator();
2490
2491        while (itr.hasNext()) {
2492            String key = itr.next();
2493
2494            String[] tagsEntry = key.split(StringPool.POUND);
2495
2496            Element el = root.addElement("tags");
2497
2498            el.addAttribute("class-name", tagsEntry[0]);
2499            el.addAttribute("class-pk", tagsEntry[1]);
2500            el.addAttribute(
2501                "entries", StringUtil.merge(tagsEntries.get(key), ","));
2502        }
2503    }
2504
2505    protected byte[] exportTheme(LayoutSet layoutSet)
2506        throws IOException, PortalException, SystemException {
2507
2508        Theme theme = layoutSet.getTheme();
2509
2510        ZipWriter zipWriter = new ZipWriter();
2511
2512        String lookAndFeelXML = ContentUtil.get(
2513            "com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl");
2514
2515        lookAndFeelXML = StringUtil.replace(
2516            lookAndFeelXML,
2517            new String[] {
2518                "[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]"
2519            },
2520            new String[] {
2521                theme.getTemplateExtension(), theme.getVirtualPath()
2522            }
2523        );
2524
2525        zipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML);
2526
2527        String servletContextName = theme.getServletContextName();
2528
2529        ServletContext ctx = VelocityContextPool.get(servletContextName);
2530
2531        if (ctx == null) {
2532            if (_log.isWarnEnabled()) {
2533                _log.warn(
2534                    "Servlet context not found for theme " +
2535                        theme.getThemeId());
2536            }
2537
2538            return null;
2539        }
2540
2541        File cssPath = null;
2542        File imagesPath = null;
2543        File javaScriptPath = null;
2544        File templatesPath = null;
2545
2546        if (!theme.isLoadFromServletContext()) {
2547            ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(
2548                servletContextName);
2549
2550            if (themeLoader == null) {
2551                _log.error(
2552                    servletContextName + " does not map to a theme loader");
2553            }
2554            else {
2555                String realPath =
2556                    themeLoader.getFileStorage().getPath() + "/" +
2557                        theme.getName();
2558
2559                cssPath = new File(realPath + "/css");
2560                imagesPath = new File(realPath + "/images");
2561                javaScriptPath = new File(realPath + "/javascript");
2562                templatesPath = new File(realPath + "/templates");
2563            }
2564        }
2565        else {
2566            cssPath = new File(ctx.getRealPath(theme.getCssPath()));
2567            imagesPath = new File(ctx.getRealPath(theme.getImagesPath()));
2568            javaScriptPath = new File(
2569                ctx.getRealPath(theme.getJavaScriptPath()));
2570            templatesPath = new File(ctx.getRealPath(theme.getTemplatesPath()));
2571        }
2572
2573        exportThemeFiles("css", cssPath, zipWriter);
2574        exportThemeFiles("images", imagesPath, zipWriter);
2575        exportThemeFiles("javascript", javaScriptPath, zipWriter);
2576        exportThemeFiles("templates", templatesPath, zipWriter);
2577
2578        return zipWriter.finish();
2579    }
2580
2581    protected void exportThemeFiles(String path, File dir, ZipWriter zipWriter)
2582        throws IOException {
2583
2584        if ((dir == null) || (!dir.exists())) {
2585            return;
2586        }
2587
2588        File[] files = dir.listFiles();
2589
2590        for (int i = 0; i < files.length; i++) {
2591            File file = files[i];
2592
2593            if (file.isDirectory()) {
2594                exportThemeFiles(path + "/" + file.getName(), file, zipWriter);
2595            }
2596            else {
2597                zipWriter.addEntry(
2598                    path + "/" + file.getName(), FileUtil.getBytes(file));
2599            }
2600        }
2601    }
2602
2603    protected void exportUserPermissions(
2604            LayoutCache layoutCache, long companyId, long groupId,
2605            String resourceName, String resourcePrimKey, Element parentEl)
2606        throws PortalException, SystemException {
2607
2608        StopWatch stopWatch = null;
2609
2610        if (_log.isDebugEnabled()) {
2611            stopWatch = new StopWatch();
2612
2613            stopWatch.start();
2614        }
2615
2616        Element userPermissionsEl = DocumentHelper.createElement(
2617            "user-permissions");
2618
2619        List<User> users = layoutCache.getGroupUsers(groupId);
2620
2621        for (User user : users) {
2622            String emailAddress = user.getEmailAddress();
2623
2624            Element userActionsEl =
2625                DocumentHelper.createElement("user-actions");
2626
2627            List<Permission> permissions =
2628                permissionLocalService.getUserPermissions(
2629                    user.getUserId(), companyId, resourceName,
2630                    ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey);
2631
2632            List<String> actions = ResourceActionsUtil.getActions(permissions);
2633
2634            for (String action : actions) {
2635                Element actionKeyEl = userActionsEl.addElement("action-key");
2636
2637                actionKeyEl.addText(action);
2638            }
2639
2640            if (!userActionsEl.elements().isEmpty()) {
2641                userActionsEl.addAttribute("email-address", emailAddress);
2642                userPermissionsEl.add(userActionsEl);
2643            }
2644        }
2645
2646        if (!userPermissionsEl.elements().isEmpty()) {
2647            parentEl.add(userPermissionsEl);
2648        }
2649
2650        if (_log.isDebugEnabled()) {
2651            _log.debug(
2652                "Export user permissions for {" + resourceName + ", " +
2653                    resourcePrimKey + "} with " + users.size() +
2654                        " users takes " + stopWatch.getTime() + " ms");
2655        }
2656    }
2657
2658    protected void exportUserRoles(
2659            LayoutCache layoutCache, long companyId, long groupId,
2660            String resourceName, Element parentEl)
2661        throws PortalException, SystemException {
2662
2663        Element userRolesEl = DocumentHelper.createElement("user-roles");
2664
2665        List<User> users = layoutCache.getGroupUsers(groupId);
2666
2667        for (User user : users) {
2668            long userId = user.getUserId();
2669            String emailAddress = user.getEmailAddress();
2670
2671            List<Role> userRoles = layoutCache.getUserRoles(userId);
2672
2673            Element userEl = exportRoles(
2674                companyId, resourceName, ResourceConstants.SCOPE_GROUP,
2675                String.valueOf(groupId), userRolesEl, "user", userRoles);
2676
2677            if (userEl.elements().isEmpty()) {
2678                userRolesEl.remove(userEl);
2679            }
2680            else {
2681                userEl.addAttribute("email-address", emailAddress);
2682            }
2683        }
2684
2685        if (!userRolesEl.elements().isEmpty()) {
2686            parentEl.add(userRolesEl);
2687        }
2688    }
2689
2690    protected void fixTypeSettings(Layout layout) {
2691        if (layout.getType().equals(LayoutImpl.TYPE_URL)) {
2692            Properties typeSettings = layout.getTypeSettingsProperties();
2693
2694            String url = GetterUtil.getString(typeSettings.getProperty("url"));
2695
2696            String friendlyURLPrivateGroupPath =
2697                PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
2698            String friendlyURLPrivateUserPath =
2699                PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
2700            String friendlyURLPublicPath =
2701                PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
2702
2703            if (url.startsWith(friendlyURLPrivateGroupPath) ||
2704                url.startsWith(friendlyURLPrivateUserPath) ||
2705                url.startsWith(friendlyURLPublicPath)) {
2706
2707                int x = url.indexOf(StringPool.SLASH, 1);
2708
2709                if (x > 0) {
2710                    int y = url.indexOf(StringPool.SLASH, x + 1);
2711
2712                    if (y > x) {
2713                        String fixedUrl = url.substring(0, x) +
2714
2715                        layout.getGroup().getFriendlyURL() +
2716
2717                        url.substring(y);
2718
2719                        typeSettings.setProperty("url", fixedUrl);
2720                    }
2721                }
2722            }
2723        }
2724    }
2725
2726    protected List<String> getActions(Element el) {
2727        List<String> actions = new ArrayList<String>();
2728
2729        Iterator<Element> itr = el.elements("action-key").iterator();
2730
2731        while (itr.hasNext()) {
2732            Element actionEl = itr.next();
2733
2734            actions.add(actionEl.getText());
2735        }
2736
2737        return actions;
2738    }
2739
2740    protected String getFriendlyURL(String friendlyURL) {
2741        friendlyURL = GetterUtil.getString(friendlyURL);
2742
2743        return Normalizer.normalizeToAscii(friendlyURL.trim().toLowerCase());
2744    }
2745
2746    protected String getFriendlyURL(long layoutId, String friendlyURL) {
2747        friendlyURL = getFriendlyURL(friendlyURL);
2748
2749        if (Validator.isNull(friendlyURL)) {
2750            friendlyURL = StringPool.SLASH + layoutId;
2751        }
2752
2753        return friendlyURL;
2754    }
2755
2756    protected long getNextLayoutId(long groupId, boolean privateLayout)
2757        throws SystemException {
2758
2759        long layoutId = 0;
2760
2761        List<Layout> layouts = layoutPersistence.findByG_P(
2762            groupId, privateLayout);
2763
2764        for (Layout curLayout : layouts) {
2765            long curLayoutId = curLayout.getLayoutId();
2766
2767            if (curLayoutId > layoutId) {
2768                layoutId = curLayoutId;
2769            }
2770        }
2771
2772        return ++layoutId;
2773    }
2774
2775    protected int getNextPriority(
2776            long groupId, boolean privateLayout, long parentLayoutId)
2777        throws SystemException {
2778
2779        List<Layout> layouts = layoutPersistence.findByG_P_P(
2780            groupId, privateLayout, parentLayoutId);
2781
2782        if (layouts.size() == 0) {
2783            return 0;
2784        }
2785
2786        Layout layout = layouts.get(layouts.size() - 1);
2787
2788        return layout.getPriority() + 1;
2789    }
2790
2791    protected long getParentLayoutId(
2792            long groupId, boolean privateLayout, long parentLayoutId)
2793        throws PortalException, SystemException {
2794
2795        if (parentLayoutId != LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
2796
2797            // Ensure parent layout exists
2798
2799            try {
2800                layoutPersistence.findByG_P_L(
2801                    groupId, privateLayout, parentLayoutId);
2802            }
2803            catch (NoSuchLayoutException nsfe) {
2804                parentLayoutId = LayoutImpl.DEFAULT_PARENT_LAYOUT_ID;
2805            }
2806        }
2807
2808        return parentLayoutId;
2809    }
2810
2811    protected UserIdStrategy getUserIdStrategy(
2812        User user, String userIdStrategy) {
2813
2814        if (UserIdStrategy.ALWAYS_CURRENT_USER_ID.equals(userIdStrategy)) {
2815            return new AlwaysCurrentUserIdStrategy(user);
2816        }
2817
2818        return new CurrentUserIdStrategy(user);
2819    }
2820
2821    protected boolean hasRole(List<Role> roles, String roleName) {
2822        if ((roles == null) || (roles.size() == 0)) {
2823            return false;
2824        }
2825
2826        for (int i = 0; i < roles.size(); i++) {
2827            Role role = roles.get(i);
2828
2829            if (role.getName().equals(roleName)) {
2830                return true;
2831            }
2832        }
2833
2834        return false;
2835    }
2836
2837    protected void importGroupPermissions(
2838            LayoutCache layoutCache, long companyId, long groupId,
2839            String resourceName, String resourcePrimKey, Element parentEl,
2840            String elName, boolean portletActions)
2841        throws PortalException, SystemException {
2842
2843        Element actionEl = parentEl.element(elName);
2844
2845        if (actionEl == null) {
2846            return;
2847        }
2848
2849        List<String> actions = getActions(actionEl);
2850
2851        Resource resource = layoutCache.getResource(
2852            companyId, groupId, resourceName,
2853            ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
2854            portletActions);
2855
2856        permissionLocalService.setGroupPermissions(
2857            groupId, actions.toArray(new String[actions.size()]),
2858            resource.getResourceId());
2859    }
2860
2861    protected void importGroupRoles(
2862            LayoutCache layoutCache, long companyId, long groupId,
2863            String resourceName, String entityName,
2864            Element parentEl)
2865        throws PortalException, SystemException {
2866
2867        Element entityRolesEl = parentEl.element(entityName + "-roles");
2868
2869        if (entityRolesEl == null) {
2870            return;
2871        }
2872
2873        importRolePermissions(
2874            layoutCache, companyId, resourceName, ResourceConstants.SCOPE_GROUP,
2875            String.valueOf(groupId), entityRolesEl, true);
2876    }
2877
2878    protected void importInheritedPermissions(
2879            LayoutCache layoutCache, long companyId, String resourceName,
2880            String resourcePrimKey, Element permissionsEl, String entityName,
2881            boolean portletActions)
2882        throws PortalException, SystemException {
2883
2884        Element entityPermissionsEl = permissionsEl.element(
2885            entityName + "-permissions");
2886
2887        if (entityPermissionsEl == null) {
2888            return;
2889        }
2890
2891        List<Element> actionsEls = entityPermissionsEl.elements(
2892            entityName + "-actions");
2893
2894        for (int i = 0; i < actionsEls.size(); i++) {
2895            Element actionEl = actionsEls.get(i);
2896
2897            String name = actionEl.attributeValue("name");
2898
2899            long entityGroupId = layoutCache.getEntityGroupId(
2900                companyId, entityName, name);
2901
2902            if (entityGroupId == 0) {
2903                _log.warn(
2904                    "Ignore inherited permissions for entity " + entityName +
2905                        " with name " + name);
2906            }
2907            else {
2908                Element parentEl = DocumentHelper.createElement("parent");
2909
2910                parentEl.add(actionEl.createCopy());
2911
2912                importGroupPermissions(
2913                    layoutCache, companyId, entityGroupId, resourceName,
2914                    resourcePrimKey, parentEl, entityName + "-actions",
2915                    portletActions);
2916            }
2917        }
2918    }
2919
2920    protected void importInheritedRoles(
2921            LayoutCache layoutCache, long companyId, long groupId,
2922            String resourceName, String entityName, Element parentEl)
2923        throws PortalException, SystemException {
2924
2925        Element entityRolesEl = parentEl.element(entityName + "-roles");
2926
2927        if (entityRolesEl == null) {
2928            return;
2929        }
2930
2931        List<Element> entityEls = entityRolesEl.elements(entityName);
2932
2933        for (int i = 0; i < entityEls.size(); i++) {
2934            Element entityEl = entityEls.get(i);
2935
2936            String name = entityEl.attributeValue("name");
2937
2938            long entityGroupId = layoutCache.getEntityGroupId(
2939                companyId, entityName, name);
2940
2941            if (entityGroupId == 0) {
2942                _log.warn(
2943                    "Ignore inherited roles for entity " + entityName +
2944                        " with name " + name);
2945            }
2946            else {
2947                importRolePermissions(
2948                    layoutCache, companyId, resourceName,
2949                    ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
2950                    entityEl, false);
2951            }
2952        }
2953    }
2954
2955    protected void importLayoutPermissions(
2956            LayoutCache layoutCache, long companyId, long groupId,
2957            Group guestGroup, Layout layout, Element permissionsEl,
2958            boolean importUserPermissions)
2959        throws PortalException, SystemException {
2960
2961        String resourceName = Layout.class.getName();
2962        String resourcePrimKey = String.valueOf(layout.getPlid());
2963
2964        importGroupPermissions(
2965            layoutCache, companyId, groupId, resourceName, resourcePrimKey,
2966            permissionsEl, "community-actions", false);
2967
2968        if (groupId != guestGroup.getGroupId()) {
2969            importGroupPermissions(
2970                layoutCache, companyId, guestGroup.getGroupId(), resourceName,
2971                resourcePrimKey, permissionsEl, "guest-actions", false);
2972        }
2973
2974        if (importUserPermissions) {
2975            importUserPermissions(
2976                layoutCache, companyId, groupId, resourceName, resourcePrimKey,
2977                permissionsEl, false);
2978        }
2979
2980        importInheritedPermissions(
2981            layoutCache, companyId, resourceName, resourcePrimKey,
2982            permissionsEl, "organization", false);
2983
2984        importInheritedPermissions(
2985            layoutCache, companyId, resourceName, resourcePrimKey,
2986            permissionsEl, "location", false);
2987
2988        importInheritedPermissions(
2989            layoutCache, companyId, resourceName, resourcePrimKey,
2990            permissionsEl, "user-group", false);
2991    }
2992
2993    protected void importLayoutRoles(
2994            LayoutCache layoutCache, long companyId, long groupId,
2995            Element rolesEl)
2996        throws PortalException, SystemException {
2997
2998        String resourceName = Layout.class.getName();
2999
3000        importGroupRoles(
3001            layoutCache, companyId, groupId, resourceName, "community",
3002            rolesEl);
3003
3004        importUserRoles(layoutCache, companyId, groupId, resourceName, rolesEl);
3005
3006        importInheritedRoles(
3007            layoutCache, companyId, groupId, resourceName, "organization",
3008            rolesEl);
3009
3010        importInheritedRoles(
3011            layoutCache, companyId, groupId, resourceName, "location", rolesEl);
3012
3013        importInheritedRoles(
3014            layoutCache, companyId, groupId, resourceName, "user-group",
3015            rolesEl);
3016    }
3017
3018    protected void importPortletData(
3019            PortletDataContext context, Layout layout, Element parentEl)
3020        throws PortalException, SystemException {
3021
3022        Iterator<Element> itr = parentEl.elements("portlet-data").iterator();
3023
3024        while (itr.hasNext()) {
3025            Element el = itr.next();
3026
3027            String portletId = el.attributeValue("portlet-id");
3028
3029            try {
3030                PortletPreferences portletPreferences =
3031                    portletPreferencesPersistence.findByO_O_P_P(
3032                        PortletKeys.PREFS_OWNER_ID_DEFAULT,
3033                        PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid(),
3034                        portletId);
3035
3036                String preferences = importPortletData(
3037                    context, portletId, portletPreferences, el);
3038
3039                if (preferences != null) {
3040                    portletPreferences.setPreferences(preferences);
3041
3042                    portletPreferencesPersistence.update(
3043                        portletPreferences, false);
3044                }
3045            }
3046            catch (NoSuchPortletPreferencesException nsppe) {
3047            }
3048        }
3049    }
3050
3051    protected String importPortletData(
3052            PortletDataContext context, String portletId,
3053            PortletPreferences portletPreferences, Element parentEl)
3054        throws PortalException, SystemException {
3055
3056        Portlet portlet = portletLocalService.getPortletById(
3057            context.getCompanyId(), portletId);
3058
3059        if (portlet == null) {
3060            if (_log.isDebugEnabled()) {
3061                _log.debug(
3062                    "Do not import portlet data for " + portletId +
3063                        " because the portlet does not exist");
3064            }
3065
3066            return null;
3067        }
3068
3069        PortletDataHandler portletDataHandler =
3070            portlet.getPortletDataHandlerInstance();
3071
3072        if (portletDataHandler == null) {
3073            if (_log.isDebugEnabled()) {
3074                _log.debug(
3075                    "Do not import portlet data for " + portletId +
3076                        " because the portlet does not have a " +
3077                            "PortletDataHandler");
3078            }
3079
3080            return null;
3081        }
3082
3083        if (_log.isDebugEnabled()) {
3084            _log.debug("Importing data for " + portletId);
3085        }
3086
3087        PortletPreferencesImpl prefsImpl =
3088            (PortletPreferencesImpl)PortletPreferencesSerializer.fromDefaultXML(
3089                portletPreferences.getPreferences());
3090
3091        prefsImpl = (PortletPreferencesImpl)portletDataHandler.importData(
3092            context, portletId, prefsImpl, parentEl.getText());
3093
3094        if (prefsImpl == null) {
3095            return null;
3096        }
3097
3098        return PortletPreferencesSerializer.toXML(prefsImpl);
3099    }
3100
3101    protected void importPortletPermissions(
3102            LayoutCache layoutCache, long companyId, long groupId,
3103            Group guestGroup, Layout layout, Element permissionsEl,
3104            boolean importUserPermissions)
3105        throws PortalException, SystemException {
3106
3107        Iterator<Element> itr = permissionsEl.elements("portlet").iterator();
3108
3109        while (itr.hasNext()) {
3110            Element portletEl = itr.next();
3111
3112            String portletId = portletEl.attributeValue("portlet-id");
3113
3114            String resourceName = PortletImpl.getRootPortletId(portletId);
3115            String resourcePrimKey = PortletPermissionUtil.getPrimaryKey(
3116                layout.getPlid(), portletId);
3117
3118            Portlet portlet = portletLocalService.getPortletById(
3119                companyId, resourceName);
3120
3121            if (portlet == null) {
3122                if (_log.isDebugEnabled()) {
3123                    _log.debug(
3124                        "Do not import portlet permissions for " + portletId +
3125                            " because the portlet does not exist");
3126                }
3127            }
3128            else {
3129                importGroupPermissions(
3130                    layoutCache, companyId, groupId, resourceName,
3131                    resourcePrimKey, portletEl, "community-actions", true);
3132
3133                if (groupId != guestGroup.getGroupId()) {
3134                    importGroupPermissions(
3135                        layoutCache, companyId, guestGroup.getGroupId(),
3136                        resourceName, resourcePrimKey, portletEl,
3137                        "guest-actions", true);
3138                }
3139
3140                if (importUserPermissions) {
3141                    importUserPermissions(
3142                        layoutCache, companyId, groupId, resourceName,
3143                        resourcePrimKey, portletEl, true);
3144                }
3145
3146                importInheritedPermissions(
3147                    layoutCache, companyId, resourceName, resourcePrimKey,
3148                    portletEl, "organization", true);
3149
3150                importInheritedPermissions(
3151                    layoutCache, companyId, resourceName, resourcePrimKey,
3152                    portletEl, "location", true);
3153
3154                importInheritedPermissions(
3155                    layoutCache, companyId, resourceName, resourcePrimKey,
3156                    portletEl, "user-group", true);
3157            }
3158        }
3159    }
3160
3161    protected void importPortletPreferences(
3162            PortletDataContext context, long companyId, long groupId, long plid,
3163            Element parentEl, boolean importPortletSetup,
3164            boolean importPortletArchivedSetups, boolean importUserPreferences)
3165        throws PortalException, SystemException {
3166
3167        long defaultUserId = userLocalService.getDefaultUserId(companyId);
3168
3169        Iterator<Element> itr = parentEl.elements(
3170            "portlet-preferences").iterator();
3171
3172        while (itr.hasNext()) {
3173            Element el = itr.next();
3174
3175            long ownerId = GetterUtil.getLong(el.attributeValue("owner-id"));
3176            int ownerType = GetterUtil.getInteger(
3177                el.attributeValue("owner-type"));
3178
3179            if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
3180                continue;
3181            }
3182
3183            if (((ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
3184                 (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) &&
3185                !importPortletSetup) {
3186
3187                continue;
3188            }
3189
3190            if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) &&
3191                !importPortletArchivedSetups) {
3192
3193                continue;
3194            }
3195
3196            if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) &&
3197                (ownerId != PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
3198                !importUserPreferences) {
3199
3200                continue;
3201            }
3202
3203            if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
3204                plid = PortletKeys.PREFS_PLID_SHARED;
3205            }
3206
3207            boolean defaultUser = GetterUtil.getBoolean(
3208                el.attributeValue("default-user"));
3209            String portletId = el.attributeValue("portlet-id");
3210            String preferences = el.elementText("preferences");
3211
3212            if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
3213                String userUuid = el.attributeValue("archive-user-uuid");
3214                String name = el.attributeValue("archive-name");
3215
3216                long userId = context.getUserId(userUuid);
3217
3218                PortletItem portletItem =
3219                    portletItemLocalService.updatePortletItem(
3220                        userId, groupId, name, portletId,
3221                        PortletPreferences.class.getName());
3222
3223                plid = 0;
3224                ownerId = portletItem.getPortletItemId();
3225            }
3226
3227            if (defaultUser) {
3228                ownerId = defaultUserId;
3229            }
3230
3231            try {
3232                portletPreferencesLocalService.deletePortletPreferences(
3233                    ownerId, ownerType, plid, portletId);
3234            }
3235            catch (NoSuchPortletPreferencesException nsppe) {
3236            }
3237
3238            long portletPreferencesId = counterLocalService.increment();
3239
3240            PortletPreferences portletPreferences =
3241                portletPreferencesPersistence.create(portletPreferencesId);
3242
3243            portletPreferences.setOwnerId(ownerId);
3244            portletPreferences.setOwnerType(ownerType);
3245            portletPreferences.setPlid(plid);
3246            portletPreferences.setPortletId(portletId);
3247
3248            portletPreferences.setPreferences(preferences);
3249
3250            portletPreferencesPersistence.update(portletPreferences, false);
3251        }
3252    }
3253
3254    protected void importPortletRoles(
3255            LayoutCache layoutCache, long companyId, long groupId,
3256            Element rolesEl)
3257        throws PortalException, SystemException {
3258
3259        Iterator<Element> itr = rolesEl.elements("portlet").iterator();
3260
3261        while (itr.hasNext()) {
3262            Element portletEl = itr.next();
3263
3264            String portletId = portletEl.attributeValue("portlet-id");
3265
3266            String resourceName = PortletImpl.getRootPortletId(portletId);
3267
3268            Portlet portlet = portletLocalService.getPortletById(
3269                companyId, resourceName);
3270
3271            if (portlet == null) {
3272                if (_log.isDebugEnabled()) {
3273                    _log.debug(
3274                        "Do not import portlet roles for " + portletId +
3275                            " because the portlet does not exist");
3276                }
3277            }
3278            else {
3279                importGroupRoles(
3280                    layoutCache, companyId, groupId, resourceName, "community",
3281                    portletEl);
3282
3283                importUserRoles(
3284                    layoutCache, companyId, groupId, resourceName, portletEl);
3285
3286                importInheritedRoles(
3287                    layoutCache, companyId, groupId, resourceName,
3288                    "organization", portletEl);
3289
3290                importInheritedRoles(
3291                    layoutCache, companyId, groupId, resourceName, "location",
3292                    portletEl);
3293
3294                importInheritedRoles(
3295                    layoutCache, companyId, groupId, resourceName, "user-group",
3296                    portletEl);
3297            }
3298        }
3299    }
3300
3301    protected void importRolePermissions(
3302            LayoutCache layoutCache, long companyId, String resourceName,
3303            int scope, String resourcePrimKey, Element parentEl,
3304            boolean communityRole)
3305        throws PortalException, SystemException {
3306
3307        List<Element> roleEls = parentEl.elements("role");
3308
3309        for (int i = 0; i < roleEls.size(); i++) {
3310            Element roleEl = roleEls.get(i);
3311
3312            String roleName = roleEl.attributeValue("name");
3313
3314            Role role = layoutCache.getRole(companyId, roleName);
3315
3316            if (role == null) {
3317                _log.warn(
3318                    "Ignoring permissions for role with name " + roleName);
3319            }
3320            else {
3321                List<String> actions = getActions(roleEl);
3322
3323                permissionLocalService.setRolePermissions(
3324                    role.getRoleId(), companyId, resourceName, scope,
3325                    resourcePrimKey,
3326                    actions.toArray(new String[actions.size()]));
3327
3328                if (communityRole) {
3329                    long[] groupIds = {GetterUtil.getLong(resourcePrimKey)};
3330
3331                    groupLocalService.addRoleGroups(role.getRoleId(), groupIds);
3332                }
3333            }
3334        }
3335    }
3336
3337    protected String importTheme(LayoutSet layoutSet, byte[] themeZip)
3338        throws IOException {
3339
3340        ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
3341
3342        if (themeLoader == null) {
3343            _log.error("No theme loaders are deployed");
3344
3345            return null;
3346        }
3347
3348        ZipReader zipReader = new ZipReader(new ByteArrayInputStream(themeZip));
3349
3350        Map<String, byte[]> entries = zipReader.getEntries();
3351
3352        String lookAndFeelXML = new String(
3353            entries.get("liferay-look-and-feel.xml"));
3354
3355        String themeId = String.valueOf(layoutSet.getGroupId());
3356
3357        if (layoutSet.isPrivateLayout()) {
3358            themeId += "-private";
3359        }
3360        else {
3361            themeId += "-public";
3362        }
3363
3364        if (PropsValues.THEME_LOADER_NEW_THEME_ID_ON_IMPORT) {
3365            Date now = new Date();
3366
3367            themeId += "-" + Time.getShortTimestamp(now);
3368        }
3369
3370        String themeName = themeId;
3371
3372        lookAndFeelXML = StringUtil.replace(
3373            lookAndFeelXML,
3374            new String[] {
3375                "[$GROUP_ID$]", "[$THEME_ID$]", "[$THEME_NAME$]"
3376            },
3377            new String[] {
3378                String.valueOf(layoutSet.getGroupId()), themeId, themeName
3379            }
3380        );
3381
3382        FileUtil.deltree(themeLoader.getFileStorage() + "/" + themeId);
3383
3384        Iterator<Map.Entry<String, byte[]>> itr = entries.entrySet().iterator();
3385
3386        while (itr.hasNext()) {
3387            Map.Entry<String, byte[]> entry = itr.next();
3388
3389            String key = entry.getKey();
3390            byte[] value = entry.getValue();
3391
3392            if (key.equals("liferay-look-and-feel.xml")) {
3393                value = lookAndFeelXML.getBytes();
3394            }
3395
3396            FileUtil.write(
3397                themeLoader.getFileStorage() + "/" + themeId + "/" + key,
3398                value);
3399        }
3400
3401        themeLoader.loadThemes();
3402
3403        CommLink commLink = CommLink.getInstance();
3404
3405        MethodWrapper methodWrapper = new MethodWrapper(
3406            ThemeLoaderFactory.class.getName(), "loadThemes");
3407
3408        commLink.send(methodWrapper);
3409
3410        themeId +=
3411            PortletImpl.WAR_SEPARATOR + themeLoader.getServletContextName();
3412
3413        return PortalUtil.getJsSafePortletId(themeId);
3414    }
3415
3416    protected void importUserPermissions(
3417            LayoutCache layoutCache, long companyId, long groupId,
3418            String resourceName, String resourcePrimKey, Element parentEl,
3419            boolean portletActions)
3420        throws PortalException, SystemException {
3421
3422        Element userPermissionsEl = parentEl.element("user-permissions");
3423
3424        if (userPermissionsEl == null) {
3425            return;
3426        }
3427
3428        List<Element> userActionsEls = userPermissionsEl.elements(
3429            "user-actions");
3430
3431        for (int i = 0; i < userActionsEls.size(); i++) {
3432            Element userActionsEl = userActionsEls.get(i);
3433
3434            String emailAddress = userActionsEl.attributeValue("email-address");
3435
3436            User user = layoutCache.getUser(companyId, groupId, emailAddress);
3437
3438            if (user == null) {
3439                if (_log.isWarnEnabled()) {
3440                    _log.warn(
3441                        "Ignoring permissions for user with email address " +
3442                            emailAddress);
3443                }
3444            }
3445            else {
3446                List<String> actions = getActions(userActionsEl);
3447
3448                Resource resource = layoutCache.getResource(
3449                    companyId, groupId, resourceName,
3450                    ResourceConstants.SCOPE_INDIVIDUAL, resourcePrimKey,
3451                    portletActions);
3452
3453                permissionLocalService.setUserPermissions(
3454                    user.getUserId(),
3455                    actions.toArray(new String[actions.size()]),
3456                    resource.getResourceId());
3457            }
3458        }
3459    }
3460
3461    protected void importUserRoles(
3462            LayoutCache layoutCache, long companyId, long groupId,
3463            String resourceName, Element parentEl)
3464        throws PortalException, SystemException {
3465
3466        Element userRolesEl = parentEl.element("user-roles");
3467
3468        if (userRolesEl == null) {
3469            return;
3470        }
3471
3472        List<Element> userEls = userRolesEl.elements("user");
3473
3474        for (int i = 0; i < userEls.size(); i++) {
3475            Element userEl = userEls.get(i);
3476
3477            String emailAddress = userEl.attributeValue("email-address");
3478
3479            User user = layoutCache.getUser(companyId, groupId, emailAddress);
3480
3481            if (user == null) {
3482                if (_log.isWarnEnabled()) {
3483                    _log.warn(
3484                        "Ignoring roles for user with email address " +
3485                            emailAddress);
3486                }
3487            }
3488            else {
3489                importRolePermissions(
3490                    layoutCache, companyId, resourceName,
3491                    ResourceConstants.SCOPE_GROUP, String.valueOf(groupId),
3492                    userEl, false);
3493            }
3494        }
3495    }
3496
3497    protected boolean isDescendant(Layout layout, long layoutId)
3498        throws PortalException, SystemException {
3499
3500        if (layout.getLayoutId() == layoutId) {
3501            return true;
3502        }
3503        else {
3504            for (Layout childLayout : layout.getChildren()) {
3505                if (isDescendant(childLayout, layoutId)) {
3506                    return true;
3507                }
3508            }
3509
3510            return false;
3511        }
3512    }
3513
3514    protected void readComments(PortletDataContext context, Element root)
3515        throws PortalException, SystemException {
3516
3517        try {
3518            XStream xStream = new XStream();
3519
3520            Iterator<Element> itr = root.elements("comments").iterator();
3521
3522            while (itr.hasNext()) {
3523                Element el = itr.next();
3524
3525                String className = GetterUtil.getString(
3526                    el.attributeValue("class-name"));
3527                long classPK = GetterUtil.getLong(
3528                    el.attributeValue("class-pk"));
3529
3530                Element messagesListEl = el.element("list");
3531
3532                Document tempDoc = DocumentHelper.createDocument();
3533
3534                tempDoc.content().add(messagesListEl.createCopy());
3535
3536                List messages = (List)xStream.fromXML(
3537                    XMLFormatter.toString(tempDoc));
3538
3539                context.addComments(className, new Long(classPK), messages);
3540            }
3541        }
3542        catch (Exception e) {
3543            throw new SystemException(e);
3544        }
3545    }
3546
3547    protected void readRatings(PortletDataContext context, Element root)
3548        throws PortalException, SystemException {
3549
3550        try {
3551            XStream xStream = new XStream();
3552
3553            Iterator<Element> itr = root.elements("ratings").iterator();
3554
3555            while (itr.hasNext()) {
3556                Element el = itr.next();
3557
3558                String className = GetterUtil.getString(
3559                    el.attributeValue("class-name"));
3560                long classPK = GetterUtil.getLong(
3561                    el.attributeValue("class-pk"));
3562
3563                Element entriesListEl = el.element("list");
3564
3565                Document tempDoc = DocumentHelper.createDocument();
3566
3567                tempDoc.content().add(entriesListEl.createCopy());
3568
3569                List entries = (List)xStream.fromXML(
3570                    XMLFormatter.toString(tempDoc));
3571
3572                context.addRatingsEntries(
3573                    className, new Long(classPK), entries);
3574            }
3575        }
3576        catch (Exception e) {
3577            throw new SystemException(e);
3578        }
3579    }
3580
3581    protected void readTags(PortletDataContext context, Element root)
3582        throws PortalException, SystemException {
3583
3584        Iterator<Element> itr = root.elements("tags").iterator();
3585
3586        while (itr.hasNext()) {
3587            Element el = itr.next();
3588
3589            String className = GetterUtil.getString(
3590                el.attributeValue("class-name"));
3591            long classPK = GetterUtil.getLong(el.attributeValue("class-pk"));
3592            String entries = GetterUtil.getString(el.attributeValue("entries"));
3593
3594            context.addTagsEntries(
3595                className, new Long(classPK), StringUtil.split(entries, ","));
3596        }
3597    }
3598
3599    protected void setLocalizedAttributes(
3600        Layout layout, Map<Locale, String> localeNamesMap,
3601        Map<Locale, String> localeTitlesMap) {
3602
3603        Locale[] locales = LanguageUtil.getAvailableLocales();
3604
3605        for (Locale locale : locales) {
3606            String name = localeNamesMap.get(locale);
3607            String title = localeTitlesMap.get(locale);
3608
3609            layout.setName(name, locale);
3610            layout.setTitle(title, locale);
3611        }
3612    }
3613
3614    protected void validate(
3615            long groupId, boolean privateLayout, long layoutId,
3616            long parentLayoutId, String type, boolean hidden,
3617            String friendlyURL)
3618        throws PortalException, SystemException {
3619
3620        boolean firstLayout = false;
3621
3622        if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
3623            List<Layout> layouts = layoutPersistence.findByG_P_P(
3624                groupId, privateLayout, parentLayoutId, 0, 1);
3625
3626            if (layouts.size() == 0) {
3627                firstLayout = true;
3628            }
3629            else {
3630                long firstLayoutId = layouts.get(0).getLayoutId();
3631
3632                if (firstLayoutId == layoutId) {
3633                    firstLayout = true;
3634                }
3635            }
3636        }
3637
3638        if (firstLayout) {
3639            validateFirstLayout(type, hidden);
3640        }
3641
3642        if (!PortalUtil.isLayoutParentable(type)) {
3643            if (layoutPersistence.countByG_P_P(
3644                    groupId, privateLayout, layoutId) > 0) {
3645
3646                throw new LayoutTypeException(
3647                    LayoutTypeException.NOT_PARENTABLE);
3648            }
3649        }
3650
3651        validateFriendlyURL(groupId, privateLayout, layoutId, friendlyURL);
3652    }
3653
3654    protected void validateFirstLayout(String type, boolean hidden)
3655        throws PortalException {
3656
3657        if (!type.equals(LayoutImpl.TYPE_PORTLET)) {
3658            throw new LayoutTypeException(LayoutTypeException.FIRST_LAYOUT);
3659        }
3660
3661        if (hidden) {
3662            throw new LayoutHiddenException();
3663        }
3664    }
3665
3666    protected void validateFriendlyURL(
3667            long groupId, boolean privateLayout, long layoutId,
3668            String friendlyURL)
3669        throws PortalException, SystemException {
3670
3671        if (Validator.isNull(friendlyURL)) {
3672            return;
3673        }
3674
3675        int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
3676
3677        if (exceptionType != -1) {
3678            throw new LayoutFriendlyURLException(exceptionType);
3679        }
3680
3681        try {
3682            Layout layout = layoutPersistence.findByG_P_F(
3683                groupId, privateLayout, friendlyURL);
3684
3685            if (layout.getLayoutId() != layoutId) {
3686                throw new LayoutFriendlyURLException(
3687                    LayoutFriendlyURLException.DUPLICATE);
3688            }
3689        }
3690        catch (NoSuchLayoutException nsle) {
3691        }
3692
3693        LayoutImpl.validateFriendlyURLKeyword(friendlyURL);
3694
3695        List<FriendlyURLMapper> friendlyURLMappers =
3696            portletLocalService.getFriendlyURLMappers();
3697
3698        for (FriendlyURLMapper friendlyURLMapper : friendlyURLMappers) {
3699            if (friendlyURL.indexOf(friendlyURLMapper.getMapping()) != -1) {
3700                LayoutFriendlyURLException lfurle =
3701                    new LayoutFriendlyURLException(
3702                        LayoutFriendlyURLException.KEYWORD_CONFLICT);
3703
3704                lfurle.setKeywordConflict(friendlyURLMapper.getMapping());
3705
3706                throw lfurle;
3707            }
3708        }
3709
3710        String layoutIdFriendlyURL = friendlyURL.substring(1);
3711
3712        if (Validator.isNumber(layoutIdFriendlyURL) &&
3713            !layoutIdFriendlyURL.equals(String.valueOf(layoutId))) {
3714
3715            LayoutFriendlyURLException lfurle = new LayoutFriendlyURLException(
3716                LayoutFriendlyURLException.POSSIBLE_DUPLICATE);
3717
3718            lfurle.setKeywordConflict(layoutIdFriendlyURL);
3719
3720            throw lfurle;
3721        }
3722    }
3723
3724    protected void validateParentLayoutId(
3725            long groupId, boolean privateLayout, long layoutId,
3726            long parentLayoutId)
3727        throws PortalException, SystemException {
3728
3729        Layout layout = layoutPersistence.findByG_P_L(
3730            groupId, privateLayout, layoutId);
3731
3732        if (parentLayoutId != layout.getParentLayoutId()) {
3733
3734            // Layouts can always be moved to the root level
3735
3736            if (parentLayoutId == LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
3737                return;
3738            }
3739
3740            // Layout cannot become a child of a layout that is not parentable
3741
3742            Layout parentLayout = layoutPersistence.findByG_P_L(
3743                groupId, privateLayout, parentLayoutId);
3744
3745            if (!PortalUtil.isLayoutParentable(parentLayout)) {
3746                throw new LayoutParentLayoutIdException(
3747                    LayoutParentLayoutIdException.NOT_PARENTABLE);
3748            }
3749
3750            // Layout cannot become descendant of itself
3751
3752            if (isDescendant(layout, parentLayoutId)) {
3753                throw new LayoutParentLayoutIdException(
3754                    LayoutParentLayoutIdException.SELF_DESCENDANT);
3755            }
3756
3757            // If layout is moved, the new first layout must be valid
3758
3759            if (layout.getParentLayoutId() ==
3760                    LayoutImpl.DEFAULT_PARENT_LAYOUT_ID) {
3761
3762                List<Layout> layouts = layoutPersistence.findByG_P_P(
3763                    groupId, privateLayout,
3764                    LayoutImpl.DEFAULT_PARENT_LAYOUT_ID, 0, 2);
3765
3766                // You can only reach this point if there are more than two
3767                // layouts at the root level because of the descendant check
3768
3769                long firstLayoutId = layouts.get(0).getLayoutId();
3770
3771                if (firstLayoutId == layoutId) {
3772                    Layout secondLayout = layouts.get(1);
3773
3774                    try {
3775                        validateFirstLayout(
3776                            secondLayout.getType(), secondLayout.getHidden());
3777                    }
3778                    catch (LayoutHiddenException lhe) {
3779                        throw new LayoutParentLayoutIdException(
3780                            LayoutParentLayoutIdException.FIRST_LAYOUT_HIDDEN);
3781                    }
3782                    catch (LayoutTypeException lte) {
3783                        throw new LayoutParentLayoutIdException(
3784                            LayoutParentLayoutIdException.FIRST_LAYOUT_TYPE);
3785                    }
3786                }
3787            }
3788        }
3789    }
3790
3791    private static Log _log = LogFactory.getLog(LayoutLocalServiceImpl.class);
3792
3793}