001    /**
002     * Copyright (c) 2000-2012 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.servlet.PipingServletResponse;
018    import com.liferay.portal.kernel.util.CharPool;
019    import com.liferay.portal.kernel.util.JavaConstants;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.model.Portlet;
022    import com.liferay.portal.model.PortletApp;
023    import com.liferay.portlet.PortletRequestImpl;
024    import com.liferay.portlet.PortletResponseImpl;
025    import com.liferay.portlet.PortletServletRequest;
026    import com.liferay.portlet.PortletServletResponse;
027    
028    import java.io.IOException;
029    import java.io.PrintWriter;
030    
031    import java.util.Set;
032    
033    import javax.portlet.PortletRequest;
034    import javax.portlet.PortletResponse;
035    
036    import javax.servlet.RequestDispatcher;
037    import javax.servlet.ServletException;
038    import javax.servlet.ServletRequest;
039    import javax.servlet.ServletResponse;
040    import javax.servlet.http.HttpServletRequest;
041    import javax.servlet.http.HttpServletResponse;
042    
043    /**
044     * @author Michael Young
045     * @author Brian Myunghun Kim
046     * @author Brian Wing Shun Chan
047     * @author Deepak Gothe
048     */
049    public class LiferayRequestDispatcher implements RequestDispatcher {
050    
051            public LiferayRequestDispatcher(
052                    RequestDispatcher requestDispatcher, String path) {
053    
054                    _requestDispatcher = requestDispatcher;
055                    _path = path;
056            }
057    
058            public void forward(
059                            ServletRequest servletRequest, ServletResponse servletResponse)
060                    throws IOException, ServletException {
061    
062                    forward(servletRequest, servletResponse, false);
063            }
064    
065            public void forward(
066                            ServletRequest servletRequest, ServletResponse servletResponse,
067                            boolean named)
068                    throws IOException, ServletException {
069    
070                    PortletRequest portletRequest =
071                            (PortletRequest)servletRequest.getAttribute(
072                                    JavaConstants.JAVAX_PORTLET_REQUEST);
073    
074                    if (portletRequest != null) {
075                            invoke(servletRequest, servletResponse, named, false);
076                    }
077                    else {
078                            _requestDispatcher.forward(servletRequest, servletResponse);
079                    }
080            }
081    
082            public void include(
083                            ServletRequest servletRequest, ServletResponse servletResponse)
084                    throws IOException, ServletException {
085    
086                    include(servletRequest, servletResponse, false);
087            }
088    
089            public void include(
090                            ServletRequest servletRequest, ServletResponse servletResponse,
091                            boolean named)
092                    throws IOException, ServletException {
093    
094                    PortletRequest portletRequest =
095                            (PortletRequest)servletRequest.getAttribute(
096                                    JavaConstants.JAVAX_PORTLET_REQUEST);
097    
098                    if (portletRequest != null) {
099                            invoke(servletRequest, servletResponse, named, true);
100                    }
101                    else {
102                            _requestDispatcher.include(servletRequest, servletResponse);
103                    }
104            }
105    
106            public void invoke(
107                            ServletRequest servletRequest, ServletResponse servletResponse,
108                            boolean named, boolean include)
109                    throws IOException, ServletException {
110    
111                    String pathInfo = null;
112                    String queryString = null;
113                    String requestURI = null;
114                    String servletPath = null;
115    
116                    PortletRequest portletRequest =
117                            (PortletRequest)servletRequest.getAttribute(
118                                    JavaConstants.JAVAX_PORTLET_REQUEST);
119    
120                    PortletResponse portletResponse =
121                            (PortletResponse)servletRequest.getAttribute(
122                                    JavaConstants.JAVAX_PORTLET_RESPONSE);
123    
124                    if (_path != null) {
125                            String pathNoQueryString = _path;
126    
127                            int pos = _path.indexOf(CharPool.QUESTION);
128    
129                            if (pos != -1) {
130                                    pathNoQueryString = _path.substring(0, pos);
131                                    queryString = _path.substring(pos + 1, _path.length());
132                            }
133    
134                            Set<String> servletURLPatterns = getServletURLPatterns(
135                                    servletRequest, portletRequest, portletResponse);
136    
137                            for (String urlPattern : servletURLPatterns) {
138                                    if (urlPattern.endsWith("/*")) {
139                                            pos = urlPattern.indexOf("/*");
140    
141                                            urlPattern = urlPattern.substring(0, pos + 1);
142    
143                                            if (pathNoQueryString.startsWith(urlPattern)) {
144                                                    pathInfo = pathNoQueryString.substring(
145                                                            urlPattern.length());
146                                                    servletPath = urlPattern;
147    
148                                                    break;
149                                            }
150                                    }
151                            }
152    
153                            if ((pathInfo == null) && (servletPath == null)) {
154                                    pathInfo = StringPool.BLANK;
155                                    servletPath = pathNoQueryString;
156                            }
157    
158                            requestURI = portletRequest.getContextPath() + pathNoQueryString;
159                    }
160    
161                    HttpServletRequest portletServletRequest = getPortletServletRequest(
162                            servletRequest, portletRequest, pathInfo, queryString, requestURI,
163                            servletPath, named, include);
164    
165                    HttpServletResponse portletServletResponse = getPortletServletResponse(
166                            servletResponse, portletRequest, portletResponse, include);
167    
168                    if (include) {
169                            _requestDispatcher.include(
170                                    portletServletRequest, portletServletResponse);
171                    }
172                    else {
173                            _requestDispatcher.forward(
174                                    portletServletRequest, portletServletResponse);
175                    }
176            }
177    
178            protected HttpServletRequest getPortletServletRequest(
179                    ServletRequest servletRequest, PortletRequest portletRequest,
180                    String pathInfo, String queryString, String requestURI,
181                    String servletPath, boolean named, boolean include) {
182    
183                    HttpServletRequest request = (HttpServletRequest)servletRequest;
184    
185                    PortletRequestImpl portletRequestImpl =
186                            (PortletRequestImpl)portletRequest;
187    
188                    return new PortletServletRequest(
189                            request, portletRequestImpl, pathInfo, queryString, requestURI,
190                            servletPath, named, include);
191            }
192    
193            protected HttpServletResponse getPortletServletResponse(
194                            ServletResponse servletResponse, PortletRequest portletRequest,
195                            PortletResponse portletResponse, boolean include)
196                    throws IOException {
197    
198                    HttpServletResponse response = (HttpServletResponse)servletResponse;
199    
200                    PortletResponseImpl portletResponseImpl =
201                            (PortletResponseImpl)portletResponse;
202    
203                    HttpServletResponse httpServletResponse = new PortletServletResponse(
204                            response, portletResponseImpl, include);
205    
206                    PrintWriter printWriter = servletResponse.getWriter();
207    
208                    if (printWriter != null) {
209                            httpServletResponse = new PipingServletResponse(
210                                    httpServletResponse, printWriter);
211                    }
212    
213                    return httpServletResponse;
214            }
215    
216            protected Set<String> getServletURLPatterns(
217                    ServletRequest servletRequest, PortletRequest portletRequest,
218                    PortletResponse portletResponse) {
219    
220                    PortletRequestImpl portletRequestImpl =
221                            (PortletRequestImpl)portletRequest;
222    
223                    Portlet portlet = portletRequestImpl.getPortlet();
224    
225                    PortletApp portletApp = portlet.getPortletApp();
226    
227                    return portletApp.getServletURLPatterns();
228            }
229    
230            private String _path;
231            private RequestDispatcher _requestDispatcher;
232    
233    }