Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/RuntimeCollective/webapps/bean/Session.java


1   /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/bean/Session.java,v 1.16 2003/09/30 15:13:09 joe Exp $
2    * $Revision: 1.16 $
3    * $Date: 2003/09/30 15:13:09 $
4    *
5    * ====================================================================
6    *
7    * Josephine : http://www.runtime-collective.com/josephine/index.html
8    *
9    * Copyright (C) 2003 Runtime Collective
10   * 
11   * This product includes software developed by the
12   * Apache Software Foundation (http://www.apache.org/).
13   *
14   * This library is free software; you can redistribute it and/or
15   * modify it under the terms of the GNU Lesser General Public
16   * License as published by the Free Software Foundation; either
17   * version 2.1 of the License, or (at your option) any later version.
18   *
19   * This library is distributed in the hope that it will be useful,
20   * but WITHOUT ANY WARRANTY; without even the implied warranty of
21   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22   * Lesser General Public License for more details.
23   *
24   * You should have received a copy of the GNU Lesser General Public
25   * License along with this library; if not, write to the Free Software
26   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27   *
28   */
29  
30  package com.RuntimeCollective.webapps.bean; 
31  
32  import java.sql.SQLException;
33  import java.util.Date;
34  
35  import com.RuntimeCollective.webapps.RuntimeParameters;
36  import com.RuntimeCollective.webapps.bean.EntityBean;
37  import com.RuntimeCollective.webapps.bean.DateBean;
38  import com.RuntimeCollective.webapps.bean.User;
39  import com.RuntimeCollective.webapps.RuntimeDataSource;
40  import com.RuntimeCollective.webapps.EntityBeanStore;
41  import com.RuntimeCollective.webapps.DateUtils;
42  import com.RuntimeCollective.permission.SecurityConstants;
43  
44  import java.text.SimpleDateFormat;
45  import java.util.ArrayList;
46  import java.util.Iterator;
47  import java.util.List;
48  import javax.servlet.http.HttpServletRequest;
49  
50  
51  /** 
52   * The Session object is the identification that a User has logged in, and when.
53   * <p>
54   * It is particularly useful in conjunction with TrackedUsers. EditorCheckLogon supports it,
55   * but CheckLogon doesn't (yet).
56   * <p>
57   * It is recommended to use the updateSessionTag at the top of all JSP pages, for the Session to be
58   * kept up-to-date.
59   * 
60   * @version $Id: Session.java,v 1.16 2003/09/30 15:13:09 joe Exp $ 
61   */ 
62  public class Session implements EntityBean { 
63  
64      /** The name of the database table for this bean type. */
65      public static final String DATABASE_TABLE = "user_session";
66  
67      /* The name of this bean within the <code>EntityBeanStore</code>. */
68      public static String ENTITY_NAME = Session.class.getName();
69  
70      /* The key under which this Session objects are stored under the User's HttpSessions. */
71      public static String SESSION_KEY = "sessionForThisSession";
72  
73      /* The key under which the no of minutes until TimeOut is stored. */
74      public static String TIMEOUT_KEY = "noMinutesUntilSessionTimeOut";
75  
76      /* Where the name of the page used to redirect after the Session has timed out, is stored. */
77      public static String TIMEOUT_PAGE_KEY = "redirectPageAfterSessionTimeOut";
78  
79      /** Get the entity name of this entity bean, used to identify this bean within the <code>EntityBeanStore</code>.
80       * And also optionally used as the key for this bean on the HttpSession.
81       */
82      public String getEntityName() { return ENTITY_NAME; }
83  
84  
85      private static final String SELECT_DATA = "select id, user_id, creation_date, last_used_date FROM user_session WHERE id=";
86      private static final String DELETE_FROM = "delete from ";
87      private static final String WHERE_ID = " where id = ";
88      private static final String WHERE_T_ID = " t where t.id = ";
89      private static final String USER_ID = "user_id";
90      private static final String CREATION_DATE = "creation_date";
91      private static final String LAST_USED_DATE = "last_used_date";
92      private static final String AND = " and ";
93      private static final String SPACE = " ";
94      private static final String SPACE_OPEN = " (";
95      private static final String CLOSE = ")";
96      private static final String LOGON_USER_KEY = "logonUserKey";
97      private static final String UPDATE = "update ";
98      private static final String SET_LAST_USED_DATE = " set last_used_date = ";
99      private static final String SELECT_ID = "select id from ";
100     private static final String WHERE_USER = " where user_id = ";
101     private static final String LAST_USED = " - last_used_date >= 60 * ";
102 
103     // == Constructors ================================================= 
104 
105     /**
106     /* Called to make a new session.
107      */
108     public Session() throws SQLException {
109   this.id = RuntimeDataSource.nextId();
110   // Set creation date to now
111   setCreateDate( new Date() );
112     }
113 
114     /** Get a sesssion from the RuntimeDataSource, given an id.
115      * @param id ID of the session.
116      * @exception SQLException is thrown if no such session exists.
117      */
118     public Session(int id) throws SQLException {
119         Object[] result = RuntimeDataSource.queryRow(SELECT_DATA+id);
120         if ( result != null ) {
121             setId( Integer.parseInt( result[0].toString() ) );
122             setTheUser( (User) RuntimeParameters.getStore().get(User.class.getName(), Integer.parseInt( result[1].toString() ) ) );
123             setCreateDate( DateBean.fromSql( result[2] ) );
124             if (result[3] != null)
125                 setLastUsedDate(DateBean.fromSql(result[3]));
126             else
127                 setLastUsedDate(null);
128         }
129     }
130 
131 
132     // == Properties =================================================== 
133 
134     /** The session's User. */ 
135     protected User theUser = null; 
136     /** Get the session's User. */ 
137     public User getTheUser() { return this.theUser; } 
138     /** Set the session's User. */ 
139     public void setTheUser(User theUser) { this.theUser = theUser; } 
140 
141     /** The date of the session */ 
142     protected Date createDate = null; 
143     /** Get the date of the session */ 
144     public Date getCreateDate() { return this.createDate; } 
145     /** Set the date of the session */ 
146     public void setCreateDate(Date createDate) { this.createDate = createDate; } 
147 
148     /** The last used date of the session */ 
149     protected Date lastUsedDate = null; 
150     /** Get the date of the session */ 
151     public Date getLastUsedDate() { return this.lastUsedDate; } 
152     /** Set the date of the session */ 
153     public void setLastUsedDate(Date lastUsedDate) { this.lastUsedDate = lastUsedDate; } 
154 
155     /** Whether this Session has timed out.
156      * @return a boolean
157      */
158     public boolean hasTimedOut() {
159   return (System.currentTimeMillis() - getLastUsedDate().getTime() > timeout_span_millis);
160     }
161 
162     /** No of minutes until time out. */
163     protected int timeout_span_mins = Integer.parseInt(RuntimeParameters.get(TIMEOUT_KEY));
164 
165     /** No of millis until time out. */
166     protected int timeout_span_millis = timeout_span_mins * 60000;
167 
168     /** The session id */ 
169     protected int id = -1; 
170     /** Get the session id */ 
171     public int getId() { return this.id; } 
172     /** Set the session id */ 
173     public void setId(int id) { this.id = id; } 
174 
175     /** Save this session */
176     public void save() throws SQLException {
177   // Make an entry in user_session
178 
179   // Check if theUser is null; if so, there's a problem!
180   if (getTheUser() == null) {
181       throw new SQLException ("Cannot save a session that does not have a user!");
182   }
183   Integer theUserId = new Integer(getTheUser().getId());
184 
185   RuntimeDataSource.save(getId(), DATABASE_TABLE, new String[]{ USER_ID, CREATION_DATE, LAST_USED_DATE }, new Object[] { theUserId, getCreateDate(), getLastUsedDate() });
186     }
187 
188     /** Tear down this session */
189     public void delete() throws SQLException {
190   // Deletes from user_session
191         RuntimeDataSource.update(DELETE_FROM+DATABASE_TABLE+WHERE_ID+getId());
192     }
193 
194     /** Log a user in to the website.
195      * Put their User object on the HttpSession, create a new <code>Session</code>, and update the user's
196      * last login date on the Pivotal database.
197      */
198     public static Session logUserIn(User user, HttpServletRequest request) throws SQLException {
199 
200   if (user==null) {
201       return null;
202   }
203 
204   // Make a new session
205   Session newSession = (Session) RuntimeParameters.getStore().create(Session.class.getName());
206   newSession.setTheUser(user);
207   Date now = new Date();
208   newSession.setCreateDate(now);
209   newSession.setLastUsedDate(now);
210   RuntimeParameters.getStore().save(Session.class.getName(), newSession.getId());
211 
212   // Put the user on the session, in the correct place
213   request.getSession().setAttribute(RuntimeParameters.get(LOGON_USER_KEY), user);
214   request.getSession().setAttribute(SecurityConstants.AUTH_TOKEN, new Integer(user.getId()));
215 
216   return newSession;
217     }
218 
219     /**
220      * Update the last used date in the db, by hitting it only once.
221      * This to make UpdateSessionTag more efficient.
222      */
223     public void doQuickUpdate() {
224         try {
225             RuntimeDataSource.update((new StringBuffer(100)).append(UPDATE).append(DATABASE_TABLE).append(SET_LAST_USED_DATE).append(RuntimeDataSource.toSqlString(lastUsedDate)).append(WHERE_ID).append(id).toString());
226         } catch (SQLException e) {
227             RuntimeParameters.logError(this, "Could not perform doQuickUpdate.", e);
228         }
229     }
230 
231 
232     /** The date format used. */
233     protected static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
234 
235 
236 
237     /**
238      * Delete all expired Sessions for a given User.
239      */
240     public static void deleteExpiredSessionsForUser(User user) {
241 
242         if (user == null)
243             return;
244 
245         int userId = user.getId();
246         
247         int returnVal = 0;
248         String nowString = df.format(DateUtils.getCurrentDate());
249         Session session;
250         EntityBeanStore ebs = RuntimeParameters.getStore();
251         int[] ids;
252         
253         try {
254             ids = RuntimeDataSource.queryInts((new StringBuffer(90))
255                                               .append(SELECT_ID)
256                                               .append(Session.DATABASE_TABLE)
257                                               .append(WHERE_USER)
258                                               .append(userId)
259                                               .append(AND)
260                                               .append(RuntimeDataSource.toSqlString(new Date()))
261                                               .append(LAST_USED)
262                                               .append(RuntimeParameters.get(Session.TIMEOUT_KEY))
263                                               .toString());
264 
265             for (int i=0; i < ids.length; i++) {
266                 session = (Session) ebs.get(Session.class.getName(), ids[i]);
267                 RuntimeParameters.log(session, "Session deleted by Session.deleteExpiredSessionsForUser.");
268                 ebs.delete(session);
269             }
270 
271         } catch (SQLException sqle) {
272             RuntimeParameters.logDebug("Session", "Unable to get number of active sessions from the database.");
273         }
274     }
275     
276 
277     /**
278      * Gets the number of active sessions, for all users.
279      */
280     public static int getNumberOfActiveSessions() {   
281         return getActiveSessionsList().size();
282     }
283     
284 
285     /**
286      * Gets an Iterator of all active User beans in the system.
287      */
288     public static Iterator getUsersWithActiveSessions() {
289         return getUsersWithActiveSessionsAsList().iterator();
290     }
291 
292     /**
293      * Gets a List of all active User beans in the system.
294      */
295     public static List getUsersWithActiveSessionsAsList() {
296         List sessions = getActiveSessionsList();
297         List users = new ArrayList(sessions.size());
298         for (int i=0; i<sessions.size(); i++) {
299             users.add(((Session) sessions.get(i)).getTheUser());
300         }
301         return users;
302     }
303 
304     /**
305      * Gets a List of all active session.
306      */
307     public static List getActiveSessionsList() {
308 
309         int[] ids;
310         ArrayList objects = new ArrayList();
311         String nowString = df.format(DateUtils.getCurrentDate());
312         
313         try {
314             ids = RuntimeDataSource.queryInts((new StringBuffer(150)).append("select id from ").append(DATABASE_TABLE).append(" where last_used_date > timestamp without time zone '").append(nowString).append("' - interval '").append(RuntimeParameters.get(TIMEOUT_KEY)).append(" minutes'").toString());
315             for (int i=0; i < ids.length; i++) {
316                 objects.add(RuntimeParameters.getStore().get(Session.class.getName(), ids[i]));
317             }
318         }
319         catch (SQLException sqle) {
320             RuntimeParameters.logDebug("Session", "Unable to get active sessions from the database.");
321         }                
322 
323         return objects;
324     }
325 }
326