1 // ========================================================================
2 // $Id: Manager.java,v 1.6 2004/12/22 23:28:11 janb 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;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.EventListener;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Timer;
29 import java.util.TimerTask;
30 
31 import javax.servlet.ServletContext;
32 import javax.servlet.http.Cookie;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpSession;
35 import javax.servlet.http.HttpSessionAttributeListener;
36 import javax.servlet.http.HttpSessionBindingEvent;
37 import javax.servlet.http.HttpSessionContext;
38 import javax.servlet.http.HttpSessionEvent;
39 import javax.servlet.http.HttpSessionListener;
40 
41 import org.jboss.jetty.JBossWebAppContext;
42 import org.mortbay.jetty.HttpOnlyCookie;
43 import org.mortbay.jetty.SessionIdManager;
44 import org.mortbay.jetty.SessionManager;
45 import org.mortbay.jetty.servlet.AbstractSessionManager;
46 import org.mortbay.jetty.servlet.ServletHandler;
47 import org.mortbay.jetty.servlet.SessionHandler;
48 import org.mortbay.jetty.webapp.WebAppContext;
49 import org.mortbay.log.Log;
50 
51 //----------------------------------------
52 
53 // TODO
54 // This class needs a lot of work to make it run.
55 //-----
56 
57 // we need a SnapshotInterceptor
58 // we need to package this into JBoss and Mort Bay spaces
59 // Cluster/CMR & JDO Stores should be finished/done
60 // a DebugInterceptor could be fun....
61 // Jetty should be user:jetty, role:webcontainer in order to use the session EJBs - wil probably need a SecurityInterceptor
62 // can I optimise return of objects from set/removeAttribute?
63 // CMPState should use local not remote interfaces
64 // FAQ entry should be finished
65 // Throttle/BufferInterceptor - could be written very like MigrationInterceptor
66 // StateAdaptor needs a name change
67 // We need some predefined containers
68 // tighten up access priviledges
69 // javadoc
70 //----------------------------------------
71 
72 // we need to rethink the strategies for flushing the local cache into
73 // the distributed cache - specifically how they can be aggregated
74 // (or-ed as opposed to and-ed).
75 
76 // the spec does not say (?) whether session attribute events should
77 // be received in the order that the changes took place - we can
78 // control this by placing the SynchronizationInterceptor before or
79 // after the BindingInterceptor
80 
81 // we could use a TransactionInterceptor to ensure that compound
82 // operations on e.g. a CMPState are atomic - or we could explicitly
83 // code the use of transactions where needed (we should be able to
84 // make all multiple calls collapse into one call to server - look
85 // into this). Since HttpSessions have no transactional semantics,
86 // there is no way for the user to inform us of any requirements...
87 
88 //----------------------------------------
89 
90 public class Manager implements org.mortbay.jetty.SessionManager
91 {
92     // ----------------------------------------
93     protected WebAppContext _context;
94 
95     /**
96      * Whether or not the session manager will use cookies
97      * or URLs only.
98      */
99     protected boolean _usingCookies = true;
100 
getContext()101     public WebAppContext getContext()
102     {
103         return _context;
104     }
105 
setContext(WebAppContext context)106     public void setContext(WebAppContext context)
107     {
108         _context = context;
109     }
110 
111     // ----------------------------------------
112     protected int _scavengerPeriod = 60; // every 1 min
113 
setScavengerPeriod(int period)114     public void setScavengerPeriod(int period)
115     {
116         _scavengerPeriod = period;
117     }
118 
getScavengerPeriod()119     public int getScavengerPeriod()
120     {
121         return _scavengerPeriod;
122     }
123 
124     // ----------------------------------------
125     protected StateInterceptor[] _interceptorStack = null;
126 
getInterceptorStack()127     public StateInterceptor[] getInterceptorStack()
128     {
129         return _interceptorStack;
130     }
131 
setInterceptorStack(StateInterceptor[] interceptorStack)132     public void setInterceptorStack(StateInterceptor[] interceptorStack)
133     {
134         _interceptorStack = interceptorStack;
135     }
136 
137     // ----------------------------------------
138     protected IdGenerator _idGenerator = null;
139 
getIdGenerator()140     public IdGenerator getIdGenerator()
141     {
142         return _idGenerator;
143     }
144 
setIdGenerator(IdGenerator idGenerator)145     public void setIdGenerator(IdGenerator idGenerator)
146     {
147         _idGenerator = idGenerator;
148     }
149 
150     // ----------------------------------------
151     protected int _maxInactiveInterval;
152 
getMaxInactiveInterval()153     public int getMaxInactiveInterval()
154     {
155         return _maxInactiveInterval;
156     }
157 
setMaxInactiveInterval(int seconds)158     public void setMaxInactiveInterval(int seconds)
159     {
160         _maxInactiveInterval = seconds;
161     }
162 
163     // ----------------------------------------
164     protected Store _store = null;
165 
166     private boolean _crossContextSessionIDs = false;
167 
getStore()168     public Store getStore()
169     {
170         return _store;
171     }
172 
setStore(Store store)173     public void setStore(Store store)
174     {
175         _store = store;
176 
177         if (_store != null)
178             _store.setManager(this);
179     }
180 
181     // ----------------------------------------
182 
clone()183     public Object clone()
184     {
185         // Log.info("cloning Manager: "+this);
186         Manager m = new Manager();
187 
188         // deep-copy Store attribute - each Manager gets it's own Store instance
189         Store store = getStore();
190         if (store != null)
191             m.setStore((Store) store.clone());
192 
193         // deep-copy IdGenerator attribute - each Manager gets it's own
194         // IdGenerator instance
195         IdGenerator ig = getIdGenerator();
196         if (ig != null)
197             m.setIdGenerator((IdGenerator) ig.clone());
198 
199         // Container uses InterceptorStack as a prototype to clone a stack for
200         // each new session...
201         m.setInterceptorStack(getInterceptorStack());
202 
203         m.setMaxInactiveInterval(getMaxInactiveInterval());
204         m.setScavengerPeriod(getScavengerPeriod());
205 
206         return m;
207     }
208 
209     // ----------------------------------------
210 
211     final Map _sessions = new HashMap();
212 
getContextPath()213     public String getContextPath()
214     {
215         return _context.getContextPath();
216     }
217 
218     // ----------------------------------------
219     // LifeCycle API
220     // ----------------------------------------
221 
222     boolean _started = false;
223 
224     Object _startedLock = new Object();
225 
226     Timer _scavenger;
227 
228     class Scavenger extends TimerTask
229     {
run()230         public void run()
231         {
232             try
233             {
234                 scavenge();
235             }
236             catch (Throwable e)
237             {
238                 Log.warn("could not scavenge local sessions", e);
239             }
240         }
241     }
242 
start()243     public void start()
244     {
245         Log.debug("starting...");
246         synchronized (_startedLock)
247         {
248             if (_started)
249             {
250                 Log.warn("already started");
251                 return;
252             }
253 
254             if (_store == null)
255             {
256                 Log.warn("No Store. Falling back to a local session implementation - NO HTTPSESSION DISTRIBUTION");
257                 setStore(new LocalStore());
258             }
259 
260             if (_idGenerator == null)
261                 _idGenerator = new DistributableIdGenerator();
262 
263             try
264             {
265                 _store.start();
266             }
267             catch (Exception e)
268             {
269                 Log.warn("Faulty Store. Falling back to a local session implementation - NO HTTPSESSION DISTRIBUTION", e);
270                 setStore(new LocalStore());
271                 try
272                 {
273                     _store.start();
274                 }
275                 catch (Exception e2)
276                 {
277                     Log.warn("could not start Store", e2);
278                 }
279             }
280 
281             if (Log.isDebugEnabled())
282                 Log.debug("starting local scavenger thread...(period: " + getScavengerPeriod() + " secs)");
283             long delay = getScavengerPeriod() * 1000;
284             boolean isDaemon = true;
285             _scavenger = new Timer(isDaemon);
286             _scavenger.scheduleAtFixedRate(new Scavenger(), delay, delay);
287             Log.debug("...local scavenger thread started");
288             _started = true;
289         }
290 
291         Log.debug("...started");
292     }
293 
isStarted()294     public boolean isStarted()
295     {
296         synchronized (_startedLock)
297         {
298             return _started;
299         }
300     }
301 
stop()302     public void stop()
303     {
304         Log.debug("stopping...");
305 
306         synchronized (_startedLock)
307         {
308             if (!_started)
309             {
310                 Log.warn("already stopped/not yet started");
311                 return;
312             }
313 
314             // I guess we will have to ask the store for a list of sessions
315             // to migrate... - TODO
316 
317             synchronized (_sessions)
318             {
319                 List copy = new ArrayList(_sessions.values());
320                 for (Iterator i = copy.iterator(); i.hasNext();)
321                     ((StateAdaptor) i.next()).migrate();
322 
323                 _sessions.clear();
324             }
325 
326             Log.debug("stopping local scavenger thread...");
327             _scavenger.cancel();
328             _scavenger = null;
329             Log.debug("...local scavenger thread stopped");
330             scavenge();
331 
332             _store.stop();
333             _store.destroy();
334             setStore(null);
335             _started = false;
336         }
337 
338         Log.debug("...stopped");
339     }
340 
341     // ----------------------------------------
342     // SessionManager API
343     // ----------------------------------------
344 
345     protected SessionHandler _handler;
346 
setSessionHandler(SessionHandler handler)347     public void setSessionHandler(SessionHandler handler)
348     {
349         this._handler = handler;
350     }
351 
352     // ----------------------------------------
353     // SessionManager API
354     // ----------------------------------------
355 
getHttpSession(String id)356     public HttpSession getHttpSession(String id)
357     {
358         return findSession(id, true);
359     }
360 
sessionExists(String id)361     public boolean sessionExists(String id)
362     {
363         return findSession(id, false) != null;
364     }
365 
newHttpSession(HttpServletRequest request)366     public HttpSession newHttpSession(HttpServletRequest request) // TODO
367     {
368         return newSession(request);
369     }
370 
371     // ----------------------------------------
372     // this does not need locking as it is an int and access should be atomic...
373 
374     // ----------------------------------------
375     // Listeners
376 
377     // These lists are only modified at webapp [un]deployment time, by a
378     // single thread, so although read by multiple threads whilst the
379     // Manager is running, need no synchronization...
380 
381     final List _sessionListeners = new ArrayList();
382 
383     final List _sessionAttributeListeners = new ArrayList();
384 
addEventListener(EventListener listener)385     public void addEventListener(EventListener listener) throws IllegalArgumentException, IllegalStateException
386     {
387         synchronized (_startedLock)
388         {
389             if (isStarted())
390                 throw new IllegalStateException("EventListeners must be added before a Session Manager starts");
391 
392             boolean known = false;
393             if (listener instanceof HttpSessionAttributeListener)
394             {
395                 // Log.info("adding HttpSessionAttributeListener: "+listener);
396                 _sessionAttributeListeners.add(listener);
397                 known = true;
398             }
399             if (listener instanceof HttpSessionListener)
400             {
401                 // Log.info("adding HttpSessionListener: "+listener);
402                 _sessionListeners.add(listener);
403                 known = true;
404             }
405 
406             if (!known)
407                 throw new IllegalArgumentException("Unknown EventListener type " + listener);
408         }
409     }
410 
clearEventListeners()411     public void clearEventListeners()
412     {
413         _sessionAttributeListeners.clear();
414         _sessionListeners.clear();
415     }
416 
removeEventListener(EventListener listener)417     public void removeEventListener(EventListener listener) throws IllegalStateException
418     {
419         synchronized (_startedLock)
420         {
421             if (isStarted())
422                 throw new IllegalStateException("EventListeners may not be removed while a Session Manager is running");
423 
424             if (listener instanceof HttpSessionAttributeListener)
425                 _sessionAttributeListeners.remove(listener);
426             if (listener instanceof HttpSessionListener)
427                 _sessionListeners.remove(listener);
428         }
429     }
430 
431     // ----------------------------------------
432     // Implementation...
433     // ----------------------------------------
434 
getServletContext()435     public ServletContext getServletContext()
436     {
437         return _context.getServletHandler().getServletContext();
438     }
439 
getSessionContext()440     public HttpSessionContext getSessionContext()
441     {
442         return null;
443     }
444 
445     // --------------------
446     // session lifecycle
447     // --------------------
448 
449     // I need to think more about where the list of extant sessions is
450     // held...
451 
452     // is it held by the State Factory/Type (static), which best knows
453     // how to find it ? The trouble is we are not asking for just the
454     // State but the whole container...
455 
456     // if the State was an EJB, the Manager could hold a HashMap of
457     // id:State and the State would just be an EJB handle...
458 
459     // How does the ThrottleInterceptor fit into this. If it is holding
460     // a local cache in front of a DistributedState, do we check them
461     // both and compare timestamps, or flush() all ThrottleInterceptors
462     // in the WebApp before we do the lookup (could be expensive...)
463 
464     // when finding a distributed session assume we are on nodeB
465     // receiving a request for a session immediately after it has just
466     // been created on NodeA. If we can't find it straight away, we need
467     // to take into account how long it's flushing and distribution may
468     // take, wait that long and then look again. This may hold up the
469     // request, but without the session the request is not much good.
470 
471     // overload this to change the construction of the Container....
472 
newContainer(String id, State state)473     protected HttpSession newContainer(String id, State state)
474     {
475         // put together the make-believe container and HttpSession state
476 
477         return Container.newContainer(this, id, state, getMaxInactiveInterval(), currentSecond(), getInterceptorStack());
478     }
479 
newSession(HttpServletRequest request)480     protected Session newSession(HttpServletRequest request)
481     {
482         String id = null;
483         HttpSession session = null;
484         try
485         {
486             id = _store.allocateId(request);
487             State state = _store.newState(id, getMaxInactiveInterval());
488             session = newContainer(id, state);
489         }
490         catch (Exception e)
491         {
492             Log.debug("could not create HttpSession", e);
493             return null; // BAD - TODO
494         }
495 
496         if (Log.isDebugEnabled())
497             Log.debug("remembering session - " + id);
498 
499         synchronized (_sessions)
500         {
501             _sessions.put(id, session);
502         }
503 
504         notifySessionCreated(session);
505 
506         return (Session) session;
507     }
508 
destroyContainer(HttpSession session)509     protected State destroyContainer(HttpSession session)
510     {
511         return Container.destroyContainer(session, getInterceptorStack());
512     }
513 
destroySession(HttpSession container)514     protected void destroySession(HttpSession container)
515     {
516         String id = container.getId();
517         if (Log.isDebugEnabled())
518             Log.debug("forgetting session - " + id);
519         Object tmp;
520         synchronized (_sessions)
521         {
522             tmp = _sessions.remove(id);
523         }
524         container = (HttpSession) tmp;
525         if (Log.isDebugEnabled())
526             Log.debug("forgetting session - " + container);
527 
528         if (container == null)
529         {
530             Log.warn("session - " + id + " has already been destroyed");
531             return;
532         }
533 
534         // TODO remove all the attributes - generating correct events
535         // check ordering on unbind and destroy notifications - The
536         // problem is that we want these calls to go all the way through
537         // the container - but not to the store - because that would be
538         // too expensive and we can predict the final state...
539 
540         // we don't need to do this if we know that none of the attributes
541         // are BindingListers AND there are no AttributeListeners
542         // registered... - TODO
543 
544         // This will do for the moment...
545 
546         // LATER - TODO
547 
548         try
549         {
550             State state = ((StateAdaptor) container).getState();
551 
552             // filthy hack...
553             // stop InvalidInterceptors - otherwise we can't clean up session...
554             // - TODO
555             {
556                 State s = state;
557                 StateInterceptor si = null;
558                 while (s instanceof StateInterceptor)
559                 {
560                     si = (StateInterceptor) s;
561                     s = si.getState(); // next interceptor
562                     if (si instanceof ValidatingInterceptor)
563                         si.stop();
564                 }
565             }
566 
567             String[] names = state.getAttributeNameStringArray();
568             for (int i = 0; i < names.length; i++)
569                 state.removeAttribute(names[i], false);
570 
571             // should just do this for attributes which are BindingListeners
572             // - then just clear() the rest... - TODO
573         }
574         catch (RemoteException e)
575         {
576             Log.debug("could not raise events on session destruction - problem in distribution layer", e);
577         }
578 
579         if (Log.isDebugEnabled())
580             Log.debug("notifying session - " + id);
581         notifySessionDestroyed(container);
582 
583         if (Log.isDebugEnabled())
584             Log.debug("destroying container - " + id);
585         State state = destroyContainer(container);
586 
587         try
588         {
589             if (state != null) // an interceptor may preempt us, if
590             // it does not want this state
591             // removed...
592             {
593                 if (Log.isDebugEnabled())
594                     Log.debug("removing state - " + id);
595                 _store.removeState(state);
596             }
597         }
598         catch (Exception e)
599         {
600             Log.debug("could not remove session state", e);
601         }
602     }
603 
findSession(String id, boolean create)604     protected HttpSession findSession(String id, boolean create)
605     {
606         HttpSession container = null;
607 
608         try
609         {
610             // find the state
611             State state = _store.loadState(id);
612 
613             // is it valid ?
614             state = ((state != null) && state.isValid()) ? state : null; // expensive
615             // ?
616 
617             // if so
618             if (state != null)
619             {
620 
621                 // this looks slow - but to be 100% safe we need to make sure
622                 // that no-one can enter another container for the same id,
623                 // whilst we are thinking about it...
624 
625                 // is there a container already available ?
626                 synchronized (_sessions)
627                 {
628                     // do we have an existing container ?
629                     container = (HttpSession) _sessions.get(id);
630 
631                     // if not...
632                     if (container == null && create)
633                     {
634                         // make a new one...
635                         container = newContainer(id, state);// we could lower
636                         // contention by
637                         // preconstructing
638                         // containers... -
639                         // TODO
640                         _sessions.put(id, container);
641                     }
642                 }
643             }
644         }
645         catch (Exception ignore)
646         {
647             if (Log.isDebugEnabled())
648                 Log.debug("did not find distributed session: " + id);
649         }
650 
651         return container;
652     }
653 
654     // --------------------
655     // session events
656     // --------------------
657 
658     // should this all be delegated to the event raising interceptor....
659 
notifyAttributeAdded(HttpSession session, String name, Object value)660     public Object notifyAttributeAdded(HttpSession session, String name, Object value)
661     {
662         int n = _sessionAttributeListeners.size();
663         if (n > 0)
664         {
665             HttpSessionBindingEvent event = new HttpSessionBindingEvent(session, name, value);
666 
667             for (int i = 0; i < n; i++)
668                 ((HttpSessionAttributeListener) _sessionAttributeListeners.get(i)).attributeAdded(event);
669 
670             event = null;
671         }
672 
673         return value;
674     }
675 
notifyAttributeReplaced(HttpSession session, String name, Object value)676     public Object notifyAttributeReplaced(HttpSession session, String name, Object value)
677     {
678         int n = _sessionAttributeListeners.size();
679         if (n > 0)
680         {
681             HttpSessionBindingEvent event = new HttpSessionBindingEvent(session, name, value);
682 
683             for (int i = 0; i < n; i++)
684                 ((HttpSessionAttributeListener) _sessionAttributeListeners.get(i)).attributeReplaced(event);
685 
686             event = null;
687         }
688 
689         return value;
690     }
691 
notifyAttributeRemoved(HttpSession session, String name, Object value)692     public Object notifyAttributeRemoved(HttpSession session, String name, Object value)
693     {
694         int n = _sessionAttributeListeners.size();
695         if (n > 0)
696         {
697             HttpSessionBindingEvent event = new HttpSessionBindingEvent(session, name, value);
698 
699             for (int i = 0; i < n; i++)
700                 ((HttpSessionAttributeListener) _sessionAttributeListeners.get(i)).attributeRemoved(event);
701 
702             event = null;
703         }
704 
705         return value;
706     }
707 
notifySessionCreated(HttpSession session)708     public void notifySessionCreated(HttpSession session)
709     {
710         int n = _sessionListeners.size();
711         if (n > 0)
712         {
713             HttpSessionEvent event = new HttpSessionEvent(session);
714 
715             for (int i = 0; i < n; i++)
716                 ((HttpSessionListener) _sessionListeners.get(i)).sessionCreated(event);
717 
718             event = null;
719         }
720     }
721 
notifySessionDestroyed(HttpSession session)722     public void notifySessionDestroyed(HttpSession session)
723     {
724         int n = _sessionListeners.size();
725         if (n > 0)
726         {
727             HttpSessionEvent event = new HttpSessionEvent(session);
728 
729             for (int i = 0; i < n; i++)
730                 ((HttpSessionListener) _sessionListeners.get(i)).sessionDestroyed(event);
731 
732             event = null;
733         }
734     }
735 
736     // this is to help sessions decide if they have timed out... It is
737     // wrapped here so that if I decide that System.currentTimeMillis()
738     // is too heavy, I can figure out a lighter way to return a rough
739     // time to the sessions...
740 
currentSecond()741     public long currentSecond()
742     {
743         return System.currentTimeMillis();
744     }
745 
746     // ensure that this code is run with the correct ContextClassLoader...
scavenge()747     protected void scavenge()
748     {
749         Log.debug("starting local scavenging...");
750         try
751         {
752             // prevent session destruction (from scavenging)
753             // from being replicated to other members in the cluster.
754             // Let them scavenge locally instead.
755             AbstractReplicatedStore.setReplicating(true);
756             //
757             // take a quick copy...
758             Collection copy;
759             synchronized (_sessions)
760             {
761                 copy = new ArrayList(_sessions.values());
762             }
763             if (Log.isDebugEnabled())
764                 Log.debug(copy.size() + " local sessions");
765             //
766             // iterate over it at our leisure...
767             int n = 0;
768             for (Iterator i = copy.iterator(); i.hasNext();)
769             {
770                 // all we have to do is check if a session isValid() to force it
771                 // to examine itself and invalidate() itself if necessary... -
772                 // because it has a local cache of the necessary details, it
773                 // will only go to the Stored State if it really thinks that it
774                 // is invalid...
775                 StateAdaptor sa = null;
776                 try
777                 {
778                     sa = (StateAdaptor) i.next();
779                     // the ValidationInterceptor should pick this up and throw an IllegalStateException
780                     long lat = sa.getLastAccessedTime();
781                 }
782                 catch (IllegalStateException ignore)
783                 {
784                     if (Log.isDebugEnabled())
785                         Log.debug("scavenging local session " + sa.getId());
786                     destroySession(sa);
787                     i.remove();
788                     ++n;
789                 }
790             }
791             if (Log.isDebugEnabled())
792                 Log.debug("scavenged " + n + " local sessions");
793         }
794         finally
795         {
796             AbstractReplicatedStore.setReplicating(false);
797         }
798         Log.debug("...finished local scavenging");
799     }
800 
801     /**
802      * @return True if cross context session IDs are first considered for new
803      * session IDs
804      */
getCrossContextSessionIDs()805     public boolean getCrossContextSessionIDs()
806     {
807         return _crossContextSessionIDs;
808     }
809 
810     /* ------------------------------------------------------------ */
811     /** Set Cross Context sessions IDs
812      * This option activates a mode where a requested session ID can be used to create a
813      * new session. This facilitates the sharing of session cookies when cross context
814      * dispatches use sessions.
815      *
816      * @param useRequestedId True if cross context session ID are first considered for new
817      * session IDs
818      */
setCrossContextSessionIDs(boolean useRequestedId)819     public void setCrossContextSessionIDs(boolean useRequestedId)
820     {
821         _crossContextSessionIDs = useRequestedId;
822     }
823 
getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)824     public Cookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
825     {
826 //        if (_handler.isUsingCookies())
827 //        { what's the jetty6 counterpart for isUsingCookies? - nik
828             Cookie cookie = _handler.getSessionManager().getHttpOnly() ? new HttpOnlyCookie(SessionManager.__SessionCookieProperty, session.getId()) : new Cookie(
829                 SessionManager.__SessionCookieProperty, session.getId());
830             String domain = getServletContext().getInitParameter(SessionManager.__SessionDomainProperty);
831             String maxAge = getServletContext().getInitParameter(SessionManager.__MaxAgeProperty);
832             String path = getServletContext().getInitParameter(SessionManager.__SessionPathProperty);
833             if (path == null)
834                 path = getCrossContextSessionIDs() ? "/" : ((JBossWebAppContext)_context).getUniqueName();
835             if (path == null || path.length() == 0)
836                 path = "/";
837 
838             if (domain != null)
839                 cookie.setDomain(domain);
840             if (maxAge != null)
841                 cookie.setMaxAge(Integer.parseInt(maxAge));
842             else
843                 cookie.setMaxAge(-1);
844 
845             cookie.setSecure(requestIsSecure && getSecureCookies());
846             cookie.setPath(path);
847 
848             return cookie;
849 //        }
850 //        return null;
851     }
852 
isStarting()853     public boolean isStarting()
854     {
855         // TODO Auto-generated method stub
856         return false;
857     }
858 
getMetaManager()859     public SessionIdManager getMetaManager()
860     {
861         // TODO Auto-generated method stub
862         return null;
863     }
864 
isFailed()865     public boolean isFailed()
866     {
867         // TODO Auto-generated method stub
868         return false;
869     }
870 
isRunning()871     public boolean isRunning()
872     {
873         // TODO Auto-generated method stub
874         return false;
875     }
876 
isStopped()877     public boolean isStopped()
878     {
879         // TODO Auto-generated method stub
880         return false;
881     }
882 
isStopping()883     public boolean isStopping()
884     {
885         // TODO Auto-generated method stub
886         return false;
887     }
888 
889 
getSessionPath()890     public String getSessionPath()
891     {
892         // TODO Auto-generated method stub
893         return null;
894     }
895 
getSessionCookie()896     public String getSessionCookie()
897     {
898         // TODO Auto-generated method stub
899         return null;
900     }
901 
getSessionURL()902     public String getSessionURL()
903     {
904         // TODO Auto-generated method stub
905         return null;
906     }
907 
access(HttpSession arg0,boolean secure)908     public Cookie access(HttpSession arg0,boolean secure)
909     {
910         // TODO Auto-generated method stub
911         return null;
912     }
913 
complete(HttpSession arg0)914     public void complete(HttpSession arg0)
915     {
916         // TODO Auto-generated method stub
917 
918     }
919 
getHttpOnly()920     public boolean getHttpOnly()
921     {
922         // TODO Auto-generated method stub
923         return false;
924     }
925 
getMaxCookieAge()926     public int getMaxCookieAge()
927     {
928         // TODO Auto-generated method stub
929         return 0;
930     }
931 
getSecureCookies()932     public boolean getSecureCookies()
933     {
934         // TODO Auto-generated method stub
935         return false;
936     }
937 
getSessionDomain()938     public String getSessionDomain()
939     {
940         // TODO Auto-generated method stub
941         return null;
942     }
943 
getSessionURLPrefix()944     public String getSessionURLPrefix()
945     {
946         // TODO Auto-generated method stub
947         return null;
948     }
949 
isValid(HttpSession session)950     public boolean isValid(HttpSession session)
951     {
952         // TODO Auto-generated method stub
953         return ((Session)session).isValid();
954     }
955 
setIdManager(SessionIdManager arg0)956     public void setIdManager(SessionIdManager arg0)
957     {
958         // TODO Auto-generated method stub
959 
960     }
961 
setMaxCookieAge(int arg0)962     public void setMaxCookieAge(int arg0)
963     {
964         // TODO Auto-generated method stub
965 
966     }
967 
setSessionCookie(String arg0)968     public void setSessionCookie(String arg0)
969     {
970         // TODO Auto-generated method stub
971 
972     }
973 
setSessionDomain(String arg0)974     public void setSessionDomain(String arg0)
975     {
976         // TODO Auto-generated method stub
977 
978     }
979 
setSessionPath(String arg0)980     public void setSessionPath(String arg0)
981     {
982         // TODO Auto-generated method stub
983 
984     }
985 
setSessionURL(String arg0)986     public void setSessionURL(String arg0)
987     {
988         // TODO Auto-generated method stub
989 
990     }
991 
992     public interface Session extends HttpSession
993     {
994         /* ------------------------------------------------------------ */
isValid()995         public boolean isValid();
996 
997         /* ------------------------------------------------------------ */
access()998         public void access();
999     }
1000 
1001     /**
1002      * @see org.mortbay.jetty.SessionManager#getClusterId(javax.servlet.http.HttpSession)
1003      */
getClusterId(HttpSession session)1004     public String getClusterId(HttpSession session)
1005     {
1006         // TODO check that this is correct. There does not
1007         // seem to be any difference between the id as the
1008         // node knows it and the id within the cluster, so
1009         // we presume that the id is unique within the cluster.
1010         return session.getId();
1011     }
1012 
1013     /**
1014      * @see org.mortbay.jetty.SessionManager#getIdManager()
1015      */
getIdManager()1016     public SessionIdManager getIdManager()
1017     {
1018         // TODO Auto-generated method stub
1019         return null;
1020     }
1021 
1022     /**
1023      * @see org.mortbay.jetty.SessionManager#getNodeId(javax.servlet.http.HttpSession)
1024      */
getNodeId(HttpSession session)1025     public String getNodeId(HttpSession session)
1026     {
1027         // TODO check that this is correct. There does not
1028         // seem to be any difference between the id as the
1029         // node knows it and the id within the cluster, so
1030         // we presume that the id is unique within the cluster.
1031         return session.getId();
1032     }
1033 
1034     /**
1035      * @see org.mortbay.jetty.SessionManager#isUsingCookies()
1036      */
isUsingCookies()1037     public boolean isUsingCookies()
1038     {
1039         return _usingCookies;
1040     }
1041 }
1042