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