1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portal.events;
16  
17  import com.liferay.portal.LayoutPermissionException;
18  import com.liferay.portal.NoSuchGroupException;
19  import com.liferay.portal.NoSuchLayoutException;
20  import com.liferay.portal.NoSuchUserException;
21  import com.liferay.portal.PortalException;
22  import com.liferay.portal.SystemException;
23  import com.liferay.portal.kernel.dao.orm.QueryUtil;
24  import com.liferay.portal.kernel.events.Action;
25  import com.liferay.portal.kernel.events.ActionException;
26  import com.liferay.portal.kernel.language.LanguageUtil;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.portlet.LiferayWindowState;
30  import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
31  import com.liferay.portal.kernel.servlet.ImageServletTokenUtil;
32  import com.liferay.portal.kernel.servlet.SessionErrors;
33  import com.liferay.portal.kernel.util.GetterUtil;
34  import com.liferay.portal.kernel.util.HttpUtil;
35  import com.liferay.portal.kernel.util.LocaleUtil;
36  import com.liferay.portal.kernel.util.ParamUtil;
37  import com.liferay.portal.kernel.util.PropsKeys;
38  import com.liferay.portal.kernel.util.SessionParamUtil;
39  import com.liferay.portal.kernel.util.StringBundler;
40  import com.liferay.portal.kernel.util.StringPool;
41  import com.liferay.portal.kernel.util.StringUtil;
42  import com.liferay.portal.kernel.util.UnicodeProperties;
43  import com.liferay.portal.kernel.util.Validator;
44  import com.liferay.portal.lar.PortletDataHandlerKeys;
45  import com.liferay.portal.model.ColorScheme;
46  import com.liferay.portal.model.Company;
47  import com.liferay.portal.model.Group;
48  import com.liferay.portal.model.GroupConstants;
49  import com.liferay.portal.model.Image;
50  import com.liferay.portal.model.Layout;
51  import com.liferay.portal.model.LayoutConstants;
52  import com.liferay.portal.model.LayoutSet;
53  import com.liferay.portal.model.LayoutTypePortlet;
54  import com.liferay.portal.model.Portlet;
55  import com.liferay.portal.model.RoleConstants;
56  import com.liferay.portal.model.Theme;
57  import com.liferay.portal.model.User;
58  import com.liferay.portal.model.impl.ColorSchemeImpl;
59  import com.liferay.portal.model.impl.LayoutImpl;
60  import com.liferay.portal.model.impl.LayoutTypePortletImpl;
61  import com.liferay.portal.model.impl.ThemeImpl;
62  import com.liferay.portal.security.auth.PrincipalException;
63  import com.liferay.portal.security.permission.ActionKeys;
64  import com.liferay.portal.security.permission.PermissionChecker;
65  import com.liferay.portal.security.permission.PermissionCheckerFactory;
66  import com.liferay.portal.security.permission.PermissionThreadLocal;
67  import com.liferay.portal.service.GroupLocalServiceUtil;
68  import com.liferay.portal.service.ImageLocalServiceUtil;
69  import com.liferay.portal.service.LayoutLocalServiceUtil;
70  import com.liferay.portal.service.LayoutSetLocalServiceUtil;
71  import com.liferay.portal.service.OrganizationLocalServiceUtil;
72  import com.liferay.portal.service.PortletLocalServiceUtil;
73  import com.liferay.portal.service.RoleLocalServiceUtil;
74  import com.liferay.portal.service.ThemeLocalServiceUtil;
75  import com.liferay.portal.service.UserLocalServiceUtil;
76  import com.liferay.portal.service.permission.GroupPermissionUtil;
77  import com.liferay.portal.service.permission.LayoutPermissionUtil;
78  import com.liferay.portal.service.permission.OrganizationPermissionUtil;
79  import com.liferay.portal.service.permission.UserPermissionUtil;
80  import com.liferay.portal.theme.ThemeDisplay;
81  import com.liferay.portal.theme.ThemeDisplayFactory;
82  import com.liferay.portal.util.CookieKeys;
83  import com.liferay.portal.util.FriendlyURLNormalizer;
84  import com.liferay.portal.util.LayoutClone;
85  import com.liferay.portal.util.LayoutCloneFactory;
86  import com.liferay.portal.util.PortalUtil;
87  import com.liferay.portal.util.PortletKeys;
88  import com.liferay.portal.util.PropsUtil;
89  import com.liferay.portal.util.PropsValues;
90  import com.liferay.portal.util.WebKeys;
91  import com.liferay.portlet.PortletURLImpl;
92  
93  import java.io.File;
94  
95  import java.util.ArrayList;
96  import java.util.HashMap;
97  import java.util.LinkedHashMap;
98  import java.util.List;
99  import java.util.Locale;
100 import java.util.Map;
101 import java.util.TimeZone;
102 
103 import javax.portlet.PortletMode;
104 import javax.portlet.PortletRequest;
105 import javax.portlet.PortletURL;
106 import javax.portlet.WindowState;
107 
108 import javax.servlet.http.HttpServletRequest;
109 import javax.servlet.http.HttpServletResponse;
110 import javax.servlet.http.HttpSession;
111 
112 import org.apache.commons.lang.time.StopWatch;
113 import org.apache.struts.Globals;
114 
115 /**
116  * <a href="ServicePreAction.java.html"><b><i>View Source</i></b></a>
117  *
118  * @author Brian Wing Shun Chan
119  * @author Felix Ventero
120  */
121 public class ServicePreAction extends Action {
122 
123     public ServicePreAction() {
124         initImportLARFiles();
125     }
126 
127     public void run(HttpServletRequest request, HttpServletResponse response)
128         throws ActionException {
129 
130         StopWatch stopWatch = null;
131 
132         if (_log.isDebugEnabled()) {
133             stopWatch = new StopWatch();
134 
135             stopWatch.start();
136         }
137 
138         try {
139             servicePre(request, response);
140         }
141         catch (Exception e) {
142             throw new ActionException(e);
143         }
144 
145         if (_log.isDebugEnabled()) {
146             _log.debug("Running takes " + stopWatch.getTime() + " ms");
147         }
148     }
149 
150     protected void addDefaultLayoutsByLAR(
151             long userId, long groupId, boolean privateLayout, File larFile)
152         throws PortalException, SystemException {
153 
154         Map<String, String[]> parameterMap = new HashMap<String, String[]>();
155 
156         parameterMap.put(
157             PortletDataHandlerKeys.PERMISSIONS,
158             new String[] {Boolean.TRUE.toString()});
159         parameterMap.put(
160             PortletDataHandlerKeys.PORTLET_DATA,
161             new String[] {Boolean.TRUE.toString()});
162         parameterMap.put(
163             PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
164             new String[] {Boolean.TRUE.toString()});
165         parameterMap.put(
166             PortletDataHandlerKeys.PORTLET_SETUP,
167             new String[] {Boolean.TRUE.toString()});
168         parameterMap.put(
169             PortletDataHandlerKeys.USER_PERMISSIONS,
170             new String[] {Boolean.FALSE.toString()});
171 
172         LayoutLocalServiceUtil.importLayouts(
173             userId, groupId, privateLayout, parameterMap, larFile);
174     }
175 
176     protected void addDefaultUserPrivateLayoutByProperties(
177             long userId, long groupId)
178         throws PortalException, SystemException {
179 
180         String friendlyURL = getFriendlyURL(
181             PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL);
182 
183         Layout layout = LayoutLocalServiceUtil.addLayout(
184             userId, groupId, true, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
185             PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_NAME, StringPool.BLANK,
186             StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL);
187 
188         LayoutTypePortlet layoutTypePortlet =
189             (LayoutTypePortlet)layout.getLayoutType();
190 
191         layoutTypePortlet.setLayoutTemplateId(
192             0, PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_TEMPLATE_ID, false);
193 
194         for (int i = 0; i < 10; i++) {
195             String columnId = "column-" + i;
196             String portletIds = PropsUtil.get(
197                 PropsKeys.DEFAULT_USER_PRIVATE_LAYOUT_COLUMN + i);
198 
199             String[] portletIdsArray = StringUtil.split(portletIds);
200 
201             layoutTypePortlet.addPortletIds(
202                 0, portletIdsArray, columnId, false);
203         }
204 
205         LayoutLocalServiceUtil.updateLayout(
206             layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
207             layout.getTypeSettings());
208 
209         boolean updateLayoutSet = false;
210 
211         LayoutSet layoutSet = layout.getLayoutSet();
212 
213         if (Validator.isNotNull(
214                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_REGULAR_THEME_ID)) {
215 
216             layoutSet.setThemeId(
217                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_REGULAR_THEME_ID);
218 
219             updateLayoutSet = true;
220         }
221 
222         if (Validator.isNotNull(
223                 PropsValues.
224                     DEFAULT_USER_PRIVATE_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
225 
226             layoutSet.setColorSchemeId(
227                 PropsValues.
228                     DEFAULT_USER_PRIVATE_LAYOUT_REGULAR_COLOR_SCHEME_ID);
229 
230             updateLayoutSet = true;
231         }
232 
233         if (Validator.isNotNull(
234                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_WAP_THEME_ID)) {
235 
236             layoutSet.setWapThemeId(
237                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_WAP_THEME_ID);
238 
239             updateLayoutSet = true;
240         }
241 
242         if (Validator.isNotNull(
243                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_WAP_COLOR_SCHEME_ID)) {
244 
245             layoutSet.setWapColorSchemeId(
246                 PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_WAP_COLOR_SCHEME_ID);
247 
248             updateLayoutSet = true;
249         }
250 
251         if (updateLayoutSet) {
252             LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
253         }
254     }
255 
256     protected void addDefaultUserPrivateLayouts(User user)
257         throws PortalException, SystemException {
258 
259         Group userGroup = user.getGroup();
260 
261         if (privateLARFile != null) {
262             addDefaultLayoutsByLAR(
263                 user.getUserId(), userGroup.getGroupId(), true, privateLARFile);
264         }
265         else {
266             addDefaultUserPrivateLayoutByProperties(
267                 user.getUserId(), userGroup.getGroupId());
268         }
269     }
270 
271     protected void addDefaultUserPublicLayoutByProperties(
272             long userId, long groupId)
273         throws PortalException, SystemException {
274 
275         String friendlyURL = getFriendlyURL(
276             PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_FRIENDLY_URL);
277 
278         Layout layout = LayoutLocalServiceUtil.addLayout(
279             userId, groupId, false, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
280             PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
281             StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL);
282 
283         LayoutTypePortlet layoutTypePortlet =
284             (LayoutTypePortlet)layout.getLayoutType();
285 
286         layoutTypePortlet.setLayoutTemplateId(
287             0, PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_TEMPLATE_ID, false);
288 
289         for (int i = 0; i < 10; i++) {
290             String columnId = "column-" + i;
291             String portletIds = PropsUtil.get(
292                 PropsKeys.DEFAULT_USER_PUBLIC_LAYOUT_COLUMN + i);
293 
294             String[] portletIdsArray = StringUtil.split(portletIds);
295 
296             layoutTypePortlet.addPortletIds(
297                 0, portletIdsArray, columnId, false);
298         }
299 
300         LayoutLocalServiceUtil.updateLayout(
301             layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
302             layout.getTypeSettings());
303 
304         boolean updateLayoutSet = false;
305 
306         LayoutSet layoutSet = layout.getLayoutSet();
307 
308         if (Validator.isNotNull(
309                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
310 
311             layoutSet.setThemeId(
312                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_REGULAR_THEME_ID);
313 
314             updateLayoutSet = true;
315         }
316 
317         if (Validator.isNotNull(
318                 PropsValues.
319                     DEFAULT_USER_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
320 
321             layoutSet.setColorSchemeId(
322                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
323 
324             updateLayoutSet = true;
325         }
326 
327         if (Validator.isNotNull(
328                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_WAP_THEME_ID)) {
329 
330             layoutSet.setWapThemeId(
331                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_WAP_THEME_ID);
332 
333             updateLayoutSet = true;
334         }
335 
336         if (Validator.isNotNull(
337                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
338 
339             layoutSet.setWapColorSchemeId(
340                 PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
341 
342             updateLayoutSet = true;
343         }
344 
345         if (updateLayoutSet) {
346             LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
347         }
348     }
349 
350     protected void addDefaultUserPublicLayouts(User user)
351         throws PortalException, SystemException {
352 
353         Group userGroup = user.getGroup();
354 
355         if (publicLARFile != null) {
356             addDefaultLayoutsByLAR(
357                 user.getUserId(), userGroup.getGroupId(), false, publicLARFile);
358         }
359         else {
360             addDefaultUserPublicLayoutByProperties(
361                 user.getUserId(), userGroup.getGroupId());
362         }
363     }
364 
365     protected void deleteDefaultUserPrivateLayouts(User user)
366         throws PortalException, SystemException {
367 
368         Group userGroup = user.getGroup();
369 
370         LayoutLocalServiceUtil.deleteLayouts(userGroup.getGroupId(), true);
371     }
372 
373     protected void deleteDefaultUserPublicLayouts(User user)
374         throws PortalException, SystemException {
375 
376         Group userGroup = user.getGroup();
377 
378         LayoutLocalServiceUtil.deleteLayouts(userGroup.getGroupId(), false);
379     }
380 
381     protected Object[] getDefaultLayout(
382             HttpServletRequest request, User user, boolean signedIn)
383         throws PortalException, SystemException {
384 
385         // Check the virtual host
386 
387         LayoutSet layoutSet = (LayoutSet)request.getAttribute(
388             WebKeys.VIRTUAL_HOST_LAYOUT_SET);
389 
390         if (layoutSet != null) {
391             List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
392                 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
393                 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
394 
395             if (layouts.size() > 0) {
396                 Layout layout = layouts.get(0);
397 
398                 return new Object[] {layout, layouts};
399             }
400         }
401 
402         Layout layout = null;
403         List<Layout> layouts = null;
404 
405         if (signedIn) {
406 
407             // Check the user's personal layouts
408 
409             Group userGroup = user.getGroup();
410 
411             layouts = LayoutLocalServiceUtil.getLayouts(
412                 userGroup.getGroupId(), true,
413                 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
414 
415             if (layouts.size() == 0) {
416                 layouts = LayoutLocalServiceUtil.getLayouts(
417                     userGroup.getGroupId(), false,
418                     LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
419             }
420 
421             if (layouts.size() > 0) {
422                 layout = layouts.get(0);
423             }
424 
425             // Check the user's communities
426 
427             if (layout == null) {
428                 LinkedHashMap<String, Object> groupParams =
429                     new LinkedHashMap<String, Object>();
430 
431                 groupParams.put("usersGroups", new Long(user.getUserId()));
432 
433                 List<Group> groups = GroupLocalServiceUtil.search(
434                     user.getCompanyId(), null, null, groupParams,
435                     QueryUtil.ALL_POS, QueryUtil.ALL_POS);
436 
437                 for (int i = 0; i < groups.size(); i++) {
438                     Group group = groups.get(i);
439 
440                     layouts = LayoutLocalServiceUtil.getLayouts(
441                         group.getGroupId(), true,
442                         LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
443 
444                     if (layouts.size() == 0) {
445                         layouts = LayoutLocalServiceUtil.getLayouts(
446                             group.getGroupId(), false,
447                             LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
448                     }
449 
450                     if (layouts.size() > 0) {
451                         layout = layouts.get(0);
452 
453                         break;
454                     }
455                 }
456             }
457         }
458 
459         if (layout == null) {
460 
461             // Check the guest community
462 
463             Group guestGroup = GroupLocalServiceUtil.getGroup(
464                 user.getCompanyId(), GroupConstants.GUEST);
465 
466             layouts = LayoutLocalServiceUtil.getLayouts(
467                 guestGroup.getGroupId(), false,
468                 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
469 
470             if (layouts.size() > 0) {
471                 layout = layouts.get(0);
472             }
473         }
474 
475         return new Object[] {layout, layouts};
476     }
477 
478     protected String getFriendlyURL(String friendlyURL) {
479         friendlyURL = GetterUtil.getString(friendlyURL);
480 
481         return FriendlyURLNormalizer.normalize(friendlyURL);
482     }
483 
484     protected Object[] getViewableLayouts(
485             HttpServletRequest request, User user,
486             PermissionChecker permissionChecker, Layout layout,
487             List<Layout> layouts)
488         throws PortalException, SystemException {
489 
490         if ((layouts == null) || (layouts.size() == 0)) {
491             return new Object[] {layout, layouts};
492         }
493 
494         boolean replaceLayout = true;
495 
496         if (LayoutPermissionUtil.contains(
497                 permissionChecker, layout, ActionKeys.VIEW)) {
498 
499             replaceLayout = false;
500         }
501 
502         List<Layout> accessibleLayouts = new ArrayList<Layout>();
503 
504         for (int i = 0; i < layouts.size(); i++) {
505             Layout curLayout = layouts.get(i);
506 
507             if (!curLayout.isHidden() &&
508                 LayoutPermissionUtil.contains(
509                     permissionChecker, curLayout, ActionKeys.VIEW)) {
510 
511                 if ((accessibleLayouts.size() == 0) && replaceLayout) {
512                     layout = curLayout;
513                 }
514 
515                 accessibleLayouts.add(curLayout);
516             }
517         }
518 
519         if (accessibleLayouts.size() == 0) {
520             layouts = null;
521 
522             SessionErrors.add(
523                 request, LayoutPermissionException.class.getName());
524         }
525         else {
526             layouts = accessibleLayouts;
527         }
528 
529         return new Object[] {layout, layouts};
530     }
531 
532     protected Boolean hasPowerUserRole(User user) throws Exception {
533         return RoleLocalServiceUtil.hasUserRole(
534             user.getUserId(), user.getCompanyId(), RoleConstants.POWER_USER,
535             true);
536     }
537 
538     protected void initImportLARFiles() {
539         String privateLARFileName =
540             PropsValues.DEFAULT_USER_PRIVATE_LAYOUTS_LAR;
541 
542         if (_log.isDebugEnabled()) {
543             _log.debug("Reading private LAR file " + privateLARFileName);
544         }
545 
546         if (Validator.isNotNull(privateLARFileName)) {
547             privateLARFile = new File(privateLARFileName);
548 
549             if (!privateLARFile.exists()) {
550                 _log.error(
551                     "Private LAR file " + privateLARFile + " does not exist");
552 
553                 privateLARFile = null;
554             }
555             else {
556                 if (_log.isDebugEnabled()) {
557                     _log.debug("Using private LAR file " + privateLARFileName);
558                 }
559             }
560         }
561 
562         String publicLARFileName = PropsValues.DEFAULT_USER_PUBLIC_LAYOUTS_LAR;
563 
564         if (_log.isDebugEnabled()) {
565             _log.debug("Reading public LAR file " + publicLARFileName);
566         }
567 
568         if (Validator.isNotNull(publicLARFileName)) {
569             publicLARFile = new File(publicLARFileName);
570 
571             if (!publicLARFile.exists()) {
572                 _log.error(
573                     "Public LAR file " + publicLARFile + " does not exist");
574 
575                 publicLARFile = null;
576             }
577             else {
578                 if (_log.isDebugEnabled()) {
579                     _log.debug("Using public LAR file " + publicLARFileName);
580                 }
581             }
582         }
583     }
584 
585     /**
586      * @deprecated Use <code>isViewableGroup</code>.
587      */
588     protected boolean isViewableCommunity(
589             User user, long groupId, boolean privateLayout,
590             PermissionChecker permissionChecker)
591         throws PortalException, SystemException {
592 
593         return isViewableGroup(
594             user, groupId, privateLayout, 0, permissionChecker);
595     }
596 
597     protected boolean isViewableGroup(
598             User user, long groupId, boolean privateLayout, long layoutId,
599             PermissionChecker permissionChecker)
600         throws PortalException, SystemException {
601 
602         Group group = GroupLocalServiceUtil.getGroup(groupId);
603 
604         // Inactive communities are not viewable
605 
606         if (!group.isActive()) {
607             return false;
608         }
609         else if (group.isStagingGroup()) {
610             Group liveGroup = group.getLiveGroup();
611 
612             if (!liveGroup.isActive()) {
613                 return false;
614             }
615         }
616 
617         // User private layouts are only viewable by the user and anyone who can
618         // update the user. The user must also be active.
619 
620         if (group.isUser()) {
621             long groupUserId = group.getClassPK();
622 
623             if (groupUserId == user.getUserId()) {
624                 return true;
625             }
626             else {
627                 User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
628 
629                 if (!groupUser.isActive()) {
630                     return false;
631                 }
632 
633                 if (privateLayout) {
634                     if (UserPermissionUtil.contains(
635                             permissionChecker, groupUserId,
636                             groupUser.getOrganizationIds(),
637                             ActionKeys.UPDATE)) {
638 
639                         return true;
640                     }
641                     else {
642                         return false;
643                     }
644                 }
645             }
646         }
647 
648         // If the current group is staging, only users with editorial rights
649         // can access it
650 
651         if (group.isStagingGroup()) {
652             if (user.isDefaultUser()) {
653                 return false;
654             }
655 
656             if (GroupPermissionUtil.contains(
657                     permissionChecker, groupId, ActionKeys.APPROVE_PROPOSAL) ||
658                 GroupPermissionUtil.contains(
659                     permissionChecker, groupId, ActionKeys.ASSIGN_REVIEWER) ||
660                 GroupPermissionUtil.contains(
661                     permissionChecker, groupId, ActionKeys.MANAGE_LAYOUTS) ||
662                 GroupPermissionUtil.contains(
663                     permissionChecker, groupId, ActionKeys.MANAGE_STAGING) ||
664                 GroupPermissionUtil.contains(
665                     permissionChecker, groupId, ActionKeys.PUBLISH_STAGING) ||
666                 ((layoutId > 0) && LayoutPermissionUtil.contains(
667                     permissionChecker, groupId, privateLayout, layoutId,
668                     ActionKeys.UPDATE))) {
669 
670                 return true;
671             }
672 
673             return false;
674         }
675 
676         // Most public layouts are viewable
677 
678         if (!privateLayout) {
679             return true;
680         }
681 
682         // Community or organization layouts are only viewable by users who
683         // belong to the community or organization, or by users who can update
684         // the community or organization
685 
686         if (group.isCommunity()) {
687             if (GroupLocalServiceUtil.hasUserGroup(user.getUserId(), groupId)) {
688                 return true;
689             }
690             else if (GroupPermissionUtil.contains(
691                         permissionChecker, groupId, ActionKeys.UPDATE)) {
692 
693                 return true;
694             }
695         }
696         else if (group.isOrganization()) {
697             long organizationId = group.getClassPK();
698 
699             if (OrganizationLocalServiceUtil.hasUserOrganization(
700                     user.getUserId(), organizationId, true)) {
701 
702                 return true;
703             }
704             else if (OrganizationPermissionUtil.contains(
705                         permissionChecker, organizationId, ActionKeys.UPDATE)) {
706 
707                 return true;
708             }
709         }
710         else if (group.isUserGroup()) {
711             if (GroupPermissionUtil.contains(
712                     permissionChecker, groupId, ActionKeys.MANAGE_LAYOUTS)) {
713 
714                 return true;
715             }
716         }
717 
718         return false;
719     }
720 
721     protected List<Layout> mergeAdditionalLayouts(
722             HttpServletRequest request, User user,
723             PermissionChecker permissionChecker, Layout layout,
724             List<Layout> layouts)
725         throws PortalException, SystemException {
726 
727         if ((layout == null) || layout.isPrivateLayout()) {
728             return layouts;
729         }
730 
731         long layoutGroupId = layout.getGroupId();
732 
733         Group guestGroup = GroupLocalServiceUtil.getGroup(
734             user.getCompanyId(), GroupConstants.GUEST);
735 
736         if (layoutGroupId != guestGroup.getGroupId()) {
737             Group layoutGroup = GroupLocalServiceUtil.getGroup(layoutGroupId);
738 
739             UnicodeProperties props = layoutGroup.getTypeSettingsProperties();
740 
741             boolean mergeGuestPublicPages = GetterUtil.getBoolean(
742                 props.getProperty("mergeGuestPublicPages"));
743 
744             if (!mergeGuestPublicPages) {
745                 return layouts;
746             }
747 
748             List<Layout> guestLayouts = LayoutLocalServiceUtil.getLayouts(
749                 guestGroup.getGroupId(), false,
750                 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
751 
752             Object[] viewableLayouts = getViewableLayouts(
753                 request, user, permissionChecker, layout, guestLayouts);
754 
755             guestLayouts = (List<Layout>)viewableLayouts[1];
756 
757             layouts.addAll(0, guestLayouts);
758         }
759         else {
760             HttpSession session = request.getSession();
761 
762             Long previousGroupId = (Long)session.getAttribute(
763                 WebKeys.VISITED_GROUP_ID_PREVIOUS);
764 
765             if ((previousGroupId != null) &&
766                 (previousGroupId.longValue() != layoutGroupId)) {
767 
768                 Group previousGroup = null;
769 
770                 try {
771                     previousGroup = GroupLocalServiceUtil.getGroup(
772                         previousGroupId.longValue());
773                 }
774                 catch (NoSuchGroupException nsge) {
775                     if (_log.isWarnEnabled()) {
776                         _log.warn(nsge);
777                     }
778 
779                     return layouts;
780                 }
781 
782                 UnicodeProperties props =
783                     previousGroup.getTypeSettingsProperties();
784 
785                 boolean mergeGuestPublicPages = GetterUtil.getBoolean(
786                     props.getProperty("mergeGuestPublicPages"));
787 
788                 if (!mergeGuestPublicPages) {
789                     return layouts;
790                 }
791 
792                 List<Layout> previousLayouts =
793                     LayoutLocalServiceUtil.getLayouts(
794                         previousGroupId.longValue(), false,
795                         LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
796 
797                 Object[] viewableLayouts = getViewableLayouts(
798                     request, user, permissionChecker, layout, previousLayouts);
799 
800                 previousLayouts = (List<Layout>)viewableLayouts[1];
801 
802                 layouts.addAll(previousLayouts);
803             }
804         }
805 
806         return layouts;
807     }
808 
809     protected void rememberVisitedGroupIds(
810         HttpServletRequest request, long currentGroupId) {
811 
812         String requestURI = GetterUtil.getString(request.getRequestURI());
813 
814         if (!requestURI.endsWith(_PATH_PORTAL_LAYOUT)) {
815             return;
816         }
817 
818         HttpSession session = request.getSession();
819 
820         Long recentGroupId = (Long)session.getAttribute(
821             WebKeys.VISITED_GROUP_ID_RECENT);
822 
823         Long previousGroupId = (Long)session.getAttribute(
824             WebKeys.VISITED_GROUP_ID_PREVIOUS);
825 
826         if (recentGroupId == null) {
827             recentGroupId = new Long(currentGroupId);
828 
829             session.setAttribute(
830                 WebKeys.VISITED_GROUP_ID_RECENT, recentGroupId);
831         }
832         else if (recentGroupId.longValue() != currentGroupId) {
833             previousGroupId = new Long(recentGroupId.longValue());
834 
835             recentGroupId = new Long(currentGroupId);
836 
837             session.setAttribute(
838                 WebKeys.VISITED_GROUP_ID_RECENT, recentGroupId);
839 
840             session.setAttribute(
841                 WebKeys.VISITED_GROUP_ID_PREVIOUS, previousGroupId);
842         }
843 
844         if (_log.isDebugEnabled()) {
845             _log.debug("Current group id " + currentGroupId);
846             _log.debug("Recent group id " + recentGroupId);
847             _log.debug("Previous group id " + previousGroupId);
848         }
849     }
850 
851     protected void servicePre(
852             HttpServletRequest request, HttpServletResponse response)
853         throws Exception {
854 
855         HttpSession session = request.getSession();
856 
857         // Company
858 
859         Company company = PortalUtil.getCompany(request);
860 
861         long companyId = company.getCompanyId();
862 
863         // CDN host
864 
865         String cdnHost = null;
866 
867         if (request.isSecure()) {
868             cdnHost = PortalUtil.getCDNHostHttps();
869         }
870         else {
871             cdnHost = PortalUtil.getCDNHostHttp();
872         }
873 
874         cdnHost = ParamUtil.getString(request, "cdn_host", cdnHost);
875 
876         // Portal URL
877 
878         String portalURL = PortalUtil.getPortalURL(request);
879 
880         // Paths
881 
882         String contextPath = PortalUtil.getPathContext();
883         String friendlyURLPrivateGroupPath =
884             PortalUtil.getPathFriendlyURLPrivateGroup();
885         String friendlyURLPrivateUserPath =
886             PortalUtil.getPathFriendlyURLPrivateUser();
887         String friendlyURLPublicPath = PortalUtil.getPathFriendlyURLPublic();
888         String imagePath = cdnHost.concat(PortalUtil.getPathImage());
889         String mainPath = PortalUtil.getPathMain();
890 
891         String i18nPath = (String)request.getAttribute(WebKeys.I18N_PATH);
892 
893         if (Validator.isNotNull(i18nPath)) {
894             if (Validator.isNotNull(contextPath)) {
895                 String i18nContextPath = contextPath.concat(i18nPath);
896 
897                 friendlyURLPrivateGroupPath = StringUtil.replaceFirst(
898                     friendlyURLPrivateGroupPath, contextPath, i18nContextPath);
899                 friendlyURLPrivateUserPath = StringUtil.replaceFirst(
900                     friendlyURLPrivateUserPath, contextPath, i18nContextPath);
901                 friendlyURLPublicPath = StringUtil.replaceFirst(
902                     friendlyURLPublicPath, contextPath, i18nContextPath);
903                 mainPath = StringUtil.replaceFirst(
904                     mainPath, contextPath, i18nContextPath);
905             }
906             else {
907                 friendlyURLPrivateGroupPath = i18nPath.concat(
908                     friendlyURLPrivateGroupPath);
909                 friendlyURLPrivateUserPath = i18nPath.concat(
910                     friendlyURLPrivateUserPath);
911                 friendlyURLPublicPath = i18nPath.concat(friendlyURLPublicPath);
912                 mainPath = i18nPath.concat(mainPath);
913             }
914         }
915 
916         // Company logo
917 
918         StringBundler sb = new StringBundler(5);
919 
920         sb.append(imagePath);
921         sb.append("/company_logo?img_id=");
922         sb.append(company.getLogoId());
923         sb.append("&t=");
924         sb.append(ImageServletTokenUtil.getToken(company.getLogoId()));
925 
926         String companyLogo = sb.toString();
927 
928         Image companyLogoImage = ImageLocalServiceUtil.getCompanyLogo(
929             company.getLogoId());
930 
931         int companyLogoHeight = companyLogoImage.getHeight();
932         int companyLogoWidth = companyLogoImage.getWidth();
933 
934         String realCompanyLogo = companyLogo;
935         int realCompanyLogoHeight = companyLogoHeight;
936         int realCompanyLogoWidth = companyLogoWidth;
937 
938         // User
939 
940         User user = null;
941 
942         try {
943             user = PortalUtil.getUser(request);
944         }
945         catch (NoSuchUserException nsue) {
946             if (_log.isWarnEnabled()) {
947                 _log.warn(nsue.getMessage());
948             }
949 
950             long userId = PortalUtil.getUserId(request);
951 
952             if (userId > 0) {
953                 session.invalidate();
954             }
955 
956             return;
957         }
958 
959         boolean signedIn = false;
960 
961         if (user == null) {
962             user = company.getDefaultUser();
963         }
964         else if (!user.isDefaultUser()) {
965             signedIn = true;
966         }
967 
968         User realUser = user;
969 
970         Long realUserId = (Long)session.getAttribute(WebKeys.USER_ID);
971 
972         if (realUserId != null) {
973             if (user.getUserId() != realUserId.longValue()) {
974                 realUser = UserLocalServiceUtil.getUserById(
975                     realUserId.longValue());
976             }
977         }
978 
979         String doAsUserId = ParamUtil.getString(request, "doAsUserId");
980 
981         // Permission checker
982 
983         PermissionChecker permissionChecker = PermissionCheckerFactory.create(
984             user, true);
985 
986         PermissionThreadLocal.setPermissionChecker(permissionChecker);
987 
988         // Locale
989 
990         Locale locale = (Locale)session.getAttribute(Globals.LOCALE_KEY);
991 
992         String i18nLanguageId = (String)request.getAttribute(
993             WebKeys.I18N_LANGUAGE_ID);
994 
995         if (Validator.isNotNull(i18nLanguageId)) {
996             locale = LocaleUtil.fromLanguageId(i18nLanguageId);
997         }
998         else if (locale == null) {
999             if (signedIn) {
1000                locale = user.getLocale();
1001            }
1002            else {
1003
1004                // User previously set their preferred language
1005
1006                String languageId = CookieKeys.getCookie(
1007                    request, CookieKeys.GUEST_LANGUAGE_ID);
1008
1009                if (Validator.isNotNull(languageId)) {
1010                    locale = LocaleUtil.fromLanguageId(languageId);
1011                }
1012
1013                // Get locale from the request
1014
1015                if ((locale == null) && PropsValues.LOCALE_DEFAULT_REQUEST) {
1016                    locale = request.getLocale();
1017                }
1018
1019                // Get locale from the default user
1020
1021                if (locale == null) {
1022                    locale = user.getLocale();
1023                }
1024
1025                if (Validator.isNull(locale.getCountry())) {
1026
1027                    // Locales must contain a country code
1028
1029                    locale = LanguageUtil.getLocale(locale.getLanguage());
1030                }
1031
1032                if (!LanguageUtil.isAvailableLocale(locale)) {
1033                    locale = user.getLocale();
1034                }
1035            }
1036
1037            session.setAttribute(Globals.LOCALE_KEY, locale);
1038
1039            LanguageUtil.updateCookie(request, response, locale);
1040        }
1041
1042        // Cookie support
1043
1044        try {
1045
1046            // LEP-4069
1047
1048            CookieKeys.validateSupportCookie(request);
1049        }
1050        catch (Exception e) {
1051            CookieKeys.addSupportCookie(request, response);
1052        }
1053
1054        // Time zone
1055
1056        TimeZone timeZone = user.getTimeZone();
1057
1058        if (timeZone == null) {
1059            timeZone = company.getTimeZone();
1060        }
1061
1062        // Layouts
1063
1064        if (signedIn) {
1065            updateUserLayouts(user);
1066        }
1067
1068        Layout layout = null;
1069        List<Layout> layouts = null;
1070
1071        long plid = ParamUtil.getLong(request, "p_l_id");
1072
1073        if (plid > 0) {
1074            layout = LayoutLocalServiceUtil.getLayout(plid);
1075        }
1076        else {
1077            long groupId = ParamUtil.getLong(request, "groupId");
1078            boolean privateLayout = ParamUtil.getBoolean(
1079                request, "privateLayout");
1080            long layoutId = ParamUtil.getLong(request, "layoutId");
1081
1082            if ((groupId > 0) && layoutId > 0) {
1083                layout = LayoutLocalServiceUtil.getLayout(
1084                    groupId, privateLayout, layoutId);
1085            }
1086        }
1087
1088        if (layout != null) {
1089            try {
1090                Group group = layout.getGroup();
1091
1092                if (!signedIn && PropsValues.AUTH_FORWARD_BY_REDIRECT) {
1093                    request.setAttribute(WebKeys.REQUESTED_LAYOUT, layout);
1094                }
1095
1096                boolean isViewableCommunity = isViewableGroup(
1097                    user, layout.getGroupId(), layout.isPrivateLayout(),
1098                    layout.getLayoutId(), permissionChecker);
1099
1100                if (!isViewableCommunity && group.isStagingGroup()) {
1101                    layout = null;
1102                }
1103                else if (!isViewableCommunity) {
1104                    sb = new StringBundler(6);
1105
1106                    sb.append("User ");
1107                    sb.append(user.getUserId());
1108                    sb.append(" is not allowed to access the ");
1109                    sb.append(layout.isPrivateLayout() ? "private": "public");
1110                    sb.append(" pages of group ");
1111                    sb.append(layout.getGroupId());
1112
1113                    if (_log.isWarnEnabled()) {
1114                        _log.warn(sb.toString());
1115                    }
1116
1117                    throw new PrincipalException(sb.toString());
1118                }
1119                else if (isViewableCommunity &&
1120                        !LayoutPermissionUtil.contains(
1121                            permissionChecker, layout, ActionKeys.VIEW)) {
1122
1123                    layout = null;
1124                }
1125                else {
1126                    layouts = LayoutLocalServiceUtil.getLayouts(
1127                        layout.getGroupId(), layout.isPrivateLayout(),
1128                        LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
1129                }
1130            }
1131            catch (NoSuchLayoutException nsle) {
1132            }
1133        }
1134
1135        if (layout == null) {
1136            Object[] defaultLayout = getDefaultLayout(request, user, signedIn);
1137
1138            layout = (Layout)defaultLayout[0];
1139            layouts = (List<Layout>)defaultLayout[1];
1140
1141            request.setAttribute(WebKeys.LAYOUT_DEFAULT, Boolean.TRUE);
1142        }
1143
1144        Object[] viewableLayouts = getViewableLayouts(
1145            request, user, permissionChecker, layout, layouts);
1146
1147        String layoutSetLogo = null;
1148
1149        layout = (Layout)viewableLayouts[0];
1150        layouts = (List<Layout>)viewableLayouts[1];
1151
1152        LayoutTypePortlet layoutTypePortlet = null;
1153
1154        long scopeGroupId = PortalUtil.getScopeGroupId(layout);
1155
1156        rememberVisitedGroupIds(request, scopeGroupId);
1157
1158        layouts = mergeAdditionalLayouts(
1159            request, user, permissionChecker, layout, layouts);
1160
1161        if (layout != null) {
1162            if (company.isCommunityLogo()) {
1163                long logoId = 0;
1164
1165                if (layout.isIconImage()) {
1166                    logoId = layout.getIconImageId();
1167                }
1168                else{
1169                    LayoutSet layoutSet = layout.getLayoutSet();
1170
1171                    if (layoutSet.isLogo()) {
1172                        logoId = layoutSet.getLogoId();
1173                    }
1174                    else {
1175                        LayoutSet siblingLayoutSet =
1176                            LayoutSetLocalServiceUtil.getLayoutSet(
1177                                layout.getGroupId(), !layout.isPrivateLayout());
1178
1179                        if (siblingLayoutSet.isLogo()) {
1180                            logoId = siblingLayoutSet.getLogoId();
1181                        }
1182                    }
1183                }
1184
1185                if (logoId > 0) {
1186                    sb = new StringBundler(5);
1187
1188                    sb.append(imagePath);
1189                    sb.append("/layout_set_logo?img_id=");
1190                    sb.append(logoId);
1191                    sb.append("&t=");
1192                    sb.append(ImageServletTokenUtil.getToken(logoId));
1193
1194                    layoutSetLogo = sb.toString();
1195
1196                    Image layoutSetLogoImage =
1197                        ImageLocalServiceUtil.getCompanyLogo(logoId);
1198
1199                    companyLogo = layoutSetLogo;
1200                    companyLogoHeight = layoutSetLogoImage.getHeight();
1201                    companyLogoWidth = layoutSetLogoImage.getWidth();
1202                }
1203            }
1204
1205            plid = layout.getPlid();
1206
1207            // Updates to shared layouts are not reflected until the next time
1208            // the user logs in because group layouts are cached in the session
1209
1210            layout = (Layout)((LayoutImpl)layout).clone();
1211
1212            layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
1213
1214            LayoutClone layoutClone = LayoutCloneFactory.getInstance();
1215
1216            if (layoutClone != null) {
1217                String typeSettings = layoutClone.get(request, plid);
1218
1219                if (typeSettings != null) {
1220                    UnicodeProperties props = new UnicodeProperties(true);
1221
1222                    props.load(typeSettings);
1223
1224                    String stateMax = props.getProperty(
1225                        LayoutTypePortletImpl.STATE_MAX);
1226                    String stateMin = props.getProperty(
1227                        LayoutTypePortletImpl.STATE_MIN);
1228                    String modeAbout = props.getProperty(
1229                        LayoutTypePortletImpl.MODE_ABOUT);
1230                    String modeConfig = props.getProperty(
1231                        LayoutTypePortletImpl.MODE_CONFIG);
1232                    String modeEdit = props.getProperty(
1233                        LayoutTypePortletImpl.MODE_EDIT);
1234                    String modeEditDefaults = props.getProperty(
1235                        LayoutTypePortletImpl.MODE_EDIT_DEFAULTS);
1236                    String modeEditGuest = props.getProperty(
1237                        LayoutTypePortletImpl.MODE_EDIT_GUEST);
1238                    String modeHelp = props.getProperty(
1239                        LayoutTypePortletImpl.MODE_HELP);
1240                    String modePreview = props.getProperty(
1241                        LayoutTypePortletImpl.MODE_PREVIEW);
1242                    String modePrint = props.getProperty(
1243                        LayoutTypePortletImpl.MODE_PRINT);
1244
1245                    layoutTypePortlet.setStateMax(stateMax);
1246                    layoutTypePortlet.setStateMin(stateMin);
1247                    layoutTypePortlet.setModeAbout(modeAbout);
1248                    layoutTypePortlet.setModeConfig(modeConfig);
1249                    layoutTypePortlet.setModeEdit(modeEdit);
1250                    layoutTypePortlet.setModeEditDefaults(modeEditDefaults);
1251                    layoutTypePortlet.setModeEditGuest(modeEditGuest);
1252                    layoutTypePortlet.setModeHelp(modeHelp);
1253                    layoutTypePortlet.setModePreview(modePreview);
1254                    layoutTypePortlet.setModePrint(modePrint);
1255                }
1256            }
1257
1258            request.setAttribute(WebKeys.LAYOUT, layout);
1259            request.setAttribute(WebKeys.LAYOUTS, layouts);
1260
1261            if (layout.isPrivateLayout()) {
1262                permissionChecker.setCheckGuest(false);
1263            }
1264        }
1265
1266        // Theme and color scheme
1267
1268        Theme theme = null;
1269        ColorScheme colorScheme = null;
1270
1271        boolean wapTheme = BrowserSnifferUtil.isWap(request);
1272
1273        if (layout != null) {
1274            if (wapTheme) {
1275                theme = layout.getWapTheme();
1276                colorScheme = layout.getWapColorScheme();
1277            }
1278            else {
1279                theme = layout.getTheme();
1280                colorScheme = layout.getColorScheme();
1281            }
1282        }
1283        else {
1284            String themeId = null;
1285            String colorSchemeId = null;
1286
1287            if (wapTheme) {
1288                themeId = ThemeImpl.getDefaultWapThemeId();
1289                colorSchemeId = ColorSchemeImpl.getDefaultWapColorSchemeId();
1290            }
1291            else {
1292                themeId = ThemeImpl.getDefaultRegularThemeId();
1293                colorSchemeId =
1294                    ColorSchemeImpl.getDefaultRegularColorSchemeId();
1295            }
1296
1297            theme = ThemeLocalServiceUtil.getTheme(
1298                companyId, themeId, wapTheme);
1299            colorScheme = ThemeLocalServiceUtil.getColorScheme(
1300                companyId, theme.getThemeId(), colorSchemeId, wapTheme);
1301        }
1302
1303        request.setAttribute(WebKeys.THEME, theme);
1304        request.setAttribute(WebKeys.COLOR_SCHEME, colorScheme);
1305
1306        boolean themeCssFastLoad = SessionParamUtil.getBoolean(
1307            request, "css_fast_load", PropsValues.THEME_CSS_FAST_LOAD);
1308        boolean themeImagesFastLoad = SessionParamUtil.getBoolean(
1309            request, "images_fast_load", PropsValues.THEME_IMAGES_FAST_LOAD);
1310
1311        boolean themeJsBarebone = PropsValues.JAVASCRIPT_BAREBONE_ENABLED;
1312
1313        if (themeJsBarebone) {
1314            if (signedIn) {
1315                themeJsBarebone = false;
1316            }
1317        }
1318
1319        boolean themeJsFastLoad = SessionParamUtil.getBoolean(
1320            request, "js_fast_load", PropsValues.JAVASCRIPT_FAST_LOAD);
1321
1322        String lifecycle = ParamUtil.getString(request, "p_p_lifecycle", "0");
1323
1324        String facebookCanvasPageURL = (String)request.getAttribute(
1325            WebKeys.FACEBOOK_CANVAS_PAGE_URL);
1326
1327        boolean widget = false;
1328
1329        Boolean widgetObj = (Boolean)request.getAttribute(WebKeys.WIDGET);
1330
1331        if (widgetObj != null) {
1332            widget = widgetObj.booleanValue();
1333        }
1334
1335        // Theme display
1336
1337        ThemeDisplay themeDisplay = ThemeDisplayFactory.create();
1338
1339        // Set the CDN host, portal URL, and Facebook application ID first
1340        // because other methods (setLookAndFeel) depend on them being set
1341
1342        themeDisplay.setCDNHost(cdnHost);
1343        themeDisplay.setPortalURL(portalURL);
1344        themeDisplay.setFacebookCanvasPageURL(facebookCanvasPageURL);
1345        themeDisplay.setWidget(widget);
1346
1347        themeDisplay.setCompany(company);
1348        themeDisplay.setCompanyLogo(companyLogo);
1349        themeDisplay.setCompanyLogoHeight(companyLogoHeight);
1350        themeDisplay.setCompanyLogoWidth(companyLogoWidth);
1351        themeDisplay.setRealCompanyLogo(realCompanyLogo);
1352        themeDisplay.setRealCompanyLogoHeight(realCompanyLogoHeight);
1353        themeDisplay.setRealCompanyLogoWidth(realCompanyLogoWidth);
1354        themeDisplay.setUser(user);
1355        themeDisplay.setRealUser(realUser);
1356        themeDisplay.setDoAsUserId(doAsUserId);
1357        themeDisplay.setLayoutSetLogo(layoutSetLogo);
1358        themeDisplay.setLayout(layout);
1359        themeDisplay.setLayouts(layouts);
1360        themeDisplay.setPlid(plid);
1361        themeDisplay.setLayoutTypePortlet(layoutTypePortlet);
1362        themeDisplay.setScopeGroupId(scopeGroupId);
1363        themeDisplay.setSignedIn(signedIn);
1364        themeDisplay.setPermissionChecker(permissionChecker);
1365        themeDisplay.setLocale(locale);
1366        themeDisplay.setLanguageId(LocaleUtil.toLanguageId(locale));
1367        themeDisplay.setI18nLanguageId(i18nLanguageId);
1368        themeDisplay.setI18nPath(i18nPath);
1369        themeDisplay.setTimeZone(timeZone);
1370        themeDisplay.setLookAndFeel(contextPath, theme, colorScheme);
1371        themeDisplay.setThemeCssFastLoad(themeCssFastLoad);
1372        themeDisplay.setThemeImagesFastLoad(themeImagesFastLoad);
1373        themeDisplay.setThemeJsBarebone(themeJsBarebone);
1374        themeDisplay.setThemeJsFastLoad(themeJsFastLoad);
1375        themeDisplay.setServerName(request.getServerName());
1376        themeDisplay.setServerPort(request.getServerPort());
1377        themeDisplay.setSecure(request.isSecure());
1378        themeDisplay.setLifecycle(lifecycle);
1379        themeDisplay.setLifecycleAction(lifecycle.equals("1"));
1380        themeDisplay.setLifecycleRender(lifecycle.equals("0"));
1381        themeDisplay.setLifecycleResource(lifecycle.equals("2"));
1382        themeDisplay.setStateExclusive(LiferayWindowState.isExclusive(request));
1383        themeDisplay.setStateMaximized(LiferayWindowState.isMaximized(request));
1384        themeDisplay.setStatePopUp(LiferayWindowState.isPopUp(request));
1385        themeDisplay.setPathApplet(contextPath.concat("/applets"));
1386        themeDisplay.setPathCms(contextPath.concat("/cms"));
1387        themeDisplay.setPathContext(contextPath);
1388        themeDisplay.setPathFlash(contextPath.concat("/flash"));
1389        themeDisplay.setPathFriendlyURLPrivateGroup(
1390            friendlyURLPrivateGroupPath);
1391        themeDisplay.setPathFriendlyURLPrivateUser(friendlyURLPrivateUserPath);
1392        themeDisplay.setPathFriendlyURLPublic(friendlyURLPublicPath);
1393        themeDisplay.setPathImage(imagePath);
1394        themeDisplay.setPathJavaScript(
1395            cdnHost.concat(contextPath).concat("/html/js"));
1396        themeDisplay.setPathMain(mainPath);
1397        themeDisplay.setPathSound(contextPath.concat("/html/sound"));
1398
1399        // URLs
1400
1401        themeDisplay.setShowAddContentIcon(false);
1402        themeDisplay.setShowHomeIcon(true);
1403        themeDisplay.setShowMyAccountIcon(signedIn);
1404        themeDisplay.setShowPageSettingsIcon(false);
1405        themeDisplay.setShowPortalIcon(true);
1406        themeDisplay.setShowSignInIcon(!signedIn);
1407        themeDisplay.setShowSignOutIcon(signedIn);
1408        themeDisplay.setShowStagingIcon(false);
1409
1410        PortletURL createAccountURL = new PortletURLImpl(
1411            request, PortletKeys.LOGIN, plid, PortletRequest.ACTION_PHASE);
1412
1413        createAccountURL.setWindowState(WindowState.MAXIMIZED);
1414        createAccountURL.setPortletMode(PortletMode.VIEW);
1415
1416        createAccountURL.setParameter("saveLastPath", "0");
1417        createAccountURL.setParameter(
1418            "struts_action", "/login/create_account");
1419
1420        themeDisplay.setURLCreateAccount(createAccountURL);
1421
1422        String currentURL = PortalUtil.getCurrentURL(request);
1423
1424        themeDisplay.setURLCurrent(currentURL);
1425
1426        String urlHome = portalURL + contextPath;
1427
1428        themeDisplay.setURLHome(urlHome);
1429
1430        if (layout != null) {
1431            Group group = layout.getGroup();
1432
1433            if (layout.getType().equals(LayoutConstants.TYPE_PORTLET)) {
1434                boolean freeformLayout =
1435                    layoutTypePortlet.getLayoutTemplateId().equals(
1436                        "freeform");
1437
1438                themeDisplay.setFreeformLayout(freeformLayout);
1439
1440                boolean hasUpdateLayoutPermission =
1441                    LayoutPermissionUtil.contains(
1442                        permissionChecker, layout, ActionKeys.UPDATE);
1443
1444                if (hasUpdateLayoutPermission) {
1445                    if (!LiferayWindowState.isMaximized(request)) {
1446                        themeDisplay.setShowAddContentIcon(true);
1447                    }
1448
1449                    themeDisplay.setShowLayoutTemplatesIcon(true);
1450
1451                    themeDisplay.setURLAddContent(
1452                        "LayoutConfiguration.toggle('".concat(
1453                            PortletKeys.LAYOUT_CONFIGURATION).concat("');"));
1454
1455                    themeDisplay.setURLLayoutTemplates(
1456                        "Liferay.Layout.showTemplates();");
1457                }
1458            }
1459
1460            boolean hasManageLayoutsPermission =
1461                GroupPermissionUtil.contains(
1462                    permissionChecker, scopeGroupId, ActionKeys.MANAGE_LAYOUTS);
1463
1464            if (group.isUser()) {
1465                if ((layout.isPrivateLayout() &&
1466                     !PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_MODIFIABLE) ||
1467                    (layout.isPublicLayout() &&
1468                     !PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_MODIFIABLE)) {
1469
1470                    hasManageLayoutsPermission = false;
1471                }
1472            }
1473
1474            if (hasManageLayoutsPermission) {
1475                themeDisplay.setShowPageSettingsIcon(true);
1476
1477                PortletURL pageSettingsURL = new PortletURLImpl(
1478                    request, PortletKeys.LAYOUT_MANAGEMENT, plid,
1479                    PortletRequest.RENDER_PHASE);
1480
1481                pageSettingsURL.setWindowState(WindowState.MAXIMIZED);
1482                pageSettingsURL.setPortletMode(PortletMode.VIEW);
1483
1484                pageSettingsURL.setParameter(
1485                    "struts_action", "/layout_management/edit_pages");
1486
1487                if (layout.isPrivateLayout()) {
1488                    pageSettingsURL.setParameter("tabs1", "private-pages");
1489                }
1490                else {
1491                    pageSettingsURL.setParameter("tabs1", "public-pages");
1492                }
1493
1494                pageSettingsURL.setParameter("redirect", currentURL);
1495                pageSettingsURL.setParameter(
1496                    "groupId", String.valueOf(scopeGroupId));
1497                pageSettingsURL.setParameter("selPlid", String.valueOf(plid));
1498
1499                themeDisplay.setURLPageSettings(pageSettingsURL);
1500            }
1501
1502            if (group.hasStagingGroup() && !group.isStagingGroup()) {
1503                themeDisplay.setShowAddContentIcon(false);
1504                themeDisplay.setShowLayoutTemplatesIcon(false);
1505                themeDisplay.setShowPageSettingsIcon(false);
1506                themeDisplay.setURLPublishToLive(null);
1507            }
1508
1509            // LEP-4987
1510
1511            if (group.hasStagingGroup() || group.isStagingGroup()) {
1512                boolean hasApproveProposalPermission =
1513                    GroupPermissionUtil.contains(
1514                        permissionChecker, scopeGroupId,
1515                        ActionKeys.APPROVE_PROPOSAL);
1516
1517                boolean hasManageStagingPermission =
1518                    GroupPermissionUtil.contains(
1519                        permissionChecker, scopeGroupId,
1520                        ActionKeys.MANAGE_STAGING);
1521
1522                boolean hasPublishStagingPermission =
1523                    GroupPermissionUtil.contains(
1524                        permissionChecker, scopeGroupId,
1525                        ActionKeys.PUBLISH_STAGING);
1526
1527                if (hasApproveProposalPermission ||
1528                    hasManageStagingPermission || hasPublishStagingPermission) {
1529
1530                    themeDisplay.setShowStagingIcon(true);
1531                }
1532
1533                if (hasPublishStagingPermission) {
1534                    PortletURL publishToLiveURL = new PortletURLImpl(
1535                        request, PortletKeys.LAYOUT_MANAGEMENT, plid,
1536                        PortletRequest.RENDER_PHASE);
1537
1538                    publishToLiveURL.setWindowState(
1539                        LiferayWindowState.EXCLUSIVE);
1540                    publishToLiveURL.setPortletMode(PortletMode.VIEW);
1541
1542                    publishToLiveURL.setParameter(
1543                        "struts_action", "/layout_management/export_pages");
1544
1545                    if (layout.isPrivateLayout()) {
1546                        publishToLiveURL.setParameter("tabs1", "private-pages");
1547                    }
1548                    else {
1549                        publishToLiveURL.setParameter("tabs1", "public-pages");
1550                    }
1551
1552                    publishToLiveURL.setParameter("pagesRedirect", currentURL);
1553                    publishToLiveURL.setParameter(
1554                        "groupId", String.valueOf(scopeGroupId));
1555                    publishToLiveURL.setParameter(
1556                        "selPlid", String.valueOf(plid));
1557
1558                    themeDisplay.setURLPublishToLive(publishToLiveURL);
1559                }
1560            }
1561
1562            String myAccountNamespace = PortalUtil.getPortletNamespace(
1563                PortletKeys.MY_ACCOUNT);
1564
1565            String myAccountRedirect = ParamUtil.getString(
1566                request, myAccountNamespace.concat("backURL"), currentURL);
1567
1568            PortletURL myAccountURL = new PortletURLImpl(
1569                request, PortletKeys.MY_ACCOUNT, plid,
1570                PortletRequest.RENDER_PHASE);
1571
1572            myAccountURL.setWindowState(WindowState.MAXIMIZED);
1573            myAccountURL.setPortletMode(PortletMode.VIEW);
1574
1575            myAccountURL.setParameter("struts_action", "/my_account/edit_user");
1576            myAccountURL.setParameter("backURL", myAccountRedirect);
1577
1578            themeDisplay.setURLMyAccount(myAccountURL);
1579        }
1580
1581        if ((!user.isActive()) ||
1582            (PropsValues.TERMS_OF_USE_REQUIRED &&
1583             !user.isAgreedToTermsOfUse())) {
1584
1585            themeDisplay.setShowAddContentIcon(false);
1586            themeDisplay.setShowMyAccountIcon(false);
1587            themeDisplay.setShowPageSettingsIcon(false);
1588        }
1589
1590        themeDisplay.setURLPortal(themeDisplay.getURLHome());
1591
1592        String urlSignIn = mainPath.concat("/portal/login");
1593
1594        if (layout != null) {
1595            urlSignIn = HttpUtil.addParameter(
1596                urlSignIn, "p_l_id", layout.getPlid());
1597        }
1598
1599        themeDisplay.setURLSignIn(urlSignIn);
1600
1601        themeDisplay.setURLSignOut(mainPath.concat("/portal/logout"));
1602
1603        PortletURL updateManagerURL = new PortletURLImpl(
1604            request, PortletKeys.UPDATE_MANAGER, plid,
1605            PortletRequest.RENDER_PHASE);
1606
1607        updateManagerURL.setWindowState(WindowState.MAXIMIZED);
1608        updateManagerURL.setPortletMode(PortletMode.VIEW);
1609
1610        updateManagerURL.setParameter("struts_action", "/update_manager/view");
1611
1612        themeDisplay.setURLUpdateManager(updateManagerURL);
1613
1614        request.setAttribute(WebKeys.THEME_DISPLAY, themeDisplay);
1615
1616        // Parallel render
1617
1618        boolean parallelRenderEnable = true;
1619
1620        if (layout != null) {
1621            List<String> portletIds = layoutTypePortlet.getPortletIds();
1622
1623            if (portletIds.size() == 1) {
1624                String portletId = portletIds.get(0);
1625
1626                Portlet portlet = PortletLocalServiceUtil.getPortletById(
1627                    portletId);
1628
1629                if ((portlet != null) && !portlet.isAjaxable()) {
1630                    parallelRenderEnable = false;
1631                }
1632            }
1633        }
1634
1635        Boolean parallelRenderEnableObj = Boolean.valueOf(ParamUtil.getBoolean(
1636            request, "p_p_parallel", parallelRenderEnable));
1637
1638        request.setAttribute(
1639            WebKeys.PORTLET_PARALLEL_RENDER, parallelRenderEnableObj);
1640    }
1641
1642    protected void updateUserLayouts(User user) throws Exception {
1643        Boolean hasPowerUserRole = null;
1644
1645        // Private layouts
1646
1647        boolean addDefaultUserPrivateLayouts = false;
1648
1649        if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_ENABLED &&
1650            PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_AUTO_CREATE) {
1651
1652            addDefaultUserPrivateLayouts = true;
1653
1654            if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_POWER_USER_REQUIRED) {
1655                if (hasPowerUserRole == null) {
1656                    hasPowerUserRole = hasPowerUserRole(user);
1657                }
1658
1659                if (!hasPowerUserRole.booleanValue()) {
1660                    addDefaultUserPrivateLayouts = false;
1661                }
1662            }
1663        }
1664
1665        if (addDefaultUserPrivateLayouts && !user.hasPrivateLayouts()) {
1666            addDefaultUserPrivateLayouts(user);
1667        }
1668
1669        boolean deleteDefaultUserPrivateLayouts = false;
1670
1671        if (!PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_ENABLED) {
1672            deleteDefaultUserPrivateLayouts = true;
1673        }
1674        else if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_POWER_USER_REQUIRED) {
1675            if (hasPowerUserRole == null) {
1676                hasPowerUserRole = hasPowerUserRole(user);
1677            }
1678
1679            if (!hasPowerUserRole.booleanValue()) {
1680                deleteDefaultUserPrivateLayouts = true;
1681            }
1682        }
1683
1684        if (deleteDefaultUserPrivateLayouts && user.hasPrivateLayouts()) {
1685            deleteDefaultUserPrivateLayouts(user);
1686        }
1687
1688        // Public pages
1689
1690        boolean addDefaultUserPublicLayouts = false;
1691
1692        if (PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_ENABLED &&
1693            PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_AUTO_CREATE) {
1694
1695            addDefaultUserPublicLayouts = true;
1696
1697            if (PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_POWER_USER_REQUIRED) {
1698                if (hasPowerUserRole == null) {
1699                    hasPowerUserRole = hasPowerUserRole(user);
1700                }
1701
1702                if (!hasPowerUserRole.booleanValue()) {
1703                    addDefaultUserPublicLayouts = false;
1704                }
1705            }
1706        }
1707
1708        if (addDefaultUserPublicLayouts && !user.hasPublicLayouts()) {
1709            addDefaultUserPublicLayouts(user);
1710        }
1711
1712        boolean deleteDefaultUserPublicLayouts = false;
1713
1714        if (!PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_ENABLED) {
1715            deleteDefaultUserPublicLayouts = true;
1716        }
1717        else if (PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_POWER_USER_REQUIRED) {
1718            if (hasPowerUserRole == null) {
1719                hasPowerUserRole = hasPowerUserRole(user);
1720            }
1721
1722            if (!hasPowerUserRole.booleanValue()) {
1723                deleteDefaultUserPublicLayouts = true;
1724            }
1725        }
1726
1727        if (deleteDefaultUserPublicLayouts && user.hasPublicLayouts()) {
1728            deleteDefaultUserPublicLayouts(user);
1729        }
1730    }
1731
1732    protected File privateLARFile;
1733    protected File publicLARFile;
1734
1735    private static final String _PATH_PORTAL_LAYOUT = "/portal/layout";
1736
1737    private static Log _log = LogFactoryUtil.getLog(ServicePreAction.class);
1738
1739}