1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.apache.bridges.struts;
21  
22  import com.liferay.portal.SystemException;
23  import com.liferay.portal.kernel.util.JavaConstants;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.model.Portlet;
26  import com.liferay.portal.model.PortletApp;
27  import com.liferay.portal.portletcontainer.WindowInvokerUtil;
28  import com.liferay.portal.service.PortletLocalServiceUtil;
29  import com.liferay.portal.util.PortalUtil;
30  import com.liferay.portal.util.PropsValues;
31  import com.liferay.portlet.PortletRequestImpl;
32  import com.liferay.portlet.PortletResponseImpl;
33  import com.liferay.portlet.PortletServletRequest;
34  import com.liferay.portlet.PortletServletResponse;
35  
36  import com.sun.portal.portletcontainer.portlet.impl.RDRequestWrapper;
37  import com.sun.portal.portletcontainer.portlet.impl.RDResponseWrapper;
38  
39  import java.io.IOException;
40  
41  import java.util.Set;
42  
43  import javax.portlet.PortletRequest;
44  import javax.portlet.PortletResponse;
45  
46  import javax.servlet.RequestDispatcher;
47  import javax.servlet.ServletException;
48  import javax.servlet.ServletRequest;
49  import javax.servlet.ServletResponse;
50  import javax.servlet.http.HttpServletRequest;
51  import javax.servlet.http.HttpServletResponse;
52  
53  /**
54   * <a href="LiferayRequestDispatcher.java.html"><b><i>View Source</i></b></a>
55   *
56   * @author Michael Young
57   * @author Brian Myunghun Kim
58   * @author Brian Wing Shun Chan
59   * @author Deepak Gothe
60   *
61   */
62  public class LiferayRequestDispatcher implements RequestDispatcher {
63  
64      public LiferayRequestDispatcher(
65          RequestDispatcher requestDispatcher, String path) {
66  
67          _requestDispatcher = requestDispatcher;
68          _path = path;
69      }
70  
71      public void forward(
72              ServletRequest servletRequest, ServletResponse servletResponse)
73          throws IOException, ServletException {
74  
75          PortletRequest portletRequest =
76              (PortletRequest)servletRequest.getAttribute(
77                  JavaConstants.JAVAX_PORTLET_REQUEST);
78  
79          if (portletRequest != null) {
80              invoke(servletRequest, servletResponse, false);
81          }
82          else {
83              _requestDispatcher.forward(servletRequest, servletResponse);
84          }
85      }
86  
87      public void include(
88              ServletRequest servletRequest, ServletResponse servletResponse)
89          throws IOException, ServletException {
90  
91          PortletRequest portletRequest =
92              (PortletRequest)servletRequest.getAttribute(
93                  JavaConstants.JAVAX_PORTLET_REQUEST);
94  
95          if (portletRequest != null) {
96              invoke(servletRequest, servletResponse, true);
97          }
98          else {
99              _requestDispatcher.include(servletRequest, servletResponse);
100         }
101     }
102 
103     public void invoke(
104             ServletRequest servletRequest, ServletResponse servletResponse,
105             boolean include)
106         throws IOException, ServletException {
107 
108         String pathInfo = null;
109         String queryString = null;
110         String requestURI = null;
111         String servletPath = null;
112 
113         PortletRequest portletRequest =
114             (PortletRequest)servletRequest.getAttribute(
115                 JavaConstants.JAVAX_PORTLET_REQUEST);
116 
117         PortletResponse portletResponse =
118             (PortletResponse)servletRequest.getAttribute(
119                 JavaConstants.JAVAX_PORTLET_RESPONSE);
120 
121         if (_path != null) {
122             String pathNoQueryString = _path;
123 
124             int pos = _path.indexOf(StringPool.QUESTION);
125 
126             if (pos != -1) {
127                 pathNoQueryString = _path.substring(0, pos);
128                 queryString = _path.substring(pos + 1, _path.length());
129             }
130 
131             Set<String> servletURLPatterns = getServletURLPatterns(
132                 servletRequest, portletRequest, portletResponse);
133 
134             for (String urlPattern : servletURLPatterns) {
135                 if (urlPattern.endsWith("/*")) {
136                     pos = urlPattern.indexOf("/*");
137 
138                     urlPattern = urlPattern.substring(0, pos);
139 
140                     if (pathNoQueryString.startsWith(urlPattern)) {
141                         pathInfo = pathNoQueryString.substring(
142                             urlPattern.length());
143                         servletPath = urlPattern;
144 
145                         break;
146                     }
147                 }
148             }
149 
150             if ((pathInfo == null) && (servletPath == null)) {
151                 pathInfo = StringPool.BLANK;
152                 servletPath = pathNoQueryString;
153             }
154 
155             requestURI = portletRequest.getContextPath() + pathNoQueryString;
156         }
157 
158         HttpServletRequest portletServletRequest = getPortletServletRequest(
159             servletRequest, portletRequest, pathInfo, queryString, requestURI,
160             servletPath, include);
161 
162         HttpServletResponse portletServletResponse =
163             getPortletServletResponse(
164                 servletResponse, portletRequest, portletResponse, include);
165 
166         if (include) {
167             _requestDispatcher.include(
168                 portletServletRequest, portletServletResponse);
169         }
170         else {
171             _requestDispatcher.forward(
172                 portletServletRequest, portletServletResponse);
173         }
174     }
175 
176     protected HttpServletRequest getPortletServletRequest(
177         ServletRequest servletRequest, PortletRequest portletRequest,
178         String pathInfo, String queryString, String requestURI,
179         String servletPath, boolean include) {
180 
181         HttpServletRequest request = (HttpServletRequest)servletRequest;
182         boolean named = false;
183 
184         if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
185             String lifecyclePhase = (String)portletRequest.getAttribute(
186                 PortletRequest.LIFECYCLE_PHASE);
187 
188             return new RDRequestWrapper(
189                 null, request, portletRequest, requestURI, servletPath,
190                 pathInfo, queryString, lifecyclePhase, named, include);
191         }
192         else {
193             PortletRequestImpl portletRequestImpl =
194                 (PortletRequestImpl)portletRequest;
195 
196             return new PortletServletRequest(
197                 request, portletRequestImpl, pathInfo, queryString, requestURI,
198                 servletPath, named, include);
199         }
200     }
201 
202     protected HttpServletResponse getPortletServletResponse(
203         ServletResponse servletResponse, PortletRequest portletRequest,
204         PortletResponse portletResponse, boolean include) {
205 
206         HttpServletResponse response = (HttpServletResponse)servletResponse;
207 
208         if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
209             String lifecyclePhase = (String)portletRequest.getAttribute(
210                 PortletRequest.LIFECYCLE_PHASE);
211 
212             return new RDResponseWrapper(
213                 response, portletResponse, lifecyclePhase, include);
214         }
215         else {
216             PortletResponseImpl portletResponseImpl =
217                 (PortletResponseImpl)portletResponse;
218 
219             return new PortletServletResponse(
220                 response, portletResponseImpl, include);
221         }
222     }
223 
224     protected Set<String> getServletURLPatterns(
225             ServletRequest servletRequest, PortletRequest portletRequest,
226             PortletResponse portletResponse)
227         throws ServletException {
228 
229         if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
230             try {
231                 HttpServletRequest request = (HttpServletRequest)servletRequest;
232 
233                 long companyId = PortalUtil.getCompanyId(request);
234                 String portletId = WindowInvokerUtil.getPortletId(
235                     portletResponse.getNamespace());
236 
237                 Portlet portlet = PortletLocalServiceUtil.getPortletById(
238                     companyId, portletId);
239 
240                 PortletApp portletApp = portlet.getPortletApp();
241 
242                 return portletApp.getServletURLPatterns();
243             }
244             catch (SystemException se) {
245                 throw new ServletException(se);
246             }
247         }
248         else {
249             PortletRequestImpl portletRequestImpl =
250                 (PortletRequestImpl)portletRequest;
251 
252             Portlet portlet = portletRequestImpl.getPortlet();
253 
254             PortletApp portletApp = portlet.getPortletApp();
255 
256             return portletApp.getServletURLPatterns();
257         }
258     }
259 
260     private RequestDispatcher _requestDispatcher;
261     private String _path;
262 
263 }