KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc5 > session > SessionBasedClusteredSession


1 /*
2  * JBoss, the OpenSource WebOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.web.tomcat.tc5.session;
8
9 import org.jboss.metadata.WebMetaData;
10
11 import java.beans.PropertyChangeSupport JavaDoc;
12 import java.io.Serializable JavaDoc;
13 import java.security.Principal JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Map JavaDoc;
17
18 /**
19  * Implementation of a clustered session for the JBossCacheManager. The replication granularity
20  * level is session based; that is, we replicate per whole session object.
21  * We use JBossCache for our internal replicated data store.
22  * The internal structure is like in JBossCache:
23  * <pre>
24  * /JSESSION
25  * /web_app_path (path + session id is unique)
26  * /id Map(id, session)
27  * (VERSION_KEY, version) // Used for version tracking. version is an Integer.
28  * </pre>
29  * <p/>
30  * Note that the isolation level of the cache dictates the
31  * concurrency behavior.</p>
32  *
33  * @author Ben Wang
34  * @version $Revision: 1.3.2.5 $
35  */

36 class SessionBasedClusteredSession
37    extends ClusteredSession implements Serializable JavaDoc
38 {
39    static final long serialVersionUID = 3200976125245487256L;
40    /**
41     * Descriptive information describing this Session implementation.
42     */

43    protected static final String JavaDoc info = "SessionBasedClusteredSession/1.0";
44
45    private transient boolean isSessionModifiedSinceLastSave;
46    private transient JBossCacheService proxy_;
47
48    public SessionBasedClusteredSession(AbstractJBossManager manager)
49    {
50       super(manager);
51       initAfterLoad(manager);
52    }
53
54    /**
55     * Initialize fields marked as transient after loading this session
56     * from the distributed store
57     *
58     * @param manager the manager for this session
59     */

60    public void initAfterLoad(AbstractJBossManager manager)
61    {
62       // Use proxy to determine if this is first time session retrieval.
63
if (this.proxy_ == null)
64       {
65          if (log.isDebugEnabled())
66          {
67             log.debug("initAfterLoad(): initialize the transient variables ...");
68          }
69          setManager(manager);
70          listeners = new ArrayList JavaDoc();
71          notes = new HashMap JavaDoc();
72          support = new PropertyChangeSupport JavaDoc(this);
73          expiring = false;
74          isSessionModifiedSinceLastSave = false;
75
76          // cache invalidate purpose
77
isOutdated = false;
78
79          proxy_ = ((JBossCacheManager) manager).getCacheService();
80
81          // still null???
82
if (proxy_ == null)
83          {
84             throw new RuntimeException JavaDoc("SessionBasedClusteredSession: Cache service is null.");
85          }
86
87          // Notify all attributes of type HttpSessionActivationListener (SRV 7.7.2)
88
this.activate();
89       }
90    }
91
92    // ----------------------------------------------------- Session Properties
93
/**
94     * Set the creation time for this session. This method is called by the
95     * Manager when an existing Session instance is reused.
96     *
97     * @param time The new creation time
98     */

99    public void setCreationTime(long time)
100    {
101       super.setCreationTime(time);
102       sessionIsDirty();
103    }
104
105    /**
106     * Set the authenticated Principal that is associated with this Session.
107     * This provides an <code>Authenticator</code> with a means to cache a
108     * previously authenticated Principal, and avoid potentially expensive
109     * <code>Realm.authenticate()</code> calls on every request.
110     *
111     * @param principal The new Principal, or <code>null</code> if none
112     */

113    public void setPrincipal(Principal JavaDoc principal)
114    {
115
116       Principal JavaDoc oldPrincipal = this.principal;
117       this.principal = principal;
118       support.firePropertyChange("principal", oldPrincipal, this.principal);
119
120       if ((oldPrincipal != null && !oldPrincipal.equals(principal)) ||
121          (oldPrincipal == null && principal != null))
122          sessionIsDirty();
123
124    }
125
126    // ------------------------------------------------- Session Public Methods
127
/**
128     * Return a string representation of this object.
129     */

130    public String JavaDoc toString()
131    {
132       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
133       sb.append("SessionBasedClusteredSession[");
134       sb.append(id);
135       sb.append("]");
136       return (sb.toString());
137
138    }
139
140    /**
141     * Start to process my local attribute changes to the replication layer.
142     */

143    public synchronized void processSessionRepl()
144    {
145       if (!isSessionDirty())
146       {
147          if (log.isDebugEnabled())
148          {
149             log.debug("processSessionRepl(): session is not dirty. No need to replicate.");
150          }
151          return;
152       }
153       // Replicate this first. Note this will be lightweight since many of the attributes are transient.
154
// And also without attributes
155
if (log.isDebugEnabled())
156       {
157          log.debug("processSessionRepl(): session is dirty. Will increment version from: " +
158                  getVersion() + " and replicate.");
159       }
160       this.incrementVersion(); // cache invalidation versioning
161
proxy_.putSession(id, this);
162
163       isSessionModifiedSinceLastSave = false;
164    }
165
166    public void removeMyself()
167    {
168       proxy_.removeSession(id);
169    }
170
171    public void removeMyselfLocal()
172    {
173       proxy_.removeSessionLocal(id);
174    }
175
176    // ----------------------------------------------HttpSession Public Methods
177

178    /**
179     * Update the accessed time information for this session. This method
180     * should be called by the context when a request comes in for a particular
181     * session, even if the application does not reference it.
182     */

183    public void access()
184    {
185       super.access();
186       // If we do not use the local cache the session is dirty
187
// after every access.
188
if (invalidationPolicy == WebMetaData.SESSION_INVALIDATE_ACCESS)
189       {
190          this.sessionIsDirty();
191       }
192    }
193
194    protected Object JavaDoc getJBossInternalAttribute(String JavaDoc name)
195    {
196
197       Object JavaDoc result = attributes.get(name);
198
199       if (result != null)
200       {
201          if (invalidationPolicy == WebMetaData.SESSION_INVALIDATE_SET_AND_GET)
202          {
203             sessionIsDirty();
204          }
205          else if (invalidationPolicy == WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET)
206          {
207             if (!(result instanceof String JavaDoc ||
208                result instanceof Integer JavaDoc ||
209                result instanceof Long JavaDoc ||
210                result instanceof Byte JavaDoc ||
211                result instanceof Short JavaDoc ||
212                result instanceof Float JavaDoc ||
213                result instanceof Double JavaDoc ||
214                result instanceof Character JavaDoc ||
215                result instanceof Boolean JavaDoc)
216             )
217             {
218                sessionIsDirty();
219             }
220          }
221       }
222
223       return result;
224
225    }
226
227    protected Object JavaDoc removeJBossInternalAttribute(String JavaDoc name)
228    {
229       sessionIsDirty();
230       return attributes.remove(name);
231    }
232
233    protected Map JavaDoc getJBossInternalAttributes()
234    {
235       // TODO Add it to the doc
236
// No matter what, get all attributes is considered dirty.
237
sessionIsDirty();
238       return attributes;
239    }
240
241    protected Object JavaDoc setJBossInternalAttribute(String JavaDoc name, Object JavaDoc value)
242    {
243       sessionIsDirty();
244       return attributes.put(name, value);
245    }
246
247    protected void sessionIsDirty()
248    {
249       // Session is dirty
250
isSessionModifiedSinceLastSave = true;
251    }
252
253    public boolean isSessionDirty()
254    {
255       return isSessionModifiedSinceLastSave;
256    }
257
258 }
259
Popular Tags