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