KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > event > DefaultEventContext


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: DefaultEventContext.java,v 1.21 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.event;
21
22 import java.io.*;
23 import java.util.*;
24 import javax.servlet.*;
25 import javax.servlet.http.*;
26
27 import org.apache.log4j.*;
28
29 import org.enhydra.barracuda.core.view.*;
30 import org.enhydra.barracuda.plankton.data.*;
31
32 /**
33  * <p>The context contains information about the event (event,
34  * queue, plus request and response info if appropriate). The
35  * context also implements StateMap, so you can use it to pass
36  * information between event handlers. The scope of the context
37  * is only for the duration of an event dispatch cycle (ie. from
38  * Http Request to Http Response)
39  *
40  * <p>Note that because DefaultEventContext implements ViewEventContext
41  * it can safely be cast to its two parent interfaces: EventContext and
42  * ControlEventContext. This is in fact what the DefaultEventDispatcher
43  * actually does to control access to the appropriate information
44  * (ie. a ControlEvent handler should get a reference to an ControlEventContext,
45  * NOT an ViewEventContext, since the control handlers shouldn't have
46  * access to the HttpServletResponse object.)
47  */

48 public class DefaultEventContext implements ViewEventContext {
49
50     //public vars
51
protected static final Logger logger = Logger.getLogger(DefaultEventContext.class.getName());
52
53     //private vars
54
private static final String JavaDoc CONTEXT_ID = "$ctxid";
55     private static final String JavaDoc STATE = "_STATE";
56     private static final String JavaDoc LOCAL_OR = "_LOCAL_OR";
57     private StateMap statemap = null;
58     private static long uid = System.currentTimeMillis();
59     
60     /**
61      * Public constructor.
62      *
63      * @param queue the event dispatch queue
64      * @param config the servlet config structure
65      * @param req the HttpServletRequest
66      * @param resp the HttpServlet Response
67      * @param defaultResponseEvent the default response event to be used
68      * if none is generated by the control event handlers
69      */

70     public DefaultEventContext(DispatchQueue queue, ViewCapabilities vc, ServletConfig config, HttpServletRequest req, HttpServletResponse resp, HttpResponseEvent defaultResponseEvent) {
71         restoreContext(req);
72         this.putState(EventContext.DISPATCH_QUEUE, queue);
73         this.putState(EventContext.VIEW_CAPABILITIES, vc);
74         this.putState(ControlEventContext.SERVLET_CONFIG, config);
75         this.putState(ControlEventContext.HTTP_SERVLET_REQUEST, req);
76         this.putState(ViewEventContext.HTTP_SERVLET_RESPONSE, resp);
77         this.putState(DefaultEventDispatcher.DEFAULT_RESPONSE_EVENT, defaultResponseEvent);
78     }
79
80     /**
81      * Get the underlying BaseEvent
82      *
83      * @return the underlying BaseEvent
84      */

85     public BaseEvent getEvent() {
86         return (BaseEvent) this.getState(EventContext.BASE_EVENT);
87     }
88
89     /**
90      * Get the underlying DispatchQueue
91      *
92      * @return the underlying DispatchQueue
93      */

94     public DispatchQueue getQueue() {
95         return (DispatchQueue) this.getState(EventContext.DISPATCH_QUEUE);
96     }
97     
98     /**
99      * Get the underlying ViewCapabilities
100      */

101     public ViewCapabilities getViewCapabilities() {
102         return (ViewCapabilities) this.getState(EventContext.VIEW_CAPABILITIES);
103     }
104     
105     /**
106      * Get the associated ServletConfig structure
107      *
108      * @return the associated ServletConfig structure
109      */

110     public ServletConfig getConfig() {
111         return (ServletConfig) this.getState(ControlEventContext.SERVLET_CONFIG);
112     }
113     
114     /**
115      * Get the associated HttpServletRequest
116      *
117      * @return the associated HttpServletRequest
118      */

119     public HttpServletRequest getRequest() {
120         return (HttpServletRequest) this.getState(ControlEventContext.HTTP_SERVLET_REQUEST);
121     }
122
123     /**
124      * Get the associated HttpServletResponse
125      *
126      * @return the associated HttpServletResponse
127      */

128     public HttpServletResponse getResponse() {
129         return (HttpServletResponse) this.getState(ViewEventContext.HTTP_SERVLET_RESPONSE);
130     }
131     
132     //csc_052703.1 - rewritten to persist context in soft rather than weak session
133

134     //csc_082302.2 - rewritten to persist context using a unique id (per request)
135
//in a Global Weak Repository, rather than persisting context in user session,
136
//which inherantly had problems if multiple frames on a client were firing
137
//different events at the same time. The down side of this fix is that the
138
//redirected url shows in the browser with something like this tacked onto
139
//the url: $ctxid=_1030135624563
140
/**
141      * The event context must be able to persist its state
142      * in the user's session. NOTE: this method is primarily
143      * intended for use by the EventDispatcher class when the
144      * system needs to persist context information over multiple
145      * request-response cycels (ie. to handle ClientSideRedirectExceptions).
146      * As such, developers using the event model in applications
147      * should never really need to call this method.
148      *
149      * @param re the client side redirect exception that is the reason
150      * for this call to persistContext
151      */

152     public void persistContext(ClientSideRedirectException re) {
153         if (logger.isInfoEnabled()) logger.info("persisting context to prepare for client side redirect...");
154
155 /*
156         SessionServices.getSession(getRequest()).setAttribute(STATE, statemap);
157         //csc_022502.1_start
158         ObjectRepository lr = ObjectRepository.getLocalRepository();
159         List list = lr.getStateKeys();
160         if (list!=null && list.size()>0) {
161             StateMap sm = new DefaultStateMap();
162             SessionServices.getSession(getRequest()).setAttribute(LOCAL_OR, sm);
163             Iterator it = list.iterator();
164             while (it.hasNext()) {
165                 Object key = it.next();
166                 Object val = lr.getState(key);
167                 sm.putState(key, val);
168             }
169         }
170         //csc_022502.1_end
171 */

172         //grab a reference to the weak global repository (we use a weak reference
173
//here just in case the client hits stop or they do not support redirects;
174
//since we aren't putting the information in the session, we have to make sure
175
//it gets cleaned up, and this is the easiest way to do that)
176
//csc_052703.1 ObjectRepository wgor = ObjectRepository.getWeakGlobalRepository();
177
ObjectRepository wgor = ObjectRepository.getSoftGlobalRepository(); //csc_052703.1
178
String JavaDoc id = getUID();
179         if (logger.isDebugEnabled()) logger.debug("...getting uid:"+id);
180         
181         //persist the statemap and local repository information in the weak global
182
//repository (note that the NS is what will keep this unique)
183
//...statemap
184
wgor.putState(CONTEXT_ID+id+STATE, statemap);
185         if (logger.isDebugEnabled()) logger.debug("...saved statemap, key = "+CONTEXT_ID+id+STATE);
186         //...local or
187
ObjectRepository lr = ObjectRepository.getLocalRepository();
188         List list = lr.getStateKeys();
189         if (list!=null && list.size()>0) {
190             StateMap sm = new DefaultStateMap();
191             wgor.putState(CONTEXT_ID+id+LOCAL_OR, sm);
192             if (logger.isDebugEnabled()) logger.debug("...saved lr, key = "+CONTEXT_ID+id+LOCAL_OR);
193             Iterator it = list.iterator();
194             while (it.hasNext()) {
195                 Object JavaDoc key = it.next();
196                 Object JavaDoc val = lr.getState(key);
197                 sm.putState(key, val);
198                 if (logger.isDebugEnabled()) logger.debug("......saved lr items: key="+key+" val="+val);
199             }
200         }
201         
202         //finally, adjust the redirect url to ensure that we can extract the NS id
203
//from the url when it comes time to restore the context
204
String JavaDoc url = re.getRedirectURL();
205         int spos = url.indexOf("?");
206         String JavaDoc sep = (spos>-1 ? "&" : "?");
207         re.setRedirectURL(url+sep+CONTEXT_ID+"="+id);
208         if (logger.isDebugEnabled()) logger.debug("...adjusting redirect URL from:"+url+" to:"+re.getRedirectURL());
209     }
210     
211     //csc_082302.2 - rewritten along with above method
212
/**
213      * The event context must also be able to restore state
214      * from the user's session. Calling this method effectively
215      * removes the state from the session.
216      */

217     public void restoreContext(HttpServletRequest req) {
218         if (logger.isInfoEnabled()) logger.info("see if we need to restore context...");
219
220         //start by trying to get the NS id from the request
221
String JavaDoc id = req.getParameter(CONTEXT_ID);
222         if (logger.isDebugEnabled()) logger.debug("...looking for context id in req:"+id);
223         if (id!=null) {
224             if (logger.isDebugEnabled()) logger.debug("...found persisted context! attempting to restore...");
225
226             //see if we can find the id in the weak global or
227
//csc_052703.1 ObjectRepository wgor = ObjectRepository.getWeakGlobalRepository();
228
ObjectRepository wgor = ObjectRepository.getSoftGlobalRepository(); //csc_052703.1
229
//...statemap
230
String JavaDoc stkey = CONTEXT_ID+id+STATE;
231             Object JavaDoc o = wgor.getState(stkey);
232             if (logger.isDebugEnabled()) logger.debug("......looking for statemap in wgor, key:"+stkey+" found:"+o);
233             if (o!=null && o instanceof StateMap) statemap = (StateMap) o;
234             else logger.warn("......expected statemap context missing!");
235             wgor.removeState(stkey);
236             //...local repository
237
stkey = CONTEXT_ID+id+LOCAL_OR;
238             o = wgor.getState(stkey);
239             if (logger.isDebugEnabled()) logger.debug("......looking for lr in wgor, key:"+stkey+" found:"+o);
240             if (o!=null && o instanceof StateMap) {
241                 StateMap sm = (StateMap) o;
242                 if (sm!=null) {
243                     List list = sm.getStateKeys();
244                     if (list!=null) {
245                         ObjectRepository lr = ObjectRepository.getLocalRepository();
246                         Iterator it = list.iterator();
247                         while (it.hasNext()) {
248                             Object JavaDoc key = it.next();
249                             Object JavaDoc val = sm.getState(key);
250                             lr.putState(key, val);
251                             if (logger.isDebugEnabled()) logger.debug(".........retrieved lr items: key="+key+" val="+val);
252                         }
253                     }
254                 }
255             }
256             wgor.removeState(stkey);
257         } else {
258             if (logger.isDebugEnabled()) logger.debug("...no persisted context");
259         }
260
261         if (statemap==null) statemap = new DefaultStateMap();
262 /*
263         HttpSession session = SessionServices.getSession(req, false);
264         if (session!=null) {
265             statemap = (StateMap) session.getAttribute(STATE);
266             session.removeAttribute(STATE);
267         }
268         if (statemap==null) statemap = new DefaultStateMap();
269         //csc_022502.1_start
270         if (session!=null) {
271             StateMap sm = (StateMap) session.getAttribute(LOCAL_OR);
272             if (sm!=null) {
273                 List list = sm.getStateKeys();
274                 if (list!=null) {
275                     ObjectRepository lr = ObjectRepository.getLocalRepository();
276                     Iterator it = list.iterator();
277                     while (it.hasNext()) {
278                         Object key = it.next();
279                         Object val = sm.getState(key);
280                         lr.putState(key, val);
281                     }
282                 }
283                 session.removeAttribute(LOCAL_OR);
284             }
285         }
286         //csc_022502.1_end
287 */

288     }
289     
290     private synchronized static String JavaDoc getUID() {
291         return "_"+(++uid);
292     }
293
294     
295     
296     //-------------------- StateMap ------------------------------
297
/**
298      * set a property in this StateMap
299      *
300      * @param key the state key object
301      * @param val the state value object
302      */

303     public void putState(Object JavaDoc key, Object JavaDoc val) {
304         statemap.putState(key,val);
305     }
306     
307     /**
308      * get a property in this StateMap
309      *
310      * @param key the state key object
311      * @return the value for the given key
312      */

313     public Object JavaDoc getState(Object JavaDoc key) {
314         return statemap.getState(key);
315     }
316     
317     /**
318      * remove a property in this StateMap
319      *
320      * @param key the key object
321      * @return the object which was removed
322      */

323     public Object JavaDoc removeState(Object JavaDoc key) {
324         return statemap.removeState(key);
325     }
326     
327     /**
328      * get a list of the keys for this StateMap
329      *
330      * @return a list the keys for this StateMap
331      */

332     public List getStateKeys() {
333         return statemap.getStateKeys();
334     }
335     
336     /**
337      * get a copy of the underlying Map
338      *
339      * @return a copy of the underlying state Map
340      */

341     public Map getStateValues() {
342         return statemap.getStateValues();
343     }
344     
345     //csc_052803_2 - added
346
/**
347      * clear all state information
348      */

349     public void clearState() {
350         statemap.clearState();
351     }
352 }
353
Popular Tags