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