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