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: PagedSessionHome.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.util.Enumeration;
027: import java.util.Hashtable;
028: import java.util.Vector;
029:
030: import com.lutris.appserver.server.Enhydra;
031: import com.lutris.appserver.server.session.SessionException;
032: import com.lutris.logging.Logger;
033: import com.lutris.util.Config;
034: import com.lutris.util.ConfigException;
035:
036: /**
037: * The StandardSessionManager uses PagedSessionHome to manage
038: * a collection of sessions that can be paged to disk.<p>
039: *
040: * PagedSessionHome will page sessions to disk
041: * as soon as a pre-configured threshold of sessions has been
042: * reached. Only sessions in the 'passive' state will be
043: * paged to disk. If all sessions are in the 'active' state
044: * and the threshold has been reached, then a request to create
045: * a new session will block until one of the 'active' sessions
046: * goes into the 'passive' state. At this point the session
047: * that just became 'passive' is paged to disk and a new
048: * session is created.<p>
049: *
050: * Sessions are paged to disk by serializing
051: * the all data (excluding the session manager) that is
052: * associated with a session. This requires that
053: * the session data and user associated with a session
054: * are serializable.<p>
055: *
056: * The following parameters can be used to configure
057: * the PagedSessionHome. They should be grouped together in a section,
058: * normally <code>SessionManager.SessionHome</code>, which is specified to
059: * the constructor.<p>
060: *
061: * <ul>
062: *
063: * <li><code>PageThreshold: {int}</code><p>
064: * Specifies the maximum number of session that may reside in memory
065: * simultaneously. If set to zero the the paged session home acts
066: * as a write through cache. If set to -1, then the page threshold
067: * is assumed to be infinite and paging will never take place.
068: * If not set, defaults to -1.<p>
069: *
070: * <li><code>PageTimeThreshold: {long}</code><p>
071: * Specifies the amount of time a session may remain in memory
072: * before it is paged out to disk.
073: * If this parameter is not set, or, it is set to -1, then the session
074: * will not be paged out unless the <i>PageThreshold</i> is reached.<p>
075: *
076: * <li><code>PageWait: {int}</code><p>
077: * Specifies the maximum time (in milliseconds) that a thread will
078: * wait for a session to be created or retrieved. If the
079: * page threshold has been reached, then a thread has to wait for
080: * an existing session to be paged before a new session can be
081: * created or a pre-existing session (that has been paged to
082: * disk) can be activated. If not set, defaults to 1 minute.
083: * If this time is exceeded then an exception is thrown - this
084: * prevents a possible deadlock situation.<p>
085: *
086: * <li><code>PageDir: {String}</code><p>
087: * The directory where sessions will be paged. This setting is
088: * required.<p>
089: *
090: * <li><code>MaxSessions: {int}</code><p>
091: * Specifies the maximum number of in use concurrent sessions. If this value
092: * is exceeded then CreateSession() will throw a CreateSessionException.
093: * -1 indicates unlimited session. If MaxSessions is not set
094: * in the application's configuration then MaxSessions defaults to
095: * unlimited sessions.<p>
096: *
097: * </ul>
098: *
099: * @see StandardSession
100: * @see StandardSessionManager
101: * @version $Revision: 1.3 $
102: * @author Kyle Clark
103: */
104: public abstract class PagedSessionHome implements StandardSessionHome {
105:
106: /**
107: * The active cache contains sessions that are
108: * actively in use (associated with) by a request.
109: */
110: private Hashtable activeCache = new Hashtable();
111:
112: /**
113: * The active thread cache holds all the association
114: * between active sessions and the threads that have
115: * checked them out.
116: */
117: private Hashtable activeThreadCache = new Hashtable();
118:
119: /**
120: * The passive cache contains sessions that
121: * aren't currently associated with a request.
122: */
123: private Hashtable passiveCache = new Hashtable();
124:
125: /**
126: * Config options for paged session home.
127: */
128: // private Config config;
129: /**
130: * Maximum number of allowed sessions.
131: */
132: private long maxSessions = -1;
133:
134: /**
135: * The threshold where paging beings.
136: */
137: private long pageThreshold = -1;
138:
139: /**
140: * The amount of time a session may remain in memory
141: * unused before it is paged out. In seconds.
142: */
143: private long pageTimeThreshold = -1;
144:
145: /**
146: * The pageTimeThreshold timer.
147: */
148: private PagedSessionThresholdTimer thresholdTimer;
149:
150: /**
151: * If a thread has to wait for a session to be paged
152: * before it can retrieve (get) or create a session then
153: * pageWait specifies that maximum amount of time
154: * that the thread will wait before an exception is
155: * thrown.
156: */
157: private long pageWait = 60000; // milliseconds
158:
159: /**
160: * Configuration keys.
161: */
162: private static final String MAX_SESSIONS_KEY = "MaxSessions";
163: private static final String PAGE_THRESHOLD_KEY = "PageThreshold";
164: private static final String PAGE_TIME_THRESHOLD_KEY = "PageTimeThreshold";
165: private static final String PAGE_WAIT_KEY = "PageWait";
166: private static final long UNDEFINED_MAX_SESSIONS = -1;
167:
168: /**
169: * The class loader to use when reading in paged data.
170: */
171: protected ClassLoader loader;
172:
173: /**
174: * The session manager associated with the session home.
175: */
176: protected StandardSessionManager sessionMgr;
177:
178: /**
179: * @param sessionMgr
180: * The session manager associated with this session home.
181: * @param config
182: * Object parsed from configuration file. This should be
183: * for the section containing the standard session home configuration.
184: * @param loader
185: * The class load to use when load objects from persistent store.
186: * @exception ConfigException
187: * signifies a problem in the configuration file.
188: * @exception SessionException
189: * if the initialization fails.
190: */
191: public PagedSessionHome(StandardSessionManager sessionMgr,
192: Config config, ClassLoader loader) throws SessionException,
193: ConfigException {
194: // this.config = config;
195: this .loader = loader;
196: this .sessionMgr = sessionMgr;
197: if (config.containsKey(MAX_SESSIONS_KEY)) {
198: maxSessions = config.getLong(MAX_SESSIONS_KEY);
199: }
200: if (maxSessions <= 0) {
201: maxSessions = UNDEFINED_MAX_SESSIONS;
202: }
203: debug(MAX_SESSIONS_KEY + " = " + maxSessions);
204: pageThreshold = config.getLong(PAGE_THRESHOLD_KEY);
205: debug(PAGE_THRESHOLD_KEY + " = " + pageThreshold);
206: if (config.containsKey(PAGE_WAIT_KEY)) {
207: pageWait = config.getLong(PAGE_WAIT_KEY);
208: if (pageWait <= 0) {
209: throw new ConfigException("PagedSessionHome: "
210: + "PageWait cannot be <= 0.");
211: }
212: }
213: if (config.containsKey(PAGE_TIME_THRESHOLD_KEY)) {
214: pageTimeThreshold = config.getLong(PAGE_TIME_THRESHOLD_KEY) * 1000;
215: if (!isWriteThroughCache() && (pageTimeThreshold > 0)) {
216: thresholdTimer = new PagedSessionThresholdTimer(this ,
217: sessionMgr.app);
218: thresholdTimer.start();
219: }
220: }
221: debug(PAGE_TIME_THRESHOLD_KEY + " = " + pageTimeThreshold);
222: }
223:
224: /**
225: * Creates a new session instance in the cache. The
226: * session is associated with the session key and the
227: * current thread.
228: *
229: * @param sessionKey the key to associate with the session.
230: * @return the newly created session.
231: * @exception DuplicateKeyException
232: * if the session cannot
233: * be created because the key is already in use.
234: * @exception CreateSessionException
235: * if the session could not be created.
236: * @exception SessionException
237: * any other internal error.
238: */
239: public synchronized StandardSession createSession(String sessionKey)
240: throws CreateSessionException, DuplicateKeyException,
241: SessionException {
242: if (containsKey(sessionKey)) {
243: throw new DuplicateKeyException("Session key " + sessionKey
244: + " is already in use.");
245: }
246: if ((maxSessions != UNDEFINED_MAX_SESSIONS)
247: && (maxSessions <= size())) {
248: cleanupNewSession();
249: if (maxSessions <= size()) {
250: throw new CreateSessionException(
251: "Maximum session limit of " + maxSessions
252: + " sessions has been reached.");
253: }
254: }
255: ensureNewSession();
256: PagedSession session = newSession(sessionMgr, sessionKey);
257: SessionThread activeKey = new SessionThread(Thread
258: .currentThread(), sessionKey);
259: session.incrementRefCount(); // keeps track of # of threads that reference session
260: activeThreadCache.put(activeKey, session);
261: activeCache.put(sessionKey, session);
262: // v. strahinja, 01 okt 2002 debug(3, "createSession: " + activeKey);
263: debug("createSession: " + activeKey);
264: return (StandardSession) session;
265: }
266:
267: /**
268: * Creates a new session object. This method is intended to be
269: * overriden by classes that extend PagedSessionHome.
270: *
271: * @return a new session.
272: * @exception SessionException if an error occurs.
273: */
274: protected abstract PagedSession newSession(
275: StandardSessionManager mgr, String sessionKey)
276: throws SessionException;
277:
278: /**
279: * Deletes a paged session. If the session doesn't exist then this
280: * is a noop.
281: *
282: * @param sessionKey the key identifying the session
283: * that should be deleted.
284: */
285: protected abstract void deleteSession(String sessionKey)
286: throws SessionException;
287:
288: /**
289: * Returns the session associated with the session key.
290: * The session must already be associated with the current thread
291: * otherwize null is returned.
292: *
293: * @param sessionKey the session key
294: * @return the session.
295: * @see #getSession(Thread, String)
296: * @exception SessionException
297: * if the session could not be retrieved.
298: */
299: public synchronized StandardSession getSession(String sessionKey)
300: throws SessionException {
301: // v. strahinja, 01 okt 2002 debug(3, "get session: key = " + sessionKey);
302: debug("get session: key = " + sessionKey);
303: SessionThread activeKey = new SessionThread(Thread
304: .currentThread(), sessionKey);
305: PagedSession s = (PagedSession) activeThreadCache
306: .get(activeKey);
307: return s;
308: }
309:
310: /**
311: * Returns the session associated with the session key.
312: * The session is associated with the specified thread.
313: * The session is put into the 'active' state.
314: *
315: * @param thread the thread to associate with the session.
316: * @param sessionKey the session key for the session
317: * that will be made 'active' and returned. If the
318: * session doesn't exist or it hasn't been
319: * associated with this thread then null is returned.
320: * @return the session.
321: * @exception SessionException
322: * if the session could not be retrieved.
323: */
324: public synchronized StandardSession getSession(Thread thread,
325: String sessionKey) throws SessionException {
326: // v. strahinja, 01 okt 2002 debug(3, "getSession: " + sessionKey);
327: debug("getSession: " + sessionKey);
328: SessionThread activeKey = new SessionThread(thread, sessionKey);
329: PagedSession s = (PagedSession) activeThreadCache
330: .get(activeKey);
331: if (s == null) {
332: s = (PagedSession) activeCache.get(sessionKey);
333: if (s == null) {
334: s = activateSession(sessionKey);
335: }
336: if (s != null) {
337: activeThreadCache.put(activeKey, s);
338: // keeps track of # of threads that reference session
339: s.incrementRefCount();
340: }
341: }
342: return s;
343: }
344:
345: /**
346: * Removes the session associated with the session key.
347: *
348: * @param sessionKey the session key for the session
349: * that will be made 'active' and returned.
350: * @return the session.
351: * @exception SessionException
352: * if the session couldn't be removed.
353: */
354: public synchronized void removeSession(String sessionKey)
355: throws SessionException {
356: // v. strahinja, 01 okt 2002 debug(3, "removeSession: " + sessionKey);
357: debug("removeSession: " + sessionKey);
358: Enumeration e = activeThreadCache.keys();
359: while (e.hasMoreElements()) {
360: SessionThread key = (SessionThread) e.nextElement();
361: if (key.sessionKey.equals(sessionKey)) {
362: activeThreadCache.remove(key);
363: }
364: }
365: activeCache.remove(sessionKey);
366: passiveCache.remove(sessionKey);
367: deleteSession(sessionKey);
368: notify();
369: }
370:
371: /**
372: * Puts an 'active' session into the 'passive' state.
373: *
374: * @param thread the thread associated with the session.
375: * @param sessionKey the session key for the session
376: * that will be made persistent.
377: * @exception SessionException
378: * if the session coulnd not be put into the passive state.
379: */
380: public synchronized void passivateSession(Thread thread,
381: String sessionKey) throws SessionException {
382: SessionThread activeKey = new SessionThread(thread, sessionKey);
383: try {
384: // v. strahinja, 01 okt 2002 debug(3, "passivateSession: " + activeKey);
385: debug("passivateSession: " + activeKey);
386: if (activeThreadCache.containsKey(activeKey)) {
387: PagedSession s = (PagedSession) activeThreadCache
388: .remove(activeKey);
389: s.decrementRefCount();
390: // If there aren't any other threads associated with the session
391: if (s.getRefCount() == 0) {
392: if (isWriteThroughCache()) {
393: pageOut(s);
394: } else if ((pageThreshold < 0)
395: || ((activeCache.size() + passiveCache
396: .size()) < pageThreshold)) {
397: // v. strahinja, 01 okt 2002 debug(3, "active -> passive: " + sessionKey);
398: debug("active -> passive: " + sessionKey);
399: passiveCache.put(sessionKey, s);
400: } else {
401: pageOut(s);
402: }
403: activeCache.remove(sessionKey);
404: }
405: } else {
406: // v. strahinja, 01 okt 2002 debug(3, "passivateSession called but active session "
407: debug("passivateSession called but active session "
408: + " doesn't exist: " + sessionKey);
409: }
410: } catch (Exception e) {
411: throw new SessionException(e);
412: } finally {
413: notify();
414: }
415: }
416:
417: /**
418: * Pages a session to disk.
419: *
420: * @param session the session to page.
421: * @exception SessionException if the paged session could not be
422: * paged out.
423: */
424: protected abstract void pageOut(PagedSession s)
425: throws SessionException;
426:
427: /**
428: * Reads a paged session from disk.
429: *
430: * @param sessionKey the key identifying the session that should
431: * be paged in.
432: * @return the paged session that was read in. May be null if
433: * the session referenced by sessionKey doesn't exist.
434: * @exception SessionException if the paged session could not be
435: * read in.
436: */
437: protected abstract PagedSession pageIn(String sessionKey)
438: throws SessionException;
439:
440: /**
441: * Returns the number of paged sessions.
442: */
443: protected abstract int getPagedSessionCount()
444: throws SessionException;
445:
446: /**
447: * Puts a session into the 'active' state. Reads paged version
448: * if necessary.
449: *
450: * @param activeKey the session-thread key for the session
451: * that should be activated.
452: * @exception SessionException
453: * if the session cannot be activated.
454: */
455: private synchronized PagedSession activateSession(String sessionKey)
456: throws SessionException {
457: PagedSession session = null;
458: boolean isPaged = !activeCache.containsKey(sessionKey)
459: && !passiveCache.containsKey(sessionKey);
460: // v. strahinja, 01 okt 2002 debug(3, "activateSession: " + sessionKey);
461: debug("activateSession: " + sessionKey);
462: if (isPaged) {
463: ensureNewSession();
464: session = pageIn(sessionKey);
465: } else if (passiveCache.containsKey(sessionKey)) {
466: // v. strahinja, 01 okt 2002 debug(3, "passive -> active : " + sessionKey);
467: debug("passive -> active : " + sessionKey);
468: session = (PagedSession) passiveCache.remove(sessionKey);
469: } else if (activeCache.containsKey(sessionKey)) {
470: // v. strahinja, 01 okt 2002 debug(3, "session is active : " + sessionKey);
471: debug("session is active : " + sessionKey);
472: session = (PagedSession) activeCache.get(sessionKey);
473: }
474: if (session != null) {
475: activeCache.put(sessionKey, session);
476: }
477: return session;
478: }
479:
480: /**
481: * Specifies if a key is currently in use.
482: *
483: * @param sessionKey the session key to be tested.
484: * @return true if the session key is in use.
485: * @exception SessionException if an error occurs.
486: */
487: public boolean containsKey(String sessionKey)
488: throws SessionException {
489: if (activeCache.containsKey(sessionKey)
490: || passiveCache.containsKey(sessionKey)
491: || pagedSessionKeyExists(sessionKey)) {
492: return true;
493: }
494: return false;
495: }
496:
497: /**
498: * Returns true if the specified session key is in use
499: * by a session that has been paged out.
500: *
501: * @param sessionKey the session key to test.
502: * @return true if the session key is in use by a paged session.
503: * @exception SessionException if an error occurs.
504: */
505: protected abstract boolean pagedSessionKeyExists(String sessionKey)
506: throws SessionException;
507:
508: /**
509: * Returns the current number of sessions.
510: *
511: * @return the session count.
512: * @exception SessionException if an error occurs.
513: */
514: public int size() throws SessionException {
515: return activeCache.size() + passiveCache.size()
516: + getPagedSessionCount();
517: }
518:
519: /**
520: * Returns the current number of sessions that are paged to
521: * persistent store.
522: *
523: * @return
524: * the 'paged' session count.
525: * @exception SessionException
526: * if the size cannot be determined
527: */
528: public int pagedSize() throws SessionException {
529: return getPagedSessionCount();
530: }
531:
532: /**
533: * Returns an enumeration of keys for the cached sessions.
534: *
535: * @return the session keys enumeration.
536: * @exception SessionException if an error occurs.
537: */
538: public synchronized Enumeration keys() throws SessionException {
539: try {
540: Vector v = new Vector();
541: String sessionKey;
542: Enumeration e;
543: e = activeCache.keys();
544: while (e.hasMoreElements()) {
545: sessionKey = (String) e.nextElement();
546: if (!v.contains(sessionKey)) {
547: v.addElement(sessionKey);
548: }
549: }
550: e = passiveCache.keys();
551: while (e.hasMoreElements()) {
552: sessionKey = (String) e.nextElement();
553: if (!v.contains(sessionKey)) {
554: v.addElement(sessionKey);
555: }
556: }
557: e = getPagedSessionKeys();
558: while (e.hasMoreElements()) {
559: sessionKey = (String) e.nextElement();
560: if (!v.contains(sessionKey)) {
561: v.addElement(sessionKey);
562: }
563: }
564: return v.elements();
565: } catch (Exception e) {
566: throw new SessionException(e);
567: }
568: }
569:
570: /**
571: * Returns an enumeration of the keys of all the sessions that have
572: * been paged out to persistent storage.
573: *
574: * @return the session key enumeration.
575: * @exception SessionException if an error occurs.
576: */
577: protected abstract Enumeration getPagedSessionKeys()
578: throws SessionException;
579:
580: /**
581: * Cleans up (removes) the oldest unused (new) session from the
582: * passive cache.
583: *
584: * @return true if an unused session was cleaned up.
585: */
586: private void cleanupNewSession() throws SessionException {
587: if (!cleanupNewPagedSession()) {
588: Enumeration e;
589: String key = null;
590: long oldestTime = -1;
591: e = passiveCache.keys();
592: while (e.hasMoreElements()) {
593: PagedSession s = (PagedSession) passiveCache.get(e
594: .nextElement());
595: if (s.isNew()) {
596: if ((oldestTime < 0)
597: || (s.getTimeCreated() < oldestTime)) {
598: oldestTime = s.getTimeCreated();
599: key = s.getSessionKey();
600: }
601: }
602: }
603: if (key != null) {
604: removeSession(key);
605: }
606: }
607: }
608:
609: /**
610: * Pages out any sessions that are passive and have exceeded
611: * the page time threshold.
612: *
613: * @return returns the amount of time in milliseconds when
614: * the next check should occur.
615: */
616: long checkPassiveSessions() throws SessionException {
617: return checkPassiveSessions(pageTimeThreshold);
618: }
619:
620: /**
621: * Pages out any sessions that are passive and have exceeded
622: * the page time threshold.
623: *
624: * @param threshold the threshold when a passive session
625: * should be paged.
626: * @return returns the amount of time in milliseconds when
627: * the next check should occur.
628: */
629: private synchronized long checkPassiveSessions(long threshold)
630: throws SessionException {
631: long nextCheck = threshold;
632: Enumeration e = passiveCache.elements();
633: long now = System.currentTimeMillis();
634: while (e.hasMoreElements()) {
635: PagedSession s = (PagedSession) e.nextElement();
636: long passiveTime = now - s.getTimeLastUsed();
637: if (passiveTime >= threshold) {
638: pageOut(s);
639: passiveCache.remove(s.getSessionKey());
640: } else if (nextCheck > (threshold - passiveTime)) {
641: nextCheck = threshold - passiveTime;
642: }
643: }
644: return nextCheck;
645: }
646:
647: /**
648: * Removes a session that is new and paged.
649: *
650: * @return true is a new session was found and deleted.
651: * @exception SessionException if an error occurs.
652: */
653: protected abstract boolean cleanupNewPagedSession()
654: throws SessionException;
655:
656: /**
657: * Ensures that a new session can be put into the list
658: * in-core sessions that are being managed.
659: * If necessary, this method will page a passive session disk in
660: * in order to guarantee that another session can be
661: * read into memory (or created). This method may block
662: * if a session first needs to be paged to disk.
663: */
664: private void ensureNewSession() throws SessionException {
665: if (pageThreshold > 0) { // If not a write-through cache....
666: while ((activeCache.size() + passiveCache.size()) > pageThreshold) {
667: if (passiveCache.size() == 0) {
668: try {
669: // v. strahinja, 01 okt 2002 debug(3, "waiting for a passive session that can be paged...");
670: debug("waiting for a passive session that can be paged...");
671: wait(pageWait);
672: if (passiveCache.size() <= 0) {
673: throw new SessionException(
674: "Unable to activate session: "
675: + "no sessions are ready to be paged.");
676: }
677: } catch (InterruptedException e) {
678: // ignore
679: }
680: } else {
681: // v. strahinja, 01 okt 2002 debug(3, "a passive session ready to be paged");
682: debug("a passive session ready to be paged");
683: Enumeration keys = passiveCache.keys();
684: PagedSession s = (PagedSession) passiveCache
685: .get((String) keys.nextElement());
686: pageOut(s);
687: passiveCache.remove(s.getSessionKey());
688: }
689: }
690: }
691: }
692:
693: /**
694: * Shuts down the session home. Pages out all active sessions.
695: */
696: public synchronized void shutdown() {
697: try {
698: if (thresholdTimer != null) {
699: thresholdTimer.shutdown();
700: thresholdTimer = null;
701: }
702: // DT 17.11.2003 BEG
703: Enumeration e = activeThreadCache.keys();
704: while (e.hasMoreElements()) {
705: SessionThread s = (SessionThread) e.nextElement();
706: passivateSession(s.thread, s.sessionKey);
707: }
708: // DT 17.11.2003 END
709: checkPassiveSessions(0);
710: } catch (Exception e) {
711: Enhydra
712: .getLogChannel()
713: .write(
714: Logger.ERROR,
715: "PagedSessionHome: "
716: + "failed to page out active and passive sessions.",
717: e);
718: }
719: }
720:
721: /**
722: * Returns true if the current configuration is for
723: * a write trhough cache.
724: *
725: * @return true if write through cache is configured.
726: */
727: private boolean isWriteThroughCache() {
728: return (pageThreshold == 0);
729: }
730:
731: /**
732: * Prints debug information under Logger.DEBUG.
733: *
734: * @param msg the message to print.
735: */
736: protected void debug(String msg) {
737: debug(0, msg);
738: }
739:
740: /**
741: * Prints debug information under Logger.DEBUG.
742: *
743: * @param level the debug level.
744: * @param msg the message to print.
745: */
746: protected void debug(int level, String msg) {
747: int dbg = Logger.DEBUG;
748: switch (level) {
749: case 1:
750: dbg = Logger.DEBUG1;
751: break;
752: case 2:
753: dbg = Logger.DEBUG2;
754: break;
755: case 3:
756: dbg = Logger.DEBUG3;
757: break;
758: case 4:
759: dbg = Logger.DEBUG4;
760: break;
761: case 5:
762: dbg = Logger.DEBUG5;
763: break;
764: case 6:
765: dbg = Logger.DEBUG6;
766: break;
767: case 7:
768: dbg = Logger.DEBUG7;
769: break;
770: case 8:
771: dbg = Logger.DEBUG8;
772: break;
773: case 9:
774: dbg = Logger.DEBUG9;
775: break;
776: default:
777: dbg = Logger.DEBUG;
778: break;
779: }
780: Enhydra.getLogChannel().write(
781: dbg,
782: "PersistentSessionHome("
783: + Thread.currentThread().getName() + "): "
784: + msg);
785: }
786: }
|