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