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