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