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