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                    PortletRequest portletRequest =
063                            (PortletRequest)servletRequest.getAttribute(
064                                    JavaConstants.JAVAX_PORTLET_REQUEST);
065    
066                    if (portletRequest != null) {
067                            invoke(servletRequest, servletResponse, false);
068                    }
069                    else {
070                            _requestDispatcher.forward(servletRequest, servletResponse);
071                    }
072            }
073    
074            /**
075             * @deprecated {@link #forward(ServletRequest, ServletResponse)}
076             */
077            public void forward(
078                            ServletRequest servletRequest, ServletResponse servletResponse,
079                            boolean named)
080                    throws IOException, ServletException {
081    
082                    forward(servletRequest, servletResponse);
083            }
084    
085            public void include(
086                            ServletRequest servletRequest, ServletResponse servletResponse)
087                    throws IOException, ServletException {
088    
089                    PortletRequest portletRequest =
090                            (PortletRequest)servletRequest.getAttribute(
091                                    JavaConstants.JAVAX_PORTLET_REQUEST);
092    
093                    if (portletRequest != null) {
094                            invoke(servletRequest, servletResponse, true);
095                    }
096                    else {
097                            _requestDispatcher.include(servletRequest, servletResponse);
098                    }
099            }
100    
101            /**
102             * @deprecated {@link #include(ServletRequest, ServletResponse)}
103             */
104            public void include(
105                            ServletRequest servletRequest, ServletResponse servletResponse,
106                            boolean named)
107                    throws IOException, ServletException {
108    
109                    include(servletRequest, servletResponse);
110            }
111    
112            public void invoke(
113                            ServletRequest servletRequest, ServletResponse servletResponse,
114                            boolean include)
115                    throws IOException, ServletException {
116    
117                    String pathInfo = null;
118                    String queryString = null;
119                    String requestURI = null;
120                    String servletPath = null;
121    
122                    PortletRequest portletRequest =
123                            (PortletRequest)servletRequest.getAttribute(
124                                    JavaConstants.JAVAX_PORTLET_REQUEST);
125    
126                    PortletResponse portletResponse =
127                            (PortletResponse)servletRequest.getAttribute(
128                                    JavaConstants.JAVAX_PORTLET_RESPONSE);
129    
130                    if (_path != null) {
131                            String pathNoQueryString = _path;
132    
133                            int pos = _path.indexOf(CharPool.QUESTION);
134    
135                            if (pos != -1) {
136                                    pathNoQueryString = _path.substring(0, pos);
137                                    queryString = _path.substring(pos + 1);
138                            }
139    
140                            Set<String> servletURLPatterns = getServletURLPatterns(
141                                    servletRequest, portletRequest, portletResponse);
142    
143                            for (String urlPattern : servletURLPatterns) {
144                                    if (urlPattern.endsWith("/*")) {
145                                            pos = urlPattern.indexOf("/*");
146    
147                                            urlPattern = urlPattern.substring(0, pos + 1);
148    
149                                            if (pathNoQueryString.startsWith(urlPattern)) {
150                                                    pathInfo = pathNoQueryString.substring(
151                                                            urlPattern.length());
152                                                    servletPath = urlPattern;
153    
154                                                    break;
155                                            }
156                                    }
157                            }
158    
159                            if ((pathInfo == null) && (servletPath == null)) {
160                                    pathInfo = StringPool.BLANK;
161                                    servletPath = pathNoQueryString;
162                            }
163    
164                            requestURI = portletRequest.getContextPath() + pathNoQueryString;
165                    }
166    
167                    HttpServletRequest portletServletRequest = getPortletServletRequest(
168                            servletRequest, portletRequest, pathInfo, queryString, requestURI,
169                            servletPath, include);
170    
171                    HttpServletResponse portletServletResponse = getPortletServletResponse(
172                            servletResponse, portletRequest, portletResponse, include);
173    
174                    if (include) {
175                            _requestDispatcher.include(
176                                    portletServletRequest, portletServletResponse);
177                    }
178                    else {
179                            _requestDispatcher.forward(
180                                    portletServletRequest, portletServletResponse);
181                    }
182            }
183    
184            /**
185             * @deprecated {@link #invoke(ServletRequest, ServletResponse, boolean)}
186             */
187            public void invoke(
188                            ServletRequest servletRequest, ServletResponse servletResponse,
189                            boolean named, boolean include)
190                    throws IOException, ServletException {
191    
192                    invoke(servletRequest, servletResponse, include);
193            }
194    
195            protected HttpServletRequest getPortletServletRequest(
196                    ServletRequest servletRequest, PortletRequest portletRequest,
197                    String pathInfo, String queryString, String requestURI,
198                    String servletPath, boolean include) {
199    
200                    HttpServletRequest request = (HttpServletRequest)servletRequest;
201                    boolean named = false;
202    
203                    PortletRequestImpl portletRequestImpl =
204                            (PortletRequestImpl)portletRequest;
205    
206                    return new PortletServletRequest(
207                            request, portletRequestImpl, pathInfo, queryString, requestURI,
208                            servletPath, named, include);
209            }
210    
211            protected HttpServletResponse getPortletServletResponse(
212                            ServletResponse servletResponse, PortletRequest portletRequest,
213                            PortletResponse portletResponse, boolean include)
214                    throws IOException {
215    
216                    HttpServletResponse response = (HttpServletResponse)servletResponse;
217    
218                    PortletResponseImpl portletResponseImpl =
219                            (PortletResponseImpl)portletResponse;
220    
221                    HttpServletResponse httpServletResponse = new PortletServletResponse(
222                            response, portletResponseImpl, include);
223    
224                    PrintWriter printWriter = servletResponse.getWriter();
225    
226                    if (printWriter != null) {
227                            httpServletResponse = new PipingServletResponse(
228                                    httpServletResponse, printWriter);
229                    }
230    
231                    return httpServletResponse;
232            }
233    
234            protected Set<String> getServletURLPatterns(
235                    ServletRequest servletRequest, PortletRequest portletRequest,
236                    PortletResponse portletResponse) {
237    
238                    PortletRequestImpl portletRequestImpl =
239                            (PortletRequestImpl)portletRequest;
240    
241                    Portlet portlet = portletRequestImpl.getPortlet();
242    
243                    PortletApp portletApp = portlet.getPortletApp();
244    
245                    return portletApp.getServletURLPatterns();
246            }
247    
248            private String _path;
249            private RequestDispatcher _requestDispatcher;
250    
251    }