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