1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.context.portlet;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.security.Principal;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.Set;
32
33 import javax.faces.FacesException;
34 import javax.faces.application.ViewHandler;
35 import javax.faces.context.ExternalContext;
36 import javax.portlet.ActionRequest;
37 import javax.portlet.ActionResponse;
38 import javax.portlet.PortletContext;
39 import javax.portlet.PortletException;
40 import javax.portlet.PortletRequest;
41 import javax.portlet.PortletRequestDispatcher;
42 import javax.portlet.PortletResponse;
43 import javax.portlet.PortletSession;
44 import javax.portlet.RenderRequest;
45 import javax.portlet.RenderResponse;
46
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49 import org.apache.myfaces.context.ReleaseableExternalContext;
50 import org.apache.myfaces.util.EnumerationIterator;
51
52
53
54
55
56
57
58
59 public class PortletExternalContextImpl extends ExternalContext implements ReleaseableExternalContext {
60
61 private static final Log log = LogFactory.getLog(PortletExternalContextImpl.class);
62
63 private static final String INIT_PARAMETER_MAP_ATTRIBUTE = InitParameterMap.class.getName();
64 private static final Map EMPTY_UNMODIFIABLE_MAP = Collections.unmodifiableMap(new HashMap(0));
65
66 PortletContext _portletContext;
67 PortletRequest _portletRequest;
68 PortletResponse _portletResponse;
69
70 private Map _applicationMap;
71 private Map _sessionMap;
72 private Map _requestMap;
73 private Map _requestParameterMap;
74 private Map _requestParameterValuesMap;
75 private Map _requestHeaderMap;
76 private Map _requestHeaderValuesMap;
77 private Map _initParameterMap;
78 private boolean _isActionRequest;
79
80
81 public PortletExternalContextImpl(PortletContext portletContext,
82 PortletRequest portletRequest,
83 PortletResponse portletResponse)
84 {
85 _portletContext = portletContext;
86 _portletRequest = portletRequest;
87 _portletResponse = portletResponse;
88 _isActionRequest = (portletRequest != null &&
89 portletRequest instanceof ActionRequest);
90
91 if (_isActionRequest)
92 {
93 ActionRequest actionRequest = (ActionRequest)portletRequest;
94
95
96 try
97 {
98 String contentType = portletRequest.getProperty("Content-Type");
99
100 String characterEncoding = lookupCharacterEncoding(contentType);
101
102 if (characterEncoding == null) {
103 PortletSession session = portletRequest.getPortletSession(false);
104
105 if (session != null) {
106 characterEncoding = (String) session.getAttribute(ViewHandler.CHARACTER_ENCODING_KEY,
107 PortletSession.PORTLET_SCOPE);
108 }
109
110 if (characterEncoding != null) {
111 actionRequest.setCharacterEncoding(characterEncoding);
112 }
113 }
114 } catch (Exception e)
115 {
116 if (log.isWarnEnabled())
117 log.warn("Failed to set character encoding " + e);
118 }
119 }
120 }
121
122 private String lookupCharacterEncoding(String contentType)
123 {
124 String characterEncoding = null;
125
126 if (contentType != null)
127 {
128 int charsetFind = contentType.indexOf("charset=");
129 if (charsetFind != -1)
130 {
131 if (charsetFind == 0)
132 {
133
134 characterEncoding = contentType.substring(8);
135 }
136 else
137 {
138 char charBefore = contentType.charAt(charsetFind - 1);
139 if (charBefore == ';' || Character.isWhitespace(charBefore))
140 {
141
142 characterEncoding = contentType.substring(charsetFind + 8);
143 }
144 }
145 if (log.isDebugEnabled()) log.debug("Incoming request has Content-Type header with character encoding " + characterEncoding);
146 }
147 else
148 {
149 if (log.isDebugEnabled()) log.debug("Incoming request has Content-Type header without character encoding: " + contentType);
150 }
151 }
152 return characterEncoding;
153 }
154
155 public void dispatch(String path) throws IOException
156 {
157 if (_isActionRequest)
158 {
159 String msg = "Can not call dispatch() during a portlet ActionRequest";
160 throw new IllegalStateException(msg);
161 }
162
163 PortletRequestDispatcher requestDispatcher
164 = _portletContext.getRequestDispatcher(path);
165 try
166 {
167 requestDispatcher.include((RenderRequest)_portletRequest,
168 (RenderResponse)_portletResponse);
169 }
170 catch (PortletException e)
171 {
172 if (e.getMessage() != null)
173 {
174 throw new FacesException(e.getMessage(), e);
175 }
176 else
177 {
178 throw new FacesException(e);
179 }
180 }
181 }
182
183 public String encodeActionURL(String url) {
184 checkNull(url, "url");
185 return _portletResponse.encodeURL(url);
186 }
187
188 public String encodeNamespace(String name) {
189 if (_isActionRequest)
190 {
191 String msg = "Can not call encodeNamespace() during a portlet ActionRequest";
192 throw new IllegalStateException(msg);
193 }
194
195
196
197
198 return name+((RenderResponse)_portletResponse).getNamespace();
199 }
200
201 public String encodeResourceURL(String url) {
202 checkNull(url, "url");
203 return _portletResponse.encodeURL(url);
204 }
205
206 public Map getApplicationMap() {
207 if (_applicationMap == null)
208 {
209 _applicationMap = new ApplicationMap(_portletContext);
210 }
211 return _applicationMap;
212 }
213
214 public String getAuthType() {
215 return _portletRequest.getAuthType();
216 }
217
218 public Object getContext() {
219 return _portletContext;
220 }
221
222 public String getInitParameter(String name) {
223 return _portletContext.getInitParameter(name);
224 }
225
226 public Map getInitParameterMap() {
227 if (_initParameterMap == null)
228 {
229
230 if ((_initParameterMap = (Map) _portletContext.getAttribute(INIT_PARAMETER_MAP_ATTRIBUTE)) == null)
231 {
232 _initParameterMap = new InitParameterMap(_portletContext);
233 _portletContext.setAttribute(INIT_PARAMETER_MAP_ATTRIBUTE, _initParameterMap);
234 }
235 }
236 return _initParameterMap;
237 }
238
239 public String getRemoteUser() {
240 return _portletRequest.getRemoteUser();
241 }
242
243 public Object getRequest() {
244 return _portletRequest;
245 }
246
247 public String getRequestContextPath() {
248 return _portletRequest.getContextPath();
249 }
250
251 public Map getRequestCookieMap() {
252 return EMPTY_UNMODIFIABLE_MAP;
253 }
254
255 public Map getRequestHeaderMap() {
256 if (_requestHeaderMap == null)
257 {
258 _requestHeaderMap = new RequestHeaderMap(_portletRequest);
259 }
260 return _requestHeaderMap;
261 }
262
263 public Map getRequestHeaderValuesMap() {
264 if (_requestHeaderValuesMap == null)
265 {
266 _requestHeaderValuesMap = new RequestHeaderValuesMap(_portletRequest);
267 }
268 return _requestHeaderValuesMap;
269 }
270
271 public Locale getRequestLocale() {
272 return _portletRequest.getLocale();
273 }
274
275 public Iterator getRequestLocales() {
276 return new EnumerationIterator(_portletRequest.getLocales());
277 }
278
279 public Map getRequestMap() {
280 if (_requestMap == null)
281 {
282 _requestMap = new RequestMap(_portletRequest);
283 }
284 return _requestMap;
285 }
286
287 public Map getRequestParameterMap() {
288 if (_requestParameterMap == null)
289 {
290 _requestParameterMap = new RequestParameterMap(_portletRequest);
291 }
292 return _requestParameterMap;
293 }
294
295 public Iterator getRequestParameterNames() {
296
297 return new EnumerationIterator(_portletRequest.getParameterNames());
298 }
299
300 public Map getRequestParameterValuesMap() {
301 if (_requestParameterValuesMap == null)
302 {
303 _requestParameterValuesMap = new RequestParameterValuesMap(_portletRequest);
304 }
305 return _requestParameterValuesMap;
306 }
307
308 public String getRequestPathInfo() {
309 return null;
310 }
311
312 public String getRequestServletPath() {
313 return null;
314 }
315
316 public URL getResource(String path) throws MalformedURLException {
317 checkNull(path, "path");
318
319 return _portletContext.getResource(path);
320 }
321
322 public InputStream getResourceAsStream(String path) {
323 checkNull(path, "path");
324
325 return _portletContext.getResourceAsStream(path);
326 }
327
328 public Set getResourcePaths(String path) {
329 checkNull(path, "path");
330 return _portletContext.getResourcePaths(path);
331 }
332
333 public Object getResponse() {
334 return _portletResponse;
335 }
336
337 public void setResponse(Object response) {
338 if (response instanceof PortletResponse) {
339 this._portletResponse = (PortletResponse) response;
340 }
341 }
342
343 public Object getSession(boolean create) {
344 return _portletRequest.getPortletSession(create);
345 }
346
347 public Map getSessionMap() {
348 if (_sessionMap == null)
349 {
350 _sessionMap = new SessionMap(_portletRequest);
351 }
352 return _sessionMap;
353 }
354
355 public Principal getUserPrincipal() {
356 return _portletRequest.getUserPrincipal();
357 }
358
359 public boolean isUserInRole(String role) {
360 checkNull(role, "role");
361
362 return _portletRequest.isUserInRole(role);
363 }
364
365 public void log(String message) {
366 checkNull(message, "message");
367
368 _portletContext.log(message);
369 }
370
371 public void log(String message, Throwable exception) {
372 checkNull(message, "message");
373 checkNull(exception, "exception");
374
375 _portletContext.log(message, exception);
376 }
377
378 public void redirect(String url) throws IOException {
379 if (_portletResponse instanceof ActionResponse)
380 {
381 ((ActionResponse)_portletResponse).sendRedirect(url);
382 }
383 else
384 {
385 throw new IllegalArgumentException("Only ActionResponse supported");
386 }
387 }
388
389 public void release() {
390 _portletContext = null;
391 _portletRequest = null;
392 _portletResponse = null;
393 _applicationMap = null;
394 _sessionMap = null;
395 _requestMap = null;
396 _requestParameterMap = null;
397 _requestParameterValuesMap = null;
398 _requestHeaderMap = null;
399 _requestHeaderValuesMap = null;
400 _initParameterMap = null;
401 }
402
403 private void checkNull(Object o, String param)
404 {
405 if (o == null)
406 {
407 throw new NullPointerException(param + " can not be null.");
408 }
409 }
410
411 }