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