001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: BasicSession.java,v 1.3 2007-10-19 10:05:39 sinisa Exp $
022: */
023:
024: package com.lutris.appserver.server.sessionEnhydra;
025:
026: import java.io.Serializable;
027: import java.util.Enumeration;
028: import java.util.Hashtable;
029: import java.util.Vector;
030:
031: import javax.servlet.ServletContext;
032: import javax.servlet.http.HttpSession;
033: import javax.servlet.http.HttpSessionBindingEvent;
034: import javax.servlet.http.HttpSessionBindingListener;
035: import javax.servlet.http.HttpSessionContext;
036:
037: import com.lutris.appserver.server.session.SessionData;
038: import com.lutris.appserver.server.session.SessionException;
039: import com.lutris.appserver.server.session.SessionManager;
040: import com.lutris.appserver.server.user.User;
041:
042: /**
043: * The standard implementation of the StandardSession interface.
044: * The session reflects and instance of a client interacting
045: * with the application. A BasicSession maybe associated
046: * with a user or exist in a unauthenticated state. The
047: * session manager associated with a BasicSession object must be
048: * a StandardSessionManager or a derivation.
049: *
050: * @version $Revision: 1.3 $
051: * @author John Marco
052: * @author Shawn McMurdo
053: */
054: public class BasicSession implements StandardSession, HttpSession,
055: Serializable {
056:
057: // Intentionally transient
058: protected transient StandardSessionManager sessionManager = null;
059:
060: protected User user = null;
061: private String sessionKey = null;
062: private long timeCreated; // Milliseconds.
063: private long timeLastUsed; // Milliseconds.
064: private long timeExpires; // Milliseconds.
065: private long maxIdleTime; // Milliseconds.
066: private long maxNoUserIdleTime; // Milliseconds.
067:
068: /**
069: * The application specific data for this session.
070: */
071: public SessionData data;
072:
073: // The number of references to this session.
074: private int refCount = 0;
075:
076: /**
077: * Need the following constructor in order to serialize?
078: */
079: public BasicSession() {
080: }
081:
082: /**
083: * Construct a new session. Only called by
084: * <CODE>StandardSessionManager</CODE>.
085: *
086: * @param sessionManager
087: * The session manager that will manager this session.
088: * @param sessionKey
089: * The unique session key associated with the session.
090: */
091: protected BasicSession(StandardSessionManager sessionManager,
092: String sessionKey) {
093: this (sessionManager, sessionKey, new SessionData());
094: }
095:
096: /**
097: * Construct a new session. Only called by
098: * <CODE>StandardSessionManager</CODE>.
099: *
100: * @param sessionManager
101: * The session manager that will manager this session.
102: * @param sessionKey
103: * The unique session key associated with the session.
104: * @param sessionData
105: * The session data to associate with this session.
106: */
107: protected BasicSession(StandardSessionManager sessionManager,
108: String sessionKey, SessionData sessionData) {
109: this .sessionManager = sessionManager;
110: this .sessionKey = sessionKey;
111: /*
112: * Set session information.
113: */
114: long now = System.currentTimeMillis();
115: timeCreated = now;
116: timeLastUsed = now;
117: long lifeTime = sessionManager.getMaxSessionLifeTime();
118: if (lifeTime > 0) {
119: // Convert timeExpires from delta seconds to an absolute
120: // millisecond-based date.
121: timeExpires = now + (lifeTime * 1000);
122: } else {
123: // Not using this feature.
124: timeExpires = 0;
125: }
126: maxIdleTime = sessionManager.getMaxSessionIdleTime() * 1000;
127: maxNoUserIdleTime = sessionManager
128: .getMaxNoUserSessionIdleTime() * 1000;
129: this .data = sessionData;
130: initHttpSession();
131: }
132:
133: /**
134: * Set the "last used" timestamp to the current time, resetting the
135: * idle period.
136: */
137: public void touch() {
138: timeLastUsed = System.currentTimeMillis();
139: }
140:
141: /**
142: * Obtain the user associated with this session.
143: *
144: * @return The user object or <CODE>null</CODE> if the
145: * session is not logged in.
146: */
147: public User getUser() {
148: return user;
149: }
150:
151: /**
152: * Set the user associated with this session. This will register the
153: * user with the <CODE>SessionManager</CODE>. <P>
154: *
155: * If it is neccessary to prevent a user from logging on multiple times,
156: * this can be accomplished by synchronizing on the
157: * <CODE>Sessionmanager</CODE> object and enquiring about the number of
158: * users associated with a session. It is then possible to delete other
159: * sessions before adding a new session.
160: *
161: * @param user
162: * the user object to associate with the session.
163: * @exception SessionException
164: * if the user cannot be associated with the session.
165: */
166: public void setUser(User sessionUser) throws SessionException {
167: if (user != null) {
168: sessionManager.unregisterUser(this );
169: }
170: user = sessionUser;
171: if (sessionUser != null) {
172: sessionManager.registerUser(this );
173: }
174: }
175:
176: /**
177: * Remove the user association with this session. This will unregister the
178: * user with the <CODE>SessionManager</CODE>.
179: *
180: * @exception SessionException
181: * if an error occurs.
182: */
183: public void clearUser() throws SessionException {
184: if (user != null) {
185: sessionManager.unregisterUser(this );
186: user = null;
187: }
188: }
189:
190: /**
191: * Obtain the unique key associated with this session.
192: *
193: * @return A String containing the key for this session.
194: */
195: public String getSessionKey() {
196: return sessionKey;
197: }
198:
199: /**
200: * Obtain the session manager associated with this session.
201: *
202: * @return The session manager object.
203: */
204: public SessionManager getSessionManager() {
205: return sessionManager;
206: }
207:
208: /**
209: * Obtain the application specific data for this session.
210: *
211: * @return A SessionData object containing application specific
212: * data for this session.
213: */
214: public SessionData getSessionData() {
215: return data;
216: }
217:
218: /**
219: * Obtain the creation time for this object. The time is in
220: * milliseconds since Midnight, Jan 1, 1970 (epoch).
221: *
222: * @return The creation time since epoch for this object.
223: */
224: public long getTimeCreated() {
225: return timeCreated;
226: }
227:
228: /**
229: * Obtain the time of last use for this object. The time is in
230: * milliseconds since Midnight, Jan 1, 1970 (epoch).
231: *
232: * @return The time of last use since epoch for this object.
233: */
234: public long getTimeLastUsed() {
235: return timeLastUsed;
236: }
237:
238: /**
239: * Obtain the time of expiry for this object. The time is in
240: * milliseconds since Midnight, Jan 1, 1970 (epoch).
241: * Returns zero (or negative) if there is no expiration date.
242: * Note: this is a maximum lifespan for the session, regardless of activity.
243: *
244: * @return The time of expiry since epoch for this object.
245: */
246: public long getTimeExpires() {
247: return timeExpires;
248: }
249:
250: /**
251: * Set the time of expiry for this object. The time is in
252: * milliseconds since Midnight, Jan 1, 1970 (epoch).
253: * Set this value to zero (or less) to indicate that the session does not
254: * have a maximum age.
255: *
256: * @param timeLastUsed The time of expiry since epoch.
257: */
258: public void setTimeExpires(long timeExpires) {
259: this .timeExpires = timeExpires;
260: }
261:
262: /**
263: * Obtain the maximum idle time for this object. Zero (or negative)
264: * indicates that sessions may be idle indefinetly.
265: *
266: * @return The maximum number of milliseconds this session
267: * may be idle.
268: */
269: public long getMaxIdleTime() {
270: return maxIdleTime;
271: }
272:
273: /**
274: * Set the maximum idle time for this object. Set this to zero
275: * (or negative) to disable idle checking.
276: *
277: * @param maxIdleTime The maximum number of milliseconds this
278: * session may be idle, or zero (or negative) to allow sessions to be idle
279: * indefinetly.
280: */
281: public void setMaxIdleTime(long maxIdleTime) {
282: this .maxIdleTime = maxIdleTime;
283: }
284:
285: /**
286: * Obtain the maximum idle time when a <CODE>User</CODE> object
287: * is not associated with the session. Zero (or negative) indicates that
288: * sessions may be idle indefinetly.
289: *
290: * @return The maximum number of milliseconds this session
291: * may be idle.
292: */
293: public long getMaxNoUserIdleTime() {
294: return maxNoUserIdleTime;
295: }
296:
297: /**
298: * set the maximum idle time when a <CODE>User</CODE> object
299: * is not associated with the session. Set this to zero (or negative) to
300: * disable idle checking.
301: *
302: * @param maxIdleTime The maximum number of milliseconds this
303: * session may be idle.
304: */
305: public void setMaxNoUserIdleTime(long maxIdleTime) {
306: this .maxNoUserIdleTime = maxIdleTime;
307: }
308:
309: /**
310: * Returns true if the session is new. A session is new if it has
311: * been created but a client cookie was never used to reference it.
312: * In other words, the cookie associated with the session was
313: * never submitted by a client.
314: *
315: * @return true if the session is new.
316: */
317: public boolean isNew() {
318: checkValid();
319: return (timeCreated == timeLastUsed);
320: }
321:
322: /**
323: * Returns the number of active references to this object.
324: *
325: * @return
326: * the number of references.
327: */
328: public int getRefCount() {
329: return refCount;
330: }
331:
332: /**
333: * Returns the number of active references to this object.
334: *
335: * @return
336: * the number of references.
337: */
338: public int incrementRefCount() {
339: refCount++;
340: return refCount;
341: }
342:
343: /**
344: * Returns the number of active references to this object.
345: *
346: * @return
347: * the number of references.
348: */
349: public int decrementRefCount() {
350: if (refCount > 0) {
351: refCount--;
352: }
353: return refCount;
354: }
355:
356: /**
357: * Prints a string representation of this object.
358: *
359: * @return
360: * the string representation.
361: */
362: public String toString() {
363: StringBuffer str = new StringBuffer();
364: str.append("{");
365: str.append("sessionKey=" + sessionKey);
366: str.append(", ");
367: if (user != null) {
368: str.append("user=" + user.getName());
369: } else {
370: str.append("user=" + user);
371: }
372: str.append(", ");
373: str.append("timeCreated=" + timeCreated);
374: str.append(", ");
375: str.append("timeLastUsed=" + timeLastUsed);
376: str.append(", ");
377: str.append("timeExpires=" + timeExpires);
378: str.append(", ");
379: str.append("maxIdleTime=" + maxIdleTime);
380: str.append(", ");
381: str.append("maxNoUserIdleTime=" + maxNoUserIdleTime);
382: str.append(", ");
383: str.append("sessionData=" + data);
384: str.append("}");
385: return str.toString();
386: }
387:
388: public HttpSession getHttpSession() {
389: // should be a ref to another object
390: return this ;
391: }
392:
393: public void setHttpSession(HttpSession httpSession) {
394: }
395:
396: // The HttpSession interface implementation
397: //
398:
399: Hashtable attributes;
400: boolean valid;
401:
402: //private Context context; //DACHA
403:
404: private void initHttpSession() {
405: attributes = new Hashtable();
406: valid = true;
407: // context = null;//DACHA
408: }
409:
410: /* DACHA
411: public void setContext(Context context) {
412: this.context = context;
413: }
414: */
415: public long getCreationTime() {
416: checkValid();
417: return getTimeCreated();
418: }
419:
420: public String getId() {
421: return getSessionKey();
422: }
423:
424: public long getLastAccessedTime() {
425: checkValid();
426: return getTimeLastUsed();
427: }
428:
429: public void setMaxInactiveInterval(int interval) {
430: checkValid();
431: // convert from seconds to miliseconds
432: setMaxIdleTime(interval * 1000L);
433: }
434:
435: public int getMaxInactiveInterval() {
436: checkValid();
437: // convert from miliseconds to seconds
438: return (int) (getMaxIdleTime() / 1000);
439: }
440:
441: public HttpSessionContext getSessionContext() {
442: checkValid();
443: //return new SessionContextImpl(); //DACHA
444: return null;
445: }
446:
447: public ServletContext getServletContext() {
448: //FIXME to support servlet 2.3
449: return null;
450: }
451:
452: public Object getAttribute(String name) {
453: checkValid();
454: // Object o = attributes.get(name);
455: return attributes.get(name);
456: }
457:
458: public Object getValue(String name) {
459: checkValid();
460: return getAttribute(name);
461: }
462:
463: public Enumeration getAttributeNames() {
464: checkValid();
465: Hashtable attributesClone = (Hashtable) attributes.clone();
466: return (Enumeration) attributesClone.keys();
467: }
468:
469: public String[] getValueNames() {
470: checkValid();
471: Enumeration e = getAttributeNames();
472: Vector names = new Vector();
473: while (e.hasMoreElements()) {
474: names.addElement(e.nextElement());
475: }
476: String[] valueNames = new String[names.size()];
477: names.copyInto(valueNames);
478: return valueNames;
479: }
480:
481: public void setAttribute(String name, Object value) {
482: checkValid();
483: if (name == null) {
484: String msg = "null value";
485: throw new IllegalArgumentException(msg);
486: }
487: removeAttribute(name);
488: if (value != null
489: && value instanceof HttpSessionBindingListener) {
490: HttpSessionBindingEvent e = new HttpSessionBindingEvent(
491: this , name);
492: ((HttpSessionBindingListener) value).valueBound(e);
493: }
494: attributes.put(name, value);
495: }
496:
497: public void putValue(String name, Object value) {
498: checkValid();
499: setAttribute(name, value);
500: }
501:
502: public void removeAttribute(String name) {
503: checkValid();
504: if (name == null) {
505: String msg = "null value";
506: throw new IllegalArgumentException(msg);
507: }
508:
509: Object o = attributes.get(name);
510: if (o instanceof HttpSessionBindingListener) {
511: HttpSessionBindingEvent e = new HttpSessionBindingEvent(
512: this , name);
513: ((HttpSessionBindingListener) o).valueUnbound(e);
514: }
515: attributes.remove(name);
516: }
517:
518: public void removeValue(String name) {
519: checkValid();
520: removeAttribute(name);
521: }
522:
523: public void invalidate() {
524: checkValid();
525: Enumeration enumeration = attributes.keys();
526: while (enumeration.hasMoreElements()) {
527: String name = (String) enumeration.nextElement();
528: removeAttribute(name);
529: }
530: // valid = false;
531: try {
532: sessionManager.deleteSession(this );
533: } catch (SessionException se) {
534: se.printStackTrace();
535: }
536: // 2003/01/23 Session is nvalid Error fixed
537: valid = false;
538: }
539:
540: private void checkValid() {
541: if (!valid) {
542: String msg = "Session is invalid.";
543: throw new IllegalStateException(msg);
544: }
545:
546: }
547:
548: }
|