1   /**
2    * Copyright (c) 2000-2008 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.PortalException;
29  import com.liferay.portal.SystemException;
30  import com.liferay.portal.kernel.events.Action;
31  import com.liferay.portal.kernel.events.ActionException;
32  import com.liferay.portal.kernel.language.LanguageUtil;
33  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
34  import com.liferay.portal.kernel.portlet.LiferayWindowState;
35  import com.liferay.portal.kernel.servlet.BrowserSniffer;
36  import com.liferay.portal.kernel.servlet.ImageServletTokenUtil;
37  import com.liferay.portal.kernel.util.GetterUtil;
38  import com.liferay.portal.kernel.util.LocaleUtil;
39  import com.liferay.portal.kernel.util.ParamUtil;
40  import com.liferay.portal.kernel.util.PropertiesUtil;
41  import com.liferay.portal.kernel.util.SafeProperties;
42  import com.liferay.portal.kernel.util.StringPool;
43  import com.liferay.portal.kernel.util.StringUtil;
44  import com.liferay.portal.kernel.util.Validator;
45  import com.liferay.portal.model.ColorScheme;
46  import com.liferay.portal.model.Company;
47  import com.liferay.portal.model.Group;
48  import com.liferay.portal.model.Image;
49  import com.liferay.portal.model.Layout;
50  import com.liferay.portal.model.LayoutSet;
51  import com.liferay.portal.model.LayoutTypePortlet;
52  import com.liferay.portal.model.Theme;
53  import com.liferay.portal.model.User;
54  import com.liferay.portal.model.impl.ColorSchemeImpl;
55  import com.liferay.portal.model.impl.GroupImpl;
56  import com.liferay.portal.model.impl.LayoutImpl;
57  import com.liferay.portal.model.impl.LayoutTypePortletImpl;
58  import com.liferay.portal.model.impl.ThemeImpl;
59  import com.liferay.portal.security.permission.ActionKeys;
60  import com.liferay.portal.security.permission.PermissionChecker;
61  import com.liferay.portal.security.permission.PermissionCheckerFactory;
62  import com.liferay.portal.security.permission.PermissionCheckerImpl;
63  import com.liferay.portal.security.permission.PermissionThreadLocal;
64  import com.liferay.portal.service.GroupLocalServiceUtil;
65  import com.liferay.portal.service.LayoutLocalServiceUtil;
66  import com.liferay.portal.service.LayoutSetLocalServiceUtil;
67  import com.liferay.portal.service.OrganizationLocalServiceUtil;
68  import com.liferay.portal.service.UserLocalServiceUtil;
69  import com.liferay.portal.service.impl.ImageLocalUtil;
70  import com.liferay.portal.service.impl.ThemeLocalUtil;
71  import com.liferay.portal.service.permission.GroupPermissionUtil;
72  import com.liferay.portal.service.permission.LayoutPermissionUtil;
73  import com.liferay.portal.service.permission.OrganizationPermissionUtil;
74  import com.liferay.portal.service.permission.UserPermissionUtil;
75  import com.liferay.portal.theme.ThemeDisplay;
76  import com.liferay.portal.theme.ThemeDisplayFactory;
77  import com.liferay.portal.util.CookieKeys;
78  import com.liferay.portal.util.LayoutClone;
79  import com.liferay.portal.util.LayoutCloneFactory;
80  import com.liferay.portal.util.PortalUtil;
81  import com.liferay.portal.util.PortletKeys;
82  import com.liferay.portal.util.PropsUtil;
83  import com.liferay.portal.util.PropsValues;
84  import com.liferay.portal.util.WebKeys;
85  import com.liferay.portlet.PortletURLImpl;
86  import com.liferay.util.ListUtil;
87  import com.liferay.util.dao.hibernate.QueryUtil;
88  import com.liferay.util.servlet.SessionErrors;
89  
90  import java.io.File;
91  
92  import java.util.ArrayList;
93  import java.util.HashMap;
94  import java.util.LinkedHashMap;
95  import java.util.List;
96  import java.util.Locale;
97  import java.util.Map;
98  import java.util.Properties;
99  import java.util.TimeZone;
100 
101 import javax.portlet.PortletMode;
102 import javax.portlet.PortletRequest;
103 import javax.portlet.PortletURL;
104 import javax.portlet.WindowState;
105 
106 import javax.servlet.http.HttpServletRequest;
107 import javax.servlet.http.HttpServletResponse;
108 import javax.servlet.http.HttpSession;
109 
110 import org.apache.commons.lang.time.StopWatch;
111 import org.apache.commons.logging.Log;
112 import org.apache.commons.logging.LogFactory;
113 import org.apache.struts.Globals;
114 
115 /**
116  * <a href="ServicePreAction.java.html"><b><i>View Source</i></b></a>
117  *
118  * @author Brian Wing Shun Chan
119  * @author Felix Ventero
120  *
121  */
122 public class ServicePreAction extends Action {
123 
124     public ServicePreAction() {
125         initImportLARFiles();
126     }
127 
128     public void run(HttpServletRequest req, HttpServletResponse res)
129         throws ActionException {
130 
131         StopWatch stopWatch = null;
132 
133         if (_log.isDebugEnabled()) {
134             stopWatch = new StopWatch();
135 
136             stopWatch.start();
137         }
138 
139         try {
140             servicePre(req, res);
141         }
142         catch (Exception e) {
143             _log.error(e, e);
144 
145             throw new ActionException(e);
146         }
147 
148         if (_log.isDebugEnabled()) {
149             _log.debug("Running takes " + stopWatch.getTime() + " ms");
150         }
151     }
152 
153     protected void addDefaultLayouts(User user)
154         throws PortalException, SystemException {
155 
156         if (user.hasPrivateLayouts()) {
157             return;
158         }
159 
160         Group userGroup = user.getGroup();
161 
162         if (privateLARFile != null) {
163             importLayoutsByLAR(
164                 user.getUserId(), userGroup.getGroupId(), true, privateLARFile);
165         }
166         else {
167             importLayoutsByProperties(user.getUserId(), userGroup.getGroupId());
168         }
169 
170         if (publicLARFile != null) {
171             importLayoutsByLAR(
172                 user.getUserId(), userGroup.getGroupId(), false, publicLARFile);
173         }
174     }
175 
176     protected void deleteDefaultLayouts(User user)
177         throws PortalException, SystemException {
178 
179         if (user.hasPrivateLayouts()) {
180             Group userGroup = user.getGroup();
181 
182             LayoutLocalServiceUtil.deleteLayouts(userGroup.getGroupId(), true);
183         }
184 
185         if (user.hasPublicLayouts()) {
186             Group userGroup = user.getGroup();
187 
188             LayoutLocalServiceUtil.deleteLayouts(userGroup.getGroupId(), false);
189         }
190     }
191 
192     protected Object[] getDefaultLayout(
193             HttpServletRequest req, User user, boolean signedIn)
194         throws PortalException, SystemException {
195 
196         // Check the virtual host
197 
198         LayoutSet layoutSet = (LayoutSet)req.getAttribute(
199             WebKeys.VIRTUAL_HOST_LAYOUT_SET);
200 
201         if (layoutSet != null) {
202             List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
203                 layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
204                 LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
205 
206             if (layouts.size() > 0) {
207                 Layout layout = layouts.get(0);
208 
209                 return new Object[] {layout, layouts};
210             }
211         }
212 
213         Layout layout = null;
214         List<Layout> layouts = null;
215 
216         if (signedIn) {
217 
218             // Check the user's personal layouts
219 
220             Group userGroup = user.getGroup();
221 
222             layouts = LayoutLocalServiceUtil.getLayouts(
223                 userGroup.getGroupId(), true,
224                 LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
225 
226             if (layouts.size() == 0) {
227                 layouts = LayoutLocalServiceUtil.getLayouts(
228                     userGroup.getGroupId(), false,
229                     LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
230             }
231 
232             if (layouts.size() > 0) {
233                 layout = layouts.get(0);
234             }
235 
236             // Check the user's communities
237 
238             if (layout == null) {
239                 LinkedHashMap<String, Object> groupParams =
240                     new LinkedHashMap<String, Object>();
241 
242                 groupParams.put("usersGroups", new Long(user.getUserId()));
243 
244                 List<Group> groups = GroupLocalServiceUtil.search(
245                     user.getCompanyId(), null, null, groupParams,
246                     QueryUtil.ALL_POS, QueryUtil.ALL_POS);
247 
248                 for (int i = 0; i < groups.size(); i++) {
249                     Group group = groups.get(i);
250 
251                     layouts = LayoutLocalServiceUtil.getLayouts(
252                         group.getGroupId(), true,
253                         LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
254 
255                     if (layouts.size() == 0) {
256                         layouts = LayoutLocalServiceUtil.getLayouts(
257                             group.getGroupId(), false,
258                             LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
259                     }
260 
261                     if (layouts.size() > 0) {
262                         layout = layouts.get(0);
263 
264                         break;
265                     }
266                 }
267             }
268         }
269         else {
270 
271             // Check the guest community
272 
273             Group guestGroup = GroupLocalServiceUtil.getGroup(
274                 user.getCompanyId(), GroupImpl.GUEST);
275 
276             layouts = LayoutLocalServiceUtil.getLayouts(
277                 guestGroup.getGroupId(), false,
278                 LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
279 
280             if (layouts.size() > 0) {
281                 layout = layouts.get(0);
282             }
283         }
284 
285         return new Object[] {layout, layouts};
286     }
287 
288     protected void importLayoutsByLAR(
289             long userId, long groupId, boolean privateLayout, File larFile)
290         throws PortalException, SystemException {
291 
292         Map<String, String[]> parameterMap = new HashMap<String, String[]>();
293 
294         parameterMap.put(
295             PortletDataHandlerKeys.PERMISSIONS,
296             new String[] {Boolean.TRUE.toString()});
297         parameterMap.put(
298             PortletDataHandlerKeys.USER_PERMISSIONS,
299             new String[] {Boolean.FALSE.toString()});
300         parameterMap.put(
301             PortletDataHandlerKeys.PORTLET_DATA,
302             new String[] {Boolean.TRUE.toString()});
303         parameterMap.put(
304             PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
305             new String[] {Boolean.TRUE.toString()});
306         parameterMap.put(
307             PortletDataHandlerKeys.PORTLET_SETUP,
308             new String[] {Boolean.TRUE.toString()});
309 
310         LayoutLocalServiceUtil.importLayouts(
311             userId, groupId, privateLayout, parameterMap, larFile);
312     }
313 
314     protected void importLayoutsByProperties(long userId, long groupId)
315         throws PortalException, SystemException {
316 
317         String name = PropsValues.DEFAULT_USER_LAYOUT_NAME;
318 
319         Layout layout = LayoutLocalServiceUtil.addLayout(
320             userId, groupId, true, LayoutImpl.DEFAULT_PARENT_LAYOUT_ID, name,
321             StringPool.BLANK, StringPool.BLANK, LayoutImpl.TYPE_PORTLET, false,
322             StringPool.BLANK);
323 
324         LayoutTypePortlet layoutTypePortlet =
325             (LayoutTypePortlet)layout.getLayoutType();
326 
327         String layoutTemplateId = PropsValues.DEFAULT_USER_LAYOUT_TEMPLATE_ID;
328 
329         layoutTypePortlet.setLayoutTemplateId(0, layoutTemplateId, false);
330 
331         for (int i = 0; i < 10; i++) {
332             String columnId = "column-" + i;
333             String portletIds = PropsUtil.get(
334                 PropsUtil.DEFAULT_USER_LAYOUT_COLUMN + i);
335 
336             String[] portletIdsArray = StringUtil.split(portletIds);
337 
338             layoutTypePortlet.addPortletIds(
339                 0, portletIdsArray, columnId, false);
340         }
341 
342         LayoutLocalServiceUtil.updateLayout(
343             layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
344             layout.getTypeSettings());
345 
346         boolean updateLayoutSet = false;
347 
348         LayoutSet layoutSet = layout.getLayoutSet();
349 
350         if (Validator.isNotNull(PropsValues.DEFAULT_USER_REGULAR_THEME_ID)) {
351             layoutSet.setThemeId(PropsValues.DEFAULT_USER_REGULAR_THEME_ID);
352 
353             updateLayoutSet = true;
354         }
355 
356         if (Validator.isNotNull(
357                 PropsValues.DEFAULT_USER_REGULAR_COLOR_SCHEME_ID)) {
358 
359             layoutSet.setColorSchemeId(
360                 PropsValues.DEFAULT_USER_REGULAR_COLOR_SCHEME_ID);
361 
362             updateLayoutSet = true;
363         }
364 
365         if (Validator.isNotNull(PropsValues.DEFAULT_WAP_THEME_ID)) {
366             layoutSet.setWapThemeId(PropsValues.DEFAULT_WAP_THEME_ID);
367 
368             updateLayoutSet = true;
369         }
370 
371         if (Validator.isNotNull(PropsValues.DEFAULT_WAP_COLOR_SCHEME_ID)) {
372             layoutSet.setWapColorSchemeId(
373                 PropsValues.DEFAULT_WAP_COLOR_SCHEME_ID);
374 
375             updateLayoutSet = true;
376         }
377 
378         if (updateLayoutSet) {
379             LayoutSetLocalServiceUtil.updateLayoutSet(layoutSet);
380         }
381     }
382 
383     protected Object[] getViewableLayouts(
384             HttpServletRequest req, User user,
385             PermissionChecker permissionChecker, Layout layout,
386             List<Layout> layouts)
387         throws PortalException, SystemException {
388 
389         if ((layouts != null) && (layouts.size() > 0)) {
390             boolean replaceLayout = true;
391 
392             if (LayoutPermissionUtil.contains(
393                     permissionChecker, layout, ActionKeys.VIEW)) {
394 
395                 replaceLayout = false;
396             }
397 
398             List<Layout> accessibleLayouts = new ArrayList<Layout>();
399 
400             for (int i = 0; i < layouts.size(); i++) {
401                 Layout curLayout = layouts.get(i);
402 
403                 if (!curLayout.isHidden() &&
404                     LayoutPermissionUtil.contains(
405                         permissionChecker, curLayout, ActionKeys.VIEW)) {
406 
407                     if ((accessibleLayouts.size() == 0) && replaceLayout) {
408                         layout = curLayout;
409                     }
410 
411                     accessibleLayouts.add(curLayout);
412                 }
413             }
414 
415             if (accessibleLayouts.size() == 0) {
416                 layouts = null;
417 
418                 SessionErrors.add(
419                     req, LayoutPermissionException.class.getName());
420             }
421             else {
422                 layouts = accessibleLayouts;
423             }
424         }
425 
426         return new Object[] {layout, layouts};
427     }
428 
429     protected void initImportLARFiles() {
430         String privateLARFileName = PropsValues.DEFAULT_USER_PRIVATE_LAYOUT_LAR;
431 
432         if (_log.isDebugEnabled()) {
433             _log.debug("Reading private LAR file " + privateLARFileName);
434         }
435 
436         if (Validator.isNotNull(privateLARFileName)) {
437             privateLARFile = new File(privateLARFileName);
438 
439             if (!privateLARFile.exists()) {
440                 _log.error(
441                     "Private LAR file " + privateLARFile + " does not exist");
442 
443                 privateLARFile = null;
444             }
445             else {
446                 if (_log.isDebugEnabled()) {
447                     _log.debug("Using private LAR file " + privateLARFileName);
448                 }
449             }
450         }
451 
452         String publicLARFileName = PropsValues.DEFAULT_USER_PUBLIC_LAYOUT_LAR;
453 
454         if (_log.isDebugEnabled()) {
455             _log.debug("Reading public LAR file " + publicLARFileName);
456         }
457 
458         if (Validator.isNotNull(publicLARFileName)) {
459             publicLARFile = new File(publicLARFileName);
460 
461             if (!publicLARFile.exists()) {
462                 _log.error(
463                     "Public LAR file " + publicLARFile + " does not exist");
464 
465                 publicLARFile = null;
466             }
467             else {
468                 if (_log.isDebugEnabled()) {
469                     _log.debug("Using public LAR file " + publicLARFileName);
470                 }
471             }
472         }
473     }
474 
475     protected boolean isViewableCommunity(
476             User user, long groupId, boolean privateLayout,
477             PermissionChecker permissionChecker)
478         throws PortalException, SystemException {
479 
480         Group group = GroupLocalServiceUtil.getGroup(groupId);
481 
482         // Inactive communities are not viewable
483 
484         if (!group.isActive()) {
485             return false;
486         }
487         else if (group.isStagingGroup()) {
488             Group liveGroup = group.getLiveGroup();
489 
490             if (!liveGroup.isActive()) {
491                 return false;
492             }
493         }
494 
495         // User private layouts are only viewable by the user and anyone who can
496         // update the user. The user must also be active.
497 
498         if (group.isUser()) {
499             long groupUserId = group.getClassPK();
500 
501             if (groupUserId == user.getUserId()) {
502                 return true;
503             }
504             else {
505                 User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
506 
507                 if (!groupUser.isActive()) {
508                     return false;
509                 }
510 
511                 if (privateLayout) {
512                     if (UserPermissionUtil.contains(
513                             permissionChecker, groupUserId,
514                             groupUser.getOrganizationIds(),
515                             ActionKeys.UPDATE)) {
516 
517                         return true;
518                     }
519                     else {
520                         return false;
521                     }
522                 }
523             }
524         }
525 
526         // Most public layouts are viewable
527 
528         if (!privateLayout) {
529             return true;
530         }
531 
532         // If the current group is staging, the live group should be checked
533         // for membership instead
534 
535         if (group.isStagingGroup()) {
536             groupId = group.getLiveGroupId();
537         }
538 
539         // Community or organization layouts are only viewable by users who
540         // belong to the community or organization, or by users who can update
541         // the community or organization
542 
543         if (group.isCommunity()) {
544             if (GroupLocalServiceUtil.hasUserGroup(user.getUserId(), groupId)) {
545                 return true;
546             }
547             else if (GroupPermissionUtil.contains(
548                         permissionChecker, groupId, ActionKeys.UPDATE)) {
549 
550                 return true;
551             }
552         }
553         else if (group.isOrganization()) {
554             long organizationId = group.getClassPK();
555 
556             if (OrganizationLocalServiceUtil.hasUserOrganization(
557                     user.getUserId(), organizationId)) {
558 
559                 return true;
560             }
561             else if (OrganizationPermissionUtil.contains(
562                         permissionChecker, organizationId, ActionKeys.UPDATE)) {
563 
564                 return true;
565             }
566         }
567 
568         return false;
569     }
570 
571     protected List<Layout> mergeAdditionalLayouts(
572             User user, Layout layout, List<Layout> layouts,
573             HttpServletRequest req)
574         throws PortalException, SystemException {
575 
576         if ((layout == null) || layout.isPrivateLayout()) {
577             return layouts;
578         }
579 
580         long layoutGroupId = layout.getGroupId();
581 
582         Group guestGroup = GroupLocalServiceUtil.getGroup(
583             user.getCompanyId(), GroupImpl.GUEST);
584 
585         if (layoutGroupId != guestGroup.getGroupId()) {
586             Group layoutGroup = GroupLocalServiceUtil.getGroup(layoutGroupId);
587 
588             Properties props = layoutGroup.getTypeSettingsProperties();
589 
590             boolean mergeGuestPublicPages = GetterUtil.getBoolean(
591                 props.getProperty("mergeGuestPublicPages"));
592 
593             if (!mergeGuestPublicPages) {
594                 return layouts;
595             }
596 
597             List<Layout> guestLayouts = LayoutLocalServiceUtil.getLayouts(
598                 guestGroup.getGroupId(), false,
599                 LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
600 
601             layouts.addAll(0, guestLayouts);
602         }
603         else {
604             HttpSession ses = req.getSession();
605 
606             Long previousGroupId = (Long)ses.getAttribute(
607                 WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_PREVIOUS);
608 
609             if ((previousGroupId != null) &&
610                 (previousGroupId.longValue() != layoutGroupId)) {
611 
612                 Group previousGroup = null;
613 
614                 try {
615                     previousGroup = GroupLocalServiceUtil.getGroup(
616                         previousGroupId.longValue());
617                 }
618                 catch (NoSuchGroupException nsge) {
619                     if (_log.isWarnEnabled()) {
620                         _log.warn(nsge);
621                     }
622 
623                     return layouts;
624                 }
625 
626                 Properties props = previousGroup.getTypeSettingsProperties();
627 
628                 boolean mergeGuestPublicPages = GetterUtil.getBoolean(
629                     props.getProperty("mergeGuestPublicPages"));
630 
631                 if (!mergeGuestPublicPages) {
632                     return layouts;
633                 }
634 
635                 List<Layout> previousLayouts =
636                     LayoutLocalServiceUtil.getLayouts(
637                         previousGroupId.longValue(), false,
638                         LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
639 
640                 layouts.addAll(previousLayouts);
641             }
642         }
643 
644         return layouts;
645     }
646 
647     protected void rememberVisitedGroupIds(
648         long currentGroupId, HttpServletRequest req) {
649 
650         String requestURI = GetterUtil.getString(req.getRequestURI());
651 
652         if (!requestURI.endsWith(_PATH_PORTAL_LAYOUT)) {
653             return;
654         }
655 
656         HttpSession ses = req.getSession();
657 
658         Long recentGroupId = (Long)ses.getAttribute(
659             WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_RECENT);
660 
661         Long previousGroupId = (Long)ses.getAttribute(
662             WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_PREVIOUS);
663 
664         if (recentGroupId == null) {
665             recentGroupId = new Long(currentGroupId);
666 
667             ses.setAttribute(
668                 WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_RECENT,
669                 recentGroupId);
670         }
671         else if (recentGroupId.longValue() != currentGroupId) {
672             previousGroupId = new Long(recentGroupId.longValue());
673 
674             recentGroupId = new Long(currentGroupId);
675 
676             ses.setAttribute(
677                 WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_RECENT,
678                 recentGroupId);
679 
680             ses.setAttribute(
681                 WebKeys.LIFERAY_SHARED_VISITED_GROUP_ID_PREVIOUS,
682                 previousGroupId);
683         }
684 
685         if (_log.isDebugEnabled()) {
686             _log.debug("Current group id " + currentGroupId);
687             _log.debug("Recent group id " + recentGroupId);
688             _log.debug("Previous group id " + previousGroupId);
689         }
690     }
691 
692     protected void servicePre(HttpServletRequest req, HttpServletResponse res)
693         throws Exception {
694 
695         HttpSession ses = req.getSession();
696 
697         // Company
698 
699         Company company = PortalUtil.getCompany(req);
700 
701         long companyId = company.getCompanyId();
702 
703         // CDN host
704 
705         String cdnHost = ParamUtil.getString(
706             req, "cdn_host", PortalUtil.getCDNHost());
707 
708         // Paths
709 
710         String contextPath = PortalUtil.getPathContext();
711         String friendlyURLPrivateGroupPath =
712             PortalUtil.getPathFriendlyURLPrivateGroup();
713         String friendlyURLPrivateUserPath =
714             PortalUtil.getPathFriendlyURLPrivateUser();
715         String friendlyURLPublicPath = PortalUtil.getPathFriendlyURLPublic();
716         String imagePath = PortalUtil.getPathImage();
717         String mainPath = PortalUtil.getPathMain();
718 
719         // Company logo
720 
721         String companyLogo =
722             imagePath + "/company_logo?img_id=" + company.getLogoId() + "&t=" +
723                 ImageServletTokenUtil.getToken(company.getLogoId());
724 
725         Image companyLogoImage = ImageLocalUtil.getCompanyLogo(
726             company.getLogoId());
727 
728         int companyLogoHeight = companyLogoImage.getHeight();
729         int companyLogoWidth = companyLogoImage.getWidth();
730 
731         String realCompanyLogo = companyLogo;
732         int realCompanyLogoHeight = companyLogoHeight;
733         int realCompanyLogoWidth = companyLogoWidth;
734 
735         // User
736 
737         User user = PortalUtil.getUser(req);
738 
739         boolean signedIn = false;
740 
741         if (user == null) {
742             user = company.getDefaultUser();
743         }
744         else if (!user.isDefaultUser()) {
745             signedIn = true;
746         }
747 
748         User realUser = user;
749 
750         Long realUserId = (Long)ses.getAttribute(WebKeys.USER_ID);
751 
752         if (realUserId != null) {
753             if (user.getUserId() != realUserId.longValue()) {
754                 realUser = UserLocalServiceUtil.getUserById(
755                     realUserId.longValue());
756             }
757         }
758 
759         String doAsUserId = ParamUtil.getString(req, "doAsUserId");
760 
761         // Permission checker
762 
763         PermissionCheckerImpl permissionChecker =
764             PermissionCheckerFactory.create(user, true);
765 
766         PermissionThreadLocal.setPermissionChecker(permissionChecker);
767 
768         // Locale
769 
770         Locale locale = (Locale)ses.getAttribute(Globals.LOCALE_KEY);
771 
772         if (locale == null) {
773             if (signedIn) {
774                 locale = user.getLocale();
775             }
776             else {
777 
778                 // User previously set their preferred language
779 
780                 String languageId = CookieKeys.getCookie(
781                     req, CookieKeys.GUEST_LANGUAGE_ID);
782 
783                 if (Validator.isNotNull(languageId)) {
784                     locale = LocaleUtil.fromLanguageId(languageId);
785                 }
786 
787                 // Get locale from the request
788 
789                 if ((locale == null) && PropsValues.LOCALE_DEFAULT_REQUEST) {
790                     locale = req.getLocale();
791                 }
792 
793                 // Get locale from the default user
794 
795                 if (locale == null) {
796                     locale = user.getLocale();
797                 }
798 
799                 if (Validator.isNull(locale.getCountry())) {
800 
801                     // Locales must contain the country code
802 
803                     locale = LanguageUtil.getLocale(locale.getLanguage());
804                 }
805 
806                 List<Locale> availableLocales = ListUtil.fromArray(
807                     LanguageUtil.getAvailableLocales());
808 
809                 if (!availableLocales.contains(locale)) {
810                     locale = user.getLocale();
811                 }
812             }
813 
814             ses.setAttribute(Globals.LOCALE_KEY, locale);
815 
816             LanguageUtil.updateCookie(res, locale);
817         }
818 
819         // Cookie support
820 
821         try {
822 
823             // LEP-4069
824 
825             CookieKeys.validateSupportCookie(req);
826         }
827         catch (Exception e) {
828             CookieKeys.addSupportCookie(res);
829         }
830 
831         // Time zone
832 
833         TimeZone timeZone = user.getTimeZone();
834 
835         if (timeZone == null) {
836             timeZone = company.getTimeZone();
837         }
838 
839         // Layouts
840 
841         if (signedIn) {
842             boolean layoutsRequired = user.isLayoutsRequired();
843 
844             if (layoutsRequired) {
845                 addDefaultLayouts(user);
846             }
847             else {
848                 deleteDefaultLayouts(user);
849             }
850         }
851 
852         Layout layout = null;
853         List<Layout> layouts = null;
854 
855         long plid = ParamUtil.getLong(req, "p_l_id");
856 
857         if (plid > 0) {
858             layout = LayoutLocalServiceUtil.getLayout(plid);
859         }
860         else {
861             long groupId = ParamUtil.getLong(req, "groupId");
862             boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
863             long layoutId = ParamUtil.getLong(req, "layoutId");
864 
865             if ((groupId > 0) && layoutId > 0) {
866                 layout = LayoutLocalServiceUtil.getLayout(
867                     groupId, privateLayout, layoutId);
868             }
869         }
870 
871         if (layout != null) {
872             try {
873                 if (!signedIn && PropsValues.AUTH_FORWARD_BY_REDIRECT) {
874                     req.setAttribute(WebKeys.REQUESTED_LAYOUT, layout);
875                 }
876 
877                 boolean isViewableCommunity = isViewableCommunity(
878                     user, layout.getGroupId(), layout.isPrivateLayout(),
879                     permissionChecker);
880 
881                 if (!isViewableCommunity) {
882                     layout = null;
883                 }
884                 else if (isViewableCommunity &&
885                         !LayoutPermissionUtil.contains(
886                             permissionChecker, layout, ActionKeys.VIEW)) {
887 
888                     layout = null;
889                 }
890                 else {
891                     layouts = LayoutLocalServiceUtil.getLayouts(
892                         layout.getGroupId(), layout.isPrivateLayout(),
893                         LayoutImpl.DEFAULT_PARENT_LAYOUT_ID);
894                 }
895             }
896             catch (NoSuchLayoutException nsle) {
897             }
898         }
899 
900         if (layout == null) {
901             Object[] defaultLayout = getDefaultLayout(req, user, signedIn);
902 
903             layout = (Layout)defaultLayout[0];
904             layouts = (List<Layout>)defaultLayout[1];
905 
906             req.setAttribute(WebKeys.LAYOUT_DEFAULT, Boolean.TRUE);
907         }
908 
909         Object[] viewableLayouts = getViewableLayouts(
910             req, user, permissionChecker, layout, layouts);
911 
912         String layoutSetLogo = null;
913 
914         layout = (Layout)viewableLayouts[0];
915         layouts = (List<Layout>)viewableLayouts[1];
916 
917         LayoutTypePortlet layoutTypePortlet = null;
918 
919         long portletGroupId = PortalUtil.getPortletGroupId(layout);
920 
921         rememberVisitedGroupIds(portletGroupId, req);
922 
923         layouts = mergeAdditionalLayouts(user, layout, layouts, req);
924 
925         if (layout != null) {
926             if (company.isCommunityLogo()) {
927                 LayoutSet layoutSet = layout.getLayoutSet();
928 
929                 if (layoutSet.isLogo()) {
930                     long logoId = layoutSet.getLogoId();
931 
932                     layoutSetLogo =
933                         imagePath + "/layout_set_logo?img_id=" + logoId +
934                             "&t=" + ImageServletTokenUtil.getToken(logoId);
935 
936                     Image layoutSetLogoImage = ImageLocalUtil.getCompanyLogo(
937                         logoId);
938 
939                     companyLogo = layoutSetLogo;
940                     companyLogoHeight = layoutSetLogoImage.getHeight();
941                     companyLogoWidth = layoutSetLogoImage.getWidth();
942                 }
943             }
944 
945             plid = layout.getPlid();
946 
947             // Updates to shared layouts are not reflected until the next time
948             // the user logs in because group layouts are cached in the session
949 
950             layout = (Layout)((LayoutImpl)layout).clone();
951 
952             layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
953 
954             LayoutClone layoutClone = LayoutCloneFactory.getInstance();
955 
956             if (layoutClone != null) {
957                 String typeSettings = layoutClone.get(req, plid);
958 
959                 if (typeSettings != null) {
960                     Properties props = new SafeProperties();
961 
962                     PropertiesUtil.load(props, typeSettings);
963 
964                     String stateMax = props.getProperty(
965                         LayoutTypePortletImpl.STATE_MAX);
966                     String stateMin = props.getProperty(
967                         LayoutTypePortletImpl.STATE_MIN);
968                     String modeAbout = props.getProperty(
969                         LayoutTypePortletImpl.MODE_ABOUT);
970                     String modeConfig = props.getProperty(
971                         LayoutTypePortletImpl.MODE_CONFIG);
972                     String modeEdit = props.getProperty(
973                         LayoutTypePortletImpl.MODE_EDIT);
974                     String modeEditDefaults = props.getProperty(
975                         LayoutTypePortletImpl.MODE_EDIT_DEFAULTS);
976                     String modeEditGuest = props.getProperty(
977                         LayoutTypePortletImpl.MODE_EDIT_GUEST);
978                     String modeHelp = props.getProperty(
979                         LayoutTypePortletImpl.MODE_HELP);
980                     String modePreview = props.getProperty(
981                         LayoutTypePortletImpl.MODE_PREVIEW);
982                     String modePrint = props.getProperty(
983                         LayoutTypePortletImpl.MODE_PRINT);
984 
985                     layoutTypePortlet.setStateMax(stateMax);
986                     layoutTypePortlet.setStateMin(stateMin);
987                     layoutTypePortlet.setModeAbout(modeAbout);
988                     layoutTypePortlet.setModeConfig(modeConfig);
989                     layoutTypePortlet.setModeEdit(modeEdit);
990                     layoutTypePortlet.setModeEditDefaults(modeEditDefaults);
991                     layoutTypePortlet.setModeEditGuest(modeEditGuest);
992                     layoutTypePortlet.setModeHelp(modeHelp);
993                     layoutTypePortlet.setModePreview(modePreview);
994                     layoutTypePortlet.setModePrint(modePrint);
995                 }
996             }
997 
998             req.setAttribute(WebKeys.LAYOUT, layout);
999             req.setAttribute(WebKeys.LAYOUTS, layouts);
1000
1001            if (layout.isPrivateLayout()) {
1002                permissionChecker.setCheckGuest(false);
1003            }
1004        }
1005
1006        // Theme and color scheme
1007
1008        Theme theme = null;
1009        ColorScheme colorScheme = null;
1010
1011        boolean wapTheme = BrowserSniffer.is_wap_xhtml(req);
1012
1013        if (layout != null) {
1014            if (wapTheme) {
1015                theme = layout.getWapTheme();
1016                colorScheme = layout.getWapColorScheme();
1017            }
1018            else {
1019                theme = layout.getTheme();
1020                colorScheme = layout.getColorScheme();
1021            }
1022        }
1023        else {
1024            String themeId = null;
1025            String colorSchemeId = null;
1026
1027            if (wapTheme) {
1028                themeId = ThemeImpl.getDefaultWapThemeId();
1029                colorSchemeId = ColorSchemeImpl.getDefaultWapColorSchemeId();
1030            }
1031            else {
1032                themeId = ThemeImpl.getDefaultRegularThemeId();
1033                colorSchemeId =
1034                    ColorSchemeImpl.getDefaultRegularColorSchemeId();
1035            }
1036
1037            theme = ThemeLocalUtil.getTheme(companyId, themeId, wapTheme);
1038            colorScheme = ThemeLocalUtil.getColorScheme(
1039                companyId, theme.getThemeId(), colorSchemeId, wapTheme);
1040        }
1041
1042        req.setAttribute(WebKeys.THEME, theme);
1043        req.setAttribute(WebKeys.COLOR_SCHEME, colorScheme);
1044
1045        boolean themeCssFastLoad = ParamUtil.getBoolean(
1046            req, "css_fast_load", PropsValues.THEME_CSS_FAST_LOAD);
1047
1048        boolean themeJsBarebone = PropsValues.JAVASCRIPT_BAREBONE_ENABLED;
1049
1050        if (themeJsBarebone) {
1051            if (signedIn) {
1052                themeJsBarebone = false;
1053            }
1054        }
1055
1056        boolean themeJsFastLoad = ParamUtil.getBoolean(
1057            req, "js_fast_load", PropsValues.JAVASCRIPT_FAST_LOAD);
1058
1059        String lifecycle = ParamUtil.getString(req, "p_p_lifecycle");
1060
1061        // Theme display
1062
1063        ThemeDisplay themeDisplay = ThemeDisplayFactory.create();
1064
1065        // Set the CDN host first because other methods (setLookAndFeel) depend
1066        // on it being set
1067
1068        themeDisplay.setCDNHost(cdnHost);
1069
1070        themeDisplay.setCompany(company);
1071        themeDisplay.setCompanyLogo(companyLogo);
1072        themeDisplay.setCompanyLogoHeight(companyLogoHeight);
1073        themeDisplay.setCompanyLogoWidth(companyLogoWidth);
1074        themeDisplay.setRealCompanyLogo(realCompanyLogo);
1075        themeDisplay.setRealCompanyLogoHeight(realCompanyLogoHeight);
1076        themeDisplay.setRealCompanyLogoWidth(realCompanyLogoWidth);
1077        themeDisplay.setUser(user);
1078        themeDisplay.setRealUser(realUser);
1079        themeDisplay.setDoAsUserId(doAsUserId);
1080        themeDisplay.setLayoutSetLogo(layoutSetLogo);
1081        themeDisplay.setLayout(layout);
1082        themeDisplay.setLayouts(layouts);
1083        themeDisplay.setPlid(plid);
1084        themeDisplay.setLayoutTypePortlet(layoutTypePortlet);
1085        themeDisplay.setPortletGroupId(portletGroupId);
1086        themeDisplay.setSignedIn(signedIn);
1087        themeDisplay.setPermissionChecker(permissionChecker);
1088        themeDisplay.setLocale(locale);
1089        themeDisplay.setLanguageId(LocaleUtil.toLanguageId(locale));
1090        themeDisplay.setTimeZone(timeZone);
1091        themeDisplay.setLookAndFeel(contextPath, theme, colorScheme);
1092        themeDisplay.setThemeCssFastLoad(themeCssFastLoad);
1093        themeDisplay.setThemeJsBarebone(themeJsBarebone);
1094        themeDisplay.setThemeJsFastLoad(themeJsFastLoad);
1095        themeDisplay.setServerName(req.getServerName());
1096        themeDisplay.setServerPort(req.getServerPort());
1097        themeDisplay.setSecure(req.isSecure());
1098        themeDisplay.setLifecycle(lifecycle);
1099        themeDisplay.setLifecycleAction(lifecycle.equals("1"));
1100        themeDisplay.setLifecycleRender(lifecycle.equals("0"));
1101        themeDisplay.setLifecycleResource(lifecycle.equals("2"));
1102        themeDisplay.setStateExclusive(LiferayWindowState.isExclusive(req));
1103        themeDisplay.setStateMaximized(LiferayWindowState.isMaximized(req));
1104        themeDisplay.setStatePopUp(LiferayWindowState.isPopUp(req));
1105        themeDisplay.setPathApplet(contextPath + "/applets");
1106        themeDisplay.setPathCms(contextPath + "/cms");
1107        themeDisplay.setPathContext(contextPath);
1108        themeDisplay.setPathFlash(contextPath + "/flash");
1109        themeDisplay.setPathFriendlyURLPrivateGroup(
1110            friendlyURLPrivateGroupPath);
1111        themeDisplay.setPathFriendlyURLPrivateUser(friendlyURLPrivateUserPath);
1112        themeDisplay.setPathFriendlyURLPublic(friendlyURLPublicPath);
1113        themeDisplay.setPathImage(imagePath);
1114        themeDisplay.setPathJavaScript(cdnHost + contextPath + "/html/js");
1115        themeDisplay.setPathMain(mainPath);
1116        themeDisplay.setPathSound(contextPath + "/html/sound");
1117
1118        // URLs
1119
1120        themeDisplay.setShowAddContentIcon(false);
1121        themeDisplay.setShowHomeIcon(true);
1122        themeDisplay.setShowMyAccountIcon(signedIn);
1123        themeDisplay.setShowPageSettingsIcon(false);
1124        themeDisplay.setShowPortalIcon(true);
1125        themeDisplay.setShowSignInIcon(!signedIn);
1126        themeDisplay.setShowSignOutIcon(signedIn);
1127        themeDisplay.setShowStagingIcon(false);
1128
1129        PortletURL createAccountURL = new PortletURLImpl(
1130            req, PortletKeys.MY_ACCOUNT, plid, PortletRequest.ACTION_PHASE);
1131
1132        createAccountURL.setWindowState(WindowState.MAXIMIZED);
1133        createAccountURL.setPortletMode(PortletMode.VIEW);
1134
1135        createAccountURL.setParameter(
1136            "struts_action", "/my_account/create_account");
1137
1138        themeDisplay.setURLCreateAccount(createAccountURL);
1139
1140        String currentURL = PortalUtil.getCurrentURL(req);
1141
1142        themeDisplay.setURLCurrent(currentURL);
1143
1144        String urlHome = PortalUtil.getPortalURL(req) + contextPath;
1145
1146        themeDisplay.setURLHome(urlHome);
1147
1148        if (layout != null) {
1149            Group group = layout.getGroup();
1150
1151            if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
1152                boolean freeformLayout =
1153                    layoutTypePortlet.getLayoutTemplateId().equals(
1154                        "freeform");
1155
1156                themeDisplay.setFreeformLayout(freeformLayout);
1157
1158                boolean hasUpdateLayoutPermission =
1159                    LayoutPermissionUtil.contains(
1160                        permissionChecker, layout, ActionKeys.UPDATE);
1161
1162                if (hasUpdateLayoutPermission) {
1163                    if (!LiferayWindowState.isMaximized(req)) {
1164                        themeDisplay.setShowAddContentIcon(true);
1165                    }
1166
1167                    themeDisplay.setShowLayoutTemplatesIcon(true);
1168
1169                    themeDisplay.setURLAddContent(
1170                        "LayoutConfiguration.toggle('" + plid + "', '" +
1171                            PortletKeys.LAYOUT_CONFIGURATION + "', '" +
1172                                doAsUserId + "');");
1173
1174                    themeDisplay.setURLLayoutTemplates(
1175                        "showLayoutTemplates();");
1176                }
1177            }
1178
1179            boolean hasManageLayoutsPermission =
1180                GroupPermissionUtil.contains(
1181                    permissionChecker, portletGroupId,
1182                    ActionKeys.MANAGE_LAYOUTS);
1183
1184            if (hasManageLayoutsPermission) {
1185                themeDisplay.setShowPageSettingsIcon(true);
1186
1187                PortletURL pageSettingsURL = new PortletURLImpl(
1188                    req, PortletKeys.LAYOUT_MANAGEMENT, plid,
1189                    PortletRequest.RENDER_PHASE);
1190
1191                pageSettingsURL.setWindowState(WindowState.MAXIMIZED);
1192                pageSettingsURL.setPortletMode(PortletMode.VIEW);
1193
1194                pageSettingsURL.setParameter(
1195                    "struts_action", "/layout_management/edit_pages");
1196
1197                if (layout.isPrivateLayout()) {
1198                    pageSettingsURL.setParameter("tabs1", "private-pages");
1199                }
1200                else {
1201                    pageSettingsURL.setParameter("tabs1", "public-pages");
1202                }
1203
1204                pageSettingsURL.setParameter("redirect", currentURL);
1205                pageSettingsURL.setParameter(
1206                    "groupId", String.valueOf(portletGroupId));
1207                pageSettingsURL.setParameter("selPlid", String.valueOf(plid));
1208
1209                themeDisplay.setURLPageSettings(pageSettingsURL);
1210
1211                PortletURL publishToLiveURL = new PortletURLImpl(
1212                    req, PortletKeys.LAYOUT_MANAGEMENT, plid,
1213                    PortletRequest.RENDER_PHASE);
1214
1215                publishToLiveURL.setWindowState(LiferayWindowState.EXCLUSIVE);
1216                publishToLiveURL.setPortletMode(PortletMode.VIEW);
1217
1218                publishToLiveURL.setParameter(
1219                    "struts_action", "/layout_management/export_pages");
1220
1221                publishToLiveURL.setParameter("popupId", "publish-to-live");
1222
1223                if (layout.isPrivateLayout()) {
1224                    publishToLiveURL.setParameter("tabs1", "private-pages");
1225                }
1226                else {
1227                    publishToLiveURL.setParameter("tabs1", "public-pages");
1228                }
1229
1230                publishToLiveURL.setParameter("pagesRedirect", currentURL);
1231                publishToLiveURL.setParameter(
1232                    "groupId", String.valueOf(portletGroupId));
1233                publishToLiveURL.setParameter("selPlid", String.valueOf(plid));
1234
1235                themeDisplay.setURLPublishToLive(publishToLiveURL);
1236            }
1237
1238            if (group.hasStagingGroup() && !group.isStagingGroup()) {
1239                themeDisplay.setShowAddContentIcon(false);
1240                themeDisplay.setShowLayoutTemplatesIcon(false);
1241                themeDisplay.setShowPageSettingsIcon(false);
1242                themeDisplay.setURLPublishToLive(null);
1243            }
1244
1245            // LEP-4987
1246
1247            if (group.hasStagingGroup() || group.isStagingGroup()) {
1248                boolean hasApproveProposalPermission =
1249                    GroupPermissionUtil.contains(
1250                        permissionChecker, portletGroupId,
1251                        ActionKeys.APPROVE_PROPOSAL);
1252
1253                if (hasManageLayoutsPermission) {
1254                    themeDisplay.setShowStagingIcon(true);
1255                }
1256                else if (hasApproveProposalPermission) {
1257                    themeDisplay.setShowStagingIcon(true);
1258                }
1259            }
1260
1261            String myAccountNamespace = PortalUtil.getPortletNamespace(
1262                PortletKeys.MY_ACCOUNT);
1263
1264            String myAccountRedirect = ParamUtil.getString(
1265                req, myAccountNamespace + "backURL", currentURL);
1266
1267            PortletURL myAccountURL = new PortletURLImpl(
1268                req, PortletKeys.MY_ACCOUNT, plid, PortletRequest.RENDER_PHASE);
1269
1270            myAccountURL.setWindowState(WindowState.MAXIMIZED);
1271            myAccountURL.setPortletMode(PortletMode.VIEW);
1272
1273            myAccountURL.setParameter("struts_action", "/my_account/edit_user");
1274            myAccountURL.setParameter("backURL", myAccountRedirect);
1275
1276            themeDisplay.setURLMyAccount(myAccountURL);
1277        }
1278
1279        if ((!user.isActive()) ||
1280            (PropsValues.TERMS_OF_USE_REQUIRED &&
1281             !user.isAgreedToTermsOfUse())) {
1282
1283            themeDisplay.setShowAddContentIcon(false);
1284            themeDisplay.setShowMyAccountIcon(false);
1285            themeDisplay.setShowPageSettingsIcon(false);
1286        }
1287
1288        themeDisplay.setURLPortal(themeDisplay.getURLHome());
1289        themeDisplay.setURLSignIn(mainPath + "/portal/login");
1290        themeDisplay.setURLSignOut(mainPath + "/portal/logout");
1291
1292        PortletURL updateManagerURL = new PortletURLImpl(
1293            req, PortletKeys.UPDATE_MANAGER, plid, PortletRequest.RENDER_PHASE);
1294
1295        updateManagerURL.setWindowState(WindowState.MAXIMIZED);
1296        updateManagerURL.setPortletMode(PortletMode.VIEW);
1297
1298        updateManagerURL.setParameter("struts_action", "/update_manager/view");
1299
1300        themeDisplay.setURLUpdateManager(updateManagerURL);
1301
1302        req.setAttribute(WebKeys.THEME_DISPLAY, themeDisplay);
1303
1304        // Parallel render
1305
1306        boolean parallelRenderEnable = true;
1307
1308        if (layout != null) {
1309            if (layoutTypePortlet.getPortletIds().size() == 1) {
1310                parallelRenderEnable = false;
1311            }
1312        }
1313
1314        Boolean parallelRenderEnableObj = Boolean.valueOf(
1315            ParamUtil.getBoolean(req, "p_p_parallel", parallelRenderEnable));
1316
1317        req.setAttribute(
1318            WebKeys.PORTLET_PARALLEL_RENDER, parallelRenderEnableObj);
1319    }
1320
1321    protected File privateLARFile;
1322    protected File publicLARFile;
1323
1324    private static final String _PATH_PORTAL_LAYOUT = "/portal/layout";
1325
1326    private static Log _log = LogFactory.getLog(ServicePreAction.class);
1327
1328}