1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server.session;
20
21 import static java.lang.Math.round;
22
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.EventListener;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.concurrent.CopyOnWriteArrayList;
31
32 import javax.servlet.SessionCookieConfig;
33 import javax.servlet.SessionTrackingMode;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpSession;
36 import javax.servlet.http.HttpSessionAttributeListener;
37 import javax.servlet.http.HttpSessionBindingEvent;
38 import javax.servlet.http.HttpSessionContext;
39 import javax.servlet.http.HttpSessionEvent;
40 import javax.servlet.http.HttpSessionIdListener;
41 import javax.servlet.http.HttpSessionListener;
42
43 import org.eclipse.jetty.http.HttpCookie;
44 import org.eclipse.jetty.server.Server;
45 import org.eclipse.jetty.server.SessionIdManager;
46 import org.eclipse.jetty.server.SessionManager;
47 import org.eclipse.jetty.server.handler.ContextHandler;
48 import org.eclipse.jetty.util.annotation.ManagedAttribute;
49 import org.eclipse.jetty.util.annotation.ManagedObject;
50 import org.eclipse.jetty.util.annotation.ManagedOperation;
51 import org.eclipse.jetty.util.component.ContainerLifeCycle;
52 import org.eclipse.jetty.util.log.Logger;
53 import org.eclipse.jetty.util.statistic.CounterStatistic;
54 import org.eclipse.jetty.util.statistic.SampleStatistic;
55
56
57
58
59
60
61
62
63 @SuppressWarnings("deprecation")
64 @ManagedObject("Abstract Session Manager")
65 public abstract class AbstractSessionManager extends ContainerLifeCycle implements SessionManager
66 {
67 final static Logger __log = SessionHandler.LOG;
68
69 public Set<SessionTrackingMode> __defaultSessionTrackingModes =
70 Collections.unmodifiableSet(
71 new HashSet<SessionTrackingMode>(
72 Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE,SessionTrackingMode.URL})));
73
74
75
76
77 public final static int __distantFuture=60*60*24*7*52*20;
78
79
80
81
82
83
84
85 public final static java.math.BigDecimal MAX_INACTIVE_MINUTES = new java.math.BigDecimal(Integer.MAX_VALUE/60);
86
87 static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
88 {
89 @Override
90 public HttpSession getSession(String sessionId)
91 {
92 return null;
93 }
94
95 @Override
96 @SuppressWarnings({ "rawtypes", "unchecked" })
97 public Enumeration getIds()
98 {
99 return Collections.enumeration(Collections.EMPTY_LIST);
100 }
101 };
102
103 private boolean _usingCookies=true;
104
105
106
107
108 protected int _dftMaxIdleSecs=-1;
109 protected SessionHandler _sessionHandler;
110 protected boolean _httpOnly=false;
111 protected SessionIdManager _sessionIdManager;
112 protected boolean _secureCookies=false;
113 protected boolean _secureRequestOnly=true;
114
115 protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
116 protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
117 protected final List<HttpSessionIdListener> _sessionIdListeners = new CopyOnWriteArrayList<HttpSessionIdListener>();
118
119 protected ClassLoader _loader;
120 protected ContextHandler.Context _context;
121 protected String _sessionCookie=__DefaultSessionCookie;
122 protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
123 protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
124 protected String _sessionDomain;
125 protected String _sessionPath;
126 protected int _maxCookieAge=-1;
127 protected int _refreshCookieAge;
128 protected boolean _nodeIdInSessionId;
129 protected boolean _checkingRemoteSessionIdEncoding;
130 protected String _sessionComment;
131
132 public Set<SessionTrackingMode> _sessionTrackingModes;
133
134 private boolean _usingURLs;
135
136 protected final CounterStatistic _sessionsStats = new CounterStatistic();
137 protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
138
139
140
141 public AbstractSessionManager()
142 {
143 setSessionTrackingModes(__defaultSessionTrackingModes);
144 }
145
146
147 public ContextHandler.Context getContext()
148 {
149 return _context;
150 }
151
152
153 public ContextHandler getContextHandler()
154 {
155 return _context.getContextHandler();
156 }
157
158 @ManagedAttribute("path of the session cookie, or null for default")
159 public String getSessionPath()
160 {
161 return _sessionPath;
162 }
163
164 @ManagedAttribute("if greater the zero, the time in seconds a session cookie will last for")
165 public int getMaxCookieAge()
166 {
167 return _maxCookieAge;
168 }
169
170
171 @Override
172 public HttpCookie access(HttpSession session,boolean secure)
173 {
174 long now=System.currentTimeMillis();
175
176 AbstractSession s = ((SessionIf)session).getSession();
177
178 if (s.access(now))
179 {
180
181 if (isUsingCookies() &&
182 (s.isIdChanged() ||
183 (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge()))
184 )
185 )
186 {
187 HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure);
188 s.cookieSet();
189 s.setIdChanged(false);
190 return cookie;
191 }
192 }
193 return null;
194 }
195
196
197 @Override
198 public void addEventListener(EventListener listener)
199 {
200 if (listener instanceof HttpSessionAttributeListener)
201 _sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
202 if (listener instanceof HttpSessionListener)
203 _sessionListeners.add((HttpSessionListener)listener);
204 if (listener instanceof HttpSessionIdListener)
205 _sessionIdListeners.add((HttpSessionIdListener)listener);
206 addBean(listener,false);
207 }
208
209
210 @Override
211 public void clearEventListeners()
212 {
213 for (EventListener e :getBeans(EventListener.class))
214 removeBean(e);
215 _sessionAttributeListeners.clear();
216 _sessionListeners.clear();
217 _sessionIdListeners.clear();
218 }
219
220
221 @Override
222 public void complete(HttpSession session)
223 {
224 AbstractSession s = ((SessionIf)session).getSession();
225 s.complete();
226 }
227
228
229 @Override
230 public void doStart() throws Exception
231 {
232 _context=ContextHandler.getCurrentContext();
233 _loader=Thread.currentThread().getContextClassLoader();
234
235 final Server server=getSessionHandler().getServer();
236 synchronized (server)
237 {
238 if (_sessionIdManager==null)
239 {
240 _sessionIdManager=server.getSessionIdManager();
241 if (_sessionIdManager==null)
242 {
243
244
245
246
247 ClassLoader serverLoader = server.getClass().getClassLoader();
248 try
249 {
250 Thread.currentThread().setContextClassLoader(serverLoader);
251 _sessionIdManager=new HashSessionIdManager();
252 server.setSessionIdManager(_sessionIdManager);
253 server.manage(_sessionIdManager);
254 _sessionIdManager.start();
255 }
256 finally
257 {
258 Thread.currentThread().setContextClassLoader(_loader);
259 }
260 }
261
262
263 addBean(_sessionIdManager,false);
264 }
265 }
266
267
268
269 if (_context!=null)
270 {
271 String tmp=_context.getInitParameter(SessionManager.__SessionCookieProperty);
272 if (tmp!=null)
273 _sessionCookie=tmp;
274
275 tmp=_context.getInitParameter(SessionManager.__SessionIdPathParameterNameProperty);
276 if (tmp!=null)
277 setSessionIdPathParameterName(tmp);
278
279
280 if (_maxCookieAge==-1)
281 {
282 tmp=_context.getInitParameter(SessionManager.__MaxAgeProperty);
283 if (tmp!=null)
284 _maxCookieAge=Integer.parseInt(tmp.trim());
285 }
286
287
288 if (_sessionDomain==null)
289 _sessionDomain=_context.getInitParameter(SessionManager.__SessionDomainProperty);
290
291
292 if (_sessionPath==null)
293 _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty);
294
295 tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding);
296 if (tmp!=null)
297 _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
298 }
299
300 super.doStart();
301 }
302
303
304 @Override
305 public void doStop() throws Exception
306 {
307 super.doStop();
308
309 shutdownSessions();
310
311 _loader=null;
312 }
313
314
315
316
317
318 @Override
319 @ManagedAttribute("true if cookies use the http only flag")
320 public boolean getHttpOnly()
321 {
322 return _httpOnly;
323 }
324
325
326 @Override
327 public HttpSession getHttpSession(String nodeId)
328 {
329 String cluster_id = getSessionIdManager().getClusterId(nodeId);
330
331 AbstractSession session = getSession(cluster_id);
332 if (session!=null && !session.getNodeId().equals(nodeId))
333 session.setIdChanged(true);
334 return session;
335 }
336
337
338
339
340
341 @Override
342 @ManagedAttribute("Session ID Manager")
343 public SessionIdManager getSessionIdManager()
344 {
345 return _sessionIdManager;
346 }
347
348
349
350
351
352
353 @Override
354 @ManagedAttribute("defailt maximum time a session may be idle for (in s)")
355 public int getMaxInactiveInterval()
356 {
357 return _dftMaxIdleSecs;
358 }
359
360
361
362
363
364 @ManagedAttribute("maximum number of simultaneous sessions")
365 public int getSessionsMax()
366 {
367 return (int)_sessionsStats.getMax();
368 }
369
370
371
372
373
374 @ManagedAttribute("total number of sessions")
375 public int getSessionsTotal()
376 {
377 return (int)_sessionsStats.getTotal();
378 }
379
380
381 @ManagedAttribute("time before a session cookie is re-set (in s)")
382 public int getRefreshCookieAge()
383 {
384 return _refreshCookieAge;
385 }
386
387
388
389
390
391
392
393 @ManagedAttribute("if true, secure cookie flag is set on session cookies")
394 public boolean getSecureCookies()
395 {
396 return _secureCookies;
397 }
398
399
400
401
402
403 public boolean isSecureRequestOnly()
404 {
405 return _secureRequestOnly;
406 }
407
408
409
410
411
412
413
414
415 public void setSecureRequestOnly(boolean secureRequestOnly)
416 {
417 _secureRequestOnly = secureRequestOnly;
418 }
419
420
421 @ManagedAttribute("the set session cookie")
422 public String getSessionCookie()
423 {
424 return _sessionCookie;
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 @Override
456 public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
457 {
458 if (isUsingCookies())
459 {
460 String sessionPath = (_cookieConfig.getPath()==null) ? contextPath : _cookieConfig.getPath();
461 sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
462 String id = getNodeId(session);
463 HttpCookie cookie = null;
464 if (_sessionComment == null)
465 {
466 cookie = new HttpCookie(
467 _cookieConfig.getName(),
468 id,
469 _cookieConfig.getDomain(),
470 sessionPath,
471 _cookieConfig.getMaxAge(),
472 _cookieConfig.isHttpOnly(),
473 _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure));
474 }
475 else
476 {
477 cookie = new HttpCookie(
478 _cookieConfig.getName(),
479 id,
480 _cookieConfig.getDomain(),
481 sessionPath,
482 _cookieConfig.getMaxAge(),
483 _cookieConfig.isHttpOnly(),
484 _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure),
485 _sessionComment,
486 1);
487 }
488
489 return cookie;
490 }
491 return null;
492 }
493
494 @ManagedAttribute("domain of the session cookie, or null for the default")
495 public String getSessionDomain()
496 {
497 return _sessionDomain;
498 }
499
500
501
502
503
504 public SessionHandler getSessionHandler()
505 {
506 return _sessionHandler;
507 }
508
509
510 @ManagedAttribute("number of currently active sessions")
511 public int getSessions()
512 {
513 return (int)_sessionsStats.getCurrent();
514 }
515
516
517 @Override
518 @ManagedAttribute("name of use for URL session tracking")
519 public String getSessionIdPathParameterName()
520 {
521 return _sessionIdPathParameterName;
522 }
523
524
525 @Override
526 public String getSessionIdPathParameterNamePrefix()
527 {
528 return _sessionIdPathParameterNamePrefix;
529 }
530
531
532
533
534
535 @Override
536 public boolean isUsingCookies()
537 {
538 return _usingCookies;
539 }
540
541
542 @Override
543 public boolean isValid(HttpSession session)
544 {
545 AbstractSession s = ((SessionIf)session).getSession();
546 return s.isValid();
547 }
548
549
550 @Override
551 public String getClusterId(HttpSession session)
552 {
553 AbstractSession s = ((SessionIf)session).getSession();
554 return s.getClusterId();
555 }
556
557
558 @Override
559 public String getNodeId(HttpSession session)
560 {
561 AbstractSession s = ((SessionIf)session).getSession();
562 return s.getNodeId();
563 }
564
565
566
567
568
569 @Override
570 public HttpSession newHttpSession(HttpServletRequest request)
571 {
572 AbstractSession session=newSession(request);
573 session.setMaxInactiveInterval(_dftMaxIdleSecs);
574 if (request.isSecure())
575 session.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
576 addSession(session,true);
577 return session;
578 }
579
580
581 @Override
582 public void removeEventListener(EventListener listener)
583 {
584 if (listener instanceof HttpSessionAttributeListener)
585 _sessionAttributeListeners.remove(listener);
586 if (listener instanceof HttpSessionListener)
587 _sessionListeners.remove(listener);
588 if (listener instanceof HttpSessionIdListener)
589 _sessionIdListeners.remove(listener);
590 removeBean(listener);
591 }
592
593
594
595
596
597 @ManagedOperation(value="reset statistics", impact="ACTION")
598 public void statsReset()
599 {
600 _sessionsStats.reset(getSessions());
601 _sessionTimeStats.reset();
602 }
603
604
605
606
607
608
609 public void setHttpOnly(boolean httpOnly)
610 {
611 _httpOnly=httpOnly;
612 }
613
614
615
616
617
618 @Override
619 public void setSessionIdManager(SessionIdManager metaManager)
620 {
621 updateBean(_sessionIdManager, metaManager);
622 _sessionIdManager=metaManager;
623 }
624
625
626 @Override
627 public void setMaxInactiveInterval(int seconds)
628 {
629 _dftMaxIdleSecs=seconds;
630 if (_dftMaxIdleSecs <= 0)
631 __log.warn("Sessions created by this manager are immortal (default maxInactiveInterval={})"+_dftMaxIdleSecs);
632 else if (__log.isDebugEnabled())
633 __log.debug("SessionManager default maxInactiveInterval={}", _dftMaxIdleSecs);
634 }
635
636
637 public void setRefreshCookieAge(int ageInSeconds)
638 {
639 _refreshCookieAge=ageInSeconds;
640 }
641
642
643 public void setSessionCookie(String cookieName)
644 {
645 _sessionCookie=cookieName;
646 }
647
648
649
650
651
652
653 @Override
654 public void setSessionHandler(SessionHandler sessionHandler)
655 {
656 _sessionHandler=sessionHandler;
657 }
658
659
660
661 @Override
662 public void setSessionIdPathParameterName(String param)
663 {
664 _sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
665 _sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"=");
666 }
667
668
669
670
671
672 public void setUsingCookies(boolean usingCookies)
673 {
674 _usingCookies=usingCookies;
675 }
676
677
678 protected abstract void addSession(AbstractSession session);
679
680
681
682
683
684
685
686
687 protected void addSession(AbstractSession session, boolean created)
688 {
689 synchronized (_sessionIdManager)
690 {
691 _sessionIdManager.addSession(session);
692 addSession(session);
693 }
694
695 if (created)
696 {
697 _sessionsStats.increment();
698 if (_sessionListeners!=null)
699 {
700 HttpSessionEvent event=new HttpSessionEvent(session);
701 for (HttpSessionListener listener : _sessionListeners)
702 listener.sessionCreated(event);
703 }
704 }
705 }
706
707
708
709
710
711
712
713 public abstract AbstractSession getSession(String idInCluster);
714
715
716
717
718
719
720 protected abstract void shutdownSessions() throws Exception;
721
722
723
724
725
726
727
728
729 protected abstract AbstractSession newSession(HttpServletRequest request);
730
731
732
733
734
735
736 public boolean isNodeIdInSessionId()
737 {
738 return _nodeIdInSessionId;
739 }
740
741
742
743
744
745 public void setNodeIdInSessionId(boolean nodeIdInSessionId)
746 {
747 _nodeIdInSessionId=nodeIdInSessionId;
748 }
749
750
751
752
753
754
755
756 public void removeSession(HttpSession session, boolean invalidate)
757 {
758 AbstractSession s = ((SessionIf)session).getSession();
759 removeSession(s,invalidate);
760 }
761
762
763
764
765
766
767
768
769
770 public boolean removeSession(AbstractSession session, boolean invalidate)
771 {
772
773 boolean removed = removeSession(session.getClusterId());
774
775 if (removed)
776 {
777 _sessionsStats.decrement();
778 _sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0));
779
780
781 _sessionIdManager.removeSession(session);
782 if (invalidate)
783 _sessionIdManager.invalidateAll(session.getClusterId());
784
785 if (invalidate && _sessionListeners!=null)
786 {
787 HttpSessionEvent event=new HttpSessionEvent(session);
788 for (int i = _sessionListeners.size()-1; i>=0; i--)
789 {
790 _sessionListeners.get(i).sessionDestroyed(event);
791 }
792 }
793 }
794
795 return removed;
796 }
797
798
799 protected abstract boolean removeSession(String idInCluster);
800
801
802
803
804
805 @ManagedAttribute("maximum amount of time sessions have remained active (in s)")
806 public long getSessionTimeMax()
807 {
808 return _sessionTimeStats.getMax();
809 }
810
811
812 @Override
813 public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
814 {
815 return __defaultSessionTrackingModes;
816 }
817
818
819 @Override
820 public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
821 {
822 return Collections.unmodifiableSet(_sessionTrackingModes);
823 }
824
825
826 @Override
827 public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
828 {
829 _sessionTrackingModes=new HashSet<SessionTrackingMode>(sessionTrackingModes);
830 _usingCookies=_sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
831 _usingURLs=_sessionTrackingModes.contains(SessionTrackingMode.URL);
832 }
833
834
835 @Override
836 public boolean isUsingURLs()
837 {
838 return _usingURLs;
839 }
840
841
842 @Override
843 public SessionCookieConfig getSessionCookieConfig()
844 {
845 return _cookieConfig;
846 }
847
848
849 private SessionCookieConfig _cookieConfig =
850 new CookieConfig();
851
852
853
854
855
856
857 @ManagedAttribute("total time sessions have remained valid")
858 public long getSessionTimeTotal()
859 {
860 return _sessionTimeStats.getTotal();
861 }
862
863
864
865
866
867 @ManagedAttribute("mean time sessions remain valid (in s)")
868 public double getSessionTimeMean()
869 {
870 return _sessionTimeStats.getMean();
871 }
872
873
874
875
876
877 @ManagedAttribute("standard deviation a session remained valid (in s)")
878 public double getSessionTimeStdDev()
879 {
880 return _sessionTimeStats.getStdDev();
881 }
882
883
884
885
886
887 @Override
888 @ManagedAttribute("check remote session id encoding")
889 public boolean isCheckingRemoteSessionIdEncoding()
890 {
891 return _checkingRemoteSessionIdEncoding;
892 }
893
894
895
896
897
898 @Override
899 public void setCheckingRemoteSessionIdEncoding(boolean remote)
900 {
901 _checkingRemoteSessionIdEncoding=remote;
902 }
903
904
905
906
907
908
909
910
911
912 @Override
913 public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
914 {
915 if (!_sessionIdListeners.isEmpty())
916 {
917 AbstractSession session = getSession(newClusterId);
918 HttpSessionEvent event = new HttpSessionEvent(session);
919 for (HttpSessionIdListener l:_sessionIdListeners)
920 {
921 l.sessionIdChanged(event, oldClusterId);
922 }
923 }
924
925 }
926
927
928
929
930
931
932 public final class CookieConfig implements SessionCookieConfig
933 {
934 @Override
935 public String getComment()
936 {
937 return _sessionComment;
938 }
939
940 @Override
941 public String getDomain()
942 {
943 return _sessionDomain;
944 }
945
946 @Override
947 public int getMaxAge()
948 {
949 return _maxCookieAge;
950 }
951
952 @Override
953 public String getName()
954 {
955 return _sessionCookie;
956 }
957
958 @Override
959 public String getPath()
960 {
961 return _sessionPath;
962 }
963
964 @Override
965 public boolean isHttpOnly()
966 {
967 return _httpOnly;
968 }
969
970 @Override
971 public boolean isSecure()
972 {
973 return _secureCookies;
974 }
975
976 @Override
977 public void setComment(String comment)
978 {
979 if (_context != null && _context.getContextHandler().isAvailable())
980 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
981 _sessionComment = comment;
982 }
983
984 @Override
985 public void setDomain(String domain)
986 {
987 if (_context != null && _context.getContextHandler().isAvailable())
988 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
989 _sessionDomain=domain;
990 }
991
992 @Override
993 public void setHttpOnly(boolean httpOnly)
994 {
995 if (_context != null && _context.getContextHandler().isAvailable())
996 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
997 _httpOnly=httpOnly;
998 }
999
1000 @Override
1001 public void setMaxAge(int maxAge)
1002 {
1003 if (_context != null && _context.getContextHandler().isAvailable())
1004 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
1005 _maxCookieAge=maxAge;
1006 }
1007
1008 @Override
1009 public void setName(String name)
1010 {
1011 if (_context != null && _context.getContextHandler().isAvailable())
1012 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
1013 _sessionCookie=name;
1014 }
1015
1016 @Override
1017 public void setPath(String path)
1018 {
1019 if (_context != null && _context.getContextHandler().isAvailable())
1020 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
1021 _sessionPath=path;
1022 }
1023
1024 @Override
1025 public void setSecure(boolean secure)
1026 {
1027 if (_context != null && _context.getContextHandler().isAvailable())
1028 throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
1029 _secureCookies=secure;
1030 }
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 public interface SessionIf extends HttpSession
1042 {
1043 public AbstractSession getSession();
1044 }
1045
1046 public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value)
1047 {
1048 if (!_sessionAttributeListeners.isEmpty())
1049 {
1050 HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old);
1051
1052 for (HttpSessionAttributeListener l : _sessionAttributeListeners)
1053 {
1054 if (old==null)
1055 l.attributeAdded(event);
1056 else if (value==null)
1057 l.attributeRemoved(event);
1058 else
1059 l.attributeReplaced(event);
1060 }
1061 }
1062 }
1063
1064 @Override
1065 @Deprecated
1066 public SessionIdManager getMetaManager()
1067 {
1068 throw new UnsupportedOperationException();
1069 }
1070 }