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