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 java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.servlet.ServletContext;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpSessionActivationListener;
34 import javax.servlet.http.HttpSessionBindingEvent;
35 import javax.servlet.http.HttpSessionBindingListener;
36 import javax.servlet.http.HttpSessionContext;
37 import javax.servlet.http.HttpSessionEvent;
38
39 import org.eclipse.jetty.util.log.Logger;
40
41
42
43
44
45
46
47
48 @SuppressWarnings("deprecation")
49 public abstract class AbstractSession implements AbstractSessionManager.SessionIf
50 {
51 final static Logger LOG = SessionHandler.LOG;
52
53 private final AbstractSessionManager _manager;
54 private final String _clusterId;
55 private final String _nodeId;
56 private final Map<String,Object> _attributes=new HashMap<String, Object>();
57 private boolean _idChanged;
58 private final long _created;
59 private long _cookieSet;
60 private long _accessed;
61 private long _lastAccessed;
62 private boolean _invalid;
63 private boolean _doInvalidate;
64 private long _maxIdleMs;
65 private boolean _newSession;
66 private int _requests;
67
68
69 protected final Map<String,Object> _jdbcAttributes=_attributes;
70
71
72 protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
73 {
74 _manager = abstractSessionManager;
75
76 _newSession=true;
77 _created=System.currentTimeMillis();
78 _clusterId=_manager._sessionIdManager.newSessionId(request,_created);
79 _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request);
80 _accessed=_created;
81 _lastAccessed=_created;
82 _requests=1;
83 _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
84 if (LOG.isDebugEnabled())
85 LOG.debug("new session & id "+_nodeId+" "+_clusterId);
86 }
87
88
89 protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
90 {
91 _manager = abstractSessionManager;
92 _created=created;
93 _clusterId=clusterId;
94 _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null);
95 _accessed=accessed;
96 _lastAccessed=accessed;
97 _requests=1;
98 _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
99 if (LOG.isDebugEnabled())
100 LOG.debug("new session "+_nodeId+" "+_clusterId);
101 }
102
103
104
105
106
107 protected void checkValid() throws IllegalStateException
108 {
109 if (_invalid)
110 throw new IllegalStateException();
111 }
112
113
114 public AbstractSession getSession()
115 {
116 return this;
117 }
118
119
120 public long getAccessed()
121 {
122 synchronized (this)
123 {
124 return _accessed;
125 }
126 }
127
128
129 public Object getAttribute(String name)
130 {
131 synchronized (this)
132 {
133 checkValid();
134 return _attributes.get(name);
135 }
136 }
137
138
139 public int getAttributes()
140 {
141 synchronized (this)
142 {
143 checkValid();
144 return _attributes.size();
145 }
146 }
147
148
149 @SuppressWarnings({ "unchecked" })
150 public Enumeration<String> getAttributeNames()
151 {
152 synchronized (this)
153 {
154 checkValid();
155 List<String> names=_attributes==null?Collections.EMPTY_LIST:new ArrayList<String>(_attributes.keySet());
156 return Collections.enumeration(names);
157 }
158 }
159
160
161 public Set<String> getNames()
162 {
163 synchronized (this)
164 {
165 return new HashSet<String>(_attributes.keySet());
166 }
167 }
168
169
170 public long getCookieSetTime()
171 {
172 return _cookieSet;
173 }
174
175
176 public long getCreationTime() throws IllegalStateException
177 {
178 return _created;
179 }
180
181
182 public String getId() throws IllegalStateException
183 {
184 return _manager._nodeIdInSessionId?_nodeId:_clusterId;
185 }
186
187
188 public String getNodeId()
189 {
190 return _nodeId;
191 }
192
193
194 public String getClusterId()
195 {
196 return _clusterId;
197 }
198
199
200 public long getLastAccessedTime() throws IllegalStateException
201 {
202 checkValid();
203 return _lastAccessed;
204 }
205
206
207 public int getMaxInactiveInterval()
208 {
209 checkValid();
210 return (int)(_maxIdleMs/1000);
211 }
212
213
214
215
216
217 public ServletContext getServletContext()
218 {
219 return _manager._context;
220 }
221
222
223 @Deprecated
224 public HttpSessionContext getSessionContext() throws IllegalStateException
225 {
226 checkValid();
227 return AbstractSessionManager.__nullSessionContext;
228 }
229
230
231
232
233
234
235 @Deprecated
236 public Object getValue(String name) throws IllegalStateException
237 {
238 return getAttribute(name);
239 }
240
241
242
243
244
245
246 @Deprecated
247 public String[] getValueNames() throws IllegalStateException
248 {
249 synchronized(this)
250 {
251 checkValid();
252 if (_attributes==null)
253 return new String[0];
254 String[] a=new String[_attributes.size()];
255 return (String[])_attributes.keySet().toArray(a);
256 }
257 }
258
259
260 protected boolean access(long time)
261 {
262 synchronized(this)
263 {
264 if (_invalid)
265 return false;
266 _newSession=false;
267 _lastAccessed=_accessed;
268 _accessed=time;
269
270 if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
271 {
272 invalidate();
273 return false;
274 }
275 _requests++;
276 return true;
277 }
278 }
279
280
281 protected void complete()
282 {
283 synchronized(this)
284 {
285 _requests--;
286 if (_doInvalidate && _requests<=0 )
287 doInvalidate();
288 }
289 }
290
291
292
293 protected void timeout() throws IllegalStateException
294 {
295
296 _manager.removeSession(this,true);
297
298
299 synchronized (this)
300 {
301 if (!_invalid)
302 {
303 if (_requests<=0)
304 doInvalidate();
305 else
306 _doInvalidate=true;
307 }
308 }
309 }
310
311
312 public void invalidate() throws IllegalStateException
313 {
314
315 _manager.removeSession(this,true);
316 doInvalidate();
317 }
318
319
320 protected void doInvalidate() throws IllegalStateException
321 {
322 try
323 {
324 LOG.debug("invalidate {}",_clusterId);
325 if (isValid())
326 clearAttributes();
327 }
328 finally
329 {
330 synchronized (this)
331 {
332
333 _invalid=true;
334 }
335 }
336 }
337
338
339 public void clearAttributes()
340 {
341 while (_attributes!=null && _attributes.size()>0)
342 {
343 ArrayList<String> keys;
344 synchronized(this)
345 {
346 keys=new ArrayList<String>(_attributes.keySet());
347 }
348
349 Iterator<String> iter=keys.iterator();
350 while (iter.hasNext())
351 {
352 String key=(String)iter.next();
353
354 Object value;
355 synchronized(this)
356 {
357 value=doPutOrRemove(key,null);
358 }
359 unbindValue(key,value);
360
361 _manager.doSessionAttributeListeners(this,key,value,null);
362 }
363 }
364 if (_attributes!=null)
365 _attributes.clear();
366 }
367
368
369 public boolean isIdChanged()
370 {
371 return _idChanged;
372 }
373
374
375 public boolean isNew() throws IllegalStateException
376 {
377 checkValid();
378 return _newSession;
379 }
380
381
382
383
384
385
386 @Deprecated
387 public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
388 {
389 setAttribute(name,value);
390 }
391
392
393 public void removeAttribute(String name)
394 {
395 setAttribute(name,null);
396 }
397
398
399
400
401
402
403 @Deprecated
404 public void removeValue(java.lang.String name) throws IllegalStateException
405 {
406 removeAttribute(name);
407 }
408
409
410 protected Object doPutOrRemove(String name, Object value)
411 {
412 return value==null?_attributes.remove(name):_attributes.put(name,value);
413 }
414
415
416 protected Object doGet(String name)
417 {
418 return _attributes.get(name);
419 }
420
421
422 public void setAttribute(String name, Object value)
423 {
424 Object old=null;
425 synchronized (this)
426 {
427 checkValid();
428 old=doPutOrRemove(name,value);
429 }
430
431 if (value==null || !value.equals(old))
432 {
433 if (old!=null)
434 unbindValue(name,old);
435 if (value!=null)
436 bindValue(name,value);
437
438 _manager.doSessionAttributeListeners(this,name,old,value);
439
440 }
441 }
442
443
444 public void setIdChanged(boolean changed)
445 {
446 _idChanged=changed;
447 }
448
449
450 public void setMaxInactiveInterval(int secs)
451 {
452 _maxIdleMs=(long)secs*1000L;
453 }
454
455
456 @Override
457 public String toString()
458 {
459 return this.getClass().getName()+":"+getId()+"@"+hashCode();
460 }
461
462
463
464 public void bindValue(java.lang.String name, Object value)
465 {
466 if (value!=null&&value instanceof HttpSessionBindingListener)
467 ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
468 }
469
470
471 public boolean isValid()
472 {
473 return !_invalid;
474 }
475
476
477 protected void cookieSet()
478 {
479 synchronized (this)
480 {
481 _cookieSet=_accessed;
482 }
483 }
484
485
486 public int getRequests()
487 {
488 synchronized (this)
489 {
490 return _requests;
491 }
492 }
493
494
495 public void setRequests(int requests)
496 {
497 synchronized (this)
498 {
499 _requests=requests;
500 }
501 }
502
503
504
505 public void unbindValue(java.lang.String name, Object value)
506 {
507 if (value!=null&&value instanceof HttpSessionBindingListener)
508 ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
509 }
510
511
512 public void willPassivate()
513 {
514 synchronized(this)
515 {
516 HttpSessionEvent event = new HttpSessionEvent(this);
517 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
518 {
519 Object value = iter.next();
520 if (value instanceof HttpSessionActivationListener)
521 {
522 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
523 listener.sessionWillPassivate(event);
524 }
525 }
526 }
527 }
528
529
530 public void didActivate()
531 {
532 synchronized(this)
533 {
534 HttpSessionEvent event = new HttpSessionEvent(this);
535 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
536 {
537 Object value = iter.next();
538 if (value instanceof HttpSessionActivationListener)
539 {
540 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
541 listener.sessionDidActivate(event);
542 }
543 }
544 }
545 }
546
547
548 }