KickJava   Java API By Example, From Geeks To Geeks.

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


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 JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.EventListener JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Timer JavaDoc;
29 import java.util.TimerTask JavaDoc;
30
31 import javax.servlet.ServletContext JavaDoc;
32 import javax.servlet.http.Cookie JavaDoc;
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.http.HttpSession JavaDoc;
35 import javax.servlet.http.HttpSessionAttributeListener JavaDoc;
36 import javax.servlet.http.HttpSessionBindingEvent JavaDoc;
37 import javax.servlet.http.HttpSessionContext JavaDoc;
38 import javax.servlet.http.HttpSessionEvent JavaDoc;
39 import javax.servlet.http.HttpSessionListener JavaDoc;
40
41 import org.jfox.ioc.logger.Logger;
42 import org.mortbay.http.HttpOnlyCookie;
43 import org.mortbay.jetty.servlet.SessionManager;
44 import org.mortbay.jetty.servlet.WebApplicationContext;
45
46 //----------------------------------------
47

48 // TODO
49
//-----
50

51 // we need a SnapshotInterceptor
52
// we need to package this into JBoss and Mort Bay spaces
53
// Cluster/CMR & JDO Stores should be finished/done
54
// a DebugInterceptor could be fun....
55
// Jetty should be user:jetty, role:webcontainer in order to use the session EJBs - wil probably need a SecurityInterceptor
56
// can I optimise return of objects from set/removeAttribute?
57
// CMPState should use local not remote interfaces
58
// FAQ entry should be finished
59
// Throttle/BufferInterceptor - could be written very like MigrationInterceptor
60
// StateAdaptor needs a name change
61
// We need some predefined containers
62
// tighten up access priviledges
63
// javadoc
64
//----------------------------------------
65

66 // we need to rethink the strategies for flushing the local cache into
67
// the distributed cache - specifically how they can be aggregated
68
// (or-ed as opposed to and-ed).
69

70 // the spec does not say (?) whether session attribute events should
71
// be received in the order that the changes took place - we can
72
// control this by placing the SynchronizationInterceptor before or
73
// after the BindingInterceptor
74

75 // we could use a TransactionInterceptor to ensure that compound
76
// operations on e.g. a CMPState are atomic - or we could explicitly
77
// code the use of transactions where needed (we should be able to
78
// make all multiple calls collapse into one call to server - look
79
// into this). Since HttpSessions have no transactional semantics,
80
// there is no way for the user to inform us of any requirements...
81

82 //----------------------------------------
83

84 public class Manager
85   implements org.mortbay.jetty.servlet.SessionManager
86 {
87   protected static final Logger _log=Logger.getLogger(Manager.class);
88
89
90   //----------------------------------------
91
protected WebApplicationContext _context;
92   public WebApplicationContext getContext() {return _context;}
93   public void setContext(WebApplicationContext context) {_context=context;}
94   //----------------------------------------
95
protected int _scavengerPeriod=60; // every 1 min
96
public void setScavengerPeriod(int period) {_scavengerPeriod=period;}
97   public int getScavengerPeriod() {return _scavengerPeriod;}
98   //----------------------------------------
99
protected StateInterceptor[] _interceptorStack=null;
100   public StateInterceptor[] getInterceptorStack() {return _interceptorStack;}
101   public void setInterceptorStack(StateInterceptor[] interceptorStack) {_interceptorStack=interceptorStack;}
102   //----------------------------------------
103
protected IdGenerator _idGenerator=null;
104   public IdGenerator getIdGenerator() {return _idGenerator;}
105   public void setIdGenerator(IdGenerator idGenerator) {_idGenerator=idGenerator;}
106   //----------------------------------------
107
protected int _maxInactiveInterval;
108   public int getMaxInactiveInterval() {return _maxInactiveInterval;}
109   public void setMaxInactiveInterval(int seconds) {_maxInactiveInterval=seconds;}
110   //----------------------------------------
111
protected Store _store = null;
112
113   private boolean _secureCookies = false;
114   private boolean _httpOnly = false;
115   private boolean _crossContextSessionIDs = false;
116
117
118   public Store
119     getStore()
120   {
121     return _store;
122   }
123
124   public void
125     setStore(Store store)
126   {
127     _store=store;
128
129     if (_store!=null)
130       _store.setManager(this);
131   }
132
133   //----------------------------------------
134

135   public Object JavaDoc
136     clone()
137   {
138     // _log.info("cloning Manager: "+this);
139
Manager m=new Manager();
140
141     // deep-copy Store attribute - each Manager gets it's own Store instance
142
Store store=getStore();
143     if (store!=null)
144       m.setStore((Store)store.clone());
145
146     // deep-copy IdGenerator attribute - each Manager gets it's own IdGenerator instance
147
IdGenerator ig=getIdGenerator();
148     if (ig!=null)
149       m.setIdGenerator((IdGenerator)ig.clone());
150
151     // Container uses InterceptorStack as a prototype to clone a stack for each new session...
152
m.setInterceptorStack(getInterceptorStack());
153
154     m.setMaxInactiveInterval(getMaxInactiveInterval());
155     m.setScavengerPeriod(getScavengerPeriod());
156
157     return m;
158   }
159
160   //----------------------------------------
161

162   final Map JavaDoc _sessions = new HashMap JavaDoc();
163
164   public String JavaDoc getContextPath() {return _handler.getHttpContext().getContextPath();}
165
166   //----------------------------------------
167
// LifeCycle API
168
//----------------------------------------
169

170   boolean _started=false;
171   Object JavaDoc _startedLock=new Object JavaDoc();
172   Timer JavaDoc _scavenger;
173
174   class Scavenger
175     extends TimerTask JavaDoc
176   {
177     public void
178       run()
179     {
180       try
181       {
182     scavenge();
183       }
184       catch (Throwable JavaDoc e)
185       {
186     _log.warn("could not scavenge local sessions", e);
187       }
188     }
189   }
190
191   public void
192     start()
193   {
194     _log.trace("starting...");
195     synchronized (_startedLock)
196     {
197       if (_started)
198       {
199     _log.warn("already started");
200     return;
201       }
202
203       if (_store==null)
204       {
205     _log.warn("No Store. Falling back to a local session implementation - NO HTTPSESSION DISTRIBUTION");
206     setStore(new LocalStore());
207       }
208
209       if (_idGenerator==null)
210     _idGenerator=new DistributableIdGenerator();
211
212       try
213       {
214     _store.start();
215       }
216       catch (Exception JavaDoc e)
217       {
218     _log.warn("Faulty Store. Falling back to a local session implementation - NO HTTPSESSION DISTRIBUTION", e);
219     setStore(new LocalStore());
220     try{_store.start();}catch(Exception JavaDoc e2){_log.error("could not start Store", e2);}
221       }
222
223       if (_log.isTraceEnabled()) _log.trace("starting local scavenger thread...(period: "+getScavengerPeriod()+" secs)");
224       long delay=getScavengerPeriod()*1000;
225       boolean isDaemon=true;
226       _scavenger=new Timer JavaDoc(isDaemon);
227       _scavenger.scheduleAtFixedRate(new Scavenger() ,delay,delay);
228       _log.trace("...local scavenger thread started");
229       _started=true;
230     }
231
232     _log.trace("...started");
233   }
234
235   public boolean
236     isStarted()
237   {
238     synchronized (_startedLock) {return _started;}
239   }
240
241   public void
242     stop()
243   {
244     _log.trace("stopping...");
245
246     synchronized (_startedLock)
247     {
248       if (!_started)
249       {
250     _log.warn("already stopped/not yet started");
251     return;
252       }
253
254       // I guess we will have to ask the store for a list of sessions
255
// to migrate... - TODO
256

257       synchronized (_sessions)
258       {
259     List JavaDoc copy=new ArrayList JavaDoc(_sessions.values());
260     for (Iterator JavaDoc i=copy.iterator(); i.hasNext();)
261       ((StateAdaptor)i.next()).migrate();
262
263     _sessions.clear();
264       }
265
266       _log.trace("stopping local scavenger thread...");
267       _scavenger.cancel();
268       _scavenger=null;
269       _log.trace("...local scavenger thread stopped");
270       scavenge();
271
272       _store.stop();
273       _store.destroy();
274       setStore(null);
275       _started=false;
276     }
277
278     _log.trace("...stopped");
279   }
280
281   //----------------------------------------
282
// SessionManager API
283
//----------------------------------------
284

285   protected org.mortbay.jetty.servlet.ServletHandler _handler;
286
287   public void
288     initialize(org.mortbay.jetty.servlet.ServletHandler handler)
289   {
290     _log.trace("initialising...");
291     _handler=handler;
292     // _log = Logger.getLogger(getClass().getName()+"#" + getServletContext().getServletContextName());
293
// perhaps we should cache the interceptor classes here as well...
294

295     // _log.info("initialised("+_handler+"): "+Thread.currentThread().getContextClassLoader());
296
_log.trace("...initialised");
297   }
298
299   //----------------------------------------
300
// SessionManager API
301
//----------------------------------------
302

303   public HttpSession JavaDoc
304     getHttpSession(String JavaDoc id)
305   {
306     return findSession(id,true);
307   }
308     
309   public boolean
310     sessionExists(String JavaDoc id)
311   {
312      return findSession(id,false)!=null;
313   }
314     
315   public HttpSession JavaDoc
316     newHttpSession(HttpServletRequest JavaDoc request) // TODO
317
{
318     return newSession(request);
319   }
320
321   //----------------------------------------
322
// this does not need locking as it is an int and access should be atomic...
323

324   //----------------------------------------
325
// Listeners
326

327   // These lists are only modified at webapp [un]deployment time, by a
328
// single thread, so although read by multiple threads whilst the
329
// Manager is running, need no synchronization...
330

331   final List JavaDoc _sessionListeners =new ArrayList JavaDoc();
332   final List JavaDoc _sessionAttributeListeners =new ArrayList JavaDoc();
333
334   public void
335     addEventListener(EventListener JavaDoc listener)
336     throws IllegalArgumentException JavaDoc, IllegalStateException JavaDoc
337   {
338     synchronized (_startedLock)
339     {
340       if (isStarted())
341     throw new IllegalStateException JavaDoc("EventListeners must be added before a Session Manager starts");
342
343       boolean known=false;
344       if (listener instanceof HttpSessionAttributeListener JavaDoc)
345       {
346     // _log.info("adding HttpSessionAttributeListener: "+listener);
347
_sessionAttributeListeners.add(listener);
348     known=true;
349       }
350       if (listener instanceof HttpSessionListener JavaDoc)
351       {
352     // _log.info("adding HttpSessionListener: "+listener);
353
_sessionListeners.add(listener);
354     known=true;
355       }
356
357       if (!known)
358     throw new IllegalArgumentException JavaDoc("Unknown EventListener type "+listener);
359     }
360   }
361
362   public void
363     removeEventListener(EventListener JavaDoc listener)
364     throws IllegalStateException JavaDoc
365   {
366     synchronized (_startedLock)
367     {
368       if (isStarted())
369     throw new IllegalStateException JavaDoc("EventListeners may not be removed while a Session Manager is running");
370
371       if (listener instanceof HttpSessionAttributeListener JavaDoc)
372     _sessionAttributeListeners.remove(listener);
373       if (listener instanceof HttpSessionListener JavaDoc)
374     _sessionListeners.remove(listener);
375     }
376   }
377
378   //----------------------------------------
379
// Implementation...
380
//----------------------------------------
381

382   public ServletContext JavaDoc
383     getServletContext()
384   {
385     return _handler.getServletContext();
386   }
387
388   public HttpSessionContext JavaDoc
389     getSessionContext()
390   {
391     return org.mortbay.jetty.servlet.SessionContext.NULL_IMPL;
392   }
393
394   //--------------------
395
// session lifecycle
396
//--------------------
397

398
399   // I need to think more about where the list of extant sessions is
400
// held...
401

402   // is it held by the State Factory/Type (static), which best knows
403
// how to find it ? The trouble is we are not asking for just the
404
// State but the whole container...
405

406   // if the State was an EJB, the Manager could hold a HashMap of
407
// id:State and the State would just be an EJB handle...
408

409   // How does the ThrottleInterceptor fit into this. If it is holding
410
// a local cache in front of a DistributedState, do we check them
411
// both and compare timestamps, or flush() all ThrottleInterceptors
412
// in the WebApp before we do the lookup (could be expensive...)
413

414   // when finding a distributed session assume we are on nodeB
415
// receiving a request for a session immediately after it has just
416
// been created on NodeA. If we can't find it straight away, we need
417
// to take into account how long it's flushing and distribution may
418
// take, wait that long and then look again. This may hold up the
419
// request, but without the session the request is not much good.
420

421   // overload this to change the construction of the Container....
422

423   protected HttpSession JavaDoc
424     newContainer(String JavaDoc id, State state)
425   {
426     // put together the make-believe container and HttpSession state
427

428     return Container.newContainer(this, id, state, getMaxInactiveInterval(), currentSecond(), getInterceptorStack());
429   }
430
431   protected HttpSession JavaDoc
432     newSession(HttpServletRequest JavaDoc request)
433   {
434     String JavaDoc id=null;
435     HttpSession JavaDoc session=null;
436     try
437     {
438       id=_store.allocateId(request);
439       State state=_store.newState(id, getMaxInactiveInterval());
440       session=newContainer(id, state);
441     }
442     catch (Exception JavaDoc e)
443     {
444       _log.error("could not create HttpSession", e);
445       return null; // BAD - TODO
446
}
447
448     if (_log.isDebugEnabled()) _log.debug("remembering session - "+id);
449
450     synchronized (_sessions) {_sessions.put(id, session);}
451
452     notifySessionCreated(session);
453
454     return session;
455   }
456
457   protected State
458     destroyContainer(HttpSession JavaDoc session)
459   {
460     return Container.destroyContainer(session, getInterceptorStack());
461   }
462
463   protected void
464     destroySession(HttpSession JavaDoc container)
465   {
466     String JavaDoc id=container.getId();
467     if (_log.isDebugEnabled()) _log.debug("forgetting session - "+id);
468     Object JavaDoc tmp;
469     synchronized (_sessions) {tmp=_sessions.remove(id);}
470     container=(HttpSession JavaDoc)tmp;
471     if (_log.isDebugEnabled()) _log.debug("forgetting session - "+ container);
472
473     if (container==null)
474     {
475       _log.warn("session - "+id+" has already been destroyed");
476       return;
477     }
478
479     // TODO remove all the attributes - generating correct events
480
// check ordering on unbind and destroy notifications - The
481
// problem is that we want these calls to go all the way through
482
// the container - but not to the store - because that would be
483
// too expensive and we can predict the final state...
484

485     // we don't need to do this if we know that none of the attributes
486
// are BindingListers AND there are no AttributeListeners
487
// registered... - TODO
488

489     // This will do for the moment...
490

491
492     // LATER - TODO
493

494     try
495     {
496       State state=((StateAdaptor)container).getState();
497
498       // filthy hack...
499
// stop InvalidInterceptors - otherwise we can't clean up session... - TODO
500
{
501     State s=state;
502     StateInterceptor si=null;
503     while (s instanceof StateInterceptor)
504     {
505       si=(StateInterceptor)s;
506       s=si.getState(); // next interceptor
507
if (si instanceof ValidatingInterceptor)
508         si.stop();
509     }
510       }
511
512       String JavaDoc[] names=state.getAttributeNameStringArray();
513       for (int i=0; i<names.length; i++)
514     state.removeAttribute(names[i], false);
515
516       // should just do this for attributes which are BindingListeners
517
// - then just clear() the rest... - TODO
518
}
519     catch(RemoteException JavaDoc e)
520     {
521       _log.error("could not raise events on session destruction - problem in distribution layer", e);
522     }
523
524     if (_log.isDebugEnabled()) _log.debug("notifying session - "+id);
525     notifySessionDestroyed(container);
526
527     if (_log.isDebugEnabled()) _log.debug("destroying container - "+id);
528     State state=destroyContainer(container);
529
530     try
531     {
532       if (state!=null) // an interceptor may preempt us, if
533
// it does not want this state
534
// removed...
535
{
536     if (_log.isDebugEnabled()) _log.debug("removing state - "+id);
537     _store.removeState(state);
538       }
539     }
540     catch (Exception JavaDoc e)
541     {
542       _log.error("could not remove session state", e);
543     }
544   }
545
546
547   protected HttpSession JavaDoc
548     findSession(String JavaDoc id,boolean create)
549   {
550     HttpSession JavaDoc container=null;
551
552     try
553     {
554       // find the state
555
State state=_store.loadState(id);
556
557       // is it valid ?
558
state=((state!=null) && state.isValid())?state:null; // expensive ?
559

560       // if so
561
if (state!=null)
562       {
563
564     // this looks slow - but to be 100% safe we need to make sure
565
// that no-one can enter another container for the same id,
566
// whilst we are thinking about it...
567

568     // is there a container already available ?
569
synchronized (_sessions)
570     {
571       // do we have an existing container ?
572
container=(HttpSession JavaDoc)_sessions.get(id);
573
574       // if not...
575
if (container==null && create)
576       {
577         // make a new one...
578
container=newContainer(id, state);// we could lower contention by preconstructing containers... - TODO
579
_sessions.put(id, container);
580       }
581     }
582       }
583     }
584     catch (Exception JavaDoc ignore)
585     {
586       if (_log.isDebugEnabled()) _log.debug("did not find distributed session: "+id);
587     }
588
589     return container;
590   }
591
592   //--------------------
593
// session events
594
//--------------------
595

596   // should this all be delegated to the event raising interceptor....
597

598   public Object JavaDoc
599     notifyAttributeAdded(HttpSession JavaDoc session, String JavaDoc name, Object JavaDoc value)
600   {
601     int n=_sessionAttributeListeners.size();
602     if (n>0)
603     {
604       HttpSessionBindingEvent JavaDoc event =
605     new HttpSessionBindingEvent JavaDoc(session, name, value);
606
607       for(int i=0;i<n;i++)
608     ((HttpSessionAttributeListener JavaDoc)
609      _sessionAttributeListeners.get(i)).attributeAdded(event);
610
611       event=null;
612     }
613
614     return value;
615   }
616
617   public Object JavaDoc
618     notifyAttributeReplaced(HttpSession JavaDoc session, String JavaDoc name, Object JavaDoc value)
619   {
620     int n=_sessionAttributeListeners.size();
621     if (n>0)
622     {
623       HttpSessionBindingEvent JavaDoc event =
624     new HttpSessionBindingEvent JavaDoc(session, name, value);
625
626       for(int i=0;i<n;i++)
627     ((HttpSessionAttributeListener JavaDoc)
628      _sessionAttributeListeners.get(i)).attributeReplaced(event);
629
630       event=null;
631     }
632
633     return value;
634   }
635
636   public Object JavaDoc
637     notifyAttributeRemoved(HttpSession JavaDoc session, String JavaDoc name, Object JavaDoc value)
638   {
639     int n=_sessionAttributeListeners.size();
640     if (n>0)
641     {
642       HttpSessionBindingEvent JavaDoc event =
643     new HttpSessionBindingEvent JavaDoc(session, name, value);
644
645       for(int i=0;i<n;i++)
646     ((HttpSessionAttributeListener JavaDoc)
647      _sessionAttributeListeners.get(i)).attributeRemoved(event);
648
649       event=null;
650     }
651
652     return value;
653   }
654
655   public void
656     notifySessionCreated(HttpSession JavaDoc session)
657   {
658     int n=_sessionListeners.size();
659     if (n>0)
660     {
661       HttpSessionEvent JavaDoc event = new HttpSessionEvent JavaDoc(session);
662
663       for(int i=0;i<n;i++)
664     ((HttpSessionListener JavaDoc)_sessionListeners.get(i)) .sessionCreated(event);
665
666       event=null;
667     }
668   }
669
670   public void
671     notifySessionDestroyed(HttpSession JavaDoc session)
672   {
673     int n=_sessionListeners.size();
674     if (n>0)
675     {
676       HttpSessionEvent JavaDoc event = new HttpSessionEvent JavaDoc(session);
677
678       for(int i=0;i<n;i++)
679     ((HttpSessionListener JavaDoc)_sessionListeners.get(i)).sessionDestroyed(event);
680
681       event=null;
682     }
683   }
684
685   // this is to help sessions decide if they have timed out... It is
686
// wrapped here so that if I decide that System.currentTimeMillis()
687
// is too heavy, I can figure out a lighter way to return a rough
688
// time to the sessions...
689

690   public long
691     currentSecond()
692   {
693     return System.currentTimeMillis();
694   }
695
696   // ensure that this code is run with the correct ContextClassLoader...
697
protected void
698     scavenge()
699   {
700     _log.trace("starting local scavenging...");
701     try
702     {
703       // prevent session destruction (from scavenging)
704
// from being replicated to other members in the cluster.
705
// Let them scavenge locally instead.
706
AbstractReplicatedStore.setReplicating(true);
707     //
708
// take a quick copy...
709
Collection JavaDoc copy;
710     synchronized (_sessions) {copy=new ArrayList JavaDoc(_sessions.values());}
711       if (_log.isTraceEnabled()) _log.trace(copy.size()+" local sessions");
712     //
713
// iterate over it at our leisure...
714
int n=0;
715     for (Iterator JavaDoc i=copy.iterator(); i.hasNext();)
716     {
717       // all we have to do is check if a session isValid() to force it
718
// to examine itself and invalidate() itself if necessary... -
719
// because it has a local cache of the necessary details, it
720
// will only go to the Stored State if it really thinks that it
721
// is invalid...
722
StateAdaptor sa=null;
723       try
724       {
725           sa=(StateAdaptor)i.next();
726     // the ValidationInterceptor should pick this up and throw an IllegalStateException
727
long lat=sa.getLastAccessedTime();
728       }
729       catch (IllegalStateException JavaDoc ignore)
730       {
731           if (_log.isDebugEnabled()) _log.debug("scavenging local session "+sa.getId());
732           destroySession(sa);
733           i.remove();
734           ++n;
735         }
736       }
737       if (_log.isTraceEnabled()) _log.trace("scavenged "+n+" local sessions");
738     }
739     finally
740     {
741       AbstractReplicatedStore.setReplicating(false);
742     }
743     _log.trace("...finished local scavenging");
744   }
745       /* ------------------------------------------------------------ */
746       /**
747        * @return Returns the secureCookies.
748        *
749        *
750        */

751       public boolean getSecureCookies()
752       {
753         return _secureCookies;
754       }
755                                                                                                                                 
756       /* ------------------------------------------------------------ */
757       /**
758        * @param secureCookies The secureCookies to set.
759        */

760       public void setSecureCookies(boolean secureCookies)
761       {
762         _secureCookies = secureCookies;
763       }
764       /* ------------------------------------------------------------ */
765       /**
766        * @return Returns the httpOnly.
767        */

768       public boolean getHttpOnly()
769       {
770          return _httpOnly;
771       }
772                                                                                                                          
773      /* ------------------------------------------------------------ */
774      /**
775       * @param httpOnly The httpOnly to set.
776       */

777      public void setHttpOnly(boolean httpOnly)
778      {
779         _httpOnly = httpOnly;
780      }
781      
782      /**
783       * @return True if cross context session IDs are first considered for new
784       * session IDs
785       */

786      public boolean getCrossContextSessionIDs()
787      {
788          return _crossContextSessionIDs;
789      }
790      
791      /* ------------------------------------------------------------ */
792      /** Set Cross Context sessions IDs
793       * This option activates a mode where a requested session ID can be used to create a
794       * new session. This facilitates the sharing of session cookies when cross context
795       * dispatches use sessions.
796       *
797       * @param useRequestedId True if cross context session ID are first considered for new
798       * session IDs
799       */

800      public void setCrossContextSessionIDs(boolean useRequestedId)
801      {
802          _crossContextSessionIDs = useRequestedId;
803      }
804
805      public Cookie JavaDoc getSessionCookie(HttpSession JavaDoc session,boolean requestIsSecure)
806      {
807          if (_handler.isUsingCookies())
808          {
809              Cookie JavaDoc cookie = _handler.getSessionManager().getHttpOnly()
810                  ?new HttpOnlyCookie(SessionManager.__SessionCookie,session.getId())
811                  :new Cookie JavaDoc(SessionManager.__SessionCookie,session.getId());
812              String JavaDoc domain=_handler.getServletContext().getInitParameter(SessionManager.__SessionDomain);
813              String JavaDoc maxAge=_handler.getServletContext().getInitParameter(SessionManager.__MaxAge);
814              String JavaDoc path=_handler.getServletContext().getInitParameter(SessionManager.__SessionPath);
815              if (path==null)
816                  path=getCrossContextSessionIDs()?"/":_handler.getHttpContext().getContextPath();
817              if (path==null || path.length()==0)
818                  path="/";
819              
820              if (domain!=null)
821                  cookie.setDomain(domain);
822              if (maxAge!=null)
823                  cookie.setMaxAge(Integer.parseInt(maxAge));
824              else
825                  cookie.setMaxAge(-1);
826              
827              cookie.setSecure(requestIsSecure && getSecureCookies());
828              cookie.setPath(path);
829              
830              return cookie;
831          }
832          return null;
833      }
834 }
835
Popular Tags