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