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