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