KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > j2ee > session > BindingInterceptor


1 // ========================================================================
2
// $Id: BindingInterceptor.java,v 1.4 2004/05/09 20:30:47 gregwilkins Exp $
3
// Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.j2ee.session;
17
18 //----------------------------------------
19

20 import java.rmi.RemoteException JavaDoc;
21
22 import javax.servlet.http.HttpSessionBindingEvent JavaDoc;
23 import javax.servlet.http.HttpSessionBindingListener JavaDoc;
24
25 import org.jfox.ioc.logger.Logger;
26
27 //----------------------------------------
28

29 /**
30  * A <code>BindingInterceptor</code> is responsible for notifying
31  * HttpSessionAttributeListeners when Attributes are added to, removed
32  * from or replaced in a Session and HttpSessionBindingListeners when
33  * attributes are bound into or unbound from a Session. <P/> This is
34  * an expensive Interceptor to use since it requires that on rebinding
35  * an attribute in the Session, the old value is returned in case it
36  * is a Listener requiring notification of it's removal.If you are
37  * using a distributed store, this requirement will result in a
38  * serialisation and network traffic overhead which may not actually
39  * be necessary. Unfortunately it would be expensive to decide at
40  * runtime whether to add this interceptor since one of these
41  * Listeners might be bound into the session at any time from any
42  * node. This may be addressed in a future release.
43  *
44  * @author <a HREF="mailto:jules@mortbay.com">Jules Gosnell</a>
45  * @version 1.0
46  */

47 public class BindingInterceptor
48   extends StateInterceptor
49 {
50   protected static final Logger _log=Logger.getLogger(BindingInterceptor.class);
51   // All Interceptors are expected to provide this constructor...
52

53   // HttpSessionBindingListeners are held in the SessionManager -
54
// because they are attached at the webapp, rather than session
55
// instance level. So they are notified via the Manager.
56

57   protected Object JavaDoc
58     notifyValueUnbound(String JavaDoc name, Object JavaDoc value)
59   {
60     if (!(value instanceof HttpSessionBindingListener JavaDoc))
61       return value;
62
63     HttpSessionBindingEvent JavaDoc event=new HttpSessionBindingEvent JavaDoc(getSession(), name, value);
64     ((HttpSessionBindingListener JavaDoc)value).valueUnbound(event);
65     event=null;
66
67     return value;
68   }
69
70   protected Object JavaDoc
71     notifyValueBound(String JavaDoc name, Object JavaDoc value)
72   {
73     if (!(value instanceof HttpSessionBindingListener JavaDoc))
74       return value;
75
76     HttpSessionBindingEvent JavaDoc event=new HttpSessionBindingEvent JavaDoc(getSession(), name, value);
77     ((HttpSessionBindingListener JavaDoc)value).valueBound(event);
78     event=null;
79
80     return value;
81   }
82
83   // if we knew whether there were any HttpSessionAttributeListeners
84
// registered with our Manager and the DistributedState knew whether
85
// the oldValue was an HttpSessionBindingListener then we could make
86
// the decision in the e.g. EJB tier as to whether to return the
87
// oldValue or not. Unfortunately, all attributes are preserialised
88
// in the Web Tier, in case the EJB tier doesn't have their class,
89
// so this interceptor would have to mark relevant attributes on
90
// their way into the EJB tier, so it would know whether to return
91
// them in a set/removeAttribute situation later... - How can this
92
// be done efficiently ?
93

94   /**
95    * <code>setAttribute</code> is overriden in order to notify
96    * HttpSessionAttribute and HttpSessionBindingListeners of relative
97    * Attribute changes.
98    *
99    * @param name a <code>String</code> value
100    * @param value an <code>Object</code> value
101    * @return an <code>Object</code> value
102    * @exception RemoteException if an error occurs
103    */

104   public Object JavaDoc
105     setAttribute(String JavaDoc name, Object JavaDoc value, boolean returnValue)
106     throws RemoteException JavaDoc
107   {
108     // assert(name!=null);
109
// assert(value!=null);
110

111     boolean needOldValue=true;
112
113     // we want the old binding back if it was an HttpSessionBindingListener
114
Object JavaDoc oldValue=super.setAttribute(name, value, true);
115
116     // send binding notifications
117

118     try
119     {
120       if (oldValue!=null)
121     notifyValueUnbound(name, oldValue);
122
123       notifyValueBound(name, value);
124
125       // send attribute notifications
126
if (oldValue!=null)
127     getManager().notifyAttributeReplaced(getSession(), name, oldValue);
128       else
129     getManager().notifyAttributeAdded(getSession(), name, value);
130     }
131     catch (Throwable JavaDoc t)
132     {
133       _log.error("error in user owned Listener - notifications may be incomplete", t);
134     }
135
136     return oldValue;
137   }
138
139   /**
140    * <code>removeAttribute</code> is overriden in order to notify
141    * HttpSessionAttribute and HttpSessionBindingListeners of relative
142    * Attribute changes.
143    *
144    * @param name a <code>String</code> value
145    * @return an <code>Object</code> value
146    * @exception RemoteException if an error occurs
147    */

148   public Object JavaDoc
149     removeAttribute(String JavaDoc name, boolean returnValue)
150     throws RemoteException JavaDoc
151   {
152     // we want the old binding back if it was an HttpSessionBindingListener
153
Object JavaDoc oldValue=super.removeAttribute(name, true);
154
155     if (oldValue!=null)
156     {
157       try
158       {
159     notifyValueUnbound(name, oldValue);
160     getManager().notifyAttributeRemoved(getSession(), name, oldValue);
161       }
162       catch (Throwable JavaDoc t)
163       {
164     _log.error("error in user owned Listener - notifications may be incomplete", t);
165       }
166     }
167
168     return oldValue;
169   }
170
171   // public Object clone() { return null; } // Stateful
172
}
173
Popular Tags