KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > sessions > Session


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19
20 package org.openharmonise.rm.sessions;
21
22 import java.security.SecureRandom JavaDoc;
23 import java.sql.*;
24 import java.text.SimpleDateFormat JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.logging.*;
27
28 import javax.servlet.http.HttpServletRequest JavaDoc;
29
30 import org.openharmonise.commons.cache.*;
31 import org.openharmonise.commons.dsi.*;
32 import org.openharmonise.commons.dsi.dml.*;
33 import org.openharmonise.rm.*;
34 import org.openharmonise.rm.config.*;
35 import org.openharmonise.rm.dsi.DataStoreObject;
36 import org.openharmonise.rm.factory.*;
37 import org.openharmonise.rm.logging.*;
38 import org.openharmonise.rm.publishing.*;
39 import org.openharmonise.rm.resources.AbstractObject;
40 import org.openharmonise.rm.resources.publishing.Template;
41 import org.openharmonise.rm.resources.users.User;
42 import org.openharmonise.rm.security.authentication.*;
43 import org.w3c.dom.*;
44
45
46 /**
47  * Represents a user session within the system, with an
48  * associated timeout value.
49  *
50  * Through the implementation of <code>Publishable</code> a user
51  * can log in and out, i.e. create and delete sessions, in a web
52  * session.
53  *
54  * @author Michael Bell
55  * @version $Revision: 1.3 $
56  *
57  */

58 public class Session implements DataStoreObject, Publishable {
59
60     //DB constants
61
protected static final String JavaDoc CLMN_SESSION_ID = "id";
62     protected static final String JavaDoc CLMN_SESSION_DATE = "date";
63     protected static final String JavaDoc CLMN_SESSION_TIMEOUT = "timeout";
64     protected static final String JavaDoc CLMN_USER_ID = "users_id";
65     protected static final String JavaDoc CLMN_TYPE = "type";
66     protected static final String JavaDoc TBL_SESSION = "session";
67
68     //XML constants
69
public static final String JavaDoc TAG_SESSION = "Session";
70     public static final String JavaDoc TAG_LOGON = "Logon";
71     public static final String JavaDoc TAG_LOGOFF = "Logoff";
72
73     public static final String JavaDoc DEFAULT_TIMEOUT_PNAME = "DEFAULT_TIMEOUT";
74     private static final int m_nDefaultNumChars = 20;
75     private static final String JavaDoc sCharBase =
76         "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
77     private static final String JavaDoc DB_DATEFORMAT = "MM-dd-yyyy HH:mm:ss.SSS";
78     private AbstractDataStoreInterface m_dsi;
79
80     public static String JavaDoc LAG_PERCENT_PNAME = "LAGTIME_PERCENT";
81     public static String JavaDoc PREFIX_SEPARATOR = "_";
82     public static String JavaDoc DEFAULT_USER_PREFIX = "D" + PREFIX_SEPARATOR;
83     public static String JavaDoc LOGGED_IN_USER_PREFIX = "L" + PREFIX_SEPARATOR;
84
85     protected CachePointer m_usrPtr = null;
86     protected String JavaDoc m_sSessionId = "";
87     protected java.util.Date JavaDoc m_dtTimeout;
88     protected boolean m_bTimedOut = false;
89     protected boolean m_bDefaultUser = true;
90     
91     //default to 1
92
protected int DEFAULT_USER_ID = 1;
93     protected int m_nTimeout = 60;
94     protected int m_nLagPercent = -1;
95     protected String JavaDoc sDefaultLagPercent = "25";
96     protected java.util.Date JavaDoc m_dtLagTime;
97     
98     /**
99      * Logger for this class
100      */

101     private static final Logger m_logger = Logger.getLogger(Session.class.getName());
102
103     public static User m_QueryUser = null;
104
105     static {
106         m_QueryUser = new User();
107     }
108
109     /**
110      * Constructs a new empty session.
111      * @param dbinterf
112      */

113     public Session(AbstractDataStoreInterface dbinterf) {
114         m_dsi = dbinterf;
115     }
116
117     /**
118      * Standard constructor for a new <code>Session</code> object with the given data.
119      *
120      * @param dbinterf
121      * @param usr
122      * @param sessionId
123      * @param timeout
124      * @throws SessionException
125      */

126     public Session(
127         AbstractDataStoreInterface dbinterf,
128         User usr,
129         String JavaDoc sessionId,
130         int timeout)
131         throws SessionException {
132         m_dsi = dbinterf;
133
134         try {
135             m_usrPtr = CacheHandler.getInstance(dbinterf).getCachePointer(usr);
136         } catch (CacheException e) {
137             throw new SessionException(e.getLocalizedMessage(),e);
138         }
139         this.m_sSessionId = sessionId;
140
141         setTimeout(timeout);
142         try {
143             setLagTime(timeout);
144         } catch (ConfigException e) {
145             throw new SessionException("Error occured setting lag time", e);
146         }
147
148         if (isSessionIdUnique(sessionId) == false) {
149             m_logger.logp(Level.INFO, this.getClass().getName(), "Session", "Session id " + sessionId + " is not unique and therefore not valid");
150             throw new InvalidSessionIdException(
151                 "Invalid session id - " + sessionId);
152         }
153
154         save();
155     }
156
157     /**
158      * Constructs a session from a known session id.
159      * @param dbinterf
160      * @param sSessionId
161      */

162     public Session(AbstractDataStoreInterface dbinterf, String JavaDoc sSessionId) throws SessionException {
163         m_dsi = dbinterf;
164
165         setDetailsFromId(sSessionId);
166     }
167
168     /**
169      * Constructs a new sessio with the specified timeout.
170      * with a default user.
171      * @param dbinterf
172      * @param timeout
173      */

174     public Session(AbstractDataStoreInterface dbinterf, int timeout) throws SessionException {
175         m_dsi = dbinterf;
176
177         User user = null;
178         try {
179             user = (User) HarmoniseObjectFactory.instantiateHarmoniseObject(dbinterf, User.class.getName(), DEFAULT_USER_ID);
180         } catch (HarmoniseFactoryException e) {
181             throw new SessionException(e);
182         }
183         initialize(user, timeout);
184     }
185
186     /**
187      * Constructs a new session object for the given user and timeout.
188      * @param dbinterf
189      * @param user
190      * @param timeout
191      */

192     public Session(AbstractDataStoreInterface dbinterf, User user, int timeout)
193         throws SessionException {
194         m_dsi = dbinterf;
195         initialize(user, timeout);
196     }
197
198     /**
199      * Removes session id prefix if found.
200      * For example:<blockquote><pre>D_hHk1IsvRlfC1iksMH6lt becomes hHk1IsvRlfC1iksMH6lt</pre></blockquote>
201      *
202      * Note: Used to save session id in the database and cache.
203      *
204      * @param sSessId session id.
205      * @return session id without prefix.
206      */

207     public static String JavaDoc removeSessionIdPrefix(String JavaDoc sSessId) {
208         String JavaDoc newSessId = sSessId;
209         int index = sSessId.indexOf(PREFIX_SEPARATOR);
210
211         if (index > 0) {
212             newSessId = sSessId.substring(index + 1);
213         }
214
215         return newSessId;
216     }
217
218     /**
219      * Returns the id of this session.
220      *
221      * @return session id variable.
222      */

223     public String JavaDoc getSessionId() {
224         return m_sSessionId;
225     }
226
227     /**
228      * Returns the user associated with this session.
229      *
230      * @return User variable.
231      */

232     public User getUser() throws DataAccessException {
233         User usr = null;
234         
235         try {
236             usr = (User) m_usrPtr.getObject();
237         } catch (CacheException e) {
238             throw new DataAccessException(e.getLocalizedMessage(),e);
239         }
240         
241         return usr;
242     }
243
244
245     /**
246      * Register the servlet request with the session so the session has access to request info.
247      */

248     public void registerHttpRequest(HttpServletRequest JavaDoc request) {
249
250     }
251
252     /**
253      * Gets session id from state and if found validates against object session id.
254      * Checks for log off, switching session id prefix to default if logging off.
255      * Updates timeout, throwing error if timed out unless default user.
256      * Checks for log on, logging on user if found and switching session id prefix to logged on.
257      * If no session id was found in the state, <code>initialize(user, nTimeout)</code> is called.
258      * Otherwise, <code>updateUser(user)</code> is called.
259      *
260      * @exception SessionException
261      * @param state
262      * @param nTimeout
263      */

264     public void processState(State state, int nTimeout)
265         throws SessionException {
266         String JavaDoc sSessId = "";
267         boolean bHasSessionId = false;
268
269         if (state == null) {
270             throw new SessionException("Null state object");
271         }
272
273         NodeList nodeSession = state.getElementsByTagName(TAG_SESSION);
274
275         if (nodeSession.getLength() > 0) {
276             // get the session id from the session tag, throw
277
//exception if absent or different to current session id
278
Element sessEl = (Element) nodeSession.item(0);
279             sSessId = sessEl.getAttribute(AbstractObject.ATTRIB_ID);
280
281             if ((sSessId.length() == 0) && (m_sSessionId.length() == 0)) {
282                 throw new InvalidSessionIdException("Not found a Session Id");
283             }
284
285             if (sSessId.length() > 0) {
286                 if (!m_sSessionId.equals(sSessId)) {
287                     throw new InvalidSessionIdException(
288                         "Attempt to validate Session ID: "
289                             + sSessId
290                             + " against Session: "
291                             + m_sSessionId);
292                 }
293             }
294
295             bHasSessionId = true;
296         }
297
298         // check for logoff tag before checking timeout
299
// never want logging off user to time out
300
NodeList nodes = state.getElementsByTagName(TAG_LOGOFF);
301
302         if (nodes.getLength() > 0) {
303
304             try {
305                 logoff((Element) nodes.item(0), getSessionId());
306             } catch (DataStoreException e) {
307                 throw new SessionException("Error occured with log off",e);
308             }
309
310             //switch prefix to default user
311
m_sSessionId = removeSessionIdPrefix(m_sSessionId);
312             m_sSessionId = DEFAULT_USER_PREFIX + m_sSessionId;
313         }
314
315         if (bHasSessionId) {
316             // update timeout, if timed out will throw exception unless default user
317
updateTimeout(nTimeout);
318         }
319
320         // check for logon tag in state after checking timeout
321
// so that logging in user switching from default user
322
// will never time out
323
boolean bIsLogOn = false;
324         NodeList nodeLogOn = state.getElementsByTagName(TAG_LOGON);
325
326         if (nodeLogOn.getLength() > 0) {
327             bIsLogOn = true;
328         }
329
330         //user logging on
331
if (bIsLogOn == true) {
332
333             User user = logon((Element) nodeLogOn.item(0), state);
334
335             if (bHasSessionId
336                 || (this.m_sSessionId != null
337                     && this.m_sSessionId.length() > 0)) {
338                 // user already has session so update
339
try {
340                     updateUser(user);
341                 } catch (DataStoreException e) {
342                     throw new SessionException("Error occured updating user",e);
343                 }
344             } else {
345                 // create new session
346
initialize(user, nTimeout);
347
348                 bHasSessionId = true;
349             }
350
351             //switch prefix to default user
352
m_sSessionId = removeSessionIdPrefix(m_sSessionId);
353             m_sSessionId = LOGGED_IN_USER_PREFIX + m_sSessionId;
354
355             // set default user flag
356
} else if (
357             bHasSessionId == false
358                 && (this.m_sSessionId == null
359                     || this.m_sSessionId.length() == 0)) {
360             // create new session for default user
361

362             User user = getDefaultUser();
363             sSessId = initialize(user, nTimeout);
364
365             bHasSessionId = true;
366         }
367
368     }
369
370
371
372     /**
373      * Saves session id, user key and timeout values to database.
374      *
375      * @throws InvalidSessionIdException if there is no session id or user.
376      */

377     public void save() throws SessionException {
378         ResultSet rs = null;
379         InsertStatement insert = new InsertStatement();
380         
381         User usr = null;
382         
383         try {
384             usr = getUser();
385         } catch (DataAccessException e) {
386             throw new SessionException(e.getLocalizedMessage(),e);
387         }
388
389         if ((m_sSessionId.length() > 0) && (usr != null)) {
390             // insert this entry WITHOUT session id prefix
391
try {
392                 insert.addColumnValue(
393                     getInstanceColumnRef(CLMN_SESSION_ID),
394                     removeSessionIdPrefix(m_sSessionId));
395                 insert.addColumnValue(
396                     getInstanceColumnRef(CLMN_USER_ID),
397                 usr.getId());
398                 insert.addColumnValue(
399                     getInstanceColumnRef(CLMN_SESSION_TIMEOUT),
400                     m_dtTimeout);
401
402                 m_dsi.execute(insert);
403             } catch (DataStoreException e) {
404                 
405                 m_logger.log(Level.WARNING, e.getMessage(), e);
406                 throw new SessionException("Error occured saving session", e);
407             }
408         } else {
409             throw new InvalidSessionIdException("Error saving session");
410         }
411     }
412
413
414     /**
415      * Records an event.
416      *
417      * @param nEvent
418      * @param sMessage
419      * @param nTimeout
420      * @throws SessionException
421      * @deprecated
422      */

423     public void recordEvent(LogEvent event) throws SessionException {
424         try {
425             event.setSession(this);
426             
427             EventLogController.getInstance().logEvent(event);
428         } catch (LogException e) {
429             throw new SessionException("Error logging event",e);
430         }
431         
432     }
433
434
435     /**
436      * Generates a SessionId with default number of characters.
437      *
438      * @return int the session id generated
439      */

440     public static String JavaDoc generateSessionId() {
441         return (generateSessionId(m_nDefaultNumChars));
442     }
443
444
445     /* (non-Javadoc)
446      * @see java.lang.Object#toString()
447      */

448     public String JavaDoc toString() {
449         StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc();
450         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc(DB_DATEFORMAT);
451
452         try {
453             strbuf
454                 .append(" [")
455                 .append("Session_id:")
456                 .append(m_sSessionId)
457                 .append(" for user_id:")
458                 .append(m_usrPtr.getKey())
459                 .append(", timeout:")
460                 .append(
461                     (m_dtTimeout != null)
462                         ? formatter.format(m_dtTimeout)
463                         : "null")
464                 .append(", Timed Out?:")
465                 .append(m_bTimedOut)
466                 .append(", lagtime:")
467                 .append(
468                     (m_dtLagTime != null)
469                         ? formatter.format(m_dtLagTime)
470                         : "null")
471                 .append(", Lag timed out?:")
472                 .append(isLagTimedOut())
473                 .append(" ]");
474         } catch (Exception JavaDoc e) {
475             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
476         }
477
478         return strbuf.toString();
479     }
480
481     /**
482      * Removes session from the database and cache.
483      *
484      * @throws SessionException
485      */

486     public void delete() throws SessionException {
487
488         try {
489             DeleteStatement delete = new DeleteStatement();
490             ColumnRef crSessId =
491                 new Session(m_dsi).getInstanceColumnRef(CLMN_SESSION_ID);
492             delete.addWhereCondition(crSessId, "=", m_sSessionId);
493             m_dsi.execute(delete);
494             
495             WebPageEngineCache.getInstance(m_dsi).changeObject(
496                 m_sSessionId,
497                 AbstractCache.CHANGE_DELETE,
498                 this);
499         } catch (DataStoreException e) {
500             throw new SessionException("Error occured deleting from DB",e);
501         } catch (CacheException e) {
502             throw new SessionException("Error getting webpage engine cache",e);
503         }
504     }
505
506
507     /* (non-Javadoc)
508      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceColumnRef(java.lang.String, boolean)
509      */

510     public ColumnRef getInstanceColumnRef(String JavaDoc sColumn, boolean bIsHist)
511         throws DataStoreException {
512         return getInstanceColumnRef(sColumn);
513     }
514
515     /* (non-Javadoc)
516      * @see org.openharmonise.rm.dsi.DataStoreObject#getInstanceJoinConditions(java.lang.String, boolean)
517      */

518     public JoinConditions getInstanceJoinConditions(
519         String JavaDoc sObjectTag,
520         boolean bIsOuter)
521         throws DataStoreException {
522         // nothing to do
523
return null;
524     }
525
526     /* (non-Javadoc)
527      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement)
528      */

529     public List JavaDoc processResultSet(CachedResultSet resultSet,SelectStatement select) {
530         //nothing to do
531
return null;
532     }
533
534     /* (non-Javadoc)
535      * @see org.openharmonise.rm.dsi.DataStoreObject#processResultSet(org.openharmonise.commons.dsi.CachedResultSet, org.openharmonise.commons.dsi.dml.SelectStatement, int)
536      */

537     public List JavaDoc processResultSet(CachedResultSet resultSet,SelectStatement select, int limit) {
538         // nothing to do
539
return null;
540     }
541
542     /* (non-Javadoc)
543      * @see org.openharmonise.rm.dsi.DataStoreObject#getDBTableName()
544      */

545     public String JavaDoc getDBTableName() {
546         return TBL_SESSION;
547     }
548     
549     /**
550      * Returns a Session tag with a session id attribute.
551      *
552      * @param output
553      * @param state
554      * @return
555      * @throws PublishException
556      */

557     public Element publish(HarmoniseOutput output) throws PublishException {
558         Element xnSession = output.createElement(TAG_SESSION);
559         xnSession.setAttribute(AbstractObject.ATTRIB_ID, getSessionId());
560
561         return xnSession;
562     }
563
564     /* (non-Javadoc)
565      * @see org.openharmonise.rm.publishing.Publishable#publish(org.openharmonise.rm.resources.publishing.Template, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
566      */

567     public Element publish(Template template, HarmoniseOutput output, State state) throws PublishException {
568         Element resultEl = null;
569
570         try {
571
572             resultEl =
573                 publish(template.getTemplateRootElement(), output, state);
574         } catch (DataAccessException e) {
575             throw new PublishException(e);
576         }
577
578         return resultEl;
579     }
580
581     /* (non-Javadoc)
582      * @see org.openharmonise.rm.publishing.Publishable#publish(org.w3c.dom.Element, org.openharmonise.rm.publishing.HarmoniseOutput, org.openharmonise.rm.publishing.State)
583      */

584     public Element publish(Element topEl, HarmoniseOutput output, State state) throws PublishException {
585         Element xnSession = output.createElement(TAG_SESSION);
586         xnSession.setAttribute(AbstractObject.ATTRIB_ID, getSessionId());
587
588         return xnSession;
589     }
590
591     /* (non-Javadoc)
592      * @see org.openharmonise.rm.publishing.Publishable#populate(org.w3c.dom.Element, org.openharmonise.rm.publishing.State)
593      */

594     public void populate(Element xmlElement, State state) throws PopulateException {
595         if(xmlElement.getTagName().equals(TAG_SESSION)) {
596             m_sSessionId = xmlElement.getAttribute(AbstractObject.ATTRIB_ID);
597         }
598         
599     }
600
601     /* (non-Javadoc)
602      * @see org.openharmonise.rm.publishing.Publishable#getTagName()
603      */

604     public String JavaDoc getTagName() {
605         return TAG_SESSION;
606     }
607     
608
609     /* (non-Javadoc)
610      * @see org.openharmonise.rm.dsi.DataStoreObject#getId()
611      */

612     public int getId() {
613         //int id not applicable
614
return -1;
615     }
616     
617     /*----------------------------------------------------------------------------
618     Protected Functions
619     -----------------------------------------------------------------------------*/

620     
621
622     /**
623      * Tries to log on and return the user with username and password
624      * found in the state. Sets default user flag to false.
625      *
626      * @param logon
627      * @param state
628      * @return User
629      * @throws SessionException
630      */

631     protected User logon(Element logon, State state) throws SessionException {
632         String JavaDoc sName = "";
633         String JavaDoc sPassword = "";
634
635         //find user element
636
Element userEl =
637             (Element) logon.getElementsByTagName(User.TAG_USER).item(0);
638
639         //get node list from user element to find name and pwd
640
NodeList nodes = userEl.getChildNodes();
641
642         for (int i = 0; i < nodes.getLength(); i++) {
643             Element el = (Element) nodes.item(i);
644
645             if (el.getTagName().equals(User.TAG_NAME)) {
646                 sName = el.getFirstChild().getNodeValue();
647             } else if (el.getTagName().equals(User.TAG_PASSWORD)) {
648                 sPassword = el.getFirstChild().getNodeValue();
649             }
650         }
651
652         User user = null;
653         try {
654             // user = new User(m_dsi, sName, sPassword);
655
UserAuthenticator authenticator = UserAuthenticatorFactory.getAuthenticator();
656             user = authenticator.getUser(sName, sPassword);
657             
658             int nId = user.getId();
659             user =
660                 (User) HarmoniseObjectFactory.instantiatePublishableObject(
661                     m_dsi,
662                     new User().getClass().getName(),
663                     nId);
664         } catch (HarmoniseFactoryException e) {
665             throw new SessionException("Error occured getting user from factory",e);
666         }
667         catch (UserAuthenticationException e) {
668             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
669         }
670
671         setDefaultUser(false);
672
673         return user;
674     }
675     
676
677     /**
678      * Compares timeout variable against current time, removing session from
679      * database if true.
680      *
681      * @return true or false.
682      * @throws SessionException
683      */

684     protected boolean isTimedOut() throws SessionException {
685
686         java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
687
688         if (m_dtTimeout == null) {
689             throw new RuntimeException JavaDoc("Timeout is null for this user " + this);
690         }
691
692         if (dtNow.after(m_dtTimeout)) {
693
694             DeleteStatement delete = new DeleteStatement();
695
696             //remove session from database.
697
delete();
698
699             m_bTimedOut = true;
700             m_sSessionId = "";
701         }
702
703         return m_bTimedOut;
704     }
705     
706
707     /**
708      * Returns a <code>ColumnRef</code> corresponding to the column given.
709      *
710      * @param sColumn
711      * @return
712      * @throws DataStoreException
713      */

714     protected ColumnRef getInstanceColumnRef(String JavaDoc sColumn)
715         throws DataStoreException {
716         ColumnRef returnColRef = null;
717
718         if (sColumn.equals(CLMN_SESSION_ID)) {
719             return new ColumnRef(TBL_SESSION, CLMN_SESSION_ID, ColumnRef.TEXT);
720         } else if (sColumn.equals(CLMN_USER_ID)) {
721             return new ColumnRef(TBL_SESSION, CLMN_USER_ID, ColumnRef.NUMBER);
722         } else if (sColumn.equals(CLMN_SESSION_TIMEOUT)) {
723             return new ColumnRef(
724                 TBL_SESSION,
725                 CLMN_SESSION_TIMEOUT,
726                 ColumnRef.DATE);
727         } else if (sColumn.equals(CLMN_SESSION_DATE)) {
728             return new ColumnRef(
729                 TBL_SESSION,
730                 CLMN_SESSION_DATE,
731                 ColumnRef.DATE);
732         } else if (sColumn.equals(CLMN_TYPE)) {
733             return new ColumnRef(TBL_SESSION, CLMN_TYPE, ColumnRef.DATE);
734         }
735
736         if (returnColRef != null) {
737             return returnColRef;
738         } else {
739             throw new InvalidColumnReferenceException(
740                 "No column of the name [" + sColumn + "] in Session");
741         }
742     }
743     
744
745     /**
746      * Tests whether the <code>User</code> associated with this <code>Session</code>
747      * is the system default <code>User</code>.
748      *
749      * @return true or false.
750      */

751     protected boolean isDefaultUser() {
752         return m_bDefaultUser;
753     }
754
755     /**
756      * Sets default user boolean.
757      *
758      * @param defaultUser true or false.
759      */

760     protected void setDefaultUser(boolean defaultUser) {
761         m_bDefaultUser = defaultUser;
762     }
763
764     /**
765      * Fills timeout variable by adding timeout to the current time.
766      *
767      * @param nTimeout timeout in minutes.
768      */

769     protected void setTimeout(int nTimeout) {
770         m_nTimeout = nTimeout;
771
772         //fill timeout variable
773
java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
774         m_dtTimeout =
775             new java.util.Date JavaDoc(dtNow.getTime() + (m_nTimeout * 60 * 1000));
776     }
777
778     /**
779      * Fills lag time variable by calling <code>calculateLagTime(nTimeout)</code>
780      * and adding this value to the current time.
781      *
782      * @param nTimeout timeout in minutes.
783      * @throws ConfigException
784      */

785     protected void setLagTime(int nTimeout) throws ConfigException {
786         //fill lagtime variable
787
java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
788         m_dtLagTime =
789             new java.util.Date JavaDoc(dtNow.getTime() + calculateLagTime(nTimeout));
790     }
791
792     /**
793      * Populates session details from database.
794      *
795      * @param sSessId
796      * @throws SessionException
797      */

798     protected void setDetailsFromId(String JavaDoc sSessId) throws SessionException {
799         ResultSet rs = null;
800
801         if (sSessId == null || sSessId.length() == 0) {
802             if(m_logger.isLoggable(Level.INFO)) {
803                 m_logger.logp(Level.INFO, this.getClass().getName(), "setDetailFromId", "Invalid session id to process; null value or length = 0");
804             }
805             throw new InvalidSessionIdException();
806         }
807         
808         SelectStatement select = new SelectStatement();
809
810         try {
811             select.addSelectColumn(getInstanceColumnRef(CLMN_USER_ID));
812             select.addSelectColumn(getInstanceColumnRef(CLMN_SESSION_TIMEOUT));
813
814             select.addWhereCondition(
815                 getInstanceColumnRef(CLMN_SESSION_ID),
816                 "=",
817                 removeSessionIdPrefix(sSessId));
818         } catch (DataStoreException e) {
819             m_logger.log(Level.WARNING, "Error occured building query to populate session " + sSessId, e);
820             throw new SessionException("Error occured building query", e);
821         }
822
823         try {
824
825             rs = m_dsi.execute(select);
826
827             if (rs.next()) {
828
829                 User usr =
830                     (User) HarmoniseObjectFactory.instantiatePublishableObject(
831                         m_dsi,
832                         m_QueryUser.getClass().getName(),
833                         rs.getInt(1));
834                 
835                 if(usr == null || usr.exists() == false) {
836                     
837                     DeleteStatement delete = new DeleteStatement();
838                     
839                     delete.addWhereCondition(getInstanceColumnRef(CLMN_SESSION_ID),
840                         "=",
841                         removeSessionIdPrefix(sSessId));
842                         
843                     m_dsi.execute(delete);
844                         
845                     throw new InvalidSessionIdException();
846                 }
847                 
848                 m_usrPtr = CacheHandler.getInstance(m_dsi).getCachePointer(usr);
849                 m_dtTimeout = rs.getTimestamp(2);
850
851                 int timeout =
852                     Integer.parseInt(
853                         ConfigSettings.getProperty(
854                             Session.DEFAULT_TIMEOUT_PNAME));
855                 setLagTime(timeout);
856                 m_sSessionId = sSessId;
857             } else {
858                 int index = sSessId.indexOf(DEFAULT_USER_PREFIX);
859
860                 if (index > -1) {
861
862                     m_sSessionId = sSessId;
863
864                     int timeout =
865                         Integer.parseInt(
866                             ConfigSettings.getProperty(
867                                 Session.DEFAULT_TIMEOUT_PNAME));
868                     initialize(getDefaultUser(), timeout);
869                 } else {
870                     if(m_logger.isLoggable(Level.INFO)) {
871                         m_logger.logp(Level.INFO, this.getClass().getName(), "setDetailFromId", "Session " + sSessId + " is not valid");
872                     }
873                     throw new InvalidSessionIdException();
874                 }
875             }
876         } catch (SQLException e) {
877             throw new SessionException("SQL exception", e);
878         } catch (NumberFormatException JavaDoc e) {
879             throw new SessionException("Error parsing default timeout", e);
880         } catch (ConfigException e) {
881             throw new SessionException("Error getting config setting", e);
882         } catch (HarmoniseFactoryException e) {
883             throw new SessionException("Error getting user from factory", e);
884         } catch (DataStoreException e) {
885             m_logger.log(Level.WARNING, e.getMessage(), e);
886             throw new SessionException("Error processing query", e);
887         } catch (CacheException e) {
888             throw new SessionException(e.getLocalizedMessage(),e);
889         } finally {
890             if (rs != null) {
891                 try {
892                     rs.close();
893                 } catch (SQLException e) {
894                     throw new SessionException("Error closing result set", e);
895                 }
896             }
897         }
898     }
899     
900
901     /**
902      * Checks timeout for session. Calls <code>updateSession()</code> if ok.
903      *
904      * @throws SessionException if timed out, unless default user
905      */

906     protected void updateTimeout(int nTimeout) throws SessionException {
907         if (!isDefaultUser() && isTimedOut()) {
908             if(m_logger.isLoggable(Level.INFO)) {
909                 m_logger.info("Session " + m_sSessionId + " timed out");
910             }
911             
912             throw new SessionTimeOutException("Session: " + this.m_sSessionId);
913         } else {
914
915             m_nTimeout = nTimeout;
916
917             java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
918             m_dtTimeout =
919             new java.util.Date JavaDoc(dtNow.getTime() + (m_nTimeout * 60 * 1000));
920
921         
922             try {
923                 updateSession();
924             } catch (ConfigException e) {
925                 throw new SessionException("Error occured accessig config setting",e);
926             } catch (DataStoreException e) {
927                 throw new SessionException("Error occured updating session",e);
928             }
929             
930         }
931     }
932     
933
934     /**
935      * Attempts to log off user. Resets session user as default user.
936      *
937      * @param logoff_tag
938      * @param sessId
939      * @return true if successful.
940      * @throws DataStoreException
941      */

942     protected boolean logoff(Element logoff_tag, String JavaDoc sessId) throws DataStoreException {
943         
944         if(m_logger.isLoggable(Level.FINE)) {
945             m_logger.logp(Level.FINE, this.getClass().getName(), "logoff", "Loging off session " + sessId);
946         }
947         
948         // let the logoff happen to the session_id passed, if there
949
// is no session id defined within the logoff tag.
950
// Prefer to use the session_id within the tag
951
NodeList nodes = logoff_tag.getChildNodes();
952
953         for (int i = 0; i < nodes.getLength(); i++) {
954             Element el = (Element) nodes.item(i);
955
956             if (el.getTagName().equals(TAG_SESSION)) {
957                 sessId = el.getAttribute(AbstractObject.ATTRIB_ID);
958             }
959         }
960
961         if (sessId.length() == 0) {
962             if(m_logger.isLoggable(Level.SEVERE)) {
963                 m_logger.logp(Level.SEVERE, this.getClass().getName(), "logoff", "Invalid session to log off - [" + sessId +"]");
964             }
965             throw new RuntimeException JavaDoc(
966                 "Attempt to log off without a valid session id"
967                     + ", session id:"
968                     + sessId);
969         }
970
971         //reset user in session to default user
972
User user = getDefaultUser();
973         updateUser(user);
974         setDefaultUser(true);
975
976         return true;
977     }
978     
979
980     /**
981      * Retrieves lag percent set in harmonise.prop file.
982      *
983      * @return lag percent
984      * @throws ConfigException
985      */

986     protected int getLagPercent() throws ConfigException {
987         if (m_nLagPercent < 0) {
988             m_nLagPercent =
989                 ConfigSettings.getIntProperty(
990                     LAG_PERCENT_PNAME,
991                     sDefaultLagPercent);
992         }
993
994         return m_nLagPercent;
995     }
996
997     /**
998      * Calls <code>getLagPercent()</code> to calculate lagtime as a percentage of timeout.
999      *
1000     * @param timeout
1001     * @return lagtime lagtime in minutes.
1002     * @throws ConfigException
1003     */

1004    protected int calculateLagTime(int timeout) throws ConfigException {
1005        int lagtime = (timeout * 60 * 1000 * getLagPercent()) / 100;
1006
1007        return lagtime;
1008    }
1009
1010    /**
1011     * Checks lagtime against current time.
1012     *
1013     * @return
1014     */

1015    protected boolean isLagTimedOut() {
1016        boolean lagTimedOut = false;
1017
1018        java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
1019
1020        if (dtNow.after(m_dtLagTime)) {
1021            lagTimedOut = true;
1022        }
1023
1024        return lagTimedOut;
1025    }
1026
1027    /**
1028     * Sets User member variable to user passed in.
1029     * Calls <code>updateDataBase()</code>.
1030     *
1031     * @param user
1032     * @throws DataStoreException
1033     */

1034    protected void updateUser(User user) throws DataStoreException {
1035
1036        try {
1037            m_usrPtr = CacheHandler.getInstance(m_dsi).getCachePointer(user);
1038        } catch (CacheException e) {
1039            throw new DataStoreException(e.getLocalizedMessage(),e);
1040        }
1041
1042        updateDataBase();
1043    }
1044    
1045    /*----------------------------------------------------------------------------
1046    Private Functions
1047    -----------------------------------------------------------------------------*/

1048
1049    /**
1050     * Calls <code>updateDataBase()</code> if lagtime is exceeded.
1051     * Otherwise does nothing.
1052     *
1053     * @throws ConfigException
1054     * @throws DataStoreException
1055     */

1056    private void updateSession() throws ConfigException, DataStoreException {
1057        if (isLagTimedOut()) {
1058            updateDataBase();
1059
1060            java.util.Date JavaDoc dtNow = new java.util.Date JavaDoc();
1061            m_dtLagTime =
1062                new java.util.Date JavaDoc(
1063                    dtNow.getTime() + calculateLagTime(m_nTimeout));
1064        }
1065    }
1066
1067    /**
1068     * Writes User, timeout and session id to the database.
1069     *
1070     * @throws DataStoreException
1071     */

1072    private void updateDataBase() throws DataStoreException {
1073        UpdateStatement update = new UpdateStatement();
1074
1075        User usr = null;
1076        try {
1077            usr = (User) m_usrPtr.getObject();
1078        } catch (CacheException e) {
1079            throw new DataStoreException(e.getLocalizedMessage(),e);
1080        }
1081        
1082        update.addColumnValue(
1083            getInstanceColumnRef(CLMN_USER_ID),
1084            usr.getId());
1085        update.addColumnValue(
1086            getInstanceColumnRef(CLMN_SESSION_TIMEOUT),
1087            m_dtTimeout);
1088        update.addWhereCondition(
1089            getInstanceColumnRef(CLMN_SESSION_ID),
1090            "=",
1091            removeSessionIdPrefix(m_sSessionId));
1092
1093        m_dsi.execute(update);
1094        
1095    }
1096    
1097
1098    /**
1099     * Generates a SessionId.
1100     *
1101     * @param nNumChars number of characters in session id.
1102     * @return
1103     */

1104    private static String JavaDoc generateSessionId(int nNumChars) {
1105        String JavaDoc sSession = "";
1106        SecureRandom JavaDoc rnd = new SecureRandom JavaDoc();
1107        StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
1108
1109        for (int i = 0; i < nNumChars; i++) {
1110            int nIndex = (int) (rnd.nextDouble() * (sCharBase.length() - 1));
1111            buffer.append(sCharBase.charAt(nIndex));
1112        }
1113
1114        sSession = buffer.toString();
1115
1116        return sSession;
1117    }
1118    
1119
1120    /**
1121     * Checks to see whether this Session id is unique.
1122     *
1123     * @param sSessId
1124     * @return
1125     * @throws SessionException
1126     */

1127    private boolean isSessionIdUnique(String JavaDoc sSessId) throws SessionException {
1128        ResultSet rs = null;
1129        boolean bIsUnique = true;
1130
1131        try {
1132            SelectStatement select = new SelectStatement();
1133            select.addSelectColumn(getInstanceColumnRef(CLMN_SESSION_ID));
1134            select.addWhereCondition(
1135                getInstanceColumnRef(CLMN_SESSION_ID),
1136                "=",
1137                sSessId);
1138
1139            String JavaDoc temp = m_dsi.getSelectStatement(select);
1140            rs = m_dsi.executeQuery(select);
1141
1142            if (rs.next()) {
1143                bIsUnique = false;
1144            }
1145        } catch (DataStoreException e) {
1146            throw new SessionException("Error occured on query", e);
1147        } catch (SQLException e) {
1148            throw new SessionException("Error occured on query", e);
1149        } finally {
1150            if (rs != null) {
1151                try {
1152                    rs.close();
1153                } catch (SQLException e) {
1154                    throw new SessionException(
1155                        "Error occured closing result set",
1156                        e);
1157                }
1158            }
1159        }
1160
1161        return bIsUnique;
1162    }
1163    
1164
1165    /**
1166     * Removes all session entries for a user from the database.
1167     *
1168     * @param userKey
1169     * @throws SessionException
1170     */

1171    private void removeAllSessionEntries(int userKey) throws SessionException {
1172        DeleteStatement delete = null;
1173
1174        try {
1175            delete = new DeleteStatement();
1176            delete.setTable(TBL_SESSION);
1177            delete.addWhereCondition(
1178                getInstanceColumnRef(CLMN_USER_ID),
1179                "=",
1180                userKey);
1181
1182            m_dsi.execute(delete);
1183        } catch (DataStoreException e) {
1184            throw new SessionException("Error removing sessions", e);
1185        }
1186    }
1187    
1188
1189    /**
1190     * Constructs a default user.
1191     *
1192     * @return default user.
1193     */

1194    private User getDefaultUser() {
1195        User user = new User(m_dsi,DEFAULT_USER_ID);
1196
1197        return user;
1198    }
1199    
1200    /**
1201     * Sets user, timeout and lagtime variables. Updates session id prefix, creating
1202     * new session id if there isn't one. Calls <code>save()</code>.
1203     *
1204     * @param user User of session, may be default or logged in.
1205     * @param nTimeout timeout in minutes.
1206     * @return session id.
1207     * @throws SessionException
1208     */

1209    private String JavaDoc initialize(User user, int nTimeout) throws SessionException {
1210
1211        
1212        try {
1213            m_usrPtr = CacheHandler.getInstance(m_dsi).getCachePointer(user);
1214        } catch (CacheException e) {
1215            throw new SessionException(e.getLocalizedMessage(),e);
1216        }
1217        
1218        setTimeout(nTimeout);
1219        try {
1220            setLagTime(nTimeout);
1221        } catch (ConfigException e) {
1222            throw new SessionException("Error setting lag time", e);
1223        }
1224
1225        String JavaDoc sSessId = "";
1226
1227        if (m_sSessionId.equals("") == true) {
1228            sSessId = generateSessionId();
1229        } else {
1230            sSessId = removeSessionIdPrefix(m_sSessionId);
1231        }
1232
1233        while (!isSessionIdUnique(sSessId)) {
1234            sSessId = generateSessionId();
1235        }
1236
1237        int userId = user.getId();
1238
1239        // first clear out any other session ids, unless default user
1240
//add prefix for default/logged in user
1241
if (userId != this.DEFAULT_USER_ID) {
1242            m_sSessionId = LOGGED_IN_USER_PREFIX + sSessId;
1243            removeAllSessionEntries(userId);
1244        } else {
1245            m_sSessionId = DEFAULT_USER_PREFIX + sSessId;
1246        }
1247
1248        save();
1249
1250        return m_sSessionId;
1251    }
1252
1253
1254
1255}
Popular Tags