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 String name = nameValuePair[0];
181 String value = nameValuePair[1];
182
183 String[] values = queryParams.get(name);
184
185 if (values == null) {
186 queryParams.put(name, new String[] {value});
187 }
188 else {
189 String[] newValues = new String[values.length + 1];
190
191 System.arraycopy(
192 values, 0, newValues, 0, values.length);
193
194 newValues[newValues.length - 1] = value;
195
196 queryParams.put(name, newValues);
197 }
198 }
199
200 DynamicServletRequest dynamicRequest = null;
201
202 if (portletRequestImpl.isPrivateRequestAttributes()) {
203 String portletNamespace =
204 PortalUtil.getPortletNamespace(
205 portletRequestImpl.getPortletName());
206
207 dynamicRequest = new NamespaceServletRequest(
208 request, portletNamespace, portletNamespace);
209 }
210 else {
211 dynamicRequest = new DynamicServletRequest(request);
212 }
213
214 for (Map.Entry<String, String[]> entry :
215 queryParams.entrySet()) {
216
217 String name = entry.getKey();
218 String[] values = entry.getValue();
219
220 String[] oldValues =
221 dynamicRequest.getParameterValues(name);
222
223 if (oldValues == null) {
224 dynamicRequest.setParameterValues(name, values);
225 }
226 else {
227 String[] newValues = ArrayUtil.append(
228 values, oldValues);
229
230 dynamicRequest.setParameterValues(name, newValues);
231 }
232 }
233
234 request = dynamicRequest;
235 }
236
237 Portlet portlet = portletRequestImpl.getPortlet();
238
239 PortletApp portletApp = portlet.getPortletApp();
240
241 Set<String> servletURLPatterns =
242 portletApp.getServletURLPatterns();
243
244 for (String urlPattern : servletURLPatterns) {
245 if (urlPattern.endsWith("/*")) {
246 pos = urlPattern.indexOf("/*");
247
248 urlPattern = urlPattern.substring(0, pos);
249
250 if (pathNoQueryString.startsWith(urlPattern)) {
251 pathInfo = pathNoQueryString.substring(
252 urlPattern.length());
253 servletPath = urlPattern;
254
255 break;
256 }
257 }
258 }
259
260 if ((pathInfo == null) && (servletPath == null)) {
261 pathInfo = pathNoQueryString;
262 servletPath = pathNoQueryString;
263 }
264
265 requestURI =
266 portletRequest.getContextPath() + pathNoQueryString;
267 }
268
269 PortletServletRequest portletServletRequest =
270 new PortletServletRequest(
271 request, portletRequestImpl, pathInfo, queryString,
272 requestURI, servletPath, _named, include);
273
274 PortletServletResponse portletServletResponse =
275 new PortletServletResponse(
276 response, portletResponseImpl, include);
277
278 URLEncoder urlEncoder = _portlet.getURLEncoderInstance();
279
280 if (urlEncoder != null) {
281 portletResponseImpl.setURLEncoder(urlEncoder);
282 }
283 else if (strutsURLEncoder) {
284 ThemeDisplay themeDisplay =
285 (ThemeDisplay)portletRequest.getAttribute(
286 WebKeys.THEME_DISPLAY);
287
288 URLEncoder strutsURLEncoderObj = new StrutsURLEncoder(
289 portletServletRequest.getContextPath(),
290 themeDisplay.getPathMain(),
291 (String)_portletContextImpl.getAttribute(
292 Globals.SERVLET_KEY),
293 (LiferayPortletURL)portletResponseImpl.createRenderURL());
294
295 portletResponseImpl.setURLEncoder(strutsURLEncoderObj);
296 }
297
298 if (include) {
299 _requestDispatcher.include(
300 portletServletRequest, portletServletResponse);
301 }
302 else {
303 _requestDispatcher.forward(
304 portletServletRequest, portletServletResponse);
305 }
306 }
307 catch (ServletException se) {
308 _log.error(se, se);
309
310 throw new PortletException(se);
311 }
312 }
313
314 private static Log _log =
315 LogFactoryUtil.getLog(PortletRequestDispatcherImpl.class);
316
317 private RequestDispatcher _requestDispatcher;
318 private boolean _named;
319 private Portlet _portlet;
320 private PortletContextImpl _portletContextImpl;
321 private String _path;
322
323 }