KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > jetty > servlet > AbstractSessionManager


1 // ========================================================================
2
// $Id: AbstractSessionManager.java,v 1.52 2006/06/21 09:35:28 gregwilkins Exp $
3
// Copyright 199-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.jetty.servlet;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.EventListener JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Random JavaDoc;
27
28 import javax.servlet.ServletContext JavaDoc;
29 import javax.servlet.http.Cookie JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpSession JavaDoc;
32 import javax.servlet.http.HttpSessionAttributeListener JavaDoc;
33 import javax.servlet.http.HttpSessionBindingEvent JavaDoc;
34 import javax.servlet.http.HttpSessionBindingListener JavaDoc;
35 import javax.servlet.http.HttpSessionContext JavaDoc;
36 import javax.servlet.http.HttpSessionEvent JavaDoc;
37 import javax.servlet.http.HttpSessionListener JavaDoc;
38
39 import org.apache.commons.logging.Log;
40 import org.mortbay.log.LogFactory;
41 import org.mortbay.http.HttpOnlyCookie;
42 import org.mortbay.util.LazyList;
43 import org.mortbay.util.LogSupport;
44 import org.mortbay.util.MultiMap;
45
46
47 /* ------------------------------------------------------------ */
48 /** An Abstract implementation of SessionManager.
49  * The partial implementation of SessionManager interface provides
50  * the majority of the handling required to implement a
51  * SessionManager. Concrete implementations of SessionManager based
52  * on AbstractSessionManager need only implement the newSession method
53  * to return a specialized version of the Session inner class that
54  * provides an attribute Map.
55  * <p>
56  * If the property
57  * org.mortbay.jetty.servlet.AbstractSessionManager.23Notifications is set to
58  * true, the 2.3 servlet spec notification style will be used.
59  * <p>
60  * @version $Id: AbstractSessionManager.java,v 1.52 2006/06/21 09:35:28 gregwilkins Exp $
61  * @author Greg Wilkins (gregw)
62  */

63 public abstract class AbstractSessionManager implements SessionManager
64 {
65     private static Log log = LogFactory.getLog(AbstractSessionManager.class);
66     
67     /* ------------------------------------------------------------ */
68     public final static int __distantFuture = 60*60*24*7*52*20;
69     private final static String JavaDoc __NEW_SESSION_ID="org.mortbay.jetty.newSessionId";
70
71     /* ------------------------------------------------------------ */
72     /* global Map of ID to session */
73     protected static MultiMap __allSessions=new MultiMap();
74     
75     /* ------------------------------------------------------------ */
76     // Setting of max inactive interval for new sessions
77
// -1 means no timeout
78
private int _dftMaxIdleSecs = -1;
79     private int _scavengePeriodMs = 30000;
80     private String JavaDoc _workerName ;
81     protected transient ArrayList JavaDoc _sessionListeners=new ArrayList JavaDoc();
82     protected transient ArrayList JavaDoc _sessionAttributeListeners=new ArrayList JavaDoc();
83     protected transient Map JavaDoc _sessions;
84     protected transient Random JavaDoc _random;
85     protected transient ServletHandler _handler;
86     protected int _minSessions = 0;
87     protected int _maxSessions = 0;
88     protected boolean _crossContextSessionIDs=false;
89     protected boolean _secureCookies=false;
90     protected boolean _httpOnly=false;
91     protected boolean _invalidateGlobal=true;
92     
93     private transient SessionScavenger _scavenger = null;
94     
95     /* ------------------------------------------------------------ */
96     public AbstractSessionManager()
97     {
98         this(null);
99     }
100     
101     /* ------------------------------------------------------------ */
102     public AbstractSessionManager(Random JavaDoc random)
103     {
104         _random=random;
105     }
106     
107     
108     
109     /* ------------------------------------------------------------ */
110     /**
111      * @return True if requested session ID are first considered for new
112      * @deprecated use getCrossContextSessionIDs
113      * session IDs
114      */

115     public boolean getUseRequestedId()
116     {
117         return _crossContextSessionIDs;
118     }
119     
120     /* ------------------------------------------------------------ */
121     /** Set Use Requested ID.
122      * @param useRequestedId True if requested session ID are first considered for new
123      * @deprecated use setCrossContextSessionIDs
124      * session IDs
125      */

126     public void setUseRequestedId(boolean useRequestedId)
127     {
128         _crossContextSessionIDs = useRequestedId;
129     }
130     
131     /* ------------------------------------------------------------ */
132     /**
133      * @return True if cross context session IDs are first considered for new
134      * session IDs
135      */

136     public boolean getCrossContextSessionIDs()
137     {
138         return _crossContextSessionIDs;
139     }
140     
141     /* ------------------------------------------------------------ */
142     /** Set Cross Context sessions IDs
143      * This option activates a mode where a requested session ID can be used to create a
144      * new session. This facilitates the sharing of session cookies when cross context
145      * dispatches use sessions.
146      *
147      * @param useRequestedId True if cross context session ID are first considered for new
148      * session IDs
149      */

150     public void setCrossContextSessionIDs(boolean useRequestedId)
151     {
152         _crossContextSessionIDs = useRequestedId;
153     }
154     
155     /* ------------------------------------------------------------ */
156     public void initialize(ServletHandler handler)
157     {
158         _handler=handler;
159     }
160     
161     /* ------------------------------------------------------------ */
162     public Map JavaDoc getSessionMap()
163     {
164         return Collections.unmodifiableMap(_sessions);
165     }
166     
167     /* ------------------------------------------------------------ */
168     public int getSessions ()
169     {
170         return _sessions.size ();
171     }
172     
173     /* ------------------------------------------------------------ */
174     public int getMinSessions ()
175     {
176         return _minSessions;
177     }
178     
179     /* ------------------------------------------------------------ */
180     public int getMaxSessions ()
181     {
182         return _maxSessions;
183     }
184     
185     /* ------------------------------------------------------------ */
186     public void resetStats ()
187     {
188         _minSessions = _sessions.size ();
189         _maxSessions = _sessions.size ();
190     }
191     
192     /* ------------------------------------------------------------ */
193     /* new Session ID.
194      * If the request has a requestedSessionID which is unique, that is used.
195      * The session ID is created as a unique random long, represented as in a
196      * base between 30 and 36, selected by timestamp.
197      * If the request has a jvmRoute attribute, that is appended as a
198      * worker tag, else any worker tag set on the manager is appended.
199      * @param request
200      * @param created
201      * @return Session ID.
202      */

203     private String JavaDoc newSessionId(HttpServletRequest JavaDoc request,long created)
204     {
205         synchronized(__allSessions)
206         {
207             // A requested session ID can only be used if it is in the global map of
208
// ID but not in this contexts map. Ie it is an ID in use by another context
209
// in this server and thus we are doing a cross context dispatch.
210
if (_crossContextSessionIDs)
211             {
212                 String JavaDoc requested_id=(String JavaDoc)request.getAttribute(__NEW_SESSION_ID);
213                 if (requested_id==null)
214                     requested_id=request.getRequestedSessionId();
215                 if (requested_id !=null &&
216                     requested_id!=null && __allSessions.containsKey(requested_id) && !_sessions.containsKey(requested_id))
217                 return requested_id;
218             }
219             
220             // pick a new unique ID!
221
String JavaDoc id=null;
222             while (id==null || id.length()==0 || __allSessions.containsKey(id))
223             {
224                 long r = _random.nextLong();
225                 if (r<0)r=-r;
226                 id=Long.toString(r,30+(int)(created%7));
227                 String JavaDoc worker = (String JavaDoc)request.getAttribute("org.mortbay.http.ajp.JVMRoute");
228                 if (worker!=null)
229                     id+="."+worker;
230                 else if (_workerName!=null)
231                     id+="."+_workerName;
232             }
233             return id;
234         }
235     }
236     
237     /* ------------------------------------------------------------ */
238     public HttpSession JavaDoc getHttpSession(String JavaDoc id)
239     {
240         synchronized(this)
241         {
242             return (HttpSession JavaDoc)_sessions.get(id);
243         }
244     }
245     
246     /* ------------------------------------------------------------ */
247     public HttpSession JavaDoc newHttpSession(HttpServletRequest JavaDoc request)
248     {
249         Session JavaDoc session = newSession(request);
250         session.setMaxInactiveInterval(_dftMaxIdleSecs);
251         synchronized(__allSessions)
252         {
253             synchronized(this)
254             {
255               _sessions.put(session.getId(),session);
256               __allSessions.add(session.getId(), session);
257               if (_sessions.size() > this._maxSessions)
258                   this._maxSessions = _sessions.size ();
259             }
260         }
261         
262         HttpSessionEvent JavaDoc event=new HttpSessionEvent JavaDoc(session);
263         
264         for(int i=0;i<_sessionListeners.size();i++)
265             ((HttpSessionListener JavaDoc)_sessionListeners.get(i))
266             .sessionCreated(event);
267         
268         if (getCrossContextSessionIDs())
269             request.setAttribute(__NEW_SESSION_ID, session.getId());
270         return session;
271     }
272
273     /* ------------------------------------------------------------ */
274     public Cookie JavaDoc getSessionCookie(HttpSession JavaDoc session,boolean requestIsSecure)
275     {
276         if (_handler.isUsingCookies())
277         {
278             Cookie JavaDoc cookie = _handler.getSessionManager().getHttpOnly()
279                 ?new HttpOnlyCookie(SessionManager.__SessionCookie,session.getId())
280                 :new Cookie JavaDoc(SessionManager.__SessionCookie,session.getId());
281             String JavaDoc domain=_handler.getServletContext().getInitParameter(SessionManager.__SessionDomain);
282             String JavaDoc maxAge=_handler.getServletContext().getInitParameter(SessionManager.__MaxAge);
283             String JavaDoc path=_handler.getServletContext().getInitParameter(SessionManager.__SessionPath);
284             if (path==null)
285                 path=getCrossContextSessionIDs()?"/":_handler.getHttpContext().getContextPath();
286             if (path==null || path.length()==0)
287                 path="/";
288             
289             if (domain!=null)
290                 cookie.setDomain(domain);
291             if (maxAge!=null)
292                 cookie.setMaxAge(Integer.parseInt(maxAge));
293             else
294                 cookie.setMaxAge(-1);
295             
296             cookie.setSecure(requestIsSecure && getSecureCookies());
297             cookie.setPath(path);
298             
299             return cookie;
300         }
301         return null;
302     }
303     
304     /* ------------------------------------------------------------ */
305     protected abstract Session JavaDoc newSession(HttpServletRequest JavaDoc request);
306     
307     /* ------------------------------------------------------------ */
308     /** Get the workname.
309      * If set, the workername is dot appended to the session ID
310      * and can be used to assist session affinity in a load balancer.
311      * @return String or null
312      */

313     public String JavaDoc getWorkerName()
314     {
315         return _workerName;
316     }
317     
318     /* ------------------------------------------------------------ */
319     /** Set the workname.
320      * If set, the workername is dot appended to the session ID
321      * and can be used to assist session affinity in a load balancer.
322      * @param workerName
323      */

324     public void setWorkerName(String JavaDoc workerName)
325     {
326         _workerName = workerName;
327     }
328     
329     /* ------------------------------------------------------------ */
330     /**
331      * @return seconds
332      */

333     public int getMaxInactiveInterval()
334     {
335         return _dftMaxIdleSecs;
336     }
337     
338     /* ------------------------------------------------------------ */
339     /**
340      * @param seconds
341      */

342     public void setMaxInactiveInterval(int seconds)
343     {
344         _dftMaxIdleSecs = seconds;
345         if (_dftMaxIdleSecs>0 && _scavengePeriodMs>_dftMaxIdleSecs*100)
346             setScavengePeriod((_dftMaxIdleSecs+9)/10);
347     }
348     
349     
350     /* ------------------------------------------------------------ */
351     /**
352      * @return seconds
353      */

354     public int getScavengePeriod()
355     {
356         return _scavengePeriodMs/1000;
357     }
358     
359     /* ------------------------------------------------------------ */
360     /**
361      * @param seconds
362      */

363     public void setScavengePeriod(int seconds)
364     {
365         if (seconds==0)
366             seconds=60;
367         
368         int old_period=_scavengePeriodMs;
369         int period = seconds*1000;
370         if (period>60000)
371             period=60000;
372         if (period<1000)
373             period=1000;
374         
375         if (period!=old_period)
376         {
377             synchronized(this)
378             {
379                 _scavengePeriodMs=period;
380                 if (_scavenger!=null)
381                     _scavenger.interrupt();
382             }
383         }
384     }
385     
386     /* ------------------------------------------------------------ */
387     /**
388      * @return Returns the httpOnly.
389      */

390     public boolean getHttpOnly()
391     {
392         return _httpOnly;
393     }
394     
395     /* ------------------------------------------------------------ */
396     /**
397      * @param httpOnly The httpOnly to set.
398      */

399     public void setHttpOnly(boolean httpOnly)
400     {
401         _httpOnly = httpOnly;
402     }
403     
404     /* ------------------------------------------------------------ */
405     /**
406      * @return Returns the secureCookies.
407      */

408     public boolean getSecureCookies()
409     {
410         return _secureCookies;
411     }
412     
413     /* ------------------------------------------------------------ */
414     /**
415      * @param secureCookies The secureCookies to set.
416      */

417     public void setSecureCookies(boolean secureCookies)
418     {
419         _secureCookies = secureCookies;
420     }
421
422     /* ------------------------------------------------------------ */
423     public boolean isInvalidateGlobal()
424     {
425         return _invalidateGlobal;
426     }
427     
428     /* ------------------------------------------------------------ */
429     /**
430      * @param global True if session invalidation should be global.
431      * ie Sessions in other contexts with the same ID (linked by cross context dispatch
432      * or shared session cookie) are invalidated as a group.
433      */

434     public void setInvalidateGlobal(boolean global)
435     {
436         _invalidateGlobal=global;
437     }
438     
439     /* ------------------------------------------------------------ */
440     public void addEventListener(EventListener JavaDoc listener)
441     throws IllegalArgumentException JavaDoc
442     {
443         
444         if (listener instanceof HttpSessionAttributeListener JavaDoc)
445             _sessionAttributeListeners.add(listener);
446         if (listener instanceof HttpSessionListener JavaDoc)
447             _sessionListeners.add(listener);
448     }
449     
450     /* ------------------------------------------------------------ */
451     public void removeEventListener(EventListener JavaDoc listener)
452     {
453         if (listener instanceof HttpSessionAttributeListener JavaDoc)
454             _sessionAttributeListeners.remove(listener);
455         if (listener instanceof HttpSessionListener JavaDoc)
456             _sessionListeners.remove(listener);
457     }
458     
459     /* ------------------------------------------------------------ */
460     public boolean isStarted()
461     {
462         return _scavenger!=null;
463     }
464     
465     /* ------------------------------------------------------------ */
466     public void start()
467     throws Exception JavaDoc
468     {
469         if (_random==null)
470         {
471             log.debug("New random session seed");
472             _random=new Random JavaDoc();
473         }
474         else
475             if(log.isDebugEnabled())log.debug("Initializing random session key: "+_random);
476         _random.nextLong();
477         
478         if (_sessions==null)
479             _sessions=new HashMap JavaDoc();
480         
481         // Start the session scavenger if we haven't already
482
if (_scavenger == null)
483         {
484             _scavenger = new SessionScavenger();
485             _scavenger.start();
486         }
487     }
488     
489     
490     /* ------------------------------------------------------------ */
491     public void stop()
492     {
493         // Invalidate all sessions to cause unbind events
494
ArrayList JavaDoc sessions = new ArrayList JavaDoc(_sessions.values());
495         for (Iterator JavaDoc i = sessions.iterator(); i.hasNext(); )
496         {
497             Session JavaDoc session = (Session JavaDoc)i.next();
498             session.invalidate();
499         }
500         _sessions.clear();
501         
502         // stop the scavenger
503
SessionScavenger scavenger = _scavenger;
504         _scavenger=null;
505         if (scavenger!=null)
506             scavenger.interrupt();
507     }
508     
509     /* -------------------------------------------------------------- */
510     /** Find sessions that have timed out and invalidate them.
511      * This runs in the SessionScavenger thread.
512      */

513     private void scavenge()
514     {
515         Thread JavaDoc thread = Thread.currentThread();
516         ClassLoader JavaDoc old_loader = thread.getContextClassLoader();
517         try
518         {
519             if (_handler==null)
520                 return;
521             
522             ClassLoader JavaDoc loader = _handler.getClassLoader();
523             if (loader!=null)
524                 thread.setContextClassLoader(loader);
525             
526             long now = System.currentTimeMillis();
527             
528             // Since Hashtable enumeration is not safe over deletes,
529
// we build a list of stale sessions, then go back and invalidate them
530
Object JavaDoc stale=null;
531             
532
533             synchronized(AbstractSessionManager.this)
534             {
535                 // For each session
536
for (Iterator JavaDoc i = _sessions.values().iterator(); i.hasNext(); )
537                 {
538                     Session JavaDoc session = (Session JavaDoc)i.next();
539                     long idleTime = session._maxIdleMs;
540                     if (idleTime > 0 && session._accessed + idleTime < now) {
541                         // Found a stale session, add it to the list
542
stale=LazyList.add(stale,session);
543                     }
544                 }
545             }
546             
547             // Remove the stale sessions
548
for (int i = LazyList.size(stale); i-->0;)
549             {
550                 // check it has not been accessed in the meantime
551
Session JavaDoc session=(Session JavaDoc)LazyList.get(stale,i);
552                 long idleTime = session._maxIdleMs;
553                 if (idleTime > 0 && session._accessed + idleTime < System.currentTimeMillis())
554                 {
555                     session.invalidate();
556                     int nbsess = this._sessions.size();
557                     if (nbsess < this._minSessions)
558                         this._minSessions = nbsess;
559                 }
560             }
561         }
562         finally
563         {
564             thread.setContextClassLoader(old_loader);
565         }
566     }
567     
568     
569     /* ------------------------------------------------------------ */
570     /* ------------------------------------------------------------ */
571     /* -------------------------------------------------------------- */
572     /** SessionScavenger is a background thread that kills off old sessions */
573     class SessionScavenger extends Thread JavaDoc
574     {
575         public void run()
576         {
577             int period=-1;
578             try{
579                 while (isStarted())
580                 {
581                     try {
582                         if (period!=_scavengePeriodMs)
583                         {
584                             if(log.isDebugEnabled())log.debug("Session scavenger period = "+_scavengePeriodMs/1000+"s");
585                             period=_scavengePeriodMs;
586                         }
587                         sleep(period>1000?period:1000);
588                         AbstractSessionManager.this.scavenge();
589                     }
590                     catch (InterruptedException JavaDoc ex){continue;}
591                     catch (Error JavaDoc e) {log.warn(LogSupport.EXCEPTION,e);}
592                     catch (Exception JavaDoc e) {log.warn(LogSupport.EXCEPTION,e);}
593                 }
594             }
595             finally
596             {
597                 AbstractSessionManager.this._scavenger=null;
598                 log.debug("Session scavenger exited");
599             }
600         }
601         
602         SessionScavenger()
603         {
604             super("SessionScavenger");
605             setDaemon(true);
606         }
607         
608     } // SessionScavenger
609

610     
611     
612     /* ------------------------------------------------------------ */
613     /* ------------------------------------------------------------ */
614     /* ------------------------------------------------------------ */
615     public abstract class Session implements SessionManager.Session
616     {
617         Map JavaDoc _values;
618         boolean _invalid=false;
619         boolean _newSession=true;
620         long _created=System.currentTimeMillis();
621         long _accessed=_created;
622         long _maxIdleMs = _dftMaxIdleSecs*1000;
623         String JavaDoc _id;
624         
625         /* ------------------------------------------------------------- */
626         protected Session(HttpServletRequest JavaDoc request)
627         {
628             _id=newSessionId(request,_created);
629             if (_dftMaxIdleSecs>=0)
630                 _maxIdleMs=_dftMaxIdleSecs*1000;
631         }
632         
633         /* ------------------------------------------------------------ */
634         protected abstract Map JavaDoc newAttributeMap();
635         
636         /* ------------------------------------------------------------ */
637         public void access()
638         {
639             _newSession=false;
640             _accessed=System.currentTimeMillis();
641         }
642         
643         /* ------------------------------------------------------------ */
644         public boolean isValid()
645         {
646             return !_invalid;
647         }
648         
649         /* ------------------------------------------------------------ */
650         public ServletContext JavaDoc getServletContext()
651         {
652             return _handler.getServletContext();
653         }
654         
655         /* ------------------------------------------------------------- */
656         public String JavaDoc getId()
657         throws IllegalStateException JavaDoc
658         {
659             return _id;
660         }
661         
662         /* ------------------------------------------------------------- */
663         public long getCreationTime()
664         throws IllegalStateException JavaDoc
665         {
666             if (_invalid) throw new IllegalStateException JavaDoc();
667             return _created;
668         }
669         
670         /* ------------------------------------------------------------- */
671         public long getLastAccessedTime()
672         throws IllegalStateException JavaDoc
673         {
674             if (_invalid) throw new IllegalStateException JavaDoc();
675             return _accessed;
676         }
677         
678         /* ------------------------------------------------------------- */
679         public int getMaxInactiveInterval()
680         {
681             if (_invalid) throw new IllegalStateException JavaDoc();
682             return (int)(_maxIdleMs / 1000);
683         }
684         
685         /* ------------------------------------------------------------- */
686         /**
687          * @deprecated
688          */

689         public HttpSessionContext JavaDoc getSessionContext()
690         throws IllegalStateException JavaDoc
691         {
692             if (_invalid) throw new IllegalStateException JavaDoc();
693             return SessionContext.NULL_IMPL;
694         }
695         
696         /* ------------------------------------------------------------- */
697         public void setMaxInactiveInterval(int secs)
698         {
699             _maxIdleMs = (long)secs * 1000;
700             if (_maxIdleMs>0 && (_maxIdleMs/10)<_scavengePeriodMs)
701                 AbstractSessionManager.this.setScavengePeriod((secs+9)/10);
702         }
703         
704         /* ------------------------------------------------------------- */
705         public void invalidate() throws IllegalStateException JavaDoc
706         {
707             if (log.isDebugEnabled()) log.debug("Invalidate session "+getId()+" in "+_handler.getHttpContext());
708             try
709             {
710                 // Notify listeners and unbind values
711
synchronized (this)
712                 {
713                     if (_invalid)
714                         throw new IllegalStateException JavaDoc();
715
716                     if (_sessionListeners!=null)
717                     {
718                         HttpSessionEvent JavaDoc event=new HttpSessionEvent JavaDoc(this);
719                         for (int i=_sessionListeners.size(); i-->0;)
720                             ((HttpSessionListener JavaDoc)_sessionListeners.get(i)).sessionDestroyed(event);
721                     }
722
723                     if (_values!=null)
724                     {
725                         Iterator JavaDoc iter=_values.keySet().iterator();
726                         while (iter.hasNext())
727                         {
728                             String JavaDoc key=(String JavaDoc)iter.next();
729                             Object JavaDoc value=_values.get(key);
730                             iter.remove();
731                             unbindValue(key,value);
732
733                             if (_sessionAttributeListeners.size()>0)
734                             {
735                                 HttpSessionBindingEvent JavaDoc event=new HttpSessionBindingEvent JavaDoc(this,key,value);
736
737                                 for (int i=0; i<_sessionAttributeListeners.size(); i++)
738                                 {
739                                     ((HttpSessionAttributeListener JavaDoc)_sessionAttributeListeners.get(i)).attributeRemoved(event);
740                                 }
741                             }
742                         }
743                     }
744                 }
745             }
746             finally
747             {
748                 // Remove session from context and global maps
749
synchronized (__allSessions)
750                 {
751                     synchronized (_sessions)
752                     {
753                         _invalid=true;
754                         _sessions.remove(getId());
755                         __allSessions.removeValue(getId(), this);
756                         
757                         if (isInvalidateGlobal())
758                         {
759                             // Don't iterate as other sessions may also be globally invalidating
760
while(__allSessions.containsKey(getId()))
761                             {
762                                 Session JavaDoc session=(Session JavaDoc)__allSessions.getValue(getId(),0);
763                                 session.invalidate();
764                             }
765                         }
766                     }
767                 }
768             }
769         }
770         
771         /* ------------------------------------------------------------- */
772         public boolean isNew()
773         throws IllegalStateException JavaDoc
774         {
775             if (_invalid) throw new IllegalStateException JavaDoc();
776             return _newSession;
777         }
778         
779         
780         /* ------------------------------------------------------------ */
781         public synchronized Object JavaDoc getAttribute(String JavaDoc name)
782         {
783             if (_invalid) throw new IllegalStateException JavaDoc();
784             if (_values==null)
785                 return null;
786             return _values.get(name);
787         }
788         
789         /* ------------------------------------------------------------ */
790         public synchronized Enumeration JavaDoc getAttributeNames()
791         {
792             if (_invalid) throw new IllegalStateException JavaDoc();
793             List JavaDoc names = _values==null?Collections.EMPTY_LIST:new ArrayList JavaDoc(_values.keySet());
794             return Collections.enumeration(names);
795         }
796         
797         /* ------------------------------------------------------------ */
798         public synchronized void setAttribute(String JavaDoc name, Object JavaDoc value)
799         {
800             if (_invalid) throw new IllegalStateException JavaDoc();
801             if (_values==null)
802                 _values=newAttributeMap();
803             Object JavaDoc oldValue = _values.put(name,value);
804             
805             if (value==null || !value.equals(oldValue))
806             {
807                 unbindValue(name, oldValue);
808                 bindValue(name, value);
809                 
810                 if (_sessionAttributeListeners.size()>0)
811                 {
812                     HttpSessionBindingEvent JavaDoc event =
813                         new HttpSessionBindingEvent JavaDoc(this,name,
814                                 oldValue==null?value:oldValue);
815                     
816                     for(int i=0;i<_sessionAttributeListeners.size();i++)
817                     {
818                         HttpSessionAttributeListener JavaDoc l =
819                             (HttpSessionAttributeListener JavaDoc)
820                             _sessionAttributeListeners.get(i);
821                         
822                         if (oldValue==null)
823                             l.attributeAdded(event);
824                         else if (value==null)
825                             l.attributeRemoved(event);
826                         else
827                             l.attributeReplaced(event);
828                     }
829                 }
830             }
831         }
832         
833         /* ------------------------------------------------------------ */
834         public synchronized void removeAttribute(String JavaDoc name)
835         {
836             if (_invalid) throw new IllegalStateException JavaDoc();
837             if (_values==null)
838                 return;
839             
840             Object JavaDoc old=_values.remove(name);
841             if (old!=null)
842             {
843                 unbindValue(name, old);
844                 if (_sessionAttributeListeners.size()>0)
845                 {
846                     HttpSessionBindingEvent JavaDoc event =
847                         new HttpSessionBindingEvent JavaDoc(this,name,old);
848                     
849                     for(int i=0;i<_sessionAttributeListeners.size();i++)
850                     {
851                         HttpSessionAttributeListener JavaDoc l =
852                             (HttpSessionAttributeListener JavaDoc)
853                             _sessionAttributeListeners.get(i);
854                         l.attributeRemoved(event);
855                     }
856                 }
857             }
858         }
859         
860         /* ------------------------------------------------------------- */
861         /**
862          * @deprecated As of Version 2.2, this method is
863          * replaced by {@link #getAttribute}
864          */

865         public Object JavaDoc getValue(String JavaDoc name)
866         throws IllegalStateException JavaDoc
867         {
868             return getAttribute(name);
869         }
870         
871         /* ------------------------------------------------------------- */
872         /**
873          * @deprecated As of Version 2.2, this method is
874          * replaced by {@link #getAttributeNames}
875          */

876         public synchronized String JavaDoc[] getValueNames()
877         throws IllegalStateException JavaDoc
878         {
879             if (_invalid) throw new IllegalStateException JavaDoc();
880             if (_values==null)
881                 return new String JavaDoc[0];
882             String JavaDoc[] a = new String JavaDoc[_values.size()];
883             return (String JavaDoc[])_values.keySet().toArray(a);
884         }
885         
886         /* ------------------------------------------------------------- */
887         /**
888          * @deprecated As of Version 2.2, this method is
889          * replaced by {@link #setAttribute}
890          */

891         public void putValue(java.lang.String JavaDoc name,
892                 java.lang.Object JavaDoc value)
893         throws IllegalStateException JavaDoc
894         {
895             setAttribute(name,value);
896         }
897         
898         /* ------------------------------------------------------------- */
899         /**
900          * @deprecated As of Version 2.2, this method is
901          * replaced by {@link #removeAttribute}
902          */

903         public void removeValue(java.lang.String JavaDoc name)
904         throws IllegalStateException JavaDoc
905         {
906             removeAttribute(name);
907         }
908         
909         /* ------------------------------------------------------------- */
910         /** If value implements HttpSessionBindingListener, call valueBound() */
911         private void bindValue(java.lang.String JavaDoc name, Object JavaDoc value)
912         {
913             if (value!=null && value instanceof HttpSessionBindingListener JavaDoc)
914                 ((HttpSessionBindingListener JavaDoc)value)
915                 .valueBound(new HttpSessionBindingEvent JavaDoc(this,name));
916         }
917         
918         /* ------------------------------------------------------------- */
919         /** If value implements HttpSessionBindingListener, call valueUnbound() */
920         private void unbindValue(java.lang.String JavaDoc name, Object JavaDoc value)
921         {
922             if (value!=null && value instanceof HttpSessionBindingListener JavaDoc)
923                 ((HttpSessionBindingListener JavaDoc)value)
924                 .valueUnbound(new HttpSessionBindingEvent JavaDoc(this,name));
925         }
926     }
927
928
929 }
930
Popular Tags