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