001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.apache.bridges.struts;
016    
017    import com.liferay.portal.kernel.util.JavaConstants;
018    import com.liferay.portal.kernel.util.StringPool;
019    import com.liferay.portal.model.Portlet;
020    import com.liferay.portal.model.PortletApp;
021    import com.liferay.portlet.PortletRequestImpl;
022    import com.liferay.portlet.PortletResponseImpl;
023    import com.liferay.portlet.PortletServletRequest;
024    import com.liferay.portlet.PortletServletResponse;
025    
026    import java.io.IOException;
027    
028    import java.util.Set;
029    
030    import javax.portlet.PortletRequest;
031    import javax.portlet.PortletResponse;
032    
033    import javax.servlet.RequestDispatcher;
034    import javax.servlet.ServletException;
035    import javax.servlet.ServletRequest;
036    import javax.servlet.ServletResponse;
037    import javax.servlet.http.HttpServletRequest;
038    import javax.servlet.http.HttpServletResponse;
039    
040    /**
041     * @author Michael Young
042     * @author Brian Myunghun Kim
043     * @author Brian Wing Shun Chan
044     * @author Deepak Gothe
045     */
046    public class LiferayRequestDispatcher implements RequestDispatcher {
047    
048            public LiferayRequestDispatcher(
049                    RequestDispatcher requestDispatcher, String path) {
050    
051                    _requestDispatcher = requestDispatcher;
052                    _path = path;
053            }
054    
055            public void forward(
056                            ServletRequest servletRequest, ServletResponse servletResponse)
057                    throws IOException, ServletException {
058    
059                    PortletRequest portletRequest =
060                            (PortletRequest)servletRequest.getAttribute(
061                                    JavaConstants.JAVAX_PORTLET_REQUEST);
062    
063                    if (portletRequest != null) {
064                            invoke(servletRequest, servletResponse, false);
065                    }
066                    else {
067                            _requestDispatcher.forward(servletRequest, servletResponse);
068                    }
069            }
070    
071            public void include(
072                            ServletRequest servletRequest, ServletResponse servletResponse)
073                    throws IOException, ServletException {
074    
075                    PortletRequest portletRequest =
076                            (PortletRequest)servletRequest.getAttribute(
077                                    JavaConstants.JAVAX_PORTLET_REQUEST);
078    
079                    if (portletRequest != null) {
080                            invoke(servletRequest, servletResponse, true);
081                    }
082                    else {
083                            _requestDispatcher.include(servletRequest, servletResponse);
084                    }
085            }
086    
087            public void invoke(
088                            ServletRequest servletRequest, ServletResponse servletResponse,
089                            boolean include)
090                    throws IOException, ServletException {
091    
092                    String pathInfo = null;
093                    String queryString = null;
094                    String requestURI = null;
095                    String servletPath = null;
096    
097                    PortletRequest portletRequest =
098                            (PortletRequest)servletRequest.getAttribute(
099                                    JavaConstants.JAVAX_PORTLET_REQUEST);
100    
101                    PortletResponse portletResponse =
102                            (PortletResponse)servletRequest.getAttribute(
103                                    JavaConstants.JAVAX_PORTLET_RESPONSE);
104    
105                    if (_path != null) {
106                            String pathNoQueryString = _path;
107    
108                            int pos = _path.indexOf(StringPool.QUESTION);
109    
110                            if (pos != -1) {
111                                    pathNoQueryString = _path.substring(0, pos);
112                                    queryString = _path.substring(pos + 1, _path.length());
113                            }
114    
115                            Set<String> servletURLPatterns = getServletURLPatterns(
116                                    servletRequest, portletRequest, portletResponse);
117    
118                            for (String urlPattern : servletURLPatterns) {
119                                    if (urlPattern.endsWith("/*")) {
120                                            pos = urlPattern.indexOf("/*");
121    
122                                            urlPattern = urlPattern.substring(0, pos);
123    
124                                            if (pathNoQueryString.startsWith(urlPattern)) {
125                                                    pathInfo = pathNoQueryString.substring(
126                                                            urlPattern.length());
127                                                    servletPath = urlPattern;
128    
129                                                    break;
130                                            }
131                                    }
132                            }
133    
134                            if ((pathInfo == null) && (servletPath == null)) {
135                                    pathInfo = StringPool.BLANK;
136                                    servletPath = pathNoQueryString;
137                            }
138    
139                            requestURI = portletRequest.getContextPath() + pathNoQueryString;
140                    }
141    
142                    HttpServletRequest portletServletRequest = getPortletServletRequest(
143                            servletRequest, portletRequest, pathInfo, queryString, requestURI,
144                            servletPath, include);
145    
146                    HttpServletResponse portletServletResponse =
147                            getPortletServletResponse(
148                                    servletResponse, portletRequest, portletResponse, include);
149    
150                    if (include) {
151                            _requestDispatcher.include(
152                                    portletServletRequest, portletServletResponse);
153                    }
154                    else {
155                            _requestDispatcher.forward(
156                                    portletServletRequest, portletServletResponse);
157                    }
158            }
159    
160            protected HttpServletRequest getPortletServletRequest(
161                    ServletRequest servletRequest, PortletRequest portletRequest,
162                    String pathInfo, String queryString, String requestURI,
163                    String servletPath, boolean include) {
164    
165                    HttpServletRequest request = (HttpServletRequest)servletRequest;
166                    boolean named = false;
167    
168                    PortletRequestImpl portletRequestImpl =
169                            (PortletRequestImpl)portletRequest;
170    
171                    return new PortletServletRequest(
172                            request, portletRequestImpl, pathInfo, queryString, requestURI,
173                            servletPath, named, include);
174            }
175    
176            protected HttpServletResponse getPortletServletResponse(
177                    ServletResponse servletResponse, PortletRequest portletRequest,
178                    PortletResponse portletResponse, boolean include) {
179    
180                    HttpServletResponse response = (HttpServletResponse)servletResponse;
181    
182                    PortletResponseImpl portletResponseImpl =
183                            (PortletResponseImpl)portletResponse;
184    
185                    return new PortletServletResponse(
186                            response, portletResponseImpl, include);
187            }
188    
189            protected Set<String> getServletURLPatterns(
190                    ServletRequest servletRequest, PortletRequest portletRequest,
191                    PortletResponse portletResponse) {
192    
193                    PortletRequestImpl portletRequestImpl =
194                            (PortletRequestImpl)portletRequest;
195    
196                    Portlet portlet = portletRequestImpl.getPortlet();
197    
198                    PortletApp portletApp = portlet.getPortletApp();
199    
200                    return portletApp.getServletURLPatterns();
201            }
202    
203            private RequestDispatcher _requestDispatcher;
204            private String _path;
205    
206    }