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