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