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