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.events.EventsProcessorUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.language.LanguageUtil;
021    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
022    import com.liferay.portal.kernel.lar.UserIdStrategy;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.util.ParamUtil;
027    import com.liferay.portal.kernel.util.PropsKeys;
028    import com.liferay.portal.kernel.util.UnicodeProperties;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.model.Group;
031    import com.liferay.portal.model.Layout;
032    import com.liferay.portal.model.LayoutConstants;
033    import com.liferay.portal.model.LayoutPrototype;
034    import com.liferay.portal.model.LayoutSet;
035    import com.liferay.portal.model.LayoutSetPrototype;
036    import com.liferay.portal.model.LayoutTypePortlet;
037    import com.liferay.portal.model.PortletConstants;
038    import com.liferay.portal.model.ResourceConstants;
039    import com.liferay.portal.model.Role;
040    import com.liferay.portal.model.RoleConstants;
041    import com.liferay.portal.model.UserGroup;
042    import com.liferay.portal.model.impl.LayoutTypePortletImpl;
043    import com.liferay.portal.model.impl.VirtualLayout;
044    import com.liferay.portal.security.auth.PrincipalException;
045    import com.liferay.portal.security.permission.ActionKeys;
046    import com.liferay.portal.security.permission.PermissionChecker;
047    import com.liferay.portal.security.permission.PermissionThreadLocal;
048    import com.liferay.portal.security.permission.ResourceActionsUtil;
049    import com.liferay.portal.service.GroupServiceUtil;
050    import com.liferay.portal.service.LayoutLocalServiceUtil;
051    import com.liferay.portal.service.LayoutServiceUtil;
052    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
053    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
054    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
055    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
056    import com.liferay.portal.service.RoleLocalServiceUtil;
057    import com.liferay.portal.service.ServiceContext;
058    import com.liferay.portal.service.ServiceContextFactory;
059    import com.liferay.portal.service.ServiceContextThreadLocal;
060    import com.liferay.portal.service.UserGroupLocalServiceUtil;
061    import com.liferay.portal.service.UserLocalServiceUtil;
062    import com.liferay.portal.service.permission.GroupPermissionUtil;
063    import com.liferay.portal.service.permission.LayoutPermissionUtil;
064    import com.liferay.portal.service.permission.PortalPermissionUtil;
065    import com.liferay.portal.service.permission.PortletPermissionUtil;
066    import com.liferay.portal.theme.PortletDisplay;
067    import com.liferay.portal.theme.ThemeDisplay;
068    import com.liferay.portal.util.LayoutSettings;
069    import com.liferay.portal.util.PortalUtil;
070    import com.liferay.portal.util.PortletKeys;
071    import com.liferay.portal.util.WebKeys;
072    import com.liferay.portlet.PortletPreferencesFactoryUtil;
073    import com.liferay.portlet.PortletPreferencesImpl;
074    
075    import java.io.File;
076    import java.io.InputStream;
077    
078    import java.util.Date;
079    import java.util.LinkedHashMap;
080    import java.util.List;
081    import java.util.Locale;
082    import java.util.Map;
083    
084    import javax.portlet.ActionRequest;
085    import javax.portlet.ActionResponse;
086    import javax.portlet.PortletPreferences;
087    import javax.portlet.PortletURL;
088    import javax.portlet.RenderRequest;
089    import javax.portlet.RenderResponse;
090    
091    import javax.servlet.http.HttpServletRequest;
092    import javax.servlet.http.HttpServletResponse;
093    
094    /**
095     * @author Raymond Augé
096     * @author Ryan Park
097     * @author Zsolt Berentey
098     */
099    public class SitesUtil {
100    
101            public static void addPortletBreadcrumbEntries(
102                            Group group, String pagesName, PortletURL redirectURL,
103                            HttpServletRequest request, RenderResponse renderResponse)
104                    throws Exception {
105    
106                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
107                            com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
108    
109                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
110    
111                    String portletName = portletDisplay.getPortletName();
112    
113                    if ((renderResponse == null) ||
114                            portletName.equals(PortletKeys.GROUP_PAGES) ||
115                            portletName.equals(PortletKeys.MY_PAGES)) {
116    
117                            return;
118                    }
119    
120                    Locale locale = themeDisplay.getLocale();
121    
122                    if (group.isLayoutPrototype()) {
123                            PortalUtil.addPortletBreadcrumbEntry(
124                                    request, LanguageUtil.get(locale, "page-template"), null);
125    
126                            PortalUtil.addPortletBreadcrumbEntry(
127                                    request, group.getDescriptiveName(), redirectURL.toString());
128                    }
129                    else {
130                            PortalUtil.addPortletBreadcrumbEntry(
131                                    request, group.getDescriptiveName(), null);
132                    }
133    
134                    if (!group.isLayoutPrototype()) {
135                            PortalUtil.addPortletBreadcrumbEntry(
136                                    request, LanguageUtil.get(locale, pagesName),
137                                    redirectURL.toString());
138                    }
139            }
140    
141            public static void applyLayoutPrototype(
142                            LayoutPrototype layoutPrototype, Layout targetLayout,
143                            boolean linkEnabled)
144                    throws Exception {
145    
146                    Layout layoutPrototypeLayout = layoutPrototype.getLayout();
147    
148                    ServiceContext serviceContext =
149                            ServiceContextThreadLocal.getServiceContext();
150    
151                    serviceContext.setAttribute("layoutPrototypeLinkEnabled", linkEnabled);
152                    serviceContext.setAttribute(
153                            "layoutPrototypeUuid", layoutPrototype.getUuid());
154    
155                    targetLayout = LayoutLocalServiceUtil.updateLayout(
156                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
157                            targetLayout.getLayoutId(),
158                            targetLayout.getParentLayoutId(), targetLayout.getNameMap(),
159                            targetLayout.getTitleMap(), targetLayout.getDescriptionMap(),
160                            targetLayout.getKeywordsMap(), targetLayout.getRobotsMap(),
161                            layoutPrototypeLayout.getType(), targetLayout.getHidden(),
162                            targetLayout.getFriendlyURL(), targetLayout.getIconImage(), null,
163                            serviceContext);
164    
165                    targetLayout = LayoutLocalServiceUtil.updateLayout(
166                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
167                            targetLayout.getLayoutId(),
168                            layoutPrototypeLayout.getTypeSettings());
169    
170                    copyLayoutPrototypePermissions(targetLayout, layoutPrototype);
171    
172                    copyPortletPermissions(targetLayout, layoutPrototypeLayout);
173    
174                    copyPortletSetups(layoutPrototypeLayout, targetLayout);
175    
176                    copyLookAndFeel(targetLayout, layoutPrototypeLayout);
177    
178                    targetLayout = LayoutLocalServiceUtil.getLayout(targetLayout.getPlid());
179    
180                    UnicodeProperties typeSettingsProperties =
181                            targetLayout.getTypeSettingsProperties();
182    
183                    typeSettingsProperties.setProperty(
184                            "last-merge-time",
185                            String.valueOf(targetLayout.getModifiedDate().getTime()));
186    
187                    LayoutLocalServiceUtil.updateLayout(targetLayout, false);
188    
189                    UnicodeProperties prototypeTypeSettingsProperties =
190                            layoutPrototypeLayout.getTypeSettingsProperties();
191    
192                    prototypeTypeSettingsProperties.setProperty("merge-fail-count", "0");
193    
194                    LayoutLocalServiceUtil.updateLayout(layoutPrototypeLayout, false);
195            }
196    
197            public static void applyLayoutSetPrototypes(
198                            Group group, long publicLayoutSetPrototypeId,
199                            long privateLayoutSetPrototypeId, ServiceContext serviceContext)
200                    throws Exception {
201    
202                    Group sourceGroup = null;
203    
204                    if (publicLayoutSetPrototypeId > 0) {
205                            LayoutSetPrototype layoutSetPrototype =
206                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
207                                            publicLayoutSetPrototypeId);
208    
209                            LayoutSet publicLayoutSet = group.getPublicLayoutSet();
210    
211                            copyLayoutSet(
212                                    layoutSetPrototype.getLayoutSet(), publicLayoutSet,
213                                    serviceContext);
214    
215                            sourceGroup = layoutSetPrototype.getGroup();
216                    }
217    
218                    if (privateLayoutSetPrototypeId > 0) {
219                            LayoutSetPrototype layoutSetPrototype =
220                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
221                                            privateLayoutSetPrototypeId);
222    
223                            LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
224    
225                            copyLayoutSet(
226                                    layoutSetPrototype.getLayoutSet(), privateLayoutSet,
227                                    serviceContext);
228    
229                            if (sourceGroup == null) {
230                                    sourceGroup = layoutSetPrototype.getGroup();
231                            }
232                    }
233    
234                    if (sourceGroup != null) {
235                            copyTypeSettings(sourceGroup, group);
236                    }
237            }
238    
239            public static void copyLayout(
240                            long userId, Layout sourceLayout, Layout targetLayout,
241                            ServiceContext serviceContext)
242                    throws Exception {
243    
244                    Map<String, String[]> parameterMap =
245                            getLayoutSetPrototypeParameters(serviceContext);
246    
247                    parameterMap.put(
248                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
249                            new String[] {Boolean.FALSE.toString()});
250    
251                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
252                            sourceLayout.getGroupId(), sourceLayout.isPrivateLayout(),
253                            new long[] {sourceLayout.getLayoutId()}, parameterMap, null, null);
254    
255                    try {
256                            LayoutLocalServiceUtil.importLayouts(
257                                    userId, targetLayout.getGroupId(),
258                                    targetLayout.isPrivateLayout(), parameterMap, file);
259                    }
260                    finally {
261                            file.delete();
262                    }
263            }
264    
265            public static void copyLayoutSet(
266                            LayoutSet sourceLayoutSet, LayoutSet targetLayoutSet,
267                            ServiceContext serviceContext)
268                    throws Exception {
269    
270                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
271                            serviceContext);
272    
273                    setLayoutSetPrototypeLinkEnabledParameter(
274                            parameterMap, targetLayoutSet, serviceContext);
275    
276                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
277                            sourceLayoutSet.getGroupId(), sourceLayoutSet.isPrivateLayout(),
278                            null, parameterMap, null, null);
279    
280                    try {
281                            LayoutServiceUtil.importLayouts(
282                                    targetLayoutSet.getGroupId(), targetLayoutSet.isPrivateLayout(),
283                                    parameterMap, file);
284                    }
285                    finally {
286                            file.delete();
287                    }
288            }
289    
290            public static void copyLookAndFeel(Layout targetLayout, Layout sourceLayout)
291                    throws Exception {
292    
293                    LayoutLocalServiceUtil.updateLookAndFeel(
294                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
295                            targetLayout.getLayoutId(), sourceLayout.getThemeId(),
296                            sourceLayout.getColorSchemeId(), sourceLayout.getCss(), false);
297    
298                    LayoutLocalServiceUtil.updateLookAndFeel(
299                            targetLayout.getGroupId(), targetLayout.isPrivateLayout(),
300                            targetLayout.getLayoutId(), sourceLayout.getWapThemeId(),
301                            sourceLayout.getWapColorSchemeId(), sourceLayout.getCss(), true);
302            }
303    
304            public static void copyPortletPermissions(
305                    Layout targetLayout, Layout sourceLayout)
306                    throws Exception {
307    
308                    long companyId = targetLayout.getCompanyId();
309    
310                    List<Role> roles = RoleLocalServiceUtil.getRoles(companyId);
311    
312                    LayoutTypePortlet sourceLayoutTypePortlet =
313                            (LayoutTypePortlet)sourceLayout.getLayoutType();
314    
315                    List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
316    
317                    for (String sourcePortletId : sourcePortletIds) {
318                            String resourceName = PortletConstants.getRootPortletId(
319                                    sourcePortletId);
320    
321                            String sourceResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
322                                    sourceLayout.getPlid(), sourcePortletId);
323    
324                            String targetResourcePrimKey = PortletPermissionUtil.getPrimaryKey(
325                                    targetLayout.getPlid(), sourcePortletId);
326    
327                            List<String> actionIds =
328                                    ResourceActionsUtil.getPortletResourceActions(resourceName);
329    
330                            for (Role role : roles) {
331                                    String roleName = role.getName();
332    
333                                    if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
334                                            continue;
335                                    }
336    
337                                    List<String> actions =
338                                            ResourcePermissionLocalServiceUtil.
339                                                    getAvailableResourcePermissionActionIds(
340                                                            companyId, resourceName,
341                                                            ResourceConstants.SCOPE_INDIVIDUAL,
342                                                            sourceResourcePrimKey, role.getRoleId(), actionIds);
343    
344                                    ResourcePermissionLocalServiceUtil.setResourcePermissions(
345                                            companyId, resourceName, ResourceConstants.SCOPE_INDIVIDUAL,
346                                            targetResourcePrimKey, role.getRoleId(),
347                                            actions.toArray(new String[actions.size()]));
348                            }
349                    }
350            }
351    
352            public static void copyPortletSetups(
353                            Layout sourceLayout, Layout targetLayout)
354                    throws Exception {
355    
356                    LayoutTypePortlet sourceLayoutTypePortlet =
357                            (LayoutTypePortlet)sourceLayout.getLayoutType();
358    
359                    List<String> sourcePortletIds = sourceLayoutTypePortlet.getPortletIds();
360    
361                    for (String sourcePortletId : sourcePortletIds) {
362                            PortletPreferences sourcePreferences =
363                                    PortletPreferencesFactoryUtil.getPortletSetup(
364                                            sourceLayout, sourcePortletId, null);
365    
366                            PortletPreferencesImpl sourcePreferencesImpl =
367                                    (PortletPreferencesImpl)sourcePreferences;
368    
369                            PortletPreferences targetPreferences =
370                                    PortletPreferencesFactoryUtil.getPortletSetup(
371                                            targetLayout, sourcePortletId, null);
372    
373                            PortletPreferencesImpl targetPreferencesImpl =
374                                    (PortletPreferencesImpl)targetPreferences;
375    
376                            PortletPreferencesLocalServiceUtil.updatePreferences(
377                                    targetPreferencesImpl.getOwnerId(),
378                                    targetPreferencesImpl.getOwnerType(),
379                                    targetPreferencesImpl.getPlid(), sourcePortletId,
380                                    sourcePreferences);
381    
382                            if ((sourcePreferencesImpl.getOwnerId() !=
383                                            PortletKeys.PREFS_OWNER_ID_DEFAULT) &&
384                                    (sourcePreferencesImpl.getOwnerType() !=
385                                            PortletKeys.PREFS_OWNER_TYPE_LAYOUT)) {
386    
387                                    sourcePreferences =
388                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
389                                                    sourceLayout, sourcePortletId);
390    
391                                    sourcePreferencesImpl =
392                                            (PortletPreferencesImpl)sourcePreferences;
393    
394                                    targetPreferences =
395                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
396                                                    targetLayout, sourcePortletId);
397    
398                                    targetPreferencesImpl =
399                                            (PortletPreferencesImpl)targetPreferences;
400    
401                                    PortletPreferencesLocalServiceUtil.updatePreferences(
402                                            targetPreferencesImpl.getOwnerId(),
403                                            targetPreferencesImpl.getOwnerType(),
404                                            targetPreferencesImpl.getPlid(), sourcePortletId,
405                                            sourcePreferences);
406                            }
407                    }
408            }
409    
410            public static void copyTypeSettings(Group sourceGroup, Group targetGroup)
411                    throws Exception {
412    
413                    GroupServiceUtil.updateGroup(
414                            targetGroup.getGroupId(), sourceGroup.getTypeSettings());
415            }
416    
417            public static Object[] deleteLayout(
418                            ActionRequest actionRequest, ActionResponse actionResponse)
419                    throws Exception {
420    
421                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
422                            actionRequest);
423                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
424                            actionResponse);
425    
426                    return deleteLayout(request, response);
427            }
428    
429            public static Object[] deleteLayout(
430                            HttpServletRequest request, HttpServletResponse response)
431                    throws Exception {
432    
433                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
434                            WebKeys.THEME_DISPLAY);
435    
436                    PermissionChecker permissionChecker =
437                            themeDisplay.getPermissionChecker();
438    
439                    long plid = ParamUtil.getLong(request, "plid");
440    
441                    long groupId = ParamUtil.getLong(request, "groupId");
442                    boolean privateLayout = ParamUtil.getBoolean(request, "privateLayout");
443                    long layoutId = ParamUtil.getLong(request, "layoutId");
444    
445                    Layout layout = null;
446    
447                    if (plid <= 0) {
448                            layout = LayoutLocalServiceUtil.getLayout(
449                                    groupId, privateLayout, layoutId);
450                    }
451                    else {
452                            layout = LayoutLocalServiceUtil.getLayout(plid);
453    
454                            groupId = layout.getGroupId();
455                            privateLayout = layout.isPrivateLayout();
456                            layoutId = layout.getLayoutId();
457                    }
458    
459                    Group group = layout.getGroup();
460                    String oldFriendlyURL = layout.getFriendlyURL();
461    
462                    if (group.isStagingGroup() &&
463                            !GroupPermissionUtil.contains(
464                                    permissionChecker, groupId, ActionKeys.MANAGE_STAGING) &&
465                            !GroupPermissionUtil.contains(
466                                    permissionChecker, groupId, ActionKeys.PUBLISH_STAGING)) {
467    
468                            throw new PrincipalException();
469                    }
470    
471                    if (LayoutPermissionUtil.contains(
472                                    permissionChecker, layout, ActionKeys.DELETE)) {
473    
474                            LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
475    
476                            EventsProcessorUtil.process(
477                                    PropsKeys.LAYOUT_CONFIGURATION_ACTION_DELETE,
478                                    layoutSettings.getConfigurationActionDelete(), request,
479                                    response);
480                    }
481    
482                    LayoutSet layoutSet = layout.getLayoutSet();
483    
484                    Group layoutSetGroup = layoutSet.getGroup();
485    
486                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
487                            request);
488    
489                    if (layoutSetGroup.isLayoutSetPrototype()) {
490                            LayoutSetPrototype layoutSetPrototype =
491                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
492                                            layoutSetGroup.getClassPK());
493    
494                            List<LayoutSet> linkedLayoutSets =
495                                    LayoutSetLocalServiceUtil.getLayoutSetsByLayoutSetPrototypeUuid(
496                                            layoutSetPrototype.getUuid());
497    
498                            for (LayoutSet linkedLayoutSet : linkedLayoutSets) {
499                                    Layout linkedLayout =
500                                            LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
501                                                    layout.getUuid(), linkedLayoutSet.getGroupId());
502    
503                                    if ((linkedLayout != null) &&
504                                            (!isLayoutUpdateable(linkedLayout) ||
505                                             isLayoutToBeUpdatedFromSourcePrototype(linkedLayout))) {
506    
507                                            LayoutServiceUtil.deleteLayout(
508                                                    linkedLayout.getPlid(), serviceContext);
509                                    }
510                            }
511                    }
512    
513                    LayoutServiceUtil.deleteLayout(
514                            groupId, privateLayout, layoutId, serviceContext);
515    
516                    long newPlid = layout.getParentPlid();
517    
518                    if (newPlid <= 0) {
519                            Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
520                                    layoutSet.getGroupId(), layoutSet.getPrivateLayout(),
521                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
522    
523                            if (firstLayout != null) {
524                                    newPlid = firstLayout.getPlid();
525                            }
526                    }
527    
528                    return new Object[] {group, oldFriendlyURL, newPlid};
529            }
530    
531            public static void deleteLayout(
532                            RenderRequest renderRequest, RenderResponse renderResponse)
533                    throws Exception {
534    
535                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
536                            renderRequest);
537                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
538                            renderResponse);
539    
540                    deleteLayout(request, response);
541            }
542    
543            public static File exportLayoutSetPrototype(
544                            LayoutSetPrototype layoutSetPrototype,
545                            ServiceContext serviceContext)
546                    throws PortalException, SystemException {
547    
548                    LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
549    
550                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
551                            serviceContext);
552    
553                    return LayoutLocalServiceUtil.exportLayoutsAsFile(
554                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
555                            null, parameterMap, null, null);
556            }
557    
558            public static Map<String, String[]> getLayoutSetPrototypeParameters(
559                    ServiceContext serviceContext) {
560    
561                    Map<String, String[]> parameterMap =
562                            new LinkedHashMap<String, String[]>();
563    
564                    parameterMap.put(
565                            PortletDataHandlerKeys.CATEGORIES,
566                            new String[] {Boolean.TRUE.toString()});
567                    parameterMap.put(
568                            PortletDataHandlerKeys.DATA_STRATEGY,
569                            new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
570                    parameterMap.put(
571                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
572                            new String[] {Boolean.TRUE.toString()});
573                    parameterMap.put(
574                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
575                            new String[] {Boolean.FALSE.toString()});
576                    parameterMap.put(
577                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
578                            new String[] {Boolean.TRUE.toString()});
579                    parameterMap.put(
580                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
581                            new String[] {
582                                    PortletDataHandlerKeys.
583                                            LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE
584                            });
585                    parameterMap.put(
586                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
587                            new String[] {Boolean.TRUE.toString()});
588                    parameterMap.put(
589                            PortletDataHandlerKeys.PERMISSIONS,
590                            new String[] {Boolean.TRUE.toString()});
591                    parameterMap.put(
592                            PortletDataHandlerKeys.PORTLET_DATA,
593                            new String[] {Boolean.TRUE.toString()});
594                    parameterMap.put(
595                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
596                            new String[] {Boolean.TRUE.toString()});
597                    parameterMap.put(
598                            PortletDataHandlerKeys.PORTLET_SETUP,
599                            new String[] {Boolean.TRUE.toString()});
600                    parameterMap.put(
601                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
602                            new String[] {Boolean.TRUE.toString()});
603                    parameterMap.put(
604                            PortletDataHandlerKeys.THEME,
605                            new String[] {Boolean.FALSE.toString()});
606                    parameterMap.put(
607                            PortletDataHandlerKeys.THEME_REFERENCE,
608                            new String[] {Boolean.TRUE.toString()});
609                    parameterMap.put(
610                            PortletDataHandlerKeys.USER_ID_STRATEGY,
611                            new String[] {UserIdStrategy.CURRENT_USER_ID});
612                    parameterMap.put(
613                            PortletDataHandlerKeys.USER_PERMISSIONS,
614                            new String[] {Boolean.FALSE.toString()});
615    
616                    return parameterMap;
617            }
618    
619            public static void importLayoutSetPrototype(
620                            LayoutSetPrototype layoutSetPrototype, InputStream inputStream,
621                            ServiceContext serviceContext)
622                    throws PortalException, SystemException {
623    
624                    LayoutSet layoutSet = layoutSetPrototype.getLayoutSet();
625    
626                    Map<String, String[]> parameterMap = getLayoutSetPrototypeParameters(
627                            serviceContext);
628    
629                    setLayoutSetPrototypeLinkEnabledParameter(
630                            parameterMap, layoutSet, serviceContext);
631    
632                    LayoutServiceUtil.importLayouts(
633                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
634                            parameterMap, inputStream);
635            }
636    
637            public static boolean isLayoutModifiedSinceLastMerge(Layout layout)
638                    throws PortalException, SystemException {
639    
640                    if ((layout == null) ||
641                            Validator.isNull(layout.getSourcePrototypeLayoutUuid()) ||
642                            layout.isLayoutPrototypeLinkActive()) {
643    
644                            return false;
645                    }
646    
647                    LayoutSet existingLayoutSet = layout.getLayoutSet();
648    
649                    long lastMergeTime = GetterUtil.getLong(
650                            existingLayoutSet.getSettingsProperty("last-merge-time"));
651    
652                    Date existingLayoutModifiedDate = layout.getModifiedDate();
653    
654                    if ((existingLayoutModifiedDate != null) &&
655                            (existingLayoutModifiedDate.getTime() > lastMergeTime) &&
656                            isLayoutUpdateable(layout)) {
657    
658                            return true;
659                    }
660    
661                    return false;
662            }
663    
664            public static boolean isLayoutSetPrototypeUpdateable(LayoutSet layoutSet) {
665                    if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
666                            return true;
667                    }
668    
669                    try {
670                            LayoutSetPrototype layoutSetPrototype =
671                                    LayoutSetPrototypeLocalServiceUtil.
672                                            getLayoutSetPrototypeByUuid(
673                                                    layoutSet.getLayoutSetPrototypeUuid());
674    
675                            String layoutsUpdateable = layoutSetPrototype.getSettingsProperty(
676                                    "layoutsUpdateable");
677    
678                            if (Validator.isNotNull(layoutsUpdateable)) {
679                                    return GetterUtil.getBoolean(layoutsUpdateable, true);
680                            }
681                    }
682                    catch (Exception e) {
683                            if (_log.isDebugEnabled()) {
684                                    _log.debug(e, e);
685                            }
686                    }
687    
688                    return true;
689            }
690    
691            public static boolean isLayoutToBeUpdatedFromSourcePrototype(Layout layout)
692                    throws Exception {
693    
694                    if (layout == null) {
695                            return false;
696                    }
697    
698                    LayoutSet layoutSet = layout.getLayoutSet();
699    
700                    if (!layoutSet.isLayoutSetPrototypeLinkActive()) {
701                            return false;
702                    }
703    
704                    Layout sourcePrototypeLayout =
705                            LayoutTypePortletImpl.getSourcePrototypeLayout(layout);
706    
707                    if (sourcePrototypeLayout == null) {
708                            return false;
709                    }
710    
711                    Date layoutModifiedDate = layout.getModifiedDate();
712    
713                    Date lastCopyDate = null;
714    
715                    String lastCopyDateString = layout.getTypeSettingsProperty(
716                            "layoutSetPrototypeLastCopyDate");
717    
718                    if (Validator.isNotNull(lastCopyDateString)) {
719                            lastCopyDate = new Date(GetterUtil.getLong(lastCopyDateString));
720                    }
721    
722                    if ((lastCopyDate != null) &&
723                            lastCopyDate.after(sourcePrototypeLayout.getModifiedDate())) {
724    
725                            return false;
726                    }
727    
728                    if (!isLayoutUpdateable(layout)) {
729                            return true;
730                    }
731    
732                    if ((layoutModifiedDate == null) ||
733                            ((lastCopyDate != null) &&
734                             layoutModifiedDate.before(lastCopyDate))) {
735    
736                            return true;
737                    }
738    
739                    return false;
740            }
741    
742            public static boolean isLayoutUpdateable(Layout layout) {
743                    try {
744                            if (layout instanceof VirtualLayout) {
745                                    return false;
746                            }
747    
748                            if (Validator.isNull(layout.getSourcePrototypeLayoutUuid())) {
749                                    return true;
750                            }
751    
752                            LayoutSet layoutSet = layout.getLayoutSet();
753    
754                            if (layoutSet.isLayoutSetPrototypeLinkActive()) {
755                                    boolean layoutSetPrototypeUpdateable =
756                                            isLayoutSetPrototypeUpdateable(layoutSet);
757    
758                                    if (!layoutSetPrototypeUpdateable) {
759                                            return false;
760                                    }
761    
762                                    LayoutTypePortlet layoutTypePortlet = new LayoutTypePortletImpl(
763                                            layout);
764    
765                                    String layoutUpdateable =
766                                            layoutTypePortlet.getSourcePrototypeLayoutProperty(
767                                                    "layoutUpdateable");
768    
769                                    if (Validator.isNull(layoutUpdateable)) {
770                                            return true;
771                                    }
772    
773                                    return GetterUtil.getBoolean(layoutUpdateable);
774                            }
775                    }
776                    catch (Exception e) {
777                            if (_log.isDebugEnabled()) {
778                                    _log.debug(e, e);
779                            }
780                    }
781    
782                    return true;
783            }
784    
785            public static boolean isUserGroupLayoutSetViewable(
786                            PermissionChecker permissionChecker, Group userGroupGroup)
787                    throws PortalException, SystemException {
788    
789                    if (!userGroupGroup.isUserGroup()) {
790                            return false;
791                    }
792    
793                    if (GroupPermissionUtil.contains(
794                                    permissionChecker, userGroupGroup.getGroupId(),
795                                    ActionKeys.VIEW)) {
796    
797                            return true;
798                    }
799    
800                    UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
801                            userGroupGroup.getClassPK());
802    
803                    if (UserLocalServiceUtil.hasUserGroupUser(
804                                    userGroup.getUserGroupId(), permissionChecker.getUserId())) {
805    
806                            return true;
807                    }
808                    else {
809                            return false;
810                    }
811            }
812    
813            protected static void copyLayoutPrototypePermissions(
814                            Layout targetLayout,
815                            LayoutPrototype sourceLayoutPrototype)
816                    throws Exception {
817    
818                    List<Role> roles = RoleLocalServiceUtil.getRoles(
819                            targetLayout.getCompanyId());
820    
821                    for (Role role : roles) {
822                            String roleName = role.getName();
823    
824                            if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
825                                    continue;
826                            }
827    
828                            List<String> actionIds = ResourceActionsUtil.getResourceActions(
829                                    LayoutPrototype.class.getName());
830    
831                            List<String> actions =
832                                    ResourcePermissionLocalServiceUtil.
833                                            getAvailableResourcePermissionActionIds(
834                                                    targetLayout.getCompanyId(),
835                                                    LayoutPrototype.class.getName(),
836                                                    ResourceConstants.SCOPE_INDIVIDUAL,
837                                                    String.valueOf(
838                                                            sourceLayoutPrototype.getLayoutPrototypeId()),
839                                                    role.getRoleId(), actionIds);
840    
841                            ResourcePermissionLocalServiceUtil.setResourcePermissions(
842                                    targetLayout.getCompanyId(), Layout.class.getName(),
843                                    ResourceConstants.SCOPE_INDIVIDUAL,
844                                    String.valueOf(targetLayout.getPlid()), role.getRoleId(),
845                                    actions.toArray(new String[actions.size()]));
846                    }
847            }
848    
849            protected static void setLayoutSetPrototypeLinkEnabledParameter(
850                    Map<String, String[]> parameterMap, LayoutSet targetLayoutSet,
851                    ServiceContext serviceContext) {
852    
853                    PermissionChecker permissionChecker =
854                            PermissionThreadLocal.getPermissionChecker();
855    
856                    if ((permissionChecker == null) ||
857                            !PortalPermissionUtil.contains(
858                                    permissionChecker, ActionKeys.UNLINK_LAYOUT_SET_PROTOTYPE)) {
859    
860                            return;
861                    }
862    
863                    if (targetLayoutSet.isPrivateLayout()) {
864                            boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
865                                    serviceContext, "privateLayoutSetPrototypeLinkEnabled", true);
866    
867                            if (!privateLayoutSetPrototypeLinkEnabled) {
868                                    privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
869                                            serviceContext, "layoutSetPrototypeLinkEnabled");
870                            }
871    
872                            parameterMap.put(
873                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
874                                    new String[] {
875                                            String.valueOf(privateLayoutSetPrototypeLinkEnabled)
876                                    });
877                    }
878                    else {
879                            boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
880                                    serviceContext, "publicLayoutSetPrototypeLinkEnabled");
881    
882                            if (!publicLayoutSetPrototypeLinkEnabled) {
883                                    publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
884                                            serviceContext, "layoutSetPrototypeLinkEnabled", true);
885                            }
886    
887                            parameterMap.put(
888                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
889                                    new String[] {
890                                            String.valueOf(publicLayoutSetPrototypeLinkEnabled)
891                                    });
892                    }
893            }
894    
895            private static Log _log = LogFactoryUtil.getLog(SitesUtil.class);
896    
897    }