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