1
22
23 package com.liferay.portlet;
24
25 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
26 import com.liferay.portal.kernel.servlet.URLEncoder;
27 import com.liferay.portal.kernel.util.ArrayUtil;
28 import com.liferay.portal.kernel.util.StringPool;
29 import com.liferay.portal.kernel.util.StringUtil;
30 import com.liferay.portal.model.Portlet;
31 import com.liferay.portal.model.PortletApp;
32 import com.liferay.portal.servlet.NamespaceServletRequest;
33 import com.liferay.portal.struts.StrutsURLEncoder;
34 import com.liferay.portal.theme.ThemeDisplay;
35 import com.liferay.portal.util.PortalUtil;
36 import com.liferay.portal.util.WebKeys;
37 import com.liferay.util.servlet.DynamicServletRequest;
38
39 import java.io.IOException;
40
41 import java.util.HashMap;
42 import java.util.Map;
43 import java.util.Set;
44
45 import javax.portlet.PortletException;
46 import javax.portlet.PortletRequest;
47 import javax.portlet.PortletRequestDispatcher;
48 import javax.portlet.PortletResponse;
49 import javax.portlet.RenderRequest;
50 import javax.portlet.RenderResponse;
51
52 import javax.servlet.RequestDispatcher;
53 import javax.servlet.ServletException;
54 import javax.servlet.http.HttpServletRequest;
55 import javax.servlet.http.HttpServletResponse;
56
57 import org.apache.commons.logging.Log;
58 import org.apache.commons.logging.LogFactory;
59 import org.apache.struts.Globals;
60
61
69 public class PortletRequestDispatcherImpl implements PortletRequestDispatcher {
70
71 public PortletRequestDispatcherImpl(
72 RequestDispatcher rd, boolean named,
73 PortletContextImpl portletCtxImpl) {
74
75 this(rd, named, portletCtxImpl, null);
76 }
77
78 public PortletRequestDispatcherImpl(
79 RequestDispatcher rd, boolean named, PortletContextImpl portletCtxImpl,
80 String path) {
81
82 _rd = rd;
83 _named = named;
84 _portlet = portletCtxImpl.getPortlet();
85 _portletCtxImpl = portletCtxImpl;
86 _path = path;
87 }
88
89 public void forward(PortletRequest req, PortletResponse res)
90 throws IllegalStateException, IOException, PortletException {
91
92 HttpServletResponse httpRes = PortalUtil.getHttpServletResponse(res);
93
94 if (httpRes.isCommitted()) {
95 throw new IllegalStateException("Response is already committed");
96 }
97
98 dispatch(req, res, false, false);
99 }
100
101 public void include(PortletRequest req, PortletResponse res)
102 throws IOException, PortletException {
103
104 dispatch(req, res, false, true);
105 }
106
107 public void include(
108 PortletRequest req, PortletResponse res, boolean strutsURLEncoder)
109 throws IOException, PortletException {
110
111 dispatch(req, res, strutsURLEncoder, true);
112 }
113
114 public void include(RenderRequest req, RenderResponse res)
115 throws IOException, PortletException {
116
117 dispatch(req, res, false, true);
118 }
119
120 protected void dispatch(
121 PortletRequest req, PortletResponse res, boolean strutsURLEncoder,
122 boolean include)
123 throws IOException, PortletException {
124
125 if (!include) {
126 if (res instanceof MimeResponseImpl) {
127 MimeResponseImpl mimeResImpl = (MimeResponseImpl)res;
128
129 if (mimeResImpl.isCalledFlushBuffer()) {
130 throw new IllegalStateException();
131 }
132 }
133 }
134
135 try {
136 PortletRequestImpl reqImpl = (PortletRequestImpl)req;
137 PortletResponseImpl resImpl =
138 PortletResponseImpl.getPortletResponseImpl(res);
139
140 HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
141 HttpServletResponse httpRes =
142 PortalUtil.getHttpServletResponse(res);
143
144 String pathInfo = null;
145 String queryString = null;
146 String requestURI = null;
147 String servletPath = null;
148
149 if (_path != null) {
150
157
158 String pathNoQueryString = _path;
159
160 int pos = _path.indexOf(StringPool.QUESTION);
161
162 if (pos != -1) {
163 pathNoQueryString = _path.substring(0, pos);
164 queryString = _path.substring(pos + 1, _path.length());
165
166 Map<String, String[]> queryParams =
167 new HashMap<String, String[]>();
168
169 String[] queryParamsArray =
170 StringUtil.split(queryString, StringPool.AMPERSAND);
171
172 for (int i = 0; i < queryParamsArray.length; i++) {
173 String[] nameValuePair = StringUtil.split(
174 queryParamsArray[i], StringPool.EQUAL);
175 String name = nameValuePair[0];
176 String value = nameValuePair[1];
177
178 String[] values = queryParams.get(name);
179
180 if (values == null) {
181 queryParams.put(name, new String[] {value});
182 }
183 else {
184 String[] newValues = new String[values.length + 1];
185
186 System.arraycopy(
187 values, 0, newValues, 0, values.length);
188
189 newValues[newValues.length - 1] = value;
190
191 queryParams.put(name, newValues);
192 }
193 }
194
195 DynamicServletRequest dynamicReq = null;
196
197 if (reqImpl.isPrivateRequestAttributes()) {
198 String portletNamespace =
199 PortalUtil.getPortletNamespace(
200 reqImpl.getPortletName());
201
202 dynamicReq = new NamespaceServletRequest(
203 httpReq, portletNamespace, portletNamespace);
204 }
205 else {
206 dynamicReq = new DynamicServletRequest(httpReq);
207 }
208
209 for (Map.Entry<String, String[]> entry :
210 queryParams.entrySet()) {
211
212 String name = entry.getKey();
213 String[] values = entry.getValue();
214
215 String[] oldValues =
216 dynamicReq.getParameterValues(name);
217
218 if (oldValues == null) {
219 dynamicReq.setParameterValues(name, values);
220 }
221 else {
222 String[] newValues = ArrayUtil.append(
223 values, oldValues);
224
225 dynamicReq.setParameterValues(name, newValues);
226 }
227 }
228
229 httpReq = dynamicReq;
230 }
231
232 Portlet portlet = reqImpl.getPortlet();
233
234 PortletApp portletApp = portlet.getPortletApp();
235
236 Set<String> servletURLPatterns =
237 portletApp.getServletURLPatterns();
238
239 for (String urlPattern : servletURLPatterns) {
240 if (urlPattern.endsWith("/*")) {
241 pos = urlPattern.indexOf("/*");
242
243 urlPattern = urlPattern.substring(0, pos);
244
245 if (pathNoQueryString.startsWith(urlPattern)) {
246 pathInfo = pathNoQueryString.substring(
247 urlPattern.length());
248 servletPath = urlPattern;
249
250 break;
251 }
252 }
253 }
254
255 if ((pathInfo == null) && (servletPath == null)) {
256 pathInfo = StringPool.BLANK;
257 servletPath = pathNoQueryString;
258 }
259
260 requestURI = req.getContextPath() + pathNoQueryString;
261 }
262
263 PortletServletRequest portletServletReq = new PortletServletRequest(
264 httpReq, reqImpl, pathInfo, queryString, requestURI,
265 servletPath, _named, include);
266
267 PortletServletResponse portletServletRes =
268 new PortletServletResponse(httpRes, resImpl, include);
269
270 URLEncoder urlEncoder = _portlet.getURLEncoderInstance();
271
272 if (urlEncoder != null) {
273 resImpl.setURLEncoder(urlEncoder);
274 }
275 else if (strutsURLEncoder) {
276 ThemeDisplay themeDisplay =
277 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
278
279 URLEncoder strutsURLEncoderObj = new StrutsURLEncoder(
280 portletServletReq.getContextPath(),
281 themeDisplay.getPathMain(),
282 (String)_portletCtxImpl.getAttribute(Globals.SERVLET_KEY),
283 (LiferayPortletURL)resImpl.createRenderURL());
284
285 resImpl.setURLEncoder(strutsURLEncoderObj);
286 }
287
288 if (include) {
289 _rd.include(portletServletReq, portletServletRes);
290 }
291 else {
292 _rd.forward(portletServletReq, portletServletRes);
293 }
294 }
295 catch (ServletException se) {
296 _log.error(se, se);
297
298 throw new PortletException(se);
299 }
300 }
301
302 private static Log _log =
303 LogFactory.getLog(PortletRequestDispatcherImpl.class);
304
305 private RequestDispatcher _rd;
306 private boolean _named;
307 private Portlet _portlet;
308 private PortletContextImpl _portletCtxImpl;
309 private String _path;
310
311 }