001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.sites.util;
016    
017    import com.liferay.portal.RequiredLayoutException;
018    import com.liferay.portal.events.EventsProcessorUtil;
019    import com.liferay.portal.kernel.dao.orm.QueryUtil;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.language.LanguageUtil;
023    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
024    import com.liferay.portal.kernel.lar.UserIdStrategy;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.FileUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.ParamUtil;
030    import com.liferay.portal.kernel.util.PropsKeys;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.SystemProperties;
033    import com.liferay.portal.kernel.util.UnicodeProperties;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
036    import com.liferay.portal.model.Group;
037    import com.liferay.portal.model.GroupConstants;
038    import com.liferay.portal.model.Layout;
039    import com.liferay.portal.model.LayoutConstants;
040    import com.liferay.portal.model.LayoutPrototype;
041    import com.liferay.portal.model.LayoutSet;
042    import com.liferay.portal.model.LayoutSetPrototype;
043    import com.liferay.portal.model.LayoutTypePortlet;
044    import com.liferay.portal.model.Lock;
045    import com.liferay.portal.model.Organization;
046    import com.liferay.portal.model.OrganizationConstants;
047    import com.liferay.portal.model.PortletConstants;
048    import com.liferay.portal.model.ResourceConstants;
049    import com.liferay.portal.model.Role;
050    import com.liferay.portal.model.RoleConstants;
051    import com.liferay.portal.model.User;
052    import com.liferay.portal.model.UserGroup;
053    import com.liferay.portal.model.impl.VirtualLayout;
054    import com.liferay.portal.security.auth.PrincipalException;
055    import com.liferay.portal.security.permission.ActionKeys;
056    import com.liferay.portal.security.permission.PermissionChecker;
057    import com.liferay.portal.security.permission.PermissionThreadLocal;
058    import com.liferay.portal.security.permission.ResourceActionsUtil;
059    import com.liferay.portal.service.GroupLocalServiceUtil;
060    import com.liferay.portal.service.GroupServiceUtil;
061    import com.liferay.portal.service.LayoutLocalServiceUtil;
062    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
063    import com.liferay.portal.service.LayoutServiceUtil;
064    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
065    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
066    import com.liferay.portal.service.LayoutSetServiceUtil;
067    import com.liferay.portal.service.LockLocalServiceUtil;
068    import com.liferay.portal.service.OrganizationLocalServiceUtil;
069    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
070    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
071    import com.liferay.portal.service.RoleLocalServiceUtil;
072    import com.liferay.portal.service.ServiceContext;
073    import com.liferay.portal.service.ServiceContextFactory;
074    import com.liferay.portal.service.ServiceContextThreadLocal;
075    import com.liferay.portal.service.UserGroupLocalServiceUtil;
076    import com.liferay.portal.service.UserLocalServiceUtil;
077    import com.liferay.portal.service.impl.LayoutLocalServiceVirtualLayoutsAdvice;
078    import com.liferay.portal.service.permission.GroupPermissionUtil;
079    import com.liferay.portal.service.permission.LayoutPermissionUtil;
080    import com.liferay.portal.service.permission.PortalPermissionUtil;
081    import com.liferay.portal.service.permission.PortletPermissionUtil;
082    import com.liferay.portal.service.persistence.LayoutSetUtil;
083    import com.liferay.portal.service.persistence.LayoutUtil;
084    import com.liferay.portal.theme.PortletDisplay;
085    import com.liferay.portal.theme.ThemeDisplay;
086    import com.liferay.portal.util.LayoutSettings;
087    import com.liferay.portal.util.PortalUtil;
088    import com.liferay.portal.util.PortletKeys;
089    import com.liferay.portal.util.PropsValues;
090    import com.liferay.portal.util.WebKeys;
091    import com.liferay.portlet.PortletPreferencesFactoryUtil;
092    import com.liferay.portlet.PortletPreferencesImpl;
093    import com.liferay.portlet.usersadmin.search.GroupSearchTerms;
094    
095    import java.io.File;
096    import java.io.InputStream;
097    
098    import java.util.Date;
099    import java.util.LinkedHashMap;
100    import java.util.List;
101    import java.util.Locale;
102    import java.util.Map;
103    
104    import javax.portlet.ActionRequest;
105    import javax.portlet.ActionResponse;
106    import javax.portlet.PortletPreferences;
107    import javax.portlet.PortletURL;
108    import javax.portlet.RenderRequest;
109    import javax.portlet.RenderResponse;
110    
111    import javax.servlet.http.HttpServletRequest;
112    import javax.servlet.http.HttpServletResponse;
113    
114    /**
115     * @author Raymond Augé
116     * @author Ryan Park
117     * @author Zsolt Berentey
118     */
119    public class SitesUtil {
120    
121            public static final String ANALYTICS_PREFIX = "analytics_";
122    
123            public static void addPortletBreadcrumbEntries(
124                            Group group, String pagesName, PortletURL redirectURL,
125                            HttpServletRequest request, RenderResponse renderResponse)
126                    throws Exception {
127    
128                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
129                            com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
130    
131                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
132    
133                    String portletName = portletDisplay.getPortletName();
134    
135                    if ((renderResponse == null) ||
136                            portletName.equals(PortletKeys.GROUP_PAGES) ||
137                            portletName.equals(PortletKeys.MY_PAGES)) {
138    
139                            return;
140                    }
141    
142                    Locale locale = themeDisplay.getLocale();
143    
144                    if (group.isLayoutPrototype()) {
145                            PortalUtil.addPortletBreadcrumbEntry(
146                                    request, LanguageUtil.get(locale, "page-template"), null);
147    
148                            PortalUtil.addPortletBreadcrumbEntry(
149                                    request, group.getDescriptiveName(), redirectURL.toString());
150                    }
151                    else {
152                            PortalUtil.addPortletBreadcrumbEntry(
153                                    request, group.getDescriptiveName(), null);
154                    }
155    
156                    if (!group.isLayoutPrototype()) {
157                            PortalUtil.addPortletBreadcrumbEntry(
158                                    request, LanguageUtil.get(locale, pagesName),
159                                    redirectURL.toString());
160                    }
161            }
162    
163            public static void applyLayoutPrototype(
164                            LayoutPrototype layoutPrototype, Layout targetLayout,
165                            boolean linkEnabled)
166                    throws Exception {
167    
168                    Layout layoutPrototypeLayout = layoutPrototype.getLayout();
169    
170                    ServiceContext serviceContext =
171                            ServiceContextThreadLocal.getServiceContext();
172    
173                    serviceContext.setAttribute("layoutPrototypeLinkEnabled", linkEnabled);
174                    serviceContext.setAttribute(
175                            "layoutPrototypeUuid", layoutPrototype.getUuid());
176    
177                    targetLayout = LayoutLocalServiceUtil.updateLayout(
178                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
179                            targetLayout.getLayoutId(), targetLayout.getParentLayoutId(),
180                            targetLayout.getNameMap(), targetLayout.getTitleMap(),
181                            targetLayout.getDescriptionMap(), targetLayout.getKeywordsMap(),
182                            targetLayout.getRobotsMap(), layoutPrototypeLayout.getType(),
183                            targetLayout.getHidden(), targetLayout.getFriendlyURL(),
184                            targetLayout.getIconImage(), null, serviceContext);
185    
186                    targetLayout = LayoutLocalServiceUtil.updateLayout(
187                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
188                            targetLayout.getLayoutId(),
189                            layoutPrototypeLayout.getTypeSettings());
190    
191                    copyPortletPermissions(targetLayout, layoutPrototypeLayout);
192    
193                    copyPortletSetups(layoutPrototypeLayout, targetLayout);
194    
195                    copyLookAndFeel(targetLayout, layoutPrototypeLayout);
196    
197                    targetLayout = LayoutLocalServiceUtil.getLayout(targetLayout.getPlid());
198    
199                    UnicodeProperties typeSettingsProperties =
200                            targetLayout.getTypeSettingsProperties();
201    
202                    typeSettingsProperties.setProperty(
203                            "last-merge-time",
204                            String.valueOf(targetLayout.getModifiedDate().getTime()));
205    
206                    LayoutLocalServiceUtil.updateLayout(targetLayout);
207    
208                    UnicodeProperties prototypeTypeSettingsProperties =
209                            layoutPrototypeLayout.getTypeSettingsProperties();
210    
211                    prototypeTypeSettingsProperties.setProperty("merge-fail-count", "0");
212    
213                    LayoutLocalServiceUtil.updateLayout(layoutPrototypeLayout);
214            }
215    
216            public static void copyLayout(
217                            long userId, Layout sourceLayout, Layout targetLayout,
218                            ServiceContext serviceContext)
219                    throws Exception {
220    
221                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
222                            serviceContext);
223    
224                    parameterMap.put(
225                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
226                            new String[] {Boolean.FALSE.toString()});
227    
228                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
229                            sourceLayout.getGroupId(), sourceLayout.isPrivateLayout(),
230                            new long[] {sourceLayout.getLayoutId()}, parameterMap, null, null);
231    
232                    try {
233                            LayoutLocalServiceUtil.importLayouts(
234                                    userId, targetLayout.getGroupId(),
235                                    targetLayout.isPrivateLayout(), parameterMap, file);
236                    }
237                    finally {
238                            file.delete();
239                    }
240            }
241    
242            public static void copyLookAndFeel(Layout targetLayout, Layout sourceLayout)
243                    throws Exception {
244    
245                    LayoutLocalServiceUtil.updateLookAndFeel(
246                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
247                            targetLayout.getLayoutId(), sourceLayout.getThemeId(),
248                            sourceLayout.getColorSchemeId(), sourceLayout.getCss(), false);
249    
250                    LayoutLocalServiceUtil.updateLookAndFeel(
251                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
252                            targetLayout.getLayoutId(), sourceLayout.getWapThemeId(),
253                            sourceLayout.getWapColorSchemeId(), sourceLayout.getCss(), true);
254            }
255    
256            public static void copyPortletPermissions(
257                    Layout targetLayout, Layout sourceLayout)
258                    throws Exception {
259    
260                    long companyId = targetLayout.getCompanyId();
261    
262                    List<Role> roles = RoleLocalServiceUtil.getRoles(companyId);
263    
264                    LayoutTypePortlet sourceLayoutTypePortlet =
265                            (LayoutTypePortlet)sourceLayout.getLayoutType();
266    
267                    List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
268    
269                    for (String sourcePortletId : sourcePortletIds) {
270                            String resourceName = PortletConstants.getRootPortletId(
271                                    sourcePortletId);
272    
273                            String sourceResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
274                                    sourceLayout.getPlid(), sourcePortletId);
275    
276                            String targetResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
277                                    targetLayout.getPlid(), sourcePortletId);
278    
279                            List<String> actionIds =
280                                    ResourceActionsUtil.getPortletResourceActions(resourceName);
281    
282                            for (Role role : roles) {
283                                    String roleName = role.getName();
284    
285                                    if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
286                                            continue;
287                                    }
288    
289                                    List<String> actions =
290                                            ResourcePermissionLocalServiceUtil.
291                                                    getAvailableResourcePermissionActionIds(
292                                                            companyId, resourceName,
293                                                            ResourceConstants.SCOPE_INDIVIDUAL,
294                                                            sourceResourcePrimKey, role.getRoleId(), actionIds);
295    
296                                    ResourcePermissionLocalServiceUtil.setResourcePermissions(
297                                            companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
298                                            targetResourcePrimKey, role.getRoleId(),
299                                            actions.toArray(new String[actions.size()]));
300                            }
301                    }
302            }
303    
304            public static void copyPortletSetups(
305                            Layout sourceLayout, Layout targetLayout)
306                    throws Exception {
307    
308                    LayoutTypePortlet sourceLayoutTypePortlet =
309                            (LayoutTypePortlet)sourceLayout.getLayoutType();
310    
311                    List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
312    
313                    for (String sourcePortletId : sourcePortletIds) {
314                            PortletPreferences sourcePreferences =
315                                    PortletPreferencesFactoryUtil.getPortletSetup(
316                                            sourceLayout, sourcePortletId, null);
317    
318                            PortletPreferencesImpl sourcePreferencesImpl =
319                                    (PortletPreferencesImpl)sourcePreferences;
320    
321                            PortletPreferences targetPreferences =
322                                    PortletPreferencesFactoryUtil.getPortletSetup(
323                                            targetLayout, sourcePortletId, null);
324    
325                            PortletPreferencesImpl targetPreferencesImpl =
326                                    (PortletPreferencesImpl)targetPreferences;
327    
328                            PortletPreferencesLocalServiceUtil.updatePreferences(
329                                    targetPreferencesImpl.getOwnerId(),
330                                    targetPreferencesImpl.getOwnerType(),
331                                    targetPreferencesImpl.getPlid(), sourcePortletId,
332                                    sourcePreferences);
333    
334                            if ((sourcePreferencesImpl.getOwnerId() !=
335                                            PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
336                                    (sourcePreferencesImpl.getOwnerType() !=
337                                            PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) {
338    
339                                    sourcePreferences =
340                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
341                                                    sourceLayout, sourcePortletId);
342    
343                                    sourcePreferencesImpl =
344                                            (PortletPreferencesImpl)sourcePreferences;
345    
346                                    targetPreferences =
347                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
348                                                    targetLayout, sourcePortletId);
349    
350                                    targetPreferencesImpl =
351                                            (PortletPreferencesImpl)targetPreferences;
352    
353                                    PortletPreferencesLocalServiceUtil.updatePreferences(
354                                            targetPreferencesImpl.getOwnerId(),
355                                            targetPreferencesImpl.getOwnerType(),
356                                            targetPreferencesImpl.getPlid(), sourcePortletId,
357                                            sourcePreferences);
358                            }
359    
360                            ServiceContext serviceContext =
361                                    ServiceContextThreadLocal.getServiceContext();
362    
363                            updateLayoutScopes(
364                                    serviceContext.getUserId(), sourceLayout, targetLayout,
365                                    sourcePreferences, targetPreferences, sourcePortletId,
366                                    serviceContext.getLanguageId());
367                    }
368            }
369    
370            public static void copyTypeSettings(Group sourceGroup, Group targetGroup)
371                    throws Exception {
372    
373                    GroupServiceUtil.updateGroup(
374                            targetGroup.getGroupId(), sourceGroup.getTypeSettings());
375            }
376    
377            public static Object[] deleteLayout(
378                            ActionRequest actionRequest, ActionResponse actionResponse)
379                    throws Exception {
380    
381                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
382                            actionRequest);
383                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
384                            actionResponse);
385    
386                    return deleteLayout(request, response);
387            }
388    
389            public static Object[] deleteLayout(
390                            HttpServletRequest request, HttpServletResponse response)
391                    throws Exception {
392    
393                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
394                            WebKeys.THEME_DISPLAY);
395    
396                    PermissionChecker permissionChecker =
397                            themeDisplay.getPermissionChecker();
398    
399                    long plid = ParamUtil.getLong(request, "plid");
400    
401                    long groupId = ParamUtil.getLong(request, "groupId");
402                    boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
403                    long layoutId = ParamUtil.getLong(request, "layoutId");
404    
405                    Layout layout = null;
406    
407                    if (plid <= 0) {
408                            layout = LayoutLocalServiceUtil.getLayout(
409                                    groupId, privateLayout, layoutId);
410                    }
411                    else {
412                            layout = LayoutLocalServiceUtil.getLayout(plid);
413    
414                            groupId = layout.getGroupId();
415                            privateLayout = layout.isPrivateLayout();
416                            layoutId = layout.getLayoutId();
417                    }
418    
419                    Group group = layout.getGroup();
420                    String oldFriendlyURL = layout.getFriendlyURL();
421    
422                    if (group.isStagingGroup() &&
423                            !GroupPermissionUtil.contains(
424                                    permissionChecker, groupId, ActionKeys.MANAGE_STAGING) &&
425                            !GroupPermissionUtil.contains(
426                                    permissionChecker, groupId, ActionKeys.PUBLISH_STAGING)) {
427    
428                            throw new PrincipalException();
429                    }
430    
431                    if (LayoutPermissionUtil.contains(
432                                    permissionChecker, layout, ActionKeys.DELETE)) {
433    
434                            LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
435    
436                            EventsProcessorUtil.process(
437                                    PropsKeys.LAYOUT_CONFIGURATION_ACTION_DELETE,
438                                    layoutSettings.getConfigurationActionDelete(), request,
439                                    response);
440                    }
441    
442                    LayoutSet layoutSet = layout.getLayoutSet();
443    
444                    if (group.isGuest() && (layoutSet.getPageCount() == 1)) {
445                            throw new RequiredLayoutException(
446                                    RequiredLayoutException.AT_LEAST_ONE);
447                    }
448    
449                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
450                            request);
451    
452                    LayoutServiceUtil.deleteLayout(
453                            groupId, privateLayout, layoutId, serviceContext);
454    
455                    long newPlid = layout.getParentPlid();
456    
457                    if (newPlid <= 0) {
458                            Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
459                                    layoutSet.getGroupId(), layoutSet.getPrivateLayout(),
460                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
461    
462                            if (firstLayout != null) {
463                                    newPlid = firstLayout.getPlid();
464                            }
465                    }
466    
467                    return new Object[] {group, oldFriendlyURL, newPlid};
468            }
469    
470            public static void deleteLayout(
471                            RenderRequest renderRequest, RenderResponse renderResponse)
472                    throws Exception {
473    
474                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
475                            renderRequest);
476                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
477                            renderResponse);
478    
479                    deleteLayout(request, response);
480            }
481    
482            public static File exportLayoutSetPrototype(
483                            LayoutSetPrototype layoutSetPrototype,
484                            ServiceContext serviceContext)
485                    throws PortalException, SystemException {
486    
487                    LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
488    
489                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
490                            serviceContext);
491    
492                    return LayoutLocalServiceUtil.exportLayoutsAsFile(
493                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(), null,
494                            parameterMap, null, null);
495            }
496    
497            public static Layout getLayoutSetPrototypeLayout(Layout layout) {
498                    try {
499                            LayoutSet layoutSet = layout.getLayoutSet();
500    
501                            if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
502                                    return null;
503                            }
504    
505                            LayoutSetPrototype layoutSetPrototype =
506                                    LayoutSetPrototypeLocalServiceUtil.
507                                            getLayoutSetPrototypeByUuidAndCompanyId(
508                                                    layoutSet.getLayoutSetPrototypeUuid(),
509                                                    layout.getCompanyId());
510    
511                            Group group = layoutSetPrototype.getGroup();
512    
513                            return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
514                                    layout.getSourcePrototypeLayoutUuid(), group.getGroupId());
515                    }
516                    catch (Exception e) {
517                            _log.error(
518                                    "Unable to fetch the the layout set prototype's layout", e);
519                    }
520    
521                    return null;
522            }
523    
524            public static Map<String, String[]> getLayoutSetPrototypeParameters(
525                    ServiceContext serviceContext) {
526    
527                    Map<String, String[]> parameterMap =
528                            new LinkedHashMap<String, String[]>();
529    
530                    parameterMap.put(
531                            PortletDataHandlerKeys.CATEGORIES,
532                            new String[] {Boolean.TRUE.toString()});
533                    parameterMap.put(
534                            PortletDataHandlerKeys.DATA_STRATEGY,
535                            new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
536                    parameterMap.put(
537                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
538                            new String[] {Boolean.TRUE.toString()});
539                    parameterMap.put(
540                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
541                            new String[] {Boolean.FALSE.toString()});
542                    parameterMap.put(
543                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
544                            new String[] {Boolean.TRUE.toString()});
545                    parameterMap.put(
546                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
547                            new String[] {Boolean.TRUE.toString()});
548                    parameterMap.put(
549                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
550                            new String[] {
551                                    PortletDataHandlerKeys.
552                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
553                            });
554                    parameterMap.put(
555                            PortletDataHandlerKeys.LOGO,
556                            new String[] {Boolean.TRUE.toString()});
557                    parameterMap.put(
558                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
559                            new String[] {Boolean.TRUE.toString()});
560                    parameterMap.put(
561                            PortletDataHandlerKeys.PERMISSIONS,
562                            new String[] {Boolean.TRUE.toString()});
563                    parameterMap.put(
564                            PortletDataHandlerKeys.PORTLET_DATA,
565                            new String[] {Boolean.TRUE.toString()});
566                    parameterMap.put(
567                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
568                            new String[] {Boolean.TRUE.toString()});
569                    parameterMap.put(
570                            PortletDataHandlerKeys.PORTLET_SETUP,
571                            new String[] {Boolean.TRUE.toString()});
572                    parameterMap.put(
573                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
574                            new String[] {Boolean.TRUE.toString()});
575                    parameterMap.put(
576                            PortletDataHandlerKeys.THEME,
577                            new String[] {Boolean.FALSE.toString()});
578                    parameterMap.put(
579                            PortletDataHandlerKeys.THEME_REFERENCE,
580                            new String[] {Boolean.TRUE.toString()});
581                    parameterMap.put(
582                            PortletDataHandlerKeys.USER_ID_STRATEGY,
583                            new String[] {UserIdStrategy.CURRENT_USER_ID});
584    
585                    return parameterMap;
586            }
587    
588            public static void importLayoutSetPrototype(
589                            LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
590                            ServiceContext serviceContext)
591                    throws PortalException, SystemException {
592    
593                    LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
594    
595                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
596                            serviceContext);
597    
598                    setLayoutSetPrototypeLinkEnabledParameter(
599                            parameterMap, layoutSet, serviceContext);
600    
601                    LayoutServiceUtil.importLayouts(
602                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(), parameterMap,
603                            inputStream);
604            }
605    
606            public static boolean isLayoutDeleteable(Layout layout) {
607                    try {
608                            if (layout instanceof VirtualLayout) {
609                                    return false;
610                            }
611    
612                            if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
613                                    return true;
614                            }
615    
616                            LayoutSet layoutSet = layout.getLayoutSet();
617    
618                            if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
619                                    return true;
620                            }
621    
622                            if (LayoutLocalServiceUtil.hasLayoutSetPrototypeLayout(
623                                            layoutSet.getLayoutSetPrototypeUuid(),
624                                            layout.getSourcePrototypeLayoutUuid(),
625                                            layout.getCompanyId())) {
626    
627                                    return false;
628                            }
629                    }
630                    catch (Exception e) {
631                            if (_log.isDebugEnabled()) {
632                                    _log.debug(e, e);
633                            }
634                    }
635    
636                    return true;
637            }
638    
639            public static boolean isLayoutModifiedSinceLastMerge(Layout layout)
640                    throws PortalException, SystemException {
641    
642                    if ((layout == null) ||
643                            Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
644                            layout.isLayoutPrototypeLinkActive()) {
645    
646                            return false;
647                    }
648    
649                    LayoutSet existingLayoutSet = layout.getLayoutSet();
650    
651                    long lastMergeTime = GetterUtil.getLong(
652                            existingLayoutSet.getSettingsProperty("last-merge-time"));
653    
654                    Date existingLayoutModifiedDate = layout.getModifiedDate();
655    
656                    if ((existingLayoutModifiedDate != null) &&
657                            (existingLayoutModifiedDate.getTime() > lastMergeTime) &&
658                            isLayoutUpdateable(layout)) {
659    
660                            return true;
661                    }
662    
663                    return false;
664            }
665    
666            public static boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
667                    if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
668                            return true;
669                    }
670    
671                    try {
672                            LayoutSetPrototype layoutSetPrototype =
673                                    LayoutSetPrototypeLocalServiceUtil.
674                                            getLayoutSetPrototypeByUuidAndCompanyId(
675                                                    layoutSet.getLayoutSetPrototypeUuid(),
676                                                    layoutSet.getCompanyId());
677    
678                            String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
679                                    "layoutsUpdateable");
680    
681                            if (Validator.isNotNull(layoutsUpdateable)) {
682                                    return GetterUtil.getBoolean(layoutsUpdateable, true);
683                            }
684                    }
685                    catch (Exception e) {
686                            if (_log.isDebugEnabled()) {
687                                    _log.debug(e, e);
688                            }
689                    }
690    
691                    return true;
692            }
693    
694            public static boolean isLayoutUpdateable(Layout layout) {
695                    try {
696                            if (layout instanceof VirtualLayout) {
697                                    return false;
698                            }
699    
700                            if (Validator.isNull(layout.getLayoutPrototypeUuid()) &&
701                                    Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
702    
703                                    return true;
704                            }
705    
706                            LayoutSet layoutSet = layout.getLayoutSet();
707    
708                            if (layoutSet.isLayoutSetPrototypeLinkActive()) {
709                                    boolean layoutSetPrototypeUpdateable =
710                                            isLayoutSetPrototypeUpdateable(layoutSet);
711    
712                                    if (!layoutSetPrototypeUpdateable) {
713                                            return false;
714                                    }
715    
716                                    Layout layoutSetPrototypeLayout = getLayoutSetPrototypeLayout(
717                                            layout);
718    
719                                    UnicodeProperties typeSettingsProperties =
720                                            layoutSetPrototypeLayout.getTypeSettingsProperties();
721    
722                                    String layoutUpdateable = typeSettingsProperties.getProperty(
723                                            "layoutUpdateable");
724    
725                                    if (Validator.isNull(layoutUpdateable)) {
726                                            return true;
727                                    }
728    
729                                    return GetterUtil.getBoolean(layoutUpdateable);
730                            }
731                    }
732                    catch (Exception e) {
733                            if (_log.isDebugEnabled()) {
734                                    _log.debug(e, e);
735                            }
736                    }
737    
738                    return true;
739            }
740    
741            public static boolean isOrganizationUser(
742                            long companyId, Group group, User user,
743                            GroupSearchTerms searchTerms, List<String> organizationNames)
744                    throws Exception {
745    
746                    boolean organizationUser = false;
747    
748                    LinkedHashMap<String, Object> organizationParams =
749                            new LinkedHashMap<String, Object>();
750    
751                    organizationParams.put(
752                            "organizationsGroups", new Long(group.getGroupId()));
753    
754                    List<Organization> organizationsGroups =
755                            OrganizationLocalServiceUtil.search(
756                                    companyId, OrganizationConstants.ANY_PARENT_ORGANIZATION_ID,
757                                    searchTerms.getKeywords(), null, null, null, organizationParams,
758                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS);
759    
760                    for (Organization organization : organizationsGroups) {
761                            for (long userOrganizationId : user.getOrganizationIds()) {
762                                    if (userOrganizationId == organization.getOrganizationId()) {
763                                            organizationNames.add(organization.getName());
764    
765                                            organizationUser = true;
766                                    }
767                            }
768                    }
769    
770                    return organizationUser;
771            }
772    
773            public static boolean isUserGroupLayoutSetViewable(
774                            PermissionChecker permissionChecker, Group userGroupGroup)
775                    throws PortalException, SystemException {
776    
777                    if (!userGroupGroup.isUserGroup()) {
778                            return false;
779                    }
780    
781                    if (GroupPermissionUtil.contains(
782                                    permissionChecker, userGroupGroup.getGroupId(),
783                                    ActionKeys.VIEW)) {
784    
785                            return true;
786                    }
787    
788                    UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
789                            userGroupGroup.getClassPK());
790    
791                    if (UserLocalServiceUtil.hasUserGroupUser(
792                                    userGroup.getUserGroupId(), permissionChecker.getUserId())) {
793    
794                            return true;
795                    }
796                    else {
797                            return false;
798                    }
799            }
800    
801            public static boolean isUserGroupUser(
802                            long companyId, Group group, User user, List<String> userGroupNames)
803                    throws Exception {
804    
805                    boolean userGroupUser = false;
806    
807                    LinkedHashMap<String, Object> userGroupParams =
808                            new LinkedHashMap<String, Object>();
809    
810                    userGroupParams.put("userGroupsGroups", new Long(group.getGroupId()));
811    
812                    List<UserGroup> userGroupsGroups = UserGroupLocalServiceUtil.search(
813                            companyId, null, null, userGroupParams, QueryUtil.ALL_POS,
814                            QueryUtil.ALL_POS, null);
815    
816                    for (UserGroup userGroup : userGroupsGroups) {
817                            for (long userGroupId : user.getUserGroupIds()) {
818                                    if (userGroupId == userGroup.getUserGroupId()) {
819                                            userGroupNames.add(userGroup.getName());
820    
821                                            userGroupUser = true;
822                                    }
823                            }
824                    }
825    
826                    return userGroupUser;
827            }
828    
829            public static void mergeLayoutProtypeLayout(Group group, Layout layout)
830                    throws Exception {
831    
832                    if (!layout.isLayoutPrototypeLinkActive() ||
833                            group.isLayoutPrototype() || group.hasStagingGroup()) {
834    
835                            return;
836                    }
837    
838                    UnicodeProperties typeSettingsProperties =
839                            layout.getTypeSettingsProperties();
840    
841                    long lastMergeTime = GetterUtil.getLong(
842                            typeSettingsProperties.getProperty("last-merge-time"));
843    
844                    LayoutPrototype layoutPrototype =
845                            LayoutPrototypeLocalServiceUtil.
846                                    getLayoutPrototypeByUuidAndCompanyId(
847                                            layout.getLayoutPrototypeUuid(), layout.getCompanyId());
848    
849                    Layout layoutPrototypeLayout = layoutPrototype.getLayout();
850    
851                    Date modifiedDate = layoutPrototypeLayout.getModifiedDate();
852    
853                    if (lastMergeTime >= modifiedDate.getTime()) {
854                            return;
855                    }
856    
857                    UnicodeProperties prototypeTypeSettingsProperties =
858                            layoutPrototypeLayout.getTypeSettingsProperties();
859    
860                    int mergeFailCount = GetterUtil.getInteger(
861                            prototypeTypeSettingsProperties.getProperty("merge-fail-count"));
862    
863                    if (mergeFailCount >
864                            PropsValues.LAYOUT_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
865    
866                            if (_log.isWarnEnabled()) {
867                                    StringBundler sb = new StringBundler(6);
868    
869                                    sb.append("Merge not performed because the fail threshold ");
870                                    sb.append("was reached for layoutPrototypeId ");
871                                    sb.append(layoutPrototype.getLayoutPrototypeId());
872                                    sb.append(" and layoutId ");
873                                    sb.append(layoutPrototypeLayout.getLayoutId());
874                                    sb.append(". Update the count in the database to try again.");
875    
876                                    _log.warn(sb.toString());
877                            }
878    
879                            return;
880                    }
881    
882                    String owner = PortalUUIDUtil.generate();
883    
884                    try {
885                            Lock lock = LockLocalServiceUtil.lock(
886                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
887                                    String.valueOf(layout.getPlid()), owner, false);
888    
889                            // Double deep check
890    
891                            if (!owner.equals(lock.getOwner())) {
892                                    Date createDate = lock.getCreateDate();
893    
894                                    if ((System.currentTimeMillis() - createDate.getTime()) >=
895                                                    PropsValues.LAYOUT_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
896    
897                                            // Acquire lock if the lock is older than the lock max time
898    
899                                            lock = LockLocalServiceUtil.lock(
900                                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
901                                                    String.valueOf(layout.getPlid()), lock.getOwner(),
902                                                    owner, false);
903    
904                                            // Check if acquiring the lock succeeded or if another
905                                            // process has the lock
906    
907                                            if (!owner.equals(lock.getOwner())) {
908                                                    return;
909                                            }
910                                    }
911                                    else {
912                                            return;
913                                    }
914                            }
915                    }
916                    catch (Exception e) {
917                            return;
918                    }
919    
920                    try {
921                            SitesUtil.applyLayoutPrototype(layoutPrototype, layout, true);
922                    }
923                    catch (Exception e) {
924                            _log.error(e, e);
925    
926                            prototypeTypeSettingsProperties.setProperty(
927                                    "merge-fail-count", String.valueOf(++mergeFailCount));
928    
929                            // Invoke updateImpl so that we do not trigger the listeners
930    
931                            LayoutUtil.updateImpl(layoutPrototypeLayout);
932                    }
933                    finally {
934                            LockLocalServiceUtil.unlock(
935                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
936                                    String.valueOf(layout.getPlid()), owner, false);
937                    }
938            }
939    
940            public static void mergeLayoutSetProtypeLayouts(
941                    Group group, LayoutSet layoutSet)
942                    throws Exception {
943    
944                    if (!layoutSet.isLayoutSetPrototypeLinkActive() ||
945                            group.isLayoutPrototype() || group.isLayoutSetPrototype()) {
946    
947                            return;
948                    }
949    
950                    UnicodeProperties settingsProperties =
951                            layoutSet.getSettingsProperties();
952    
953                    long lastMergeTime = GetterUtil.getLong(
954                            settingsProperties.getProperty("last-merge-time"));
955    
956                    LayoutSetPrototype layoutSetPrototype =
957                            LayoutSetPrototypeLocalServiceUtil.
958                                    getLayoutSetPrototypeByUuidAndCompanyId(
959                                            layoutSet.getLayoutSetPrototypeUuid(),
960                                            layoutSet.getCompanyId());
961    
962                    Date modifiedDate = layoutSetPrototype.getModifiedDate();
963    
964                    if (lastMergeTime >= modifiedDate.getTime()) {
965                            return;
966                    }
967    
968                    LayoutSet layoutSetPrototypeLayoutSet =
969                            layoutSetPrototype.getLayoutSet();
970    
971                    UnicodeProperties layoutSetPrototypeSettingsProperties =
972                            layoutSetPrototypeLayoutSet.getSettingsProperties();
973    
974                    int mergeFailCount = GetterUtil.getInteger(
975                            layoutSetPrototypeSettingsProperties.getProperty(
976                                    "merge-fail-count"));
977    
978                    if (mergeFailCount >
979                            PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_FAIL_THRESHOLD) {
980    
981                            if (_log.isWarnEnabled()) {
982                                    StringBundler sb = new StringBundler(6);
983    
984                                    sb.append("Merge not performed because the fail threshold ");
985                                    sb.append("was reached for layoutSetPrototypeId ");
986                                    sb.append(layoutSetPrototype.getLayoutSetPrototypeId());
987                                    sb.append(" and layoutId ");
988                                    sb.append(layoutSetPrototypeLayoutSet.getLayoutSetId());
989                                    sb.append(". Update the count in the database to try again.");
990    
991                                    _log.warn(sb.toString());
992                            }
993    
994                            return;
995                    }
996    
997                    String owner = PortalUUIDUtil.generate();
998    
999                    try {
1000                            Lock lock = LockLocalServiceUtil.lock(
1001                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1002                                    String.valueOf(layoutSet.getLayoutSetId()), owner, false);
1003    
1004                            // Double deep check
1005    
1006                            if (!owner.equals(lock.getOwner())) {
1007                                    Date createDate = lock.getCreateDate();
1008    
1009                                    if ((System.currentTimeMillis() - createDate.getTime()) >=
1010                                            PropsValues.LAYOUT_SET_PROTOTYPE_MERGE_LOCK_MAX_TIME) {
1011    
1012                                            // Acquire lock if the lock is older than the lock max time
1013    
1014                                            lock = LockLocalServiceUtil.lock(
1015                                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1016                                                    String.valueOf(layoutSet.getLayoutSetId()),
1017                                                    lock.getOwner(), owner, false);
1018    
1019                                            // Check if acquiring the lock succeeded or if another
1020                                            // process has the lock
1021    
1022                                            if (!owner.equals(lock.getOwner())) {
1023                                                    return;
1024                                            }
1025                                    }
1026                                    else {
1027                                            return;
1028                                    }
1029                            }
1030                    }
1031                    catch (Exception e) {
1032                            return;
1033                    }
1034    
1035                    try {
1036                            boolean importData = true;
1037    
1038                            long lastResetTime = GetterUtil.getLong(
1039                                    settingsProperties.getProperty("last-reset-time"));
1040    
1041                            if ((lastMergeTime > 0) || (lastResetTime > 0)) {
1042                                    importData = false;
1043                            }
1044    
1045                            Map<String, String[]> parameterMap =
1046                                    getLayoutSetPrototypesParameters(importData);
1047    
1048                            importLayoutSetPrototype(
1049                                    layoutSetPrototype, layoutSet.getGroupId(),
1050                                    layoutSet.isPrivateLayout(), parameterMap, importData);
1051    
1052                            layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1053                                    layoutSet.getGroupId(), layoutSet.isPrivateLayout());
1054    
1055                            settingsProperties = layoutSet.getSettingsProperties();
1056    
1057                            settingsProperties.setProperty(
1058                                    "last-merge-time", String.valueOf(System.currentTimeMillis()));
1059    
1060                            LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1061                    }
1062                    catch (Exception e) {
1063                            _log.error(e, e);
1064    
1065                            layoutSetPrototypeSettingsProperties.setProperty(
1066                                    "merge-fail-count", String.valueOf(++mergeFailCount));
1067    
1068                            // Invoke updateImpl so that we do not trigger the listeners
1069    
1070                            LayoutSetUtil.updateImpl(layoutSetPrototypeLayoutSet);
1071                    }
1072                    finally {
1073                            LockLocalServiceUtil.unlock(
1074                                    LayoutLocalServiceVirtualLayoutsAdvice.class.getName(),
1075                                    String.valueOf(layoutSet.getLayoutSetId()), owner, false);
1076                    }
1077            }
1078    
1079            public static void resetPrototype(Layout layout)
1080                    throws PortalException, SystemException {
1081    
1082                    layout.setModifiedDate(null);
1083    
1084                    LayoutLocalServiceUtil.updateLayout(layout);
1085    
1086                    LayoutSet layoutSet = layout.getLayoutSet();
1087                    UnicodeProperties settingsProperties =
1088                            layoutSet.getSettingsProperties();
1089    
1090                    settingsProperties.remove("last-merge-time");
1091    
1092                    settingsProperties.setProperty(
1093                            "last-reset-time", String.valueOf(System.currentTimeMillis()));
1094    
1095                    LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
1096            }
1097    
1098            public static void updateLayoutScopes(
1099                            long userId, Layout sourceLayout, Layout targetLayout,
1100                            PortletPreferences sourcePreferences,
1101                            PortletPreferences targetPreferences, String sourcePortletId,
1102                            String languageId)
1103                    throws Exception {
1104    
1105                    String scopeType = GetterUtil.getString(
1106                            sourcePreferences.getValue("lfrScopeType", null));
1107    
1108                    if (Validator.isNull(scopeType) || !scopeType.equals("layout")) {
1109                            return;
1110                    }
1111    
1112                    Layout targetScopeLayout =
1113                            LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1114                                    targetLayout.getUuid(), targetLayout.getGroupId());
1115    
1116                    if (!targetScopeLayout.hasScopeGroup()) {
1117                            GroupLocalServiceUtil.addGroup(
1118                                    userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
1119                                    Layout.class.getName(), targetLayout.getPlid(),
1120                                    GroupConstants.DEFAULT_LIVE_GROUP_ID,
1121                                    targetLayout.getName(languageId), null, 0, null, false, true,
1122                                    null);
1123                    }
1124    
1125                    String portletTitle = PortalUtil.getPortletTitle(
1126                            sourcePortletId, languageId);
1127    
1128                    String newPortletTitle = PortalUtil.getNewPortletTitle(
1129                            portletTitle, String.valueOf(sourceLayout.getLayoutId()),
1130                            targetLayout.getName(languageId));
1131    
1132                    targetPreferences.setValue(
1133                            "groupId", String.valueOf(targetLayout.getGroupId()));
1134                    targetPreferences.setValue("lfrScopeType", "layout");
1135                    targetPreferences.setValue(
1136                            "lfrScopeLayoutUuid", targetLayout.getUuid());
1137                    targetPreferences.setValue(
1138                            "portletSetupTitle_" + languageId, newPortletTitle);
1139                    targetPreferences.setValue(
1140                            "portletSetupUseCustomTitle", Boolean.TRUE.toString());
1141    
1142                    targetPreferences.store();
1143            }
1144    
1145            public static void updateLayoutSetPrototypesLinks(
1146                            Group group, long publicLayoutSetPrototypeId,
1147                            long privateLayoutSetPrototypeId,
1148                            boolean publicLayoutSetPrototypeLinkEnabled,
1149                            boolean privateLayoutSetPrototypeLinkEnabled)
1150                    throws Exception {
1151    
1152                    updateLayoutSetPrototypeLink(
1153                            group.getGroupId(), true, privateLayoutSetPrototypeId,
1154                            privateLayoutSetPrototypeLinkEnabled);
1155                    updateLayoutSetPrototypeLink(
1156                            group.getGroupId(), false, publicLayoutSetPrototypeId,
1157                            publicLayoutSetPrototypeLinkEnabled);
1158            }
1159    
1160            protected static Map<String, String[]> getLayoutSetPrototypesParameters(
1161                    boolean importData) {
1162    
1163                    Map<String, String[]> parameterMap =
1164                            new LinkedHashMap<String, String[]>();
1165    
1166                    parameterMap.put(
1167                            PortletDataHandlerKeys.CATEGORIES,
1168                            new String[] {Boolean.TRUE.toString()});
1169                    parameterMap.put(
1170                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1171                            new String[] {Boolean.FALSE.toString()});
1172                    parameterMap.put(
1173                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1174                            new String[] {Boolean.FALSE.toString()});
1175                    parameterMap.put(
1176                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1177                            new String[] {Boolean.TRUE.toString()});
1178                    parameterMap.put(
1179                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1180                            new String[] {Boolean.TRUE.toString()});
1181                    parameterMap.put(
1182                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1183                            new String[] {Boolean.TRUE.toString()});
1184                    parameterMap.put(
1185                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
1186                            new String[] {
1187                                    PortletDataHandlerKeys.
1188                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
1189                            });
1190                    parameterMap.put(
1191                            PortletDataHandlerKeys.LOGO,
1192                            new String[] {Boolean.TRUE.toString()});
1193                    parameterMap.put(
1194                            PortletDataHandlerKeys.PERMISSIONS,
1195                            new String[] {Boolean.TRUE.toString()});
1196                    parameterMap.put(
1197                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS,
1198                            new String[] {Boolean.TRUE.toString()});
1199                    parameterMap.put(
1200                            PortletDataHandlerKeys.PORTLET_SETUP,
1201                            new String[] {Boolean.TRUE.toString()});
1202                    parameterMap.put(
1203                            PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1204                            new String[] {Boolean.TRUE.toString()});
1205                    parameterMap.put(
1206                            PortletDataHandlerKeys.THEME,
1207                            new String[] {Boolean.FALSE.toString()});
1208                    parameterMap.put(
1209                            PortletDataHandlerKeys.THEME_REFERENCE,
1210                            new String[] {Boolean.TRUE.toString()});
1211                    parameterMap.put(
1212                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1213                            new String[] {Boolean.FALSE.toString()});
1214                    parameterMap.put(
1215                            PortletDataHandlerKeys.USER_ID_STRATEGY,
1216                            new String[] {UserIdStrategy.CURRENT_USER_ID});
1217    
1218                    if (importData) {
1219                            parameterMap.put(
1220                                    PortletDataHandlerKeys.DATA_STRATEGY,
1221                                    new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
1222                            parameterMap.put(
1223                                    PortletDataHandlerKeys.PORTLET_DATA,
1224                                    new String[] {Boolean.TRUE.toString()});
1225                            parameterMap.put(
1226                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
1227                                    new String[] {Boolean.TRUE.toString()});
1228                    }
1229                    else {
1230                            parameterMap.put(
1231                                    PortletDataHandlerKeys.PORTLET_DATA,
1232                                    new String[] {Boolean.FALSE.toString()});
1233                            parameterMap.put(
1234                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
1235                                    new String[] {Boolean.FALSE.toString()});
1236                    }
1237    
1238                    return parameterMap;
1239            }
1240    
1241            protected static void importLayoutSetPrototype(
1242                            LayoutSetPrototype layoutSetPrototype, long groupId,
1243                            boolean privateLayout, Map<String, String[]> parameterMap,
1244                            boolean importData)
1245                    throws PortalException, SystemException {
1246    
1247                    File file = null;
1248    
1249                    StringBundler sb = new StringBundler(importData ? 4 : 3);
1250    
1251                    sb.append(_TEMP_DIR);
1252                    sb.append(layoutSetPrototype.getUuid());
1253    
1254                    if (importData) {
1255                            sb.append("-data");
1256                    }
1257    
1258                    sb.append(".lar");
1259    
1260                    File cacheFile = new File(sb.toString());
1261    
1262                    if (cacheFile.exists()) {
1263                            Date modifiedDate = layoutSetPrototype.getModifiedDate();
1264    
1265                            if (cacheFile.lastModified() >= modifiedDate.getTime()) {
1266                                    if (_log.isDebugEnabled()) {
1267                                            _log.debug(
1268                                                    "Using cached layout set prototype LAR file " +
1269                                                            cacheFile.getAbsolutePath());
1270                                    }
1271    
1272                                    file = cacheFile;
1273                            }
1274                    }
1275    
1276                    boolean newFile = false;
1277    
1278                    if (file == null) {
1279                            Group layoutSetPrototypeGroup = layoutSetPrototype.getGroup();
1280    
1281                            file = LayoutLocalServiceUtil.exportLayoutsAsFile(
1282                                    layoutSetPrototypeGroup.getGroupId(), true, null, parameterMap,
1283                                    null, null);
1284    
1285                            newFile = true;
1286                    }
1287    
1288                    long userId = UserLocalServiceUtil.getDefaultUserId(
1289                            layoutSetPrototype.getCompanyId());
1290    
1291                    LayoutLocalServiceUtil.importLayouts(
1292                            userId, groupId, privateLayout, parameterMap, file);
1293    
1294                    if (newFile) {
1295                            try {
1296                                    FileUtil.copyFile(file, cacheFile);
1297    
1298                                    if (_log.isDebugEnabled()) {
1299                                            _log.debug(
1300                                                    "Copied " + file.getAbsolutePath() + " to " +
1301                                                            cacheFile.getAbsolutePath());
1302                                    }
1303                            }
1304                            catch (Exception e) {
1305                                    _log.error(
1306                                            "Unable to copy file " + file.getAbsolutePath() + " to " +
1307                                                    cacheFile.getAbsolutePath(),
1308                                            e);
1309                            }
1310                    }
1311            }
1312    
1313            protected static void setLayoutSetPrototypeLinkEnabledParameter(
1314                    Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
1315                    ServiceContext serviceContext) {
1316    
1317                    PermissionChecker permissionChecker =
1318                            PermissionThreadLocal.getPermissionChecker();
1319    
1320                    if ((permissionChecker == null) ||
1321                            !PortalPermissionUtil.contains(
1322                                    permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
1323    
1324                            return;
1325                    }
1326    
1327                    if (targetLayoutSet.isPrivateLayout()) {
1328                            boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1329                                    serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
1330    
1331                            if (!privateLayoutSetPrototypeLinkEnabled) {
1332                                    privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1333                                            serviceContext, "layoutSetPrototypeLinkEnabled");
1334                            }
1335    
1336                            parameterMap.put(
1337                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1338                                    new String[] {
1339                                            String.valueOf(privateLayoutSetPrototypeLinkEnabled)
1340                                    });
1341                    }
1342                    else {
1343                            boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1344                                    serviceContext, "publicLayoutSetPrototypeLinkEnabled");
1345    
1346                            if (!publicLayoutSetPrototypeLinkEnabled) {
1347                                    publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
1348                                            serviceContext, "layoutSetPrototypeLinkEnabled", true);
1349                            }
1350    
1351                            parameterMap.put(
1352                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1353                                    new String[] {
1354                                            String.valueOf(publicLayoutSetPrototypeLinkEnabled)
1355                                    });
1356                    }
1357            }
1358    
1359            protected static void updateLayoutSetPrototypeLink(
1360                            long groupId, boolean privateLayout, long layoutSetPrototypeId,
1361                            boolean layoutSetPrototypeLinkEnabled)
1362                    throws Exception {
1363    
1364                    String layoutSetPrototypeUuid = null;
1365    
1366                    if (layoutSetPrototypeId > 0) {
1367                            LayoutSetPrototype layoutSetPrototype =
1368                                    LayoutSetPrototypeLocalServiceUtil.fetchLayoutSetPrototype(
1369                                            layoutSetPrototypeId);
1370    
1371                            if (layoutSetPrototype != null) {
1372                                    layoutSetPrototypeUuid = layoutSetPrototype.getUuid();
1373    
1374                                    // Merge without enabling the link
1375    
1376                                    if (!layoutSetPrototypeLinkEnabled &&
1377                                            (layoutSetPrototypeId > 0)) {
1378    
1379                                            Map<String, String[]> parameterMap =
1380                                                    getLayoutSetPrototypesParameters(true);
1381    
1382                                            importLayoutSetPrototype(
1383                                                    layoutSetPrototype, groupId, privateLayout,
1384                                                    parameterMap, true);
1385                                    }
1386                            }
1387                    }
1388    
1389                    LayoutSetServiceUtil.updateLayoutSetPrototypeLinkEnabled(
1390                            groupId, privateLayout, layoutSetPrototypeLinkEnabled,
1391                            layoutSetPrototypeUuid);
1392    
1393                    LayoutLocalServiceUtil.updatePriorities(groupId, privateLayout);
1394            }
1395    
1396            private static final String _TEMP_DIR =
1397                    SystemProperties.get(SystemProperties.TMP_DIR) +
1398                            "/liferay/layout_set_prototype/";
1399    
1400            private static Log _log = LogFactoryUtil.getLog(SitesUtil.class);
1401    
1402    }