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.struts;
24  
25  import com.liferay.portal.LayoutPermissionException;
26  import com.liferay.portal.PortletActiveException;
27  import com.liferay.portal.RequiredLayoutException;
28  import com.liferay.portal.RequiredRoleException;
29  import com.liferay.portal.UserActiveException;
30  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
31  import com.liferay.portal.kernel.portlet.LiferayWindowState;
32  import com.liferay.portal.kernel.util.HttpUtil;
33  import com.liferay.portal.kernel.util.JavaConstants;
34  import com.liferay.portal.kernel.util.ParamUtil;
35  import com.liferay.portal.kernel.util.StringMaker;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.kernel.util.Validator;
38  import com.liferay.portal.model.Layout;
39  import com.liferay.portal.model.Portlet;
40  import com.liferay.portal.model.PortletPreferencesIds;
41  import com.liferay.portal.model.User;
42  import com.liferay.portal.model.UserTracker;
43  import com.liferay.portal.model.UserTrackerPath;
44  import com.liferay.portal.model.impl.LayoutImpl;
45  import com.liferay.portal.security.auth.PrincipalException;
46  import com.liferay.portal.security.permission.ActionKeys;
47  import com.liferay.portal.security.permission.PermissionChecker;
48  import com.liferay.portal.service.LayoutLocalServiceUtil;
49  import com.liferay.portal.service.PortletLocalServiceUtil;
50  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
51  import com.liferay.portal.service.permission.PortletPermissionUtil;
52  import com.liferay.portal.service.persistence.UserTrackerPathUtil;
53  import com.liferay.portal.theme.ThemeDisplay;
54  import com.liferay.portal.util.LiveUsers;
55  import com.liferay.portal.util.PortalUtil;
56  import com.liferay.portal.util.PropsUtil;
57  import com.liferay.portal.util.PropsValues;
58  import com.liferay.portal.util.WebKeys;
59  import com.liferay.portlet.InvokerPortlet;
60  import com.liferay.portlet.PortletConfigFactory;
61  import com.liferay.portlet.PortletInstanceFactory;
62  import com.liferay.portlet.PortletPreferencesFactoryUtil;
63  import com.liferay.portlet.PortletURLImpl;
64  import com.liferay.portlet.RenderRequestFactory;
65  import com.liferay.portlet.RenderRequestImpl;
66  import com.liferay.portlet.RenderResponseFactory;
67  import com.liferay.portlet.RenderResponseImpl;
68  import com.liferay.util.servlet.SessionErrors;
69  
70  import java.io.IOException;
71  
72  import java.util.Date;
73  import java.util.HashSet;
74  import java.util.Iterator;
75  import java.util.List;
76  import java.util.Map.Entry;
77  import java.util.Map;
78  import java.util.Set;
79  
80  import javax.portlet.PortletConfig;
81  import javax.portlet.PortletContext;
82  import javax.portlet.PortletMode;
83  import javax.portlet.PortletPreferences;
84  import javax.portlet.PortletRequest;
85  import javax.portlet.WindowState;
86  
87  import javax.servlet.ServletContext;
88  import javax.servlet.ServletException;
89  import javax.servlet.http.HttpServletRequest;
90  import javax.servlet.http.HttpServletResponse;
91  import javax.servlet.http.HttpSession;
92  import javax.servlet.jsp.PageContext;
93  
94  import org.apache.commons.logging.Log;
95  import org.apache.commons.logging.LogFactory;
96  import org.apache.struts.action.ActionMapping;
97  import org.apache.struts.config.ForwardConfig;
98  import org.apache.struts.tiles.TilesRequestProcessor;
99  
100 /**
101  * <a href="PortalRequestProcessor.java.html"><b><i>View Source</i></b></a>
102  *
103  * @author Brian Wing Shun Chan
104  * @author Jorge Ferrer
105  *
106  */
107 public class PortalRequestProcessor extends TilesRequestProcessor {
108 
109     public PortalRequestProcessor() {
110 
111         // auth.forward.last.path.
112 
113         _lastPaths = new HashSet<String>();
114 
115         _lastPaths.add(_PATH_PORTAL_LAYOUT);
116 
117         _addPaths(_lastPaths, PropsUtil.AUTH_FORWARD_LAST_PATHS);
118 
119         // auth.public.path.
120 
121         _publicPaths = new HashSet<String>();
122 
123         _publicPaths.add(_PATH_C);
124         _publicPaths.add(_PATH_PORTAL_CSS);
125         _publicPaths.add(_PATH_PORTAL_CSS_CACHED);
126         _publicPaths.add(_PATH_PORTAL_FLASH);
127         _publicPaths.add(_PATH_PORTAL_J_LOGIN);
128         _publicPaths.add(_PATH_PORTAL_JAVASCRIPT);
129         _publicPaths.add(_PATH_PORTAL_JAVASCRIPT_CACHED);
130         _publicPaths.add(_PATH_PORTAL_LAYOUT);
131         _publicPaths.add(_PATH_PORTAL_LOGIN);
132         _publicPaths.add(_PATH_PORTAL_LOGIN_CAPTCHA);
133         _publicPaths.add(_PATH_PORTAL_RENDER_PORTLET);
134         _publicPaths.add(_PATH_PORTAL_TCK);
135 
136         _addPaths(_publicPaths, PropsUtil.AUTH_PUBLIC_PATHS);
137 
138         _trackerIgnorePaths = new HashSet<String>();
139 
140         _addPaths(_trackerIgnorePaths, PropsUtil.SESSION_TRACKER_IGNORE_PATHS);
141     }
142 
143     public void process(HttpServletRequest req, HttpServletResponse res)
144         throws IOException, ServletException {
145 
146         String path = super.processPath(req, res);
147 
148         ActionMapping mapping =
149             (ActionMapping)moduleConfig.findActionConfig(path);
150 
151         if ((mapping == null) && !path.startsWith(_PATH_WSRP)) {
152             String lastPath = getLastPath(req);
153 
154             if (_log.isDebugEnabled()) {
155                 _log.debug("Last path " + lastPath);
156             }
157 
158             res.sendRedirect(lastPath);
159 
160             return;
161         }
162 
163         super.process(req, res);
164 
165         try {
166             if (isPortletPath(path)) {
167                 cleanUp(req);
168             }
169         }
170         catch (Exception e) {
171             _log.error(e, e);
172         }
173     }
174 
175     protected void callParentDoForward(
176             String uri, HttpServletRequest req, HttpServletResponse res)
177         throws IOException, ServletException {
178 
179         super.doForward(uri, req, res);
180     }
181 
182     protected void doForward(
183             String uri, HttpServletRequest req, HttpServletResponse res)
184         throws IOException, ServletException {
185 
186         StrutsUtil.forward(uri, getServletContext(), req, res);
187     }
188 
189     protected void doInclude(
190             String uri, HttpServletRequest req, HttpServletResponse res)
191         throws IOException, ServletException {
192 
193         StrutsUtil.include(uri, getServletContext(), req, res);
194     }
195 
196     protected HttpServletRequest callParentProcessMultipart(
197         HttpServletRequest req) {
198 
199         return super.processMultipart(req);
200     }
201 
202     protected HttpServletRequest processMultipart(HttpServletRequest req) {
203 
204         // Disable Struts from automatically wrapping a multipart request
205 
206         return req;
207     }
208 
209     protected String callParentProcessPath(
210             HttpServletRequest req, HttpServletResponse res)
211         throws IOException {
212 
213         return super.processPath(req, res);
214     }
215 
216     protected StringMaker getFriendlyTrackerPath(
217             String path, ThemeDisplay themeDisplay, HttpServletRequest req)
218         throws Exception {
219 
220         if (!path.equals(_PATH_PORTAL_LAYOUT)) {
221             return null;
222         }
223 
224         long plid = ParamUtil.getLong(req, "p_l_id");
225 
226         if (plid == 0) {
227             return null;
228         }
229 
230         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
231 
232         String layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
233             layout, themeDisplay);
234 
235         StringMaker sm = new StringMaker();
236 
237         sm.append(layoutFriendlyURL);
238 
239         String portletId = ParamUtil.getString(req, "p_p_id");
240 
241         if (Validator.isNull(portletId)) {
242             return sm;
243         }
244 
245         long companyId = PortalUtil.getCompanyId(req);
246 
247         Portlet portlet = PortletLocalServiceUtil.getPortletById(
248             companyId, portletId);
249 
250         if (portlet == null) {
251             String strutsPath = path.substring(
252                 1, path.lastIndexOf(StringPool.SLASH));
253 
254             portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
255                 companyId, strutsPath);
256         }
257 
258         if ((portlet == null) || !portlet.isActive()) {
259             sm.append(StringPool.QUESTION);
260             sm.append(req.getQueryString());
261 
262             return sm;
263         }
264 
265         String namespace = PortalUtil.getPortletNamespace(portletId);
266 
267         FriendlyURLMapper friendlyURLMapper =
268             portlet.getFriendlyURLMapperInstance();
269 
270         if (friendlyURLMapper == null) {
271             sm.append(StringPool.QUESTION);
272             sm.append(req.getQueryString());
273 
274             return sm;
275         }
276 
277         PortletURLImpl portletURL = new PortletURLImpl(
278             req, portletId, plid, PortletRequest.RENDER_PHASE);
279 
280         Iterator<Map.Entry<String, String[]>> itr =
281             req.getParameterMap().entrySet().iterator();
282 
283         while (itr.hasNext()) {
284             Entry<String, String[]> entry = itr.next();
285 
286             String key = entry.getKey();
287 
288             if (key.startsWith(namespace)) {
289                 key = key.substring(namespace.length());
290 
291                 portletURL.setParameter(key, entry.getValue());
292             }
293         }
294 
295         String portletFriendlyURL = friendlyURLMapper.buildPath(portletURL);
296 
297         if (portletFriendlyURL != null) {
298             sm.append(portletFriendlyURL);
299         }
300         else {
301             sm.append(StringPool.QUESTION);
302             sm.append(req.getQueryString());
303         }
304 
305         return sm;
306     }
307 
308     protected String processPath(
309             HttpServletRequest req, HttpServletResponse res)
310         throws IOException {
311 
312         String path = super.processPath(req, res);
313 
314         HttpSession ses = req.getSession();
315 
316         ThemeDisplay themeDisplay =
317             (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
318 
319         // Current users
320 
321         UserTracker userTracker = LiveUsers.getUserTracker(ses.getId());
322 
323         if ((userTracker != null) && (path != null) &&
324             (!path.equals(_PATH_C)) &&
325             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
326             (path.indexOf(_PATH_PORTAL_PROTECTED) == -1) &&
327             (!_trackerIgnorePaths.contains(path))) {
328 
329             StringMaker sm = null;
330 
331             try {
332                 if (PropsValues.SESSION_TRACKER_FRIENDLY_PATHS_ENABLED) {
333                     sm = getFriendlyTrackerPath(path, themeDisplay, req);
334                 }
335             }
336             catch (Exception e) {
337                 _log.error(e, e);
338             }
339 
340             if (sm == null) {
341                 sm = new StringMaker();
342 
343                 sm.append(path);
344                 sm.append(StringPool.QUESTION);
345                 sm.append(req.getQueryString());
346             }
347 
348             UserTrackerPath userTrackerPath = UserTrackerPathUtil.create(0);
349 
350             userTrackerPath.setUserTrackerId(userTracker.getUserTrackerId());
351             userTrackerPath.setPath(sm.toString());
352             userTrackerPath.setPathDate(new Date());
353 
354             userTracker.addPath(userTrackerPath);
355         }
356 
357         String remoteUser = req.getRemoteUser();
358 
359         User user = null;
360 
361         try {
362             user = PortalUtil.getUser(req);
363         }
364         catch (Exception e) {
365         }
366 
367         // Last path
368 
369         if ((path != null) && (_lastPaths.contains(path)) &&
370             (!_trackerIgnorePaths.contains(path))) {
371 
372             boolean saveLastPath = ParamUtil.getBoolean(
373                 req, "save_last_path", true);
374 
375             // Exclusive and pop up window states should never be set as the
376             // last path
377 
378             if (LiferayWindowState.isExclusive(req) ||
379                 LiferayWindowState.isPopUp(req)) {
380 
381                 saveLastPath = false;
382             }
383 
384             // Save last path
385 
386             if (saveLastPath) {
387 
388                 // Was a last path set by another servlet that dispatched to
389                 // the MainServlet? If so, use that last path instead.
390 
391                 LastPath lastPath = (LastPath)req.getAttribute(
392                     WebKeys.LAST_PATH);
393 
394                 if (lastPath == null) {
395                     lastPath = new LastPath(
396                         themeDisplay.getPathMain(), path,
397                         req.getParameterMap());
398                 }
399 
400                 ses.setAttribute(WebKeys.LAST_PATH, lastPath);
401             }
402         }
403 
404         // Authenticated users can always log out
405 
406         if (((remoteUser != null) || (user != null)) && (path != null) &&
407             (path.equals(_PATH_PORTAL_LOGOUT))) {
408 
409             return path;
410         }
411 
412         // Authenticated users can always extend or confirm their session
413 
414         if (((remoteUser != null) || (user != null)) && (path != null) &&
415             (path.equals(_PATH_PORTAL_EXPIRE_SESSION) ||
416              path.equals(_PATH_PORTAL_EXTEND_SESSION))) {
417 
418             return path;
419         }
420 
421         // Authenticated users can retrieve CSS and JavaScript
422 
423         if (((remoteUser != null) || (user != null)) && (path != null) &&
424             (path.equals(_PATH_PORTAL_CSS) ||
425              path.equals(_PATH_PORTAL_CSS_CACHED) ||
426              path.equals(_PATH_PORTAL_JAVASCRIPT) ||
427              path.equals(_PATH_PORTAL_JAVASCRIPT_CACHED))) {
428 
429             return path;
430         }
431 
432         // Authenticated users can always agree to terms of use
433 
434         if (((remoteUser != null) || (user != null)) && (path != null) &&
435             (path.equals(_PATH_PORTAL_UPDATE_TERMS_OF_USE))) {
436 
437             return path;
438         }
439 
440         // Authenticated users must still exist in the system
441 
442         if ((remoteUser != null) && (user == null)) {
443             return _PATH_PORTAL_LOGOUT;
444         }
445 
446         // Authenticated users must agree to Terms of Use
447 
448         if ((user != null) && (!user.isAgreedToTermsOfUse())) {
449             if (PropsValues.TERMS_OF_USE_REQUIRED) {
450                 return _PATH_PORTAL_TERMS_OF_USE;
451             }
452         }
453 
454         // Authenticated users must be active
455 
456         if ((user != null) && (!user.isActive())) {
457             SessionErrors.add(req, UserActiveException.class.getName());
458 
459             return _PATH_PORTAL_ERROR;
460         }
461 
462         // Authenticated users may not be allowed to have simultaneous logins
463 
464         if (!PropsValues.AUTH_SIMULTANEOUS_LOGINS) {
465             Boolean staleSession =
466                 (Boolean)ses.getAttribute(WebKeys.STALE_SESSION);
467 
468             if ((user != null) && (staleSession != null) &&
469                 (staleSession.booleanValue())) {
470 
471                 return _PATH_PORTAL_ERROR;
472             }
473         }
474 
475         // Authenticated users must have a current password
476 
477         if ((user != null) && (user.isPasswordReset())) {
478             return _PATH_PORTAL_CHANGE_PASSWORD;
479         }
480 
481         // Authenticated users must have at least one personalized page
482 
483         if (user != null) {
484             List<Layout> layouts = themeDisplay.getLayouts();
485 
486             if ((layouts == null) || (layouts.size() == 0)) {
487                 SessionErrors.add(
488                     req, RequiredLayoutException.class.getName());
489 
490                 return _PATH_PORTAL_ERROR;
491             }
492         }
493 
494         // Users must sign in
495 
496         if (!isPublicPath(path)) {
497             if (user == null) {
498                 SessionErrors.add(req, PrincipalException.class.getName());
499 
500                 return _PATH_PORTAL_LOGIN;
501             }
502         }
503 
504         ActionMapping mapping =
505             (ActionMapping)moduleConfig.findActionConfig(path);
506 
507         if (path.startsWith(_PATH_WSRP)) {
508             path = _PATH_WSRP;
509         }
510         else {
511             path = mapping.getPath();
512         }
513 
514         // Authenticated users must have at least one role
515 
516         if (user != null) {
517             try {
518 
519                 // FIX ME
520 
521                 if (false) {
522                     SessionErrors.add(
523                         req, RequiredRoleException.class.getName());
524 
525                     return _PATH_PORTAL_ERROR;
526                 }
527             }
528             catch (Exception e) {
529                 e.printStackTrace();
530             }
531         }
532 
533         // Define the portlet objects
534 
535         if (isPortletPath(path)) {
536             try {
537                 Portlet portlet = null;
538 
539                 long companyId = PortalUtil.getCompanyId(req);
540                 String portletId = ParamUtil.getString(req, "p_p_id");
541 
542                 if (Validator.isNotNull(portletId)) {
543                     portlet = PortletLocalServiceUtil.getPortletById(
544                         companyId, portletId);
545                 }
546 
547                 if (portlet == null) {
548                     String strutsPath = path.substring(
549                         1, path.lastIndexOf(StringPool.SLASH));
550 
551                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
552                         companyId, strutsPath);
553                 }
554 
555                 if ((portlet != null) && portlet.isActive()) {
556                     defineObjects(req, res, portlet);
557                 }
558             }
559             catch (Exception e) {
560                 req.setAttribute(PageContext.EXCEPTION, e);
561 
562                 path = _PATH_COMMON_ERROR;
563             }
564         }
565 
566         // Authenticated users must have access to at least one layout
567 
568         if (SessionErrors.contains(
569                 req, LayoutPermissionException.class.getName())) {
570 
571             return _PATH_PORTAL_ERROR;
572         }
573 
574         return path;
575     }
576 
577     protected boolean callParentProcessRoles(
578             HttpServletRequest req, HttpServletResponse res,
579             ActionMapping mapping)
580         throws IOException, ServletException {
581 
582         return super.processRoles(req, res, mapping);
583     }
584 
585     protected boolean processRoles(
586             HttpServletRequest req, HttpServletResponse res,
587             ActionMapping mapping)
588         throws IOException, ServletException {
589 
590         String path = mapping.getPath();
591 
592         if (isPublicPath(path)) {
593             return true;
594         }
595 
596         boolean authorized = true;
597 
598         User user = null;
599 
600         try {
601             user = PortalUtil.getUser(req);
602         }
603         catch (Exception e) {
604         }
605 
606         if ((user != null) && isPortletPath(path)) {
607             try {
608 
609                 // Authenticated users can always log out
610 
611                 if (path.equals(_PATH_PORTAL_LOGOUT)) {
612                     return true;
613                 }
614 
615                 Portlet portlet = null;
616 
617                 String portletId = ParamUtil.getString(req, "p_p_id");
618 
619                 if (Validator.isNotNull(portletId)) {
620                     portlet = PortletLocalServiceUtil.getPortletById(
621                         user.getCompanyId(), portletId);
622                 }
623 
624                 String strutsPath = path.substring(
625                     1, path.lastIndexOf(StringPool.SLASH));
626 
627                 if (portlet != null) {
628                     if (!strutsPath.equals(portlet.getStrutsPath())) {
629                         throw new PrincipalException();
630                     }
631                 }
632                 else {
633                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
634                         user.getCompanyId(), strutsPath);
635                 }
636 
637                 if ((portlet != null) && portlet.isActive()) {
638                     ThemeDisplay themeDisplay =
639                         (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
640 
641                     Layout layout = themeDisplay.getLayout();
642                     PermissionChecker permissionChecker =
643                         themeDisplay.getPermissionChecker();
644 
645                     if (!PortletPermissionUtil.contains(
646                             permissionChecker, layout.getPlid(), portlet,
647                             ActionKeys.VIEW)) {
648 
649                         throw new PrincipalException();
650                     }
651                 }
652                 else if (portlet != null && !portlet.isActive()) {
653                     SessionErrors.add(
654                         req, PortletActiveException.class.getName());
655 
656                     authorized = false;
657                 }
658             }
659             catch (Exception e) {
660                 SessionErrors.add(req, PrincipalException.class.getName());
661 
662                 authorized = false;
663             }
664         }
665 
666         if (!authorized) {
667             ForwardConfig forwardConfig =
668                 mapping.findForward(_PATH_PORTAL_ERROR);
669 
670             processForwardConfig(req, res, forwardConfig);
671 
672             return false;
673         }
674         else {
675             return true;
676         }
677     }
678 
679     protected String getLastPath(HttpServletRequest req) {
680         HttpSession ses = req.getSession();
681 
682         ThemeDisplay themeDisplay =
683             (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
684 
685         Boolean httpsInitial = (Boolean)ses.getAttribute(WebKeys.HTTPS_INITIAL);
686 
687         String portalURL = null;
688 
689         if ((PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS) &&
690             (httpsInitial != null) && (!httpsInitial.booleanValue())) {
691 
692             portalURL = PortalUtil.getPortalURL(req, false);
693         }
694         else {
695             portalURL = PortalUtil.getPortalURL(req);
696         }
697 
698         StringMaker sm = new StringMaker();
699 
700         sm.append(portalURL);
701         sm.append(themeDisplay.getPathMain());
702         sm.append(_PATH_PORTAL_LAYOUT);
703 
704         if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
705             if (req.getRemoteUser() != null) {
706 
707                 // If we do not forward by last path and the user is logged in,
708                 // forward to the user's default layout to prevent a lagging
709                 // loop
710 
711                 sm.append(StringPool.QUESTION);
712                 sm.append("p_l_id");
713                 sm.append(StringPool.EQUAL);
714                 sm.append(LayoutImpl.DEFAULT_PLID);
715             }
716 
717             return sm.toString();
718         }
719 
720         LastPath lastPath = (LastPath)ses.getAttribute(WebKeys.LAST_PATH);
721 
722         if (lastPath == null) {
723             return sm.toString();
724         }
725 
726         Map<String, String[]> parameterMap = lastPath.getParameterMap();
727 
728         // Only test for existing mappings for last paths that were set when the
729         // user accessed a layout directly instead of through its friendly URL
730 
731         if (lastPath.getContextPath().equals(themeDisplay.getPathMain())) {
732             ActionMapping mapping =
733                 (ActionMapping)moduleConfig.findActionConfig(
734                     lastPath.getPath());
735 
736             if ((mapping == null) || (parameterMap == null)) {
737                 return sm.toString();
738             }
739         }
740 
741         StringMaker lastPathSM = new StringMaker();
742 
743         lastPathSM.append(portalURL);
744         lastPathSM.append(lastPath.getContextPath());
745         lastPathSM.append(lastPath.getPath());
746         lastPathSM.append(HttpUtil.parameterMapToString(parameterMap));
747 
748         return lastPathSM.toString();
749     }
750 
751     protected boolean isPortletPath(String path) {
752         if ((path != null) &&
753             (!path.equals(_PATH_C)) &&
754             (!path.startsWith(_PATH_COMMON)) &&
755             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
756             (!path.startsWith(_PATH_PORTAL)) &&
757             (!path.startsWith(_PATH_WSRP))) {
758 
759             return true;
760         }
761         else {
762             return false;
763         }
764     }
765 
766     protected boolean isPublicPath(String path) {
767         if ((path != null) &&
768             (_publicPaths.contains(path)) ||
769             (path.startsWith(_PATH_COMMON)) ||
770             (path.startsWith(_PATH_WSRP))) {
771 
772             return true;
773         }
774         else {
775             return false;
776         }
777     }
778 
779     protected void defineObjects(
780             HttpServletRequest req, HttpServletResponse res, Portlet portlet)
781         throws Exception {
782 
783         String portletId = portlet.getPortletId();
784 
785         ServletContext ctx =
786             (ServletContext)req.getAttribute(WebKeys.CTX);
787 
788         InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
789             portlet, ctx);
790 
791         PortletPreferencesIds portletPreferencesIds =
792             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
793                 req, portletId);
794 
795         PortletPreferences portletPreferences =
796             PortletPreferencesLocalServiceUtil.getPreferences(
797                 portletPreferencesIds);
798 
799         PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
800         PortletContext portletCtx = portletConfig.getPortletContext();
801 
802         RenderRequestImpl renderReqImpl = RenderRequestFactory.create(
803             req, portlet, invokerPortlet, portletCtx, WindowState.MAXIMIZED,
804             PortletMode.VIEW, portletPreferences);
805 
806         RenderResponseImpl renderResImpl = RenderResponseFactory.create(
807             renderReqImpl, res, portletId, portlet.getCompanyId());
808 
809         renderReqImpl.defineObjects(portletConfig, renderResImpl);
810 
811         req.setAttribute(WebKeys.PORTLET_STRUTS_EXECUTE, Boolean.TRUE);
812     }
813 
814     protected void cleanUp(HttpServletRequest req) throws Exception {
815 
816         // Clean up portlet objects that may have been created by defineObjects
817         // for portlets that are called directly from a Struts path
818 
819         RenderRequestImpl renderReqImpl = (RenderRequestImpl)req.getAttribute(
820             JavaConstants.JAVAX_PORTLET_REQUEST);
821 
822         if (renderReqImpl != null) {
823             RenderRequestFactory.recycle(renderReqImpl);
824         }
825 
826         RenderResponseImpl renderResImpl = (RenderResponseImpl)req.getAttribute(
827             JavaConstants.JAVAX_PORTLET_RESPONSE);
828 
829         if (renderResImpl != null) {
830             RenderResponseFactory.recycle(renderResImpl);
831         }
832     }
833 
834     private void _addPaths(Set<String> paths, String propsKey) {
835         String[] pathsArray = PropsUtil.getArray(propsKey);
836 
837         for (int i = 0; i < pathsArray.length; i++) {
838             paths.add(pathsArray[i]);
839         }
840     }
841 
842     private static String _PATH_C = "/c";
843 
844     private static String _PATH_COMMON = "/common";
845 
846     private static String _PATH_COMMON_ERROR = "/common/error";
847 
848     private static String _PATH_J_SECURITY_CHECK = "/j_security_check";
849 
850     private static String _PATH_PORTAL = "/portal";
851 
852     private static String _PATH_PORTAL_CHANGE_PASSWORD =
853         "/portal/change_password";
854 
855     private static String _PATH_PORTAL_CSS = "/portal/css";
856 
857     private static String _PATH_PORTAL_CSS_CACHED = "/portal/css_cached";
858 
859     private static String _PATH_PORTAL_ERROR = "/portal/error";
860 
861     private static String _PATH_PORTAL_EXPIRE_SESSION =
862         "/portal/expire_session";
863 
864     private static String _PATH_PORTAL_EXTEND_SESSION =
865         "/portal/extend_session";
866 
867     private static String _PATH_PORTAL_FLASH = "/portal/flash";
868 
869     private static String _PATH_PORTAL_J_LOGIN = "/portal/j_login";
870 
871     private static String _PATH_PORTAL_JAVASCRIPT = "/portal/javascript";
872 
873     private static String _PATH_PORTAL_JAVASCRIPT_CACHED =
874         "/portal/javascript_cached";
875 
876     private static String _PATH_PORTAL_LAYOUT = "/portal/layout";
877 
878     private static String _PATH_PORTAL_LOGIN = "/portal/login";
879 
880     private static String _PATH_PORTAL_LOGIN_CAPTCHA = "/portal/login_captcha";
881 
882     private static String _PATH_PORTAL_LOGOUT = "/portal/logout";
883 
884     private static String _PATH_PORTAL_PROTECTED = "/portal/protected";
885 
886     private static String _PATH_PORTAL_RENDER_PORTLET =
887         "/portal/render_portlet";
888 
889     private static String _PATH_PORTAL_TCK = "/portal/tck";
890 
891     private static String _PATH_PORTAL_TERMS_OF_USE = "/portal/terms_of_use";
892 
893     private static String _PATH_PORTAL_UPDATE_TERMS_OF_USE =
894         "/portal/update_terms_of_use";
895 
896     private static String _PATH_WSRP = "/wsrp";
897 
898     private static Log _log = LogFactory.getLog(PortalRequestProcessor.class);
899 
900     private Set<String> _lastPaths;
901     private Set<String> _publicPaths;
902     private Set<String> _trackerIgnorePaths;
903 
904 }