1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet;
24  
25  import com.liferay.portal.kernel.servlet.URLEncoder;
26  import com.liferay.portal.kernel.util.ArrayUtil;
27  import com.liferay.portal.kernel.util.StringPool;
28  import com.liferay.portal.kernel.util.StringUtil;
29  import com.liferay.portal.model.Portlet;
30  import com.liferay.portal.servlet.NamespaceServletRequest;
31  import com.liferay.portal.struts.StrutsURLEncoder;
32  import com.liferay.portal.theme.ThemeDisplay;
33  import com.liferay.portal.util.PortalUtil;
34  import com.liferay.portal.util.WebKeys;
35  import com.liferay.util.servlet.DynamicServletRequest;
36  
37  import java.io.IOException;
38  
39  import java.util.HashMap;
40  import java.util.Iterator;
41  import java.util.List;
42  import java.util.Map;
43  
44  import javax.portlet.PortletException;
45  import javax.portlet.PortletRequestDispatcher;
46  import javax.portlet.RenderRequest;
47  import javax.portlet.RenderResponse;
48  
49  import javax.servlet.RequestDispatcher;
50  import javax.servlet.ServletException;
51  import javax.servlet.http.HttpServletRequest;
52  import javax.servlet.http.HttpServletResponse;
53  
54  import org.apache.commons.logging.Log;
55  import org.apache.commons.logging.LogFactory;
56  import org.apache.struts.Globals;
57  
58  /**
59   * <a href="PortletRequestDispatcherImpl.java.html"><b><i>View Source</i></b>
60   * </a>
61   *
62   * @author Brian Wing Shun Chan
63   * @author Brian Myunghun Kim
64   *
65   */
66  public class PortletRequestDispatcherImpl implements PortletRequestDispatcher {
67  
68      public PortletRequestDispatcherImpl(RequestDispatcher rd,
69                                          PortletContextImpl portletCtxImpl) {
70  
71          this(rd, portletCtxImpl, null);
72      }
73  
74      public PortletRequestDispatcherImpl(RequestDispatcher rd,
75                                          PortletContextImpl portletCtxImpl,
76                                          String path) {
77  
78          _rd = rd;
79          _portlet = portletCtxImpl.getPortlet();
80          _portletCtxImpl = portletCtxImpl;
81          _path = path;
82      }
83  
84      public void include(RenderRequest req, RenderResponse res)
85          throws IOException, PortletException {
86  
87          include(req, res, false);
88      }
89  
90      public void include(
91              RenderRequest req, RenderResponse res, boolean strutsURLEncoder)
92          throws IOException, PortletException {
93  
94          try {
95              RenderRequestImpl reqImpl = (RenderRequestImpl)req;
96              RenderResponseImpl resImpl = PortalUtil.getRenderResponseImpl(res);
97  
98              HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
99              HttpServletResponse httpRes =
100                 PortalUtil.getHttpServletResponse(res);
101 
102             String pathInfo = null;
103             String queryString = null;
104             String requestURI = null;
105             String servletPath = null;
106 
107             if (_path != null) {
108                 /*if (ServerDetector.isJetty()) {
109                     int pos = _path.indexOf(StringPool.QUESTION);
110 
111                     if (pos != -1) {
112                         _path = _path.substring(0, pos);
113                     }
114                 }*/
115 
116                 String pathNoQueryString = _path;
117 
118                 int pos = _path.indexOf(StringPool.QUESTION);
119 
120                 if (pos != -1) {
121                     pathNoQueryString = _path.substring(0, pos);
122                     queryString = _path.substring(pos + 1, _path.length());
123 
124                     Map queryParams = new HashMap();
125 
126                     String[] queryParamsArray =
127                         StringUtil.split(queryString, StringPool.AMPERSAND);
128 
129                     for (int i = 0; i < queryParamsArray.length; i++) {
130                         String[] nameValuePair = StringUtil.split(
131                             queryParamsArray[i], StringPool.EQUAL);
132                         String name = nameValuePair[0];
133                         String value = nameValuePair[1];
134 
135                         String[] values = (String[])queryParams.get(name);
136 
137                         if (values == null) {
138                             queryParams.put(name, new String[] {value});
139                         }
140                         else {
141                             String[] newValues = new String[values.length + 1];
142 
143                             System.arraycopy(
144                                 values, 0, newValues, 0, values.length);
145 
146                             newValues[newValues.length - 1] = value;
147 
148                             queryParams.put(name, newValues);
149                         }
150                     }
151 
152                     DynamicServletRequest dynamicReq = null;
153 
154                     if (reqImpl.isPrivateRequestAttributes()) {
155                         String portletNamespace =
156                             PortalUtil.getPortletNamespace(
157                                 reqImpl.getPortletName());
158 
159                         dynamicReq = new NamespaceServletRequest(
160                             httpReq, portletNamespace, portletNamespace);
161                     }
162                     else {
163                         dynamicReq = new DynamicServletRequest(httpReq);
164                     }
165 
166                     Iterator itr = queryParams.entrySet().iterator();
167 
168                     while (itr.hasNext()) {
169                         Map.Entry entry = (Map.Entry)itr.next();
170 
171                         String name = (String)entry.getKey();
172                         String[] values = (String[])entry.getValue();
173 
174                         String[] oldValues =
175                             dynamicReq.getParameterValues(name);
176 
177                         if (oldValues == null) {
178                             dynamicReq.setParameterValues(name, values);
179                         }
180                         else {
181                             String[] newValues = ArrayUtil.append(
182                                 values, oldValues);
183 
184                             dynamicReq.setParameterValues(name, newValues);
185                         }
186                     }
187 
188                     httpReq = dynamicReq;
189                 }
190 
191                 List servletURLPatterns =
192                     reqImpl.getPortlet().getServletURLPatterns();
193 
194                 Iterator itr = servletURLPatterns.iterator();
195 
196                 while (itr.hasNext()) {
197                     String urlPattern = (String)itr.next();
198 
199                     if (urlPattern.endsWith("/*")) {
200                         pos = urlPattern.indexOf("/*");
201 
202                         urlPattern = urlPattern.substring(0, pos);
203 
204                         if (pathNoQueryString.startsWith(urlPattern)) {
205                             pathInfo = pathNoQueryString.substring(
206                                 urlPattern.length());
207                             servletPath = urlPattern;
208 
209                             break;
210                         }
211                     }
212                 }
213 
214                 if ((pathInfo == null) && (servletPath == null)) {
215                     pathInfo = StringPool.BLANK;
216                     servletPath = pathNoQueryString;
217                 }
218 
219                 requestURI = req.getContextPath() + pathNoQueryString;
220             }
221 
222             PortletServletRequest portletServletReq = new PortletServletRequest(
223                 httpReq, reqImpl, pathInfo, queryString, requestURI,
224                 servletPath);
225 
226             PortletServletResponse portletServletRes =
227                 new PortletServletResponse(httpRes, resImpl);
228 
229             URLEncoder urlEncoder = _portlet.getURLEncoderInstance();
230 
231             if (urlEncoder != null) {
232                 resImpl.setURLEncoder(urlEncoder);
233             }
234             else if (strutsURLEncoder) {
235                 ThemeDisplay themeDisplay =
236                     (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
237 
238                 resImpl.setURLEncoder(new StrutsURLEncoder(
239                     portletServletReq.getContextPath(),
240                     themeDisplay.getPathMain(),
241                     (String)_portletCtxImpl.getAttribute(Globals.SERVLET_KEY),
242                     (com.liferay.portlet.PortletURLImpl)res.createRenderURL()));
243             }
244 
245             _rd.include(portletServletReq, portletServletRes);
246         }
247         catch (ServletException se) {
248             _log.error(se, se);
249 
250             throw new PortletException(se);
251         }
252     }
253 
254     private static Log _log =
255         LogFactory.getLog(PortletRequestDispatcherImpl.class);
256 
257     private RequestDispatcher _rd;
258     private Portlet _portlet;
259     private PortletContextImpl _portletCtxImpl;
260     private String _path;
261 
262 }