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