KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > webapp > http > servlet > ServletExternalContext


1 package com.icesoft.faces.webapp.http.servlet;
2
3 import com.icesoft.faces.context.BridgeExternalContext;
4 import com.icesoft.faces.util.EnumerationIterator;
5 import com.icesoft.faces.webapp.command.CommandQueue;
6 import com.icesoft.faces.webapp.command.Redirect;
7 import com.icesoft.faces.webapp.command.SetCookie;
8 import com.icesoft.faces.webapp.http.common.Configuration;
9 import com.icesoft.faces.webapp.xmlhttp.PersistentFacesCommonlet;
10 import com.icesoft.jasper.Constants;
11 import com.icesoft.util.SeamUtilities;
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14
15 import javax.faces.FacesException;
16 import javax.faces.context.FacesContext;
17 import javax.faces.render.ResponseStateManager;
18 import javax.servlet.ServletContext JavaDoc;
19 import javax.servlet.ServletException JavaDoc;
20 import javax.servlet.http.Cookie JavaDoc;
21 import javax.servlet.http.HttpServletRequest JavaDoc;
22 import javax.servlet.http.HttpServletResponse JavaDoc;
23 import javax.servlet.http.HttpSession JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.io.Writer JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.net.MalformedURLException JavaDoc;
30 import java.net.URI JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.util.Collections JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Locale JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Set JavaDoc;
39
40 //for now extend BridgeExternalContext since there are so many 'instanceof' tests
41
public class ServletExternalContext extends BridgeExternalContext {
42
43     private static Log log = LogFactory.getLog(ServletExternalContext.class);
44
45     private static String JavaDoc postBackKey;
46
47     static {
48         //We will place VIEW_STATE_PARAM in the requestMap so that
49
//JSF 1.2 doesn't think the request is a postback and skip
50
//execution
51
try {
52             Field JavaDoc field = ResponseStateManager.class.getField("VIEW_STATE_PARAM");
53             if (null != field) {
54                 postBackKey = (String JavaDoc) field.get(ResponseStateManager.class);
55             }
56         } catch (Exception JavaDoc e) {
57         }
58     }
59
60     private String JavaDoc viewIdentifier;
61     private ServletContext JavaDoc context;
62     private HttpServletRequest JavaDoc request;
63     private HttpServletResponse JavaDoc response;
64     private HttpSession JavaDoc session;
65     private Map JavaDoc applicationMap;
66     private Map JavaDoc sessionMap;
67     private Map JavaDoc requestParameterMap;
68     private Map JavaDoc requestParameterValuesMap;
69     private Map JavaDoc initParameterMap;
70     private Map JavaDoc requestMap;
71     private Map JavaDoc requestCookieMap;
72     private Map JavaDoc responseCookieMap;
73     private CommandQueue commandQueue;
74     private Redirector redirector;
75     private CookieTransporter cookieTransporter;
76     private boolean standardScope;
77
78     public ServletExternalContext(String JavaDoc viewIdentifier, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, CommandQueue commandQueue, Configuration configuration) {
79         this.viewIdentifier = viewIdentifier;
80         this.request = request;
81         this.response = response;
82         this.commandQueue = commandQueue;
83         this.session = this.request.getSession();
84         this.context = this.session.getServletContext();
85         this.standardScope = configuration.getAttributeAsBoolean("standardRequestScope", false);
86         this.applicationMap = new ServletApplicationMap(this.context);
87         this.sessionMap = new ServletSessionMap(this.session);
88         this.requestMap = new CopyingRequestAttributesMap(this.request);
89         this.requestCookieMap = new HashMap JavaDoc();
90         this.initParameterMap = new HashMap JavaDoc();
91         Enumeration JavaDoc names = this.context.getInitParameterNames();
92         while (names.hasMoreElements()) {
93             String JavaDoc key = (String JavaDoc) names.nextElement();
94             initParameterMap.put(key, this.context.getInitParameter(key));
95         }
96
97         this.update(request, response);
98         this.insertNewViewrootToken();
99     }
100
101     public Object JavaDoc getSession(boolean create) {
102         return session;
103     }
104
105     public Object JavaDoc getContext() {
106         return context;
107     }
108
109     public Object JavaDoc getRequest() {
110         return request;
111     }
112
113     public Object JavaDoc getResponse() {
114         return response;
115     }
116
117     public Map JavaDoc getApplicationMap() {
118         return applicationMap;
119     }
120
121     public Map JavaDoc getSessionMap() {
122         return sessionMap;
123     }
124
125     public Map JavaDoc getApplicationSessionMap() {
126         return sessionMap;
127     }
128
129     public Map JavaDoc getRequestMap() {
130         return requestMap;
131     }
132
133     public void update(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
134         //update parameters
135
boolean persistSeamKey = false;
136         if (requestParameterMap != null) {
137             persistSeamKey = (requestParameterMap.containsKey(PersistentFacesCommonlet.SEAM_LIFECYCLE_SHORTCUT));
138         }
139
140         requestParameterMap = new HashMap JavaDoc();
141         requestParameterValuesMap = new HashMap JavaDoc();
142         insertPostbackKey();
143         Enumeration JavaDoc parameterNames = request.getParameterNames();
144         while (parameterNames.hasMoreElements()) {
145             String JavaDoc name = (String JavaDoc) parameterNames.nextElement();
146             Object JavaDoc value = request.getParameter(name);
147             requestParameterMap.put(name, value);
148             requestParameterValuesMap.put(name, request.getParameterValues(name));
149         }
150
151         if (persistSeamKey) {
152             requestParameterMap.put(
153                     PersistentFacesCommonlet.SEAM_LIFECYCLE_SHORTCUT,
154                     Boolean.TRUE);
155         }
156
157         requestCookieMap = new HashMap JavaDoc();
158         Cookie[] cookies = request.getCookies();
159         if (cookies != null) {
160             for (int i = 0; i < cookies.length; i++) {
161                 Cookie cookie = cookies[i];
162                 requestCookieMap.put(cookie.getName(), cookie);
163             }
164         }
165         responseCookieMap = new HashMap JavaDoc();
166
167         this.response = response;
168     }
169
170     public void updateOnReload(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
171         Map JavaDoc previousRequestMap = this.requestMap;
172         this.requestMap = new CopyingRequestAttributesMap(request);
173         //propagate entries
174
this.requestMap.putAll(previousRequestMap);
175         this.request = request;
176         this.update(request, response);
177     }
178
179     public Map JavaDoc getRequestParameterMap() {
180         return requestParameterMap;
181     }
182
183     public Map JavaDoc getRequestParameterValuesMap() {
184         return requestParameterValuesMap;
185     }
186
187     public Iterator getRequestParameterNames() {
188         return requestParameterMap.keySet().iterator();
189     }
190
191     //todo: implement!
192
public Map JavaDoc getRequestHeaderMap() {
193         return Collections.EMPTY_MAP;
194     }
195
196     //todo: implement!
197
public Map JavaDoc getRequestHeaderValuesMap() {
198         return Collections.EMPTY_MAP;
199     }
200
201     public Map JavaDoc getRequestCookieMap() {
202         return requestCookieMap;
203     }
204
205     public Locale JavaDoc getRequestLocale() {
206         return request.getLocale();
207     }
208
209     public Iterator getRequestLocales() {
210         return new EnumerationIterator(request.getLocales());
211     }
212
213     private String JavaDoc requestPathInfo;
214
215     public void setRequestPathInfo(String JavaDoc viewId) {
216         requestPathInfo = viewId;
217     }
218
219     public String JavaDoc getRequestPathInfo() {
220
221         if (requestPathInfo != null && requestPathInfo.trim().length() > 0) {
222             return requestPathInfo;
223         }
224
225         //If we start out null (because it hasn't been specifically set) then
226
//use the wrapped request value.
227
if (requestPathInfo == null) {
228             requestPathInfo = request.getPathInfo();
229         }
230
231         //We need to fix any occurrences of the "" (the empty String) because
232
//the JSF Lifecycle implementations won't be able to properly create
233
//a view ID otherwise because they check for null but not the empty
234
//String.
235
requestPathInfo = convertEmptyStringToNull(requestPathInfo);
236         return requestPathInfo;
237     }
238
239     /**
240      * Utility method that returns the original value of the supplied String
241      * unless it is emtpy (val.trim().length() == 0). In that particlar case
242      * the value returned is null.
243      *
244      * @param val
245      * @return
246      */

247     private static String JavaDoc convertEmptyStringToNull(String JavaDoc val) {
248         if (val == null) {
249             return val;
250         }
251
252         if (val.trim().length() == 0) {
253             return null;
254         }
255
256         return val;
257     }
258
259     public String JavaDoc getRequestURI() {
260
261         //If the attribute "javax.servlet.include.request_uri" has been set
262
//then we should use it. This is typically done via dispatching. It
263
//is the way the proper view ID is set with portlets.
264
String JavaDoc uri = (String JavaDoc) request.getAttribute(Constants.INC_REQUEST_URI);
265         if (uri == null || uri.trim().length() > 0) {
266             uri = request.getRequestURI();
267         }
268
269         return uri;
270     }
271
272     public String JavaDoc getRequestContextPath() {
273         return request.getContextPath();
274     }
275
276     private String JavaDoc requestServletPath;
277
278     public void setRequestServletPath(String JavaDoc path) {
279         requestServletPath = path;
280     }
281
282     public String JavaDoc getRequestServletPath() {
283         return null == requestServletPath ? request.getServletPath() : requestServletPath;
284     }
285
286     public String JavaDoc getInitParameter(String JavaDoc name) {
287         return context.getInitParameter(name);
288     }
289
290     public Map JavaDoc getInitParameterMap() {
291         return initParameterMap;
292     }
293
294     public Set JavaDoc getResourcePaths(String JavaDoc path) {
295         return context.getResourcePaths(path);
296     }
297
298     public URL JavaDoc getResource(String JavaDoc path) throws MalformedURLException JavaDoc {
299         return context.getResource(path);
300     }
301
302     public InputStream JavaDoc getResourceAsStream(String JavaDoc path) {
303         return context.getResourceAsStream(path);
304     }
305
306     public String JavaDoc encodeActionURL(String JavaDoc url) {
307         return url;
308     }
309
310     public String JavaDoc encodeResourceURL(String JavaDoc url) {
311         try {
312             return response.encodeURL(url);
313         } catch (Exception JavaDoc e) {
314             return url;
315         }
316     }
317
318     public String JavaDoc encodeNamespace(String JavaDoc name) {
319
320         //The portlet environment should provide a namespace for encoding. This
321
//is request specific so we need to check each time. In the future, we
322
//may want to consider using our own internal view number since it's
323
//purpose is to encapsulate this concept.
324
String JavaDoc ns = (String JavaDoc) request.getAttribute(Constants.NAMESPACE_KEY);
325
326         if (ns != null) {
327             return ns + name;
328         }
329
330         return name;
331     }
332
333     public void dispatch(String JavaDoc path) throws IOException JavaDoc, FacesException {
334         try {
335             request.getRequestDispatcher(path).forward(request, response);
336         } catch (ServletException JavaDoc se) {
337             throw new FacesException(se);
338         }
339     }
340
341     public void redirect(String JavaDoc requestURI) throws IOException JavaDoc {
342         URI JavaDoc uri = URI.create(SeamUtilities.encodeSeamConversationId(requestURI, viewIdentifier));
343         String JavaDoc query = uri.getQuery();
344         if (query == null) {
345             redirector.redirect(uri + "?rvn=" + viewIdentifier);
346         } else if (query.matches(".*rvn=.*")) {
347             redirector.redirect(uri.toString());
348         } else {
349             redirector.redirect(uri + "&rvn=" + viewIdentifier);
350         }
351         FacesContext.getCurrentInstance().responseComplete();
352     }
353
354     public void log(String JavaDoc message) {
355         context.log(message);
356     }
357
358     public void log(String JavaDoc message, Throwable JavaDoc throwable) {
359         context.log(message, throwable);
360     }
361
362     public String JavaDoc getAuthType() {
363         return request.getAuthType();
364     }
365
366     public String JavaDoc getRemoteUser() {
367         return request.getRemoteUser();
368     }
369
370     public java.security.Principal JavaDoc getUserPrincipal() {
371         return request.getUserPrincipal();
372     }
373
374     public boolean isUserInRole(String JavaDoc role) {
375         return request.isUserInRole(role);
376     }
377
378     public void addCookie(Cookie cookie) {
379         responseCookieMap.put(cookie.getName(), cookie);
380         cookieTransporter.send(cookie);
381     }
382
383     public Map JavaDoc getResponseCookieMap() {
384         return responseCookieMap;
385     }
386
387     //todo: see if we can execute full JSP cycle all the time (not only when page is parsed)
388
//todo: this way the bundles are put into the request map every time, so we don't have to carry
389
//todo: them between requests
390
public Map JavaDoc collectBundles() {
391         Map JavaDoc result = new HashMap JavaDoc();
392         Iterator entries = requestMap.entrySet().iterator();
393         while (entries.hasNext()) {
394             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
395             Object JavaDoc value = entry.getValue();
396             if (value != null) {
397                 String JavaDoc className = value.getClass().getName();
398                 if ((className.indexOf("LoadBundleTag") > 0) || //Sun RI
399
(className.indexOf("BundleMap") > 0)) { //MyFaces
400
result.put(entry.getKey(), value);
401                 }
402             }
403         }
404
405         return result;
406     }
407
408     public Writer JavaDoc getWriter(String JavaDoc encoding) throws IOException JavaDoc {
409         try {
410             return new OutputStreamWriter JavaDoc(response.getOutputStream(), encoding);
411         } catch (IllegalStateException JavaDoc e) {
412             // getWriter() already called, perhaps because of JSP include
413
return response.getWriter();
414         }
415     }
416
417     /**
418      * Any GET request performed by the browser is a non-faces request to the framework.
419      * (JSF-spec chapter 2, introduction). Given this, the framework must create a new
420      * viewRoot for the request, even if the viewId has already been visited. (Spec
421      * section 2.1.1) <p>
422      * <p/>
423      * Only during GET's remember, not during partial submits, where the JSF framework must
424      * be allowed to attempt to restore the view. There is a great deal of Seam related code
425      * that depends on this happening. So put in a token that allows the D2DViewHandler
426      * to differentiate between the non-faces request, and the postbacks, for this
427      * request, which will allow the ViewHandler to make the right choice, since we keep
428      * the view around for all types of requests
429      */

430     private void insertNewViewrootToken() {
431         if (SeamUtilities.isSeamEnvironment()) {
432             requestParameterMap.put(
433                     PersistentFacesCommonlet.SEAM_LIFECYCLE_SHORTCUT,
434                     Boolean.TRUE);
435         }
436     }
437
438     public void switchToNormalMode() {
439         redirector = new Redirector() {
440             public void redirect(String JavaDoc uri) {
441                 try {
442                     response.sendRedirect(uri);
443                 } catch (IOException JavaDoc e) {
444                     throw new RuntimeException JavaDoc(e);
445                 }
446             }
447         };
448
449         cookieTransporter = new CookieTransporter() {
450             public void send(Cookie cookie) {
451                 response.addCookie(cookie);
452             }
453         };
454     }
455
456     public void switchToPushMode() {
457         redirector = new Redirector() {
458             public void redirect(String JavaDoc uri) {
459                 commandQueue.put(new Redirect(uri));
460             }
461         };
462
463         cookieTransporter = new CookieTransporter() {
464             public void send(Cookie cookie) {
465                 commandQueue.put(new SetCookie(cookie));
466             }
467         };
468
469         resetRequestMap();
470     }
471
472     /**
473      * If in Standard request scope mode, remove all parameters from
474      * the Request Map.
475      */

476     public void resetRequestMap() {
477         if (standardScope) {
478             requestMap.clear();
479         }
480     }
481
482     public void injectBundles(Map JavaDoc bundles) {
483         requestMap.putAll(bundles);
484     }
485
486     public void dispose() {
487         requestMap.clear();
488         commandQueue.take();
489     }
490
491     private interface Redirector {
492         void redirect(String JavaDoc uri);
493     }
494
495     private interface CookieTransporter {
496         void send(Cookie cookie);
497     }
498
499     private void insertPostbackKey() {
500         if (null != postBackKey) {
501             requestParameterMap.put(postBackKey, "not reload");
502             requestParameterValuesMap.put(postBackKey, new String JavaDoc[]{"not reload"});
503         }
504     }
505 }
506
Popular Tags