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