2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.server.session;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.Iterator;
25 import java.util.List;
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpSessionActivationListener;
32 import javax.servlet.http.HttpSessionBindingEvent;
33 import javax.servlet.http.HttpSessionBindingListener;
34 import javax.servlet.http.HttpSessionContext;
35 import javax.servlet.http.HttpSessionEvent;
37 import org.eclipse.jetty.server.SessionManager;
38 import org.eclipse.jetty.util.log.Logger;
43 * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
47 @SuppressWarnings("deprecation")
48 public abstract class AbstractSession implements AbstractSessionManager.SessionIf
50 final static Logger LOG = SessionHandler.LOG;
51 public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
52 private String _clusterId; // ID without any node (ie "worker") id appended
53 private String _nodeId; // ID of session with node(ie "worker") id appended
54 private final AbstractSessionManager _manager;
55 private boolean _idChanged;
56 private final long _created;
57 private long _cookieSet;
58 private long _accessed; // the time of the last access
59 private long _lastAccessed; // the time of the last access excluding this one
60 private boolean _invalid;
61 private boolean _doInvalidate;
62 private long _maxIdleMs;
63 private boolean _newSession;
64 private int _requests;
68 /* ------------------------------------------------------------- */
69 protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
71 _manager = abstractSessionManager;
74 _created=System.currentTimeMillis();
75 _clusterId=_manager._sessionIdManager.newSessionId(request,_created);
76 _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request);
78 _lastAccessed=_created;
80 _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
81 if (LOG.isDebugEnabled())
82 LOG.debug("new session & id "+_nodeId+" "+_clusterId);
85 /* ------------------------------------------------------------- */
86 protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
88 _manager = abstractSessionManager;
91 _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null);
93 _lastAccessed=accessed;
95 _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
96 if (LOG.isDebugEnabled())
97 LOG.debug("new session "+_nodeId+" "+_clusterId);
100 /* ------------------------------------------------------------- */
102 * asserts that the session is valid
104 protected void checkValid() throws IllegalStateException
107 throw new IllegalStateException();
110 /* ------------------------------------------------------------- */
111 /** Check to see if session has expired as at the time given.
115 protected boolean checkExpiry(long time)
117 if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
122 /* ------------------------------------------------------------- */
124 public AbstractSession getSession()
129 /* ------------------------------------------------------------- */
130 public long getAccessed()
138 /* ------------------------------------------------------------- */
139 public abstract Map<String,Object> getAttributeMap();
145 /* ------------------------------------------------------------ */
146 public abstract int getAttributes();
151 /* ------------------------------------------------------------ */
152 public abstract Set<String> getNames();
155 /* ------------------------------------------------------------- */
156 public long getCookieSetTime()
161 /* ------------------------------------------------------------- */
163 public long getCreationTime() throws IllegalStateException
169 /* ------------------------------------------------------------ */
171 public String getId() throws IllegalStateException
173 return _manager._nodeIdInSessionId?_nodeId:_clusterId;
176 /* ------------------------------------------------------------- */
177 public String getNodeId()
182 /* ------------------------------------------------------------- */
183 public String getClusterId()
188 /* ------------------------------------------------------------- */
190 public long getLastAccessedTime() throws IllegalStateException
193 return _lastAccessed;
196 /* ------------------------------------------------------------- */
197 public void setLastAccessedTime(long time)
199 _lastAccessed = time;
202 /* ------------------------------------------------------------- */
204 public int getMaxInactiveInterval()
206 return (int)(_maxIdleMs/1000);
209 /* ------------------------------------------------------------ */
211 * @see javax.servlet.http.HttpSession#getServletContext()
214 public ServletContext getServletContext()
216 return _manager._context;
219 /* ------------------------------------------------------------- */
222 public HttpSessionContext getSessionContext() throws IllegalStateException
225 return AbstractSessionManager.__nullSessionContext;
228 /* ------------------------------------------------------------- */
230 * @deprecated As of Version 2.2, this method is replaced by
231 * {@link #getAttribute}
235 public Object getValue(String name) throws IllegalStateException
237 return getAttribute(name);
242 /* ------------------------------------------------------------ */
243 public void renewId(HttpServletRequest request)
245 _manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request);
249 /* ------------------------------------------------------------- */
250 public SessionManager getSessionManager()
255 /* ------------------------------------------------------------ */
256 protected void setClusterId (String clusterId)
258 _clusterId = clusterId;
261 /* ------------------------------------------------------------ */
262 protected void setNodeId (String nodeId)
268 /* ------------------------------------------------------------ */
269 protected boolean access(long time)
276 _lastAccessed=_accessed;
279 if (checkExpiry(time))
289 /* ------------------------------------------------------------ */
290 protected void complete()
295 if (_doInvalidate && _requests<=0 )
301 /* ------------------------------------------------------------- */
302 protected void timeout() throws IllegalStateException
304 // remove session from context and invalidate other sessions with same ID.
305 _manager.removeSession(this,true);
307 // Notify listeners and unbind values
308 boolean do_invalidate=false;
323 /* ------------------------------------------------------------- */
325 public void invalidate() throws IllegalStateException
328 // remove session from context and invalidate other sessions with same ID.
329 _manager.removeSession(this,true);
333 /* ------------------------------------------------------------- */
334 protected void doInvalidate() throws IllegalStateException
338 LOG.debug("invalidate {}",_clusterId);
352 /* ------------------------------------------------------------- */
353 public abstract void clearAttributes();
356 /* ------------------------------------------------------------- */
357 public boolean isIdChanged()
362 /* ------------------------------------------------------------- */
364 public boolean isNew() throws IllegalStateException
370 /* ------------------------------------------------------------- */
372 * @deprecated As of Version 2.2, this method is replaced by
373 * {@link #setAttribute}
377 public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
379 changeAttribute(name,value);
382 /* ------------------------------------------------------------ */
384 public void removeAttribute(String name)
386 setAttribute(name,null);
389 /* ------------------------------------------------------------- */
391 * @deprecated As of Version 2.2, this method is replaced by
392 * {@link #removeAttribute}
396 public void removeValue(java.lang.String name) throws IllegalStateException
398 removeAttribute(name);
401 /* ------------------------------------------------------------ */
402 @SuppressWarnings({ "unchecked" })
404 public Enumeration<String> getAttributeNames()
409 return doGetAttributeNames();
413 /* ------------------------------------------------------------- */
415 * @deprecated As of Version 2.2, this method is replaced by
416 * {@link #getAttributeNames}
420 public String[] getValueNames() throws IllegalStateException
425 Enumeration<String> anames = doGetAttributeNames();
427 return new String[0];
428 ArrayList<String> names = new ArrayList<String>();
429 while (anames.hasMoreElements())
430 names.add(anames.nextElement());
431 return names.toArray(new String[names.size()]);
436 /* ------------------------------------------------------------ */
437 public abstract Object doPutOrRemove(String name, Object value);
440 /* ------------------------------------------------------------ */
441 public abstract Object doGet(String name);
444 /* ------------------------------------------------------------ */
445 public abstract Enumeration<String> doGetAttributeNames();
448 /* ------------------------------------------------------------ */
450 public Object getAttribute(String name)
460 /* ------------------------------------------------------------ */
462 public void setAttribute(String name, Object value)
464 changeAttribute(name,value);
467 /* ------------------------------------------------------------ */
471 * @deprecated use changeAttribute(String,Object) instead
474 protected boolean updateAttribute (String name, Object value)
480 old=doPutOrRemove(name,value);
483 if (value==null || !value.equals(old))
486 unbindValue(name,old);
488 bindValue(name,value);
490 _manager.doSessionAttributeListeners(this,name,old,value);
497 /* ------------------------------------------------------------ */
499 * Either set (perhaps replace) or remove the value of the attribute
500 * in the session. The appropriate session attribute listeners are
507 protected Object changeAttribute (String name, Object value)
513 old=doPutOrRemove(name,value);
516 callSessionAttributeListeners(name, value, old);
521 /* ------------------------------------------------------------ */
523 * Call binding and attribute listeners based on the new and old
524 * values of the attribute.
526 * @param name name of the attribute
527 * @param newValue new value of the attribute
528 * @param oldValue previous value of the attribute
530 protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
532 if (newValue==null || !newValue.equals(oldValue))
535 unbindValue(name,oldValue);
537 bindValue(name,newValue);
539 _manager.doSessionAttributeListeners(this,name,oldValue,newValue);
544 /* ------------------------------------------------------------- */
545 public void setIdChanged(boolean changed)
550 /* ------------------------------------------------------------- */
552 public void setMaxInactiveInterval(int secs)
554 _maxIdleMs=(long)secs*1000L;
557 /* ------------------------------------------------------------- */
559 public String toString()
561 return this.getClass().getName()+":"+getId()+"@"+hashCode();
564 /* ------------------------------------------------------------- */
565 /** If value implements HttpSessionBindingListener, call valueBound() */
566 public void bindValue(java.lang.String name, Object value)
568 if (value!=null&&value instanceof HttpSessionBindingListener)
569 ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
572 /* ------------------------------------------------------------ */
573 public boolean isValid()
578 /* ------------------------------------------------------------- */
579 protected void cookieSet()
583 _cookieSet=_accessed;
587 /* ------------------------------------------------------------ */
588 public int getRequests()
596 /* ------------------------------------------------------------ */
597 public void setRequests(int requests)
605 /* ------------------------------------------------------------- */
606 /** If value implements HttpSessionBindingListener, call valueUnbound() */
607 public void unbindValue(java.lang.String name, Object value)
609 if (value!=null&&value instanceof HttpSessionBindingListener)
610 ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
613 /* ------------------------------------------------------------- */
614 public void willPassivate()
618 HttpSessionEvent event = new HttpSessionEvent(this);
619 for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
621 Object value = iter.next();
622 if (value instanceof HttpSessionActivationListener)
624 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
625 listener.sessionWillPassivate(event);
631 /* ------------------------------------------------------------- */
632 public void didActivate()
636 HttpSessionEvent event = new HttpSessionEvent(this);
637 for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
639 Object value = iter.next();
640 if (value instanceof HttpSessionActivationListener)
642 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
643 listener.sessionDidActivate(event);