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 int getMaxInactiveInterval()
207 {
208 checkValid();
209 return (int)(_maxIdleMs/1000);
210 }
211
212
213
214
215
216 public ServletContext getServletContext()
217 {
218 return _manager._context;
219 }
220
221
222 @Deprecated
223 public HttpSessionContext getSessionContext() throws IllegalStateException
224 {
225 checkValid();
226 return AbstractSessionManager.__nullSessionContext;
227 }
228
229
230
231
232
233
234 @Deprecated
235 public Object getValue(String name) throws IllegalStateException
236 {
237 return getAttribute(name);
238 }
239
240
241
242
243
244
245 @Deprecated
246 public String[] getValueNames() throws IllegalStateException
247 {
248 synchronized(this)
249 {
250 checkValid();
251 if (_attributes==null)
252 return new String[0];
253 String[] a=new String[_attributes.size()];
254 return (String[])_attributes.keySet().toArray(a);
255 }
256 }
257
258
259 protected Map<String,Object> getAttributeMap ()
260 {
261 return _attributes;
262 }
263
264
265 protected void addAttributes(Map<String,Object> map)
266 {
267 _attributes.putAll(map);
268 }
269
270
271 protected boolean access(long time)
272 {
273 synchronized(this)
274 {
275 if (_invalid)
276 return false;
277 _newSession=false;
278 _lastAccessed=_accessed;
279 _accessed=time;
280
281 if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
282 {
283 invalidate();
284 return false;
285 }
286 _requests++;
287 return true;
288 }
289 }
290
291
292 protected void complete()
293 {
294 synchronized(this)
295 {
296 _requests--;
297 if (_doInvalidate && _requests<=0 )
298 doInvalidate();
299 }
300 }
301
302
303
304 protected void timeout() throws IllegalStateException
305 {
306
307 _manager.removeSession(this,true);
308
309
310 synchronized (this)
311 {
312 if (!_invalid)
313 {
314 if (_requests<=0)
315 doInvalidate();
316 else
317 _doInvalidate=true;
318 }
319 }
320 }
321
322
323 public void invalidate() throws IllegalStateException
324 {
325
326 _manager.removeSession(this,true);
327 doInvalidate();
328 }
329
330
331 protected void doInvalidate() throws IllegalStateException
332 {
333 try
334 {
335 LOG.debug("invalidate {}",_clusterId);
336 if (isValid())
337 clearAttributes();
338 }
339 finally
340 {
341 synchronized (this)
342 {
343
344 _invalid=true;
345 }
346 }
347 }
348
349
350 public void clearAttributes()
351 {
352 while (_attributes!=null && _attributes.size()>0)
353 {
354 ArrayList<String> keys;
355 synchronized(this)
356 {
357 keys=new ArrayList<String>(_attributes.keySet());
358 }
359
360 Iterator<String> iter=keys.iterator();
361 while (iter.hasNext())
362 {
363 String key=(String)iter.next();
364
365 Object value;
366 synchronized(this)
367 {
368 value=doPutOrRemove(key,null);
369 }
370 unbindValue(key,value);
371
372 _manager.doSessionAttributeListeners(this,key,value,null);
373 }
374 }
375 if (_attributes!=null)
376 _attributes.clear();
377 }
378
379
380 public boolean isIdChanged()
381 {
382 return _idChanged;
383 }
384
385
386 public boolean isNew() throws IllegalStateException
387 {
388 checkValid();
389 return _newSession;
390 }
391
392
393
394
395
396
397 @Deprecated
398 public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
399 {
400 setAttribute(name,value);
401 }
402
403
404 public void removeAttribute(String name)
405 {
406 setAttribute(name,null);
407 }
408
409
410
411
412
413
414 @Deprecated
415 public void removeValue(java.lang.String name) throws IllegalStateException
416 {
417 removeAttribute(name);
418 }
419
420
421 protected Object doPutOrRemove(String name, Object value)
422 {
423 return value==null?_attributes.remove(name):_attributes.put(name,value);
424 }
425
426
427 protected Object doGet(String name)
428 {
429 return _attributes.get(name);
430 }
431
432
433 public void setAttribute(String name, Object value)
434 {
435 Object old=null;
436 synchronized (this)
437 {
438 checkValid();
439 old=doPutOrRemove(name,value);
440 }
441
442 if (value==null || !value.equals(old))
443 {
444 if (old!=null)
445 unbindValue(name,old);
446 if (value!=null)
447 bindValue(name,value);
448
449 _manager.doSessionAttributeListeners(this,name,old,value);
450
451 }
452 }
453
454
455 public void setIdChanged(boolean changed)
456 {
457 _idChanged=changed;
458 }
459
460
461 public void setMaxInactiveInterval(int secs)
462 {
463 _maxIdleMs=(long)secs*1000L;
464 }
465
466
467 @Override
468 public String toString()
469 {
470 return this.getClass().getName()+":"+getId()+"@"+hashCode();
471 }
472
473
474
475 public void bindValue(java.lang.String name, Object value)
476 {
477 if (value!=null&&value instanceof HttpSessionBindingListener)
478 ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
479 }
480
481
482 public boolean isValid()
483 {
484 return !_invalid;
485 }
486
487
488 protected void cookieSet()
489 {
490 synchronized (this)
491 {
492 _cookieSet=_accessed;
493 }
494 }
495
496
497 public int getRequests()
498 {
499 synchronized (this)
500 {
501 return _requests;
502 }
503 }
504
505
506 public void setRequests(int requests)
507 {
508 synchronized (this)
509 {
510 _requests=requests;
511 }
512 }
513
514
515
516 public void unbindValue(java.lang.String name, Object value)
517 {
518 if (value!=null&&value instanceof HttpSessionBindingListener)
519 ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
520 }
521
522
523 public void willPassivate()
524 {
525 synchronized(this)
526 {
527 HttpSessionEvent event = new HttpSessionEvent(this);
528 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
529 {
530 Object value = iter.next();
531 if (value instanceof HttpSessionActivationListener)
532 {
533 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
534 listener.sessionWillPassivate(event);
535 }
536 }
537 }
538 }
539
540
541 public void didActivate()
542 {
543 synchronized(this)
544 {
545 HttpSessionEvent event = new HttpSessionEvent(this);
546 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
547 {
548 Object value = iter.next();
549 if (value instanceof HttpSessionActivationListener)
550 {
551 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
552 listener.sessionDidActivate(event);
553 }
554 }
555 }
556 }
557
558
559 }