Source Code Cross Referenced for StandardSessionManager.java in  » J2EE » Enhydra-Application-Framework » com » lutris » appserver » server » sessionEnhydra » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Enhydra Application Framework » com.lutris.appserver.server.sessionEnhydra 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Enhydra Java Application Server Project
0003:         *
0004:         * The contents of this file are subject to the Enhydra Public License
0005:         * Version 1.1 (the "License"); you may not use this file except in
0006:         * compliance with the License. You may obtain a copy of the License on
0007:         * the Enhydra web site ( http://www.enhydra.org/ ).
0008:         *
0009:         * Software distributed under the License is distributed on an "AS IS"
0010:         * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
0011:         * the License for the specific terms governing rights and limitations
0012:         * under the License.
0013:         *
0014:         * The Initial Developer of the Enhydra Application Server is Lutris
0015:         * Technologies, Inc. The Enhydra Application Server and portions created
0016:         * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
0017:         * All Rights Reserved.
0018:         *
0019:         * Contributor(s):
0020:         *
0021:         * $Id: StandardSessionManager.java,v 1.4 2007-10-19 10:05:39 sinisa Exp $
0022:         */
0023:
0024:        package com.lutris.appserver.server.sessionEnhydra;
0025:
0026:        import java.lang.reflect.Constructor;
0027:        import java.util.Date;
0028:        import java.util.Enumeration;
0029:
0030:        import javax.servlet.http.HttpSession;
0031:        import javax.servlet.http.HttpSessionBindingEvent;
0032:        import javax.servlet.http.HttpSessionBindingListener;
0033:
0034:        import com.lutris.appserver.server.Application;
0035:        import com.lutris.appserver.server.Enhydra;
0036:        import com.lutris.appserver.server.httpPresentation.HttpPresentationComms;
0037:        import com.lutris.appserver.server.httpPresentation.HttpPresentationException;
0038:        import com.lutris.appserver.server.session.MemoryPersistence;
0039:        import com.lutris.appserver.server.session.Session;
0040:        import com.lutris.appserver.server.session.SessionException;
0041:        import com.lutris.appserver.server.session.SessionManager;
0042:        import com.lutris.appserver.server.sessionEnhydra.persistent.PersistentSessionHome;
0043:        import com.lutris.appserver.server.sessionEnhydra.persistent.PersistentSessionUserTable;
0044:        import com.lutris.appserver.server.user.User;
0045:        import com.lutris.logging.LogChannel;
0046:        import com.lutris.logging.Logger;
0047:        import com.lutris.util.Config;
0048:        import com.lutris.util.ConfigException;
0049:        import com.lutris.util.KeywordValueException;
0050:
0051:        /**
0052:         * This session manager maintains the mapping between session keys and sessions.
0053:         * It generates secure session keys that are safe to use as cookie values in web
0054:         * applications. It also manages the life of a session. If a session is not used
0055:         * (touched) for a preconfigured amount of time, then it is expired and removed
0056:         * from the session manager. The following parameters can be used to configure
0057:         * the session manager. They should be grouped together in a section, normally
0058:         * <code>SessionManager</code>, which is specified to the constructor.
0059:         * <p>
0060:         * <ul>
0061:         * <li><code>SessionLifetimeMax: {int}</code>
0062:         * <p>
0063:         * 
0064:         * The maximum number of minutes a session is valid. If this value us zero, then
0065:         * there is no lifetime limit. This parameter must be set in the configuration
0066:         * file.
0067:         * <p>
0068:         * 
0069:         * <li><code>SessionIdleTimeMax: {int}</code>
0070:         * <p>
0071:         * 
0072:         * Maximum number of minutes a session may be idle before the session is expired
0073:         * (deleted). If this value is less than or equal to zero, then the session may
0074:         * be idle indefinitly.
0075:         * <p>
0076:         * 
0077:         * <li><code>SessionNoUserIdleTimeMax: {int}</code>
0078:         * <p>
0079:         * 
0080:         * Maximum number of minutes a session that does not have a <CODE>User</CODE>
0081:         * object assocaited with it may be idle before the session is expired
0082:         * (deleted). If this value is less than or equal to zero, then the session may
0083:         * be idle indefinitly. Default is the same as <code>MaxIdleTime</code>
0084:         * <p>
0085:         * 
0086:         * <li><code>IdleScanInterval: {int}</code>
0087:         * <p>
0088:         * 
0089:         * How often, in seconds, the session manager tests if any sessions should be
0090:         * expired. This parameter must be greater than zero.
0091:         * <p>
0092:         * 
0093:         * <li><code>RandomizerIntervals: {int [,int]...}</code>
0094:         * <p>
0095:         * 
0096:         * The set of varying intervals to use for adding user-generated entropy to the
0097:         * random number generator. It is a good idea to use several different prime
0098:         * numbers. These intervals are in seconds.
0099:         * <p>
0100:         * 
0101:         * <li><code>SessionHome.Mode: {BASIC | PAGE_TO_DISK | PAGE_TO_DB | CUSTOM}</code>
0102:         * <p>
0103:         * 
0104:         * Indicates the mode (StandardSessionHome interface) that the standard session
0105:         * manager will use. In 'BASIC' mode the standard session manager uses the
0106:         * <code>BasicSessionHome</code> to manage sessions. In 'PAGE_TO_DISK' the
0107:         * standard session manager uses the <code>DiskPagedSessionHome</code> to
0108:         * manage sessions. In 'PAGE_TO_DB' the standard session manager used the
0109:         * <code>PersistentSessionHome</code> to manage sessions. In 'CUSTOM' the
0110:         * application specifies the classes that should be loaded and provide the
0111:         * <code>StandardSessionHome</code> implementation. If set to 'CUSTOM' then
0112:         * the settings <code>SessionHome.Class</code> and
0113:         * <code>SessionUserTable.Class</code> should be set.
0114:         * 
0115:         * <li><code>SessionHome.Class: {String}</code>
0116:         * <p>
0117:         * 
0118:         * The class that implements the StandardSessionHome interface. This class is
0119:         * loaded by StandardSessionManager and used to managed the collection of
0120:         * sessions. If this option is not specified then BasicSessionHome is used. The
0121:         * SessionHome that is loaded by the session manager is expected to contain a
0122:         * consturctor that takes the following arguments:
0123:         * <code>SessionHome(StandardSessionManager mgr,
0124:         *                       com.lutris.util.Config config,
0125:         *                       ClassLoader loader)</code>
0126:         * <p>
0127:         * 
0128:         * <li><code>SessionUserTable.Class: {String}</code>
0129:         * <p>
0130:         * 
0131:         * The class that implements the StandardSessiondUserTable interface. This class
0132:         * is loaded by StandardSessionManager and used to managed the session to user
0133:         * relationships. If this option is not specified then BasicSessionUserTable is
0134:         * used. The SessionUserTable that is loaded by the session manager is expected
0135:         * to contain a consturctor that takes the following arguments:
0136:         * <code>SessionUserTable(com.lutris.util.Config config)</code>
0137:         * <p>
0138:         * 
0139:         * <li><code>MemoryPersistence: {true|false}</code>
0140:         * <p>
0141:         * 
0142:         * Indicate that should we keep sessions in memory when stop application
0143:         * 
0144:         * </ul>
0145:         * 
0146:         * @version $Revision: 1.4 $
0147:         * @author John Marco
0148:         * @author Shawn McMurdo
0149:         * @author Kyle Clark
0150:         * @author Mark Diekhans
0151:         * @see com.lutris.util.Config
0152:         * @see StandardSessionHome
0153:         * @see StandardSessionUserTable
0154:         * @see BasicSessionHome
0155:         * @see DiskPagedSessionHome
0156:         * @see com.lutris.appserver.server.sessionEnhydra.persistent.PersistentSessionHome
0157:         */
0158:        public class StandardSessionManager implements  SessionManager,
0159:                StandardSessionIdleHandler {
0160:            /**
0161:             * Represents the current session management mode.
0162:             */
0163:            protected int mode;
0164:
0165:            /**
0166:             * Indicates that the session manager is using the basic session home
0167:             * interface to manage sessions.
0168:             * 
0169:             * @see #getMode
0170:             * @see com.lutris.appserver.server.sessionEnhydra.BasicSessionHome
0171:             */
0172:            public static final int MODE_BASIC = 1;
0173:
0174:            /**
0175:             * Indicates that the session manager is using the page to disk home
0176:             * interface to manage sessions.
0177:             * 
0178:             * @see #getMode
0179:             * @see com.lutris.appserver.server.sessionEnhydra.DiskPagedSessionHome
0180:             */
0181:            public static final int MODE_PAGE_TO_DISK = 2;
0182:
0183:            /**
0184:             * Indicates that the session manager is using the page to database home
0185:             * interface to manage sessions.
0186:             * 
0187:             * @see #getMode
0188:             * @see com.lutris.appserver.server.sessionEnhydra.persistent.PersistentSessionHome
0189:             */
0190:            public static final int MODE_PAGE_TO_DB = 3;
0191:
0192:            /**
0193:             * Indicates that the session manager is using the custom home interface to
0194:             * manage sessions.
0195:             * 
0196:             * @see #getMode
0197:             */
0198:            public static final int MODE_CUSTOM = 4;
0199:
0200:            /**
0201:             * Indicates that url encoding of session ids is never preformed.
0202:             * 
0203:             * @see #getEncodeUrlState
0204:             */
0205:            public static final String ENCODE_URL_NEVER = "Never";
0206:
0207:            /**
0208:             * Indicates that url encoding of session ids is always preformed.
0209:             * 
0210:             * @see #getEncodeUrlState
0211:             */
0212:            public static final String ENCODE_URL_ALWAYS = "Always";
0213:
0214:            /**
0215:             * Indicates that url encoding of session ids is preformed only when cookies
0216:             * are disabled on the client browser. This is automatically detected.
0217:             * 
0218:             * @see #getEncodeUrlState
0219:             */
0220:            public static final String ENCODE_URL_AUTO = "Auto";
0221:
0222:            public static final String ENCODE_RANDOM_YES = "Yes";
0223:
0224:            public static final String ENCODE_RANDOM_NO = "No";
0225:
0226:            /**
0227:             * Default maximum session life time, in seconds. Zero if there is no limit.
0228:             * A derived <CODE>SessionManager</CODE> may override this value to use
0229:             * the default expiration logic or override <CODE>isSessionExpired</CODE>
0230:             * to define custom expiration logic.
0231:             * 
0232:             * @see lutris.session.StandardSessionManager#getMaxSessionLifeTime
0233:             */
0234:            protected static long defaultMaxSessionLifeTime = 0;
0235:
0236:            /**
0237:             * Default maximum session idle time, in seconds. A derived <CODE>SessionManager</CODE>
0238:             * may override this value to use the default expiration logic or override
0239:             * <CODE>isSessionExpired</CODE> to define custom expiration logic. A
0240:             * value less-than or equal to zero disables idle checking. Default value is
0241:             * 30 minutes.
0242:             * 
0243:             * @see #getMaxSessionIdleTime
0244:             */
0245:            protected static long defaultMaxSessionIdleTime = 30 * 60;
0246:
0247:            /**
0248:             * Indicates url encoding status. Assumes that
0249:             * comms.response.writeHTML(HTMLDocument doc) is used to commit the response
0250:             * to the client. The default is to Auto.<br>
0251:             * <code>Never</code> indicates urls are never encoded with session keys.
0252:             * This indicates that session cookies have to be used or no session state
0253:             * can be maintained.<br>
0254:             * <code>Always</code> indicates that urls are always encoded with session
0255:             * keys. Session cookies are never used.<br>
0256:             * <code>Auto</code> indicates that session cookies will be if available.
0257:             * If not, urls will automatically be encoded.<br>
0258:             * 
0259:             * @see #getEncodeUrlState
0260:             */
0261:            protected static String defaultEncodeUrlState = "Auto";
0262:
0263:            /**
0264:             * Default interval, in seconds, to scan for sessions to expire. A derived
0265:             * <CODE>SessionManager</CODE> may override this value. Default value is
0266:             * 30 seconds.
0267:             */
0268:            protected static long defaultIdleScanInterval = 30;
0269:
0270:            /**
0271:             * Default list of randomize key generator time intervals, in seconds. A
0272:             * list of prime numbers is recommended. A derived <CODE>SessionManager</CODE>
0273:             * may override this value.
0274:             */
0275:            protected static long[] defaultRandomizerIntervals = { 301, 1001,
0276:                    5003 };
0277:
0278:            /**
0279:             * Determins whether to use empty path (/) as session cookie path attribute
0280:             * value! Default value is false which means - use application context path.
0281:             */
0282:            protected static boolean defaultEmptySessionPath = false;
0283:
0284:            /**
0285:             * The name of the config variable for the EmptySessionPath.
0286:             */
0287:            public static final String CFG_EMPTY_SESSION_PATH = "EmptySessionPath";
0288:
0289:            /**
0290:             * The name of the config variable for the max session lifetime.
0291:             */
0292:            public static final String CFG_LIFE = "SessionLifetimeMax";
0293:
0294:            /**
0295:             * The name of the config variable for the max session idle time.
0296:             */
0297:            public static final String CFG_IDLE = "SessionIdleTimeMax";
0298:
0299:            /**
0300:             * The name of the config variable for the url encoding state
0301:             */
0302:            public static final String CFG_ENCODE_URL_STATE = "SessionEncodeUrlState";
0303:
0304:            /**
0305:             * Url encoding for first page state (to force it or not)
0306:             * CFG_ENCODE_URL_STATE must not be set to NEVER for this parameter to take
0307:             * efect
0308:             */
0309:            public static final String CFG_ENCODE_FIRST_URL = "SessionEncodeFirstUrl";
0310:
0311:            /**
0312:             * The name of the config variable for the max idle time for sessions with
0313:             * no user.
0314:             */
0315:            public static final String CFG_NOUSER_IDLE = "SessionNoUserIdleTimeMax";
0316:
0317:            /**
0318:             * The name of the config variable for the interval between scans for idle
0319:             * sessions.
0320:             */
0321:            public static final String CFG_SCAN = "IdleScanInterval";
0322:
0323:            /**
0324:             * The name of the config variable for the interval between introduction of
0325:             * randomness to the session key generator.
0326:             */
0327:            public static final String CFG_RANDOM = "RandomizerIntervals";
0328:
0329:            /**
0330:             * The name of the config variable for the session home settings.
0331:             */
0332:            public static final String CFG_SESSION_HOME = "SessionHome";
0333:
0334:            /**
0335:             * The name of the config variable for the session home type.
0336:             */
0337:            public static final String CFG_SESSION_HOME_TYPE = "SessionHome.Mode";
0338:
0339:            /**
0340:             * Indicates that a sesson is still active.
0341:             * 
0342:             * @see #sessionDeleted
0343:             */
0344:            public static final int SESSION_ACTIVE = 0;
0345:
0346:            /**
0347:             * Indicates that a sesson was deleted due to max time being exceeded.
0348:             * 
0349:             * @see #sessionDeleted
0350:             */
0351:            public static final int SESSION_MAX_TIME = 1;
0352:
0353:            /**
0354:             * Indicates that a sesson was deleted due to idle time being exceeded.
0355:             * 
0356:             * @see #sessionDeleted
0357:             */
0358:            public static final int SESSION_IDLE_EXPIRE = 2;
0359:
0360:            /**
0361:             * Indicates that a sesson was explictly deleted.
0362:             * 
0363:             * @see #sessionDeleted
0364:             */
0365:            public static final int SESSION_EXPLICT_DELETE = 3;
0366:
0367:            /**
0368:             * Table of currently active user sessions is managed by the session home.
0369:             * Different implementations of StandardSessionHome can be loaded by this
0370:             * manager. A specific implementation can manage failover persistence,
0371:             * paging, etc.
0372:             */
0373:            // private StandardSessionHome sessionHome;
0374:            protected StandardSessionHome sessionHome;
0375:
0376:            /**
0377:             * Table of users objects. This table tracks the number of simultaneous
0378:             * sessions a user currently has active. Table entries are of type <CODE>Vector</CODE>,
0379:             * constaining Session objects, keyed by User object reference.
0380:             */
0381:            private StandardSessionUserTable sessionUserTable;
0382:
0383:            // The maximum number of sessions (highwater mark).
0384:            protected int maxSessions;
0385:
0386:            protected Date maxSessionsDate;
0387:
0388:            /**
0389:             * Object that generates random session keys. Manages a thread to for
0390:             * increase randomization.
0391:             * 
0392:             * @see StandardSessionKeyGen
0393:             */
0394:            private StandardSessionKeyGen keyGenerator;
0395:
0396:            /**
0397:             * Maximum session life time, in seconds. Zero if there is no limit.
0398:             * 
0399:             * @see lutris.session.StandardSessionManager#getMaxSessionLifeTime
0400:             */
0401:            private long maxSessionLifeTime;
0402:
0403:            /**
0404:             * Maximum session idle time, in seconds. A value less-than or equal to zero
0405:             * disables idle checking.
0406:             * 
0407:             * @see #getMaxSessionIdleTime
0408:             */
0409:            protected long maxSessionIdleTime;
0410:
0411:            /**
0412:             * The url encoding state. Either <code>Never</code>
0413:             * <code>Always</code> <code>Auto</code>.
0414:             */
0415:            protected String encodeUrlState;
0416:
0417:            /**
0418:             * Url encoding for first page state (force it or not)
0419:             */
0420:            protected boolean encodeFirstUrl;
0421:
0422:            /**
0423:             * Background thread that keeps track of session idle time. Sessions that
0424:             * have been idle for more than a configurable time limit are terminated by
0425:             * this thread.
0426:             * 
0427:             * @see StandardSessionIdleTimer
0428:             */
0429:            private StandardSessionIdleTimer idleTimer;
0430:
0431:            /**
0432:             * Maximum session idle time, in seconds for sessions that don't have a
0433:             * <CODE>User</CODE> object associated with them. A value less-than or
0434:             * equal to zero disables idle checking.
0435:             * 
0436:             * @see #getMaxNoUserSessionIdleTime
0437:             */
0438:            protected long maxNoUserSessionIdleTime;
0439:
0440:            /**
0441:             * The time in seconds between scans for idle sessions to expire.
0442:             */
0443:            protected long scanInterval;
0444:
0445:            /**
0446:             * determins whether to use empty path (/) as session cookie path attribute
0447:             * value!
0448:             */
0449:            protected boolean emptySessionPath;
0450:
0451:            /**
0452:             * Log channel for debugging messages.
0453:             */
0454:            LogChannel logChannel = null;
0455:
0456:            /**
0457:             * The application using this session manager.
0458:             */
0459:            Application app = null;
0460:
0461:            /**
0462:             * The class loader used by this app/context.
0463:             */
0464:            ClassLoader classLoader;
0465:
0466:            /**
0467:             * The supported session home types.
0468:             */
0469:            private static final String BASIC = "BASIC";
0470:
0471:            private static final String PAGE_TO_DISK = "PAGE_TO_DISK";
0472:
0473:            private static final String PAGE_TO_DB = "PAGE_TO_DB";
0474:
0475:            private static final String CUSTOM = "CUSTOM";
0476:
0477:            /**
0478:             * The session home interface type being used.
0479:             */
0480:            String sessionHomeType = BASIC;
0481:
0482:            /**
0483:             * DACHA & TUFA variable which determine should we held sessions in memory
0484:             * during restart application
0485:             */
0486:            private boolean isMemoryPersistence = false;
0487:
0488:            /**
0489:             * Log configuration information.
0490:             */
0491:            private void logConfig() {
0492:                if (logChannel != null) {
0493:                    logChannel.write(Logger.DEBUG, "SessionManager." + CFG_LIFE
0494:                            + " = " + maxSessionLifeTime + " sec");
0495:                    logChannel.write(Logger.DEBUG, "SessionManager." + CFG_IDLE
0496:                            + " = " + maxSessionIdleTime + " sec");
0497:                    logChannel.write(Logger.DEBUG, "SessionManager."
0498:                            + CFG_NOUSER_IDLE + " = "
0499:                            + maxNoUserSessionIdleTime + " sec");
0500:                    logChannel.write(Logger.DEBUG, "SessionManager." + CFG_SCAN
0501:                            + " = " + scanInterval + " sec");
0502:                    logChannel.write(Logger.DEBUG, "SessionManager."
0503:                            + CFG_ENCODE_URL_STATE + " = " + encodeUrlState);
0504:                    logChannel.write(Logger.DEBUG, "SessionManager."
0505:                            + CFG_ENCODE_FIRST_URL + " = " + encodeFirstUrl);
0506:                    logChannel
0507:                            .write(Logger.DEBUG, "SessionManager."
0508:                                    + CFG_EMPTY_SESSION_PATH + " = "
0509:                                    + emptySessionPath);
0510:                }
0511:            }
0512:
0513:            public StandardSessionManager() {
0514:            }
0515:
0516:            /**
0517:             * Creates a new <code>SessionManager</code> object. This constructor will
0518:             * first looks for the session manager configuration parameters that have
0519:             * the specified configuration prefix prepended to the standard session
0520:             * manager configuration option.
0521:             * <p>
0522:             * 
0523:             * @param app
0524:             *            the application associate with this session manager.
0525:             * @param config
0526:             *            Object parsed from configuration file. This should be for the
0527:             *            section constaining the session manager configuration.
0528:             * @param sessionMgrLogChannel
0529:             *            If not <CODE>null</CODE>, channel to log debugging
0530:             *            information to.
0531:             * @exception ConfigException
0532:             *                signifies a problem in the configuration file.
0533:             * @exception SessionException
0534:             *                if all classes (Home and UserTable) couldn't be loaded by
0535:             *                the session manager.
0536:             */
0537:            public StandardSessionManager(Application application,
0538:                    Config config, LogChannel sessionMgrLogChannel)
0539:                    throws ConfigException, SessionException {
0540:                // DACHA: first initialize app
0541:                app = application;
0542:                initManager(application.getClass().getClassLoader(), config,
0543:                        sessionMgrLogChannel);
0544:            }
0545:
0546:            public StandardSessionManager(ClassLoader classLoader,
0547:                    Config config, LogChannel sessionMgrLogChannel)
0548:                    throws ConfigException, SessionException {
0549:                initManager(classLoader, config, sessionMgrLogChannel);
0550:            }
0551:
0552:            private void initManager(ClassLoader classLoader, Config config,
0553:                    LogChannel sessionMgrLogChannel) throws ConfigException,
0554:                    SessionException {
0555:                this .classLoader = classLoader;
0556:                logChannel = sessionMgrLogChannel;
0557:                // High-water mark
0558:                maxSessions = 0;
0559:                maxSessionsDate = new Date();
0560:                /**
0561:                 * DACHA & TUFA Config file specifies should we keep SessionManager in
0562:                 * memory during restart application
0563:                 */
0564:                if (config.containsKey("MemoryPersistence")) {
0565:                    String mp = config.getString("MemoryPersistence");
0566:                    if (mp.equals("true"))
0567:                        isMemoryPersistence = true;
0568:                }
0569:                /*
0570:                 * Config file specifies minutes, but the values are kept internally as
0571:                 * seconds.
0572:                 */
0573:                // Session lifetime
0574:                if (config.containsKey(CFG_LIFE)) {
0575:                    maxSessionLifeTime = config.getLong(CFG_LIFE) * 60;
0576:                } else if (config.containsKey("Lifetime")) {
0577:                    // backwards compatability
0578:                    maxSessionLifeTime = config.getLong("Lifetime") * 60;
0579:                } else {
0580:                    maxSessionLifeTime = defaultMaxSessionLifeTime;
0581:                }
0582:                // Idle time.
0583:                if (config.containsKey(CFG_IDLE)) {
0584:                    maxSessionIdleTime = config.getLong(CFG_IDLE) * 60;
0585:                } else if (config.containsKey("MaxIdleTime")) {
0586:                    // backwards compatability
0587:                    maxSessionIdleTime = config.getLong("MaxIdleTime") * 60;
0588:                } else {
0589:                    maxSessionIdleTime = defaultMaxSessionIdleTime;
0590:                }
0591:                // Url encoding state
0592:                if (config.containsKey(CFG_ENCODE_URL_STATE)) {
0593:                    encodeUrlState = config.getString(CFG_ENCODE_URL_STATE);
0594:                } else if (config.containsKey("EncodeUrlState")) {
0595:                    // backwards compatability
0596:                    encodeUrlState = config.getString("EncodeUrlState");
0597:                } else {
0598:                    encodeUrlState = defaultEncodeUrlState;
0599:                }
0600:                if (!encodeUrlState.equalsIgnoreCase(ENCODE_URL_NEVER)
0601:                        && !encodeUrlState.equalsIgnoreCase(ENCODE_URL_ALWAYS)
0602:                        && !encodeUrlState.equalsIgnoreCase(ENCODE_URL_AUTO)) {
0603:                    throw new ConfigException(
0604:                            "EncodeUrlState must be one of the following: "
0605:                                    + ENCODE_URL_NEVER + ", "
0606:                                    + ENCODE_URL_ALWAYS + ", or "
0607:                                    + ENCODE_URL_AUTO + ".");
0608:                }
0609:
0610:                /**
0611:                 * Url encoding for first page state (to force it or not)
0612:                 * CFG_ENCODE_URL_STATE must not be set to NEVER for this parameter to
0613:                 * take efect
0614:                 */
0615:                if (config.containsKey(CFG_ENCODE_FIRST_URL)) {
0616:                    encodeFirstUrl = config.getBoolean(CFG_ENCODE_FIRST_URL,
0617:                            false);
0618:                } else {
0619:                    encodeFirstUrl = false;
0620:                }
0621:
0622:                /**
0623:                 * Whether to use empty path for session cookies
0624:                 */
0625:                if (config.containsKey(CFG_EMPTY_SESSION_PATH)) {
0626:                    emptySessionPath = config.getBoolean(
0627:                            CFG_EMPTY_SESSION_PATH, false);
0628:                } else {
0629:                    emptySessionPath = false;
0630:                }
0631:
0632:                /**
0633:                 * if CFG_ENCODE_URL_STATE is set to ALWAYS or NEVER ignore original and
0634:                 * set adequate CFG_ENCODE_FIRST_URL parameter value
0635:                 */
0636:                if (encodeUrlState.equalsIgnoreCase(ENCODE_URL_ALWAYS)) {
0637:                    encodeFirstUrl = true;
0638:                } else if (encodeUrlState.equalsIgnoreCase(ENCODE_URL_NEVER)) {
0639:                    encodeFirstUrl = false;
0640:                }
0641:
0642:                if (config.containsKey(CFG_NOUSER_IDLE)) {
0643:                    maxNoUserSessionIdleTime = config.getLong(CFG_NOUSER_IDLE) * 60;
0644:                } else if (config.containsKey("MaxNoUserIdleTime")) {
0645:                    // backwards compatability
0646:                    maxNoUserSessionIdleTime = config
0647:                            .getLong("MaxNoUserIdleTime") * 60;
0648:                } else {
0649:                    maxNoUserSessionIdleTime = maxSessionIdleTime;
0650:                }
0651:                scanInterval = defaultIdleScanInterval;
0652:                if (config.containsKey(CFG_SCAN)) {
0653:                    scanInterval = config.getLong(CFG_SCAN);
0654:                } else if (config.containsKey("IdleScanInterval")) {
0655:                    // backwards compatability
0656:                    scanInterval = config.getLong("IdleScanInterval");
0657:                }
0658:                if (scanInterval <= 0) {
0659:                    throw new ConfigException(
0660:                            "IdleScanInterval must be greater than zero.");
0661:                }
0662:                idleTimer = new StandardSessionIdleTimer(this , app,
0663:                        scanInterval);
0664:                if (config.containsKey(CFG_SESSION_HOME_TYPE)) {
0665:                    sessionHomeType = config.getString(CFG_SESSION_HOME_TYPE);
0666:                }
0667:                if (!sessionHomeType.equalsIgnoreCase(BASIC)
0668:                        && !sessionHomeType.equalsIgnoreCase(PAGE_TO_DISK)
0669:                        && !sessionHomeType.equalsIgnoreCase(PAGE_TO_DB)
0670:                        && !sessionHomeType.equalsIgnoreCase(CUSTOM)) {
0671:                    throw new ConfigException("Invalid "
0672:                            + CFG_SESSION_HOME_TYPE + ": '" + sessionHomeType
0673:                            + "'");
0674:                }
0675:                // Session Home
0676:                sessionHome = loadSessionHome(config);
0677:                // Session User Table
0678:                sessionUserTable = loadSessionUserTable(config);
0679:                // Random key generator.
0680:                long[] intervals = config.getLongs(CFG_RANDOM,
0681:                        defaultRandomizerIntervals);
0682:                if (intervals.length == 0) {
0683:                    throw new ConfigException(CFG_RANDOM
0684:                            + " must contain some values.");
0685:                }
0686:                for (int i = 0; i < intervals.length; i++) {
0687:                    if (intervals[i] <= 0) {
0688:                        throw new ConfigException(CFG_RANDOM
0689:                                + " must contain positive integers.");
0690:                    }
0691:                }
0692:                keyGenerator = new StandardSessionKeyGen(intervals);
0693:                // Start threads.
0694:                keyGenerator.start();
0695:                idleTimer.start();
0696:                logConfig();
0697:            }
0698:
0699:            /**
0700:             * Loads the StandardSessionHome used by this session manager.
0701:             * 
0702:             * @param config
0703:             *            This session manager's config section.
0704:             * @exception ConfigException
0705:             *                if the configuration is invalid.
0706:             * @exception SessionException
0707:             *                if the StandardSessionHome could not be loaded.
0708:             */
0709:            protected StandardSessionHome loadSessionHome(Config config)
0710:                    throws ConfigException, SessionException {
0711:                try {
0712:                    StandardSessionHome sessionHome = null;
0713:                    Config homeConfig = null;
0714:                    if (config.containsKey(CFG_SESSION_HOME)) {
0715:                        homeConfig = (Config) config
0716:                                .getSection(CFG_SESSION_HOME);
0717:                    } else {
0718:                        homeConfig = new Config();
0719:                    }
0720:                    if (sessionHomeType.equalsIgnoreCase(CUSTOM)) {
0721:                        if (homeConfig.containsKey("Class")) {
0722:                            String homeClassName = homeConfig
0723:                                    .getString("Class");
0724:                            try {
0725:                                Class[] paramTypes = new Class[3];
0726:                                Object[] args = new Object[3];
0727:                                paramTypes[0] = Class
0728:                                        .forName("com.lutris.appserver.server.sessionEnhydra.StandardSessionManager");
0729:                                paramTypes[1] = Class
0730:                                        .forName("com.lutris.util.Config");
0731:                                paramTypes[2] = Class
0732:                                        .forName("java.lang.ClassLoader");
0733:                                args[0] = this ;
0734:                                args[1] = homeConfig;
0735:                                args[2] = classLoader;
0736:                                Constructor c = Class.forName(homeClassName)
0737:                                        .getConstructor(paramTypes);
0738:                                sessionHome = (StandardSessionHome) c
0739:                                        .newInstance(args);
0740:                                if (logChannel != null) {
0741:                                    logChannel.write(Logger.DEBUG,
0742:                                            "SessionMgr: "
0743:                                                    + "StandardSessionHome: "
0744:                                                    + homeClassName);
0745:                                }
0746:                            } catch (Exception e) {
0747:                                throw new SessionException("Unable to load "
0748:                                        + homeClassName, e);
0749:                            }
0750:                        }
0751:                        mode = MODE_CUSTOM;
0752:                    } else if (sessionHomeType.equalsIgnoreCase(PAGE_TO_DISK)) {
0753:                        sessionHome = new DiskPagedSessionHome(this ,
0754:                                homeConfig, classLoader);
0755:                        mode = MODE_PAGE_TO_DISK;
0756:                    } else if (sessionHomeType.equalsIgnoreCase(PAGE_TO_DB)) {
0757:                        sessionHome = new PersistentSessionHome(this ,
0758:                                homeConfig, classLoader);
0759:                        mode = MODE_PAGE_TO_DB;
0760:                    } else {
0761:                        sessionHome = new BasicSessionHome(this , homeConfig);
0762:                        mode = MODE_BASIC;
0763:                    }
0764:                    if (logChannel != null) {
0765:                        logChannel.write(Logger.DEBUG, "SessionMgr: "
0766:                                + "StandardSessionHome: " + sessionHomeType
0767:                                + "\n");
0768:                    }
0769:                    return sessionHome;
0770:                } catch (KeywordValueException e) {
0771:                    e.printStackTrace();
0772:                    throw new ConfigException(
0773:                            "SessionMgr: unable to load StandardSessionHome: "
0774:                                    + e);
0775:                }
0776:            }
0777:
0778:            /**
0779:             * Loads the StandardSessiondUserTable used by this session manager.
0780:             * 
0781:             * @param config
0782:             *            This session manager's config section.
0783:             * @exception ConfigException
0784:             *                if the StandardSessionHome could not be loaded.
0785:             */
0786:            protected StandardSessionUserTable loadSessionUserTable(
0787:                    Config config) throws ConfigException, SessionException {
0788:                try {
0789:                    StandardSessionUserTable sessionUserTable = null;
0790:                    Config userTableConfig = null;
0791:                    if (config.containsKey("SessionUserTable")) {
0792:                        userTableConfig = (Config) config
0793:                                .getSection("SessionUserTable");
0794:                    } else {
0795:                        userTableConfig = new Config();
0796:                    }
0797:                    if (sessionHomeType.equalsIgnoreCase(CUSTOM)) {
0798:                        String tableClassName = userTableConfig
0799:                                .getString("Class");
0800:                        try {
0801:                            Class[] paramTypes = new Class[1];
0802:                            Object[] args = new Object[1];
0803:                            paramTypes[0] = Class
0804:                                    .forName("com.lutris.util.Config");
0805:                            args[0] = userTableConfig;
0806:                            Constructor c = Class.forName(tableClassName)
0807:                                    .getConstructor(paramTypes);
0808:                            sessionUserTable = (StandardSessionUserTable) c
0809:                                    .newInstance(args);
0810:                            if (logChannel != null) {
0811:                                logChannel.write(Logger.DEBUG, "SessionMgr: "
0812:                                        + "StandardSessionUserTable: "
0813:                                        + tableClassName);
0814:                            }
0815:                        } catch (NoSuchMethodException e) {
0816:                            throw new SessionException("Unable to load "
0817:                                    + tableClassName + ": "
0818:                                    + "Constructor not found.", e);
0819:                        } catch (Exception e) {
0820:                            throw new SessionException(
0821:                                    "Unable to create instance of "
0822:                                            + tableClassName, e);
0823:                        }
0824:                    } else if (sessionHomeType.equalsIgnoreCase(PAGE_TO_DISK)) {
0825:                        sessionUserTable = new PagedSessionUserTable(
0826:                                userTableConfig);
0827:                    } else if (sessionHomeType.equalsIgnoreCase(PAGE_TO_DB)) {
0828:                        sessionUserTable = new PersistentSessionUserTable(
0829:                                userTableConfig);
0830:                    } else {
0831:                        sessionUserTable = new BasicSessionUserTable(
0832:                                userTableConfig);
0833:                    }
0834:                    return sessionUserTable;
0835:                } catch (KeywordValueException e) {
0836:                    throw new ConfigException(
0837:                            "SessionMgr: unable to load StandardSessionUserTable: "
0838:                                    + e);
0839:                }
0840:            }
0841:
0842:            /**
0843:             * Shutdown this session manager, stopping threads that are associated with
0844:             * it.
0845:             */
0846:            public synchronized void shutdown() {
0847:                if (isMemoryPersistence)
0848:                    MemoryPersistence.putSessionManager(app.getName(), this );
0849:                else {
0850:                    if (keyGenerator != null) {
0851:                        keyGenerator.shutdown();
0852:                        keyGenerator = null;
0853:                    }
0854:                    if (idleTimer != null) {
0855:                        idleTimer.shutdown();
0856:                        idleTimer = null;
0857:                    }
0858:                    if (sessionHome != null) {
0859:                        sessionHome.shutdown();
0860:                        sessionHome = null;
0861:                    }
0862:                    if (sessionUserTable != null) {
0863:                        sessionUserTable.shutdown();
0864:                        sessionUserTable = null;
0865:                    }
0866:                }
0867:            }
0868:
0869:            /**
0870:             * Allocate a new <CODE>StandardSession</CODE> object. This maybe
0871:             * overridden by derived session managers to allocated a <CODE>Session</CODE>
0872:             * object derived from <CODE>StandardSession</CODE>. This is called by
0873:             * <CODE>createSession</CODE>.
0874:             * 
0875:             * @param sessionKey
0876:             *            The session key to associate with the session.
0877:             * @return session The new <code>StandardSession</code> object.
0878:             * @see StandardSession
0879:             * @deprecated The instance of StandardSessionHome should be replaced
0880:             *             instead of extending this method.
0881:             */
0882:            protected StandardSession newSession(String sessionKey)
0883:                    throws CreateSessionException, SessionException {
0884:                return (StandardSession) sessionHome.createSession(sessionKey);
0885:            }
0886:
0887:            /**
0888:             * Create a new <CODE>Session</CODE> object and associate a unique random
0889:             * key. No <CODE>User</CODE> is initially associated with (<CODE>Session.getUser()</CODE>
0890:             * returns <CODE>null</CODE>/
0891:             * 
0892:             * @return session The new <code>Session</code> object.
0893:             * @exception SessionException
0894:             *                if the session cannot be created.
0895:             * @see Session
0896:             */
0897:            public Session createSession() throws SessionException {
0898:                return createSession("");
0899:            }
0900:
0901:            /**
0902:             * Create a new <CODE>Session</CODE> object and associate a unique random
0903:             * key. No <CODE>User</CODE> is initially associated with (<CODE>Session.getUser()</CODE>
0904:             * returns <CODE>null</CODE>/
0905:             * 
0906:             * @param ipPortToken
0907:             *            The base64 encoded IP and Port number to include in session
0908:             *            key
0909:             * @return session The new <code>Session</code> object.
0910:             * @exception SessionException
0911:             *                if the session cannot be created.
0912:             * @see Session
0913:             */
0914:            public Session createSession(String ipPortToken)
0915:                    throws SessionException {
0916:                StandardSession session = null;
0917:                String sessionKey = null;
0918:                /*
0919:                 * Create a new key that does not already exist in the session table.
0920:                 * The odds of this loop making more than one pass are astronomically
0921:                 * small, but not zero.
0922:                 */
0923:                do {
0924:                    try {
0925:                        sessionKey = keyGenerator.newSessionKey();
0926:                        if (ipPortToken != null && ipPortToken.length() > 0) {
0927:                            sessionKey = sessionKey.substring(0, sessionKey
0928:                                    .length() - 2)
0929:                                    + ipPortToken;
0930:                        }
0931:                        session = sessionHome.createSession(sessionKey);
0932:                    } catch (DuplicateKeyException e) {
0933:                        // TODO - log message?
0934:                        session = null;
0935:                    }
0936:                } while (session == null);
0937:                int currentSize = sessionHome.size();
0938:                if (currentSize > maxSessions) {
0939:                    maxSessions = currentSize;
0940:                    maxSessionsDate = new Date();
0941:                }
0942:                keyGenerator.incrementRandomCounter();
0943:                if (logChannel != null) {
0944:                    logChannel.write(Logger.DEBUG,
0945:                            "SessionMgr: createSession: " + sessionKey);
0946:                }
0947:                return session;
0948:            }
0949:
0950:            public Session createSession(HttpPresentationComms comms)
0951:                    throws SessionException {
0952:                Session s = null;
0953:                String saTok = null;
0954:                try {
0955:                    saTok = comms.request.getHeader(":aff:");
0956:                } catch (HttpPresentationException hpe) {
0957:                    saTok = null;
0958:                }
0959:                if (saTok == null) {
0960:                    s = createSession();
0961:                } else {
0962:                    s = createSession(saTok);
0963:                    if (logChannel != null) {
0964:                        logChannel.write(Logger.DEBUG,
0965:                                "SessionKey created for EnhydraDirector");
0966:                    }
0967:                }
0968:                return s;
0969:            }
0970:
0971:            /**
0972:             * Log a user being registered or unregistered.
0973:             */
0974:            private void logRegisterUser(Session session, String which) {
0975:                if (logChannel != null) {
0976:                    String userName = null;
0977:                    User user = session.getUser();
0978:                    if (user != null) {
0979:                        userName = user.getName();
0980:                    }
0981:                    logChannel.write(Logger.DEBUG, "SessionMgr: " + which
0982:                            + ": " + session.getSessionKey() + " user = \""
0983:                            + userName + "\"");
0984:                }
0985:            }
0986:
0987:            /**
0988:             * Adds a session's user to the session-to-user table. This is called by the
0989:             * <CODE>Session</CODE> object to associate a session with a user.
0990:             * 
0991:             * @param session
0992:             *            The now logged-in <code>Session</code> instance to store in
0993:             *            the session table.
0994:             * @see Session
0995:             * @see User
0996:             * @see #unregisterUser
0997:             * @exception SessionException
0998:             *                if an error occurs.
0999:             */
1000:            protected synchronized void registerUser(Session session)
1001:                    throws SessionException {
1002:                sessionUserTable
1003:                        .add(session.getSessionKey(), session.getUser());
1004:                logRegisterUser(session, "registerUser");
1005:            }
1006:
1007:            /**
1008:             * Removes a session's user from the session-to-user table. This is called
1009:             * by the <CODE>Session</CODE> object to disassoicate a user from a
1010:             * session.
1011:             * 
1012:             * @param session
1013:             *            The now <code>Session</code> instance the user is being
1014:             *            logged out from.
1015:             * @see Session
1016:             * @exception SessionException
1017:             *                if an error occurs.
1018:             */
1019:            protected synchronized void unregisterUser(Session session)
1020:                    throws SessionException {
1021:                logRegisterUser(session, "unregisterUser");
1022:                sessionUserTable.remove(session.getSessionKey(), session
1023:                        .getUser());
1024:            }
1025:
1026:            /**
1027:             * Determine if a session should be expired based on the idle time. This
1028:             * method is designed to be overriden by derived classes that want to use
1029:             * different idle time checks.
1030:             * 
1031:             * @param session
1032:             *            Session to check.
1033:             * @return A reason code for the experation. One of <CODE>SESSION_MAX_TIME</CODE>,
1034:             *         <CODE>SESSION_IDLE_EXPIRE</CODE>, or <CODE>SESSION_ACTIVE</CODE>,
1035:             *         to indicate that the session is not expired.
1036:             * 
1037:             * @see #sessionDeleted
1038:             * @see #maxSessionIdleTime
1039:             * @see #maxNoUserSessionIdleTime
1040:             */
1041:            protected int isSessionExpired(StandardSession session) {
1042:                long now = System.currentTimeMillis();
1043:                /*
1044:                 * Has the session reached it's maximum age, regardless of user
1045:                 * interaction? This is an optional feature.
1046:                 */
1047:                long maxAge = session.getTimeExpires();
1048:                if ((maxAge > 0) && (now > maxAge)) {
1049:                    return SESSION_MAX_TIME;
1050:                }
1051:                /*
1052:                 * Has the session been idle too long? There are two thresholds, for
1053:                 * whether or not a user is logged in. Both are optional features.
1054:                 */
1055:                long idle = now - session.getTimeLastUsed();
1056:                long maxIdle;
1057:                if (session.getUser() != null) {
1058:                    maxIdle = session.getMaxIdleTime();
1059:                } else {
1060:                    maxIdle = session.getMaxNoUserIdleTime();
1061:                }
1062:                if ((maxIdle > 0) && (idle > maxIdle)) {
1063:                    return SESSION_IDLE_EXPIRE;
1064:                }
1065:                /*
1066:                 * The session is ok.
1067:                 */
1068:                return SESSION_ACTIVE;
1069:            }
1070:
1071:            /**
1072:             * Method called when a session is deleted. This method is designed to be
1073:             * overriden by derived classes that want need to take specific action, such
1074:             * as saving the sessions state. The default implementation of this method
1075:             * does nothing.
1076:             * 
1077:             * @param session
1078:             *            Session that is being delete.
1079:             * @param reason
1080:             *            The reason the session was being deleted. One of <CODE>SESSION_MAX_TIME</CODE>,
1081:             *            <CODE>SESSION_IDLE_EXPIRE</CODE>, <CODE>SESSION_EXPLICT_DELETE</CODE>.
1082:             * @see #isSessionExpired
1083:             */
1084:            protected void sessionDeleted(Session session, int reason) {
1085:                // Default implementation does nothing.
1086:            }
1087:
1088:            /**
1089:             * Does the actual work of deleting an entry from the session table.
1090:             * 
1091:             * @param session
1092:             *            The session to delete.
1093:             * @param reason
1094:             *            The reason the session was being deleted.
1095:             * @exception SessionException
1096:             *                If the session cannot be deleted.
1097:             */
1098:            private void doDeleteSession(StandardSession session, int reason)
1099:                    throws SessionException {
1100:                keyGenerator.incrementRandomCounter();
1101:                if (logChannel != null) {
1102:                    String userName = null;
1103:                    User user = session.getUser();
1104:                    if (user != null) {
1105:                        userName = user.getName();
1106:                    }
1107:                    String reasonMsg;
1108:                    switch (reason) {
1109:                    case SESSION_ACTIVE:
1110:                        reasonMsg = "SESSION_ACTIVE";
1111:                        break;
1112:                    case SESSION_MAX_TIME:
1113:                        reasonMsg = "SESSION_MAX_TIME";
1114:                        break;
1115:                    case SESSION_IDLE_EXPIRE:
1116:                        reasonMsg = "SESSION_IDLE_EXPIRE";
1117:                        break;
1118:                    case SESSION_EXPLICT_DELETE:
1119:                        reasonMsg = "SESSION_EXPLICT_DELETE";
1120:                        break;
1121:                    default:
1122:                        reasonMsg = "bad reason code " + reason;
1123:                        break;
1124:                    }
1125:                    logChannel.write(Logger.DEBUG, "SessionMgr deleteSession: "
1126:                            + session.getSessionKey() + " user = \"" + userName
1127:                            + "\" reason = " + reasonMsg);
1128:                }
1129:                // add by K.Nakamura
1130:                // Call valueUnbound on session attributes
1131:                HttpSession hs = session.getHttpSession();
1132:                for (Enumeration e = hs.getAttributeNames(); e
1133:                        .hasMoreElements();) {
1134:                    String key = (String) e.nextElement();
1135:                    Object value = hs.getAttribute(key);
1136:                    if (value instanceof  HttpSessionBindingListener) {
1137:                        try {
1138:                            ((HttpSessionBindingListener) value)
1139:                                    .valueUnbound(new HttpSessionBindingEvent(
1140:                                            hs, key));
1141:                        } catch (Exception ex) {
1142:                            // ignored
1143:                        }
1144:                    }
1145:                }
1146:                if (session.getUser() != null) {
1147:                    sessionUserTable.remove(session.getSessionKey(), session
1148:                            .getUser());
1149:                }
1150:                sessionHome.removeSession(session.getSessionKey());
1151:            }
1152:
1153:            /**
1154:             * Removes a session from the Session Table. This method is used to log a
1155:             * user off the application. Note that <CODE>sessionDeleted()</CODE> is
1156:             * called.
1157:             * 
1158:             * @param session
1159:             *            Session object to remove from table removed.
1160:             * @exception SessionException
1161:             *                If the session cannot be deleted.
1162:             */
1163:            public synchronized void deleteSession(Session session)
1164:                    throws SessionException {
1165:                sessionDeleted((StandardSession) session,
1166:                        SESSION_EXPLICT_DELETE);
1167:                doDeleteSession((StandardSession) session,
1168:                        SESSION_EXPLICT_DELETE);
1169:            }
1170:
1171:            /**
1172:             * Removes a session from the Session Table. This method is used to log a
1173:             * user off the application. Note that <CODE>sessionDeleted()</CODE> is
1174:             * called.
1175:             * 
1176:             * @param sessionKey
1177:             *            A key corresponding to a user session to be removed.
1178:             * @exception SessionException
1179:             *                If the session cannot be deleted.
1180:             */
1181:            public synchronized void deleteSession(String sessionKey)
1182:                    throws SessionException {
1183:                Session session = (Session) sessionHome.getSession(Thread
1184:                        .currentThread(), sessionKey);
1185:                if (session != null) {
1186:                    deleteSession(session);
1187:                }
1188:            }
1189:
1190:            /**
1191:             * Puts a session into the 'passive' state. A 'passive' session may be made
1192:             * persistent.
1193:             * 
1194:             * @param thread
1195:             *            the thread currently associated with the session.
1196:             * @param sessionKey
1197:             *            the session key for the session that will be made persistent.
1198:             * @exception SessionException
1199:             *                If the session cannot be put into the passive state.
1200:             */
1201:            public void passivateSession(Thread thread, String sessionKey)
1202:                    throws SessionException {
1203:                sessionHome.passivateSession(thread, sessionKey);
1204:            }
1205:
1206:            /**
1207:             * Scans session table to determine if any sessions need to be expired.
1208:             * 
1209:             * @exception SessionException
1210:             *                if an error occurs.
1211:             */
1212:            public void cleanUpIdleSessions() throws SessionException {
1213:                Enumeration e = sessionHome.keys();
1214:                StandardSession session;
1215:                String sessionKey;
1216:                debug(3, "checking for idle sessions... ");
1217:                while (e.hasMoreElements()) {
1218:                    sessionKey = (String) e.nextElement();
1219:                    session = (StandardSession) sessionHome.getSession(Thread
1220:                            .currentThread(), sessionKey);
1221:                    if (session != null) {
1222:                        int stat = isSessionExpired(session);
1223:                        if (stat != SESSION_ACTIVE) {
1224:                            debug(3, "cleaning up idle session: " + sessionKey);
1225:                            sessionDeleted(session, stat);
1226:                            doDeleteSession(session, stat);
1227:                        } else {
1228:                            sessionHome.passivateSession(
1229:                                    Thread.currentThread(), sessionKey);
1230:                        }
1231:                    }
1232:                }
1233:            }
1234:
1235:            /**
1236:             * Returns whether the <code>Session</code> object associated with the
1237:             * specified session key exists.
1238:             * 
1239:             * @param sessionKey
1240:             *            The String used to reference a <code>Session</code> object.
1241:             * @return If the key is associated with an active session, then return
1242:             *         true, otherwise return false.
1243:             * @exception SessionException
1244:             *                If existence of the session cannot be tested.
1245:             */
1246:            public synchronized boolean sessionExists(String sessionKey)
1247:                    throws SessionException {
1248:                if (sessionKey == null) {
1249:                    return false;
1250:                }
1251:                return sessionHome.containsKey(sessionKey);
1252:            }
1253:
1254:            /**
1255:             * Lookup the <code>Session</code> object associated with the specified
1256:             * session key.
1257:             * <P>
1258:             * 
1259:             * Each time a session is returned via this method, the session's last used
1260:             * (referenced) time is updated to the current time.
1261:             * 
1262:             * @param sessionKey
1263:             *            The String used to reference a <code>Session</code> object.
1264:             * @return If the key is associated with an active session, then the
1265:             *         corresponding <code>Session</code> object is returned.
1266:             *         Otherwise <code>null</code> is returned.
1267:             * @see Session
1268:             * @see StandardSession#touch
1269:             * @exception SessionException
1270:             *                If the session cannot be retrieved.
1271:             */
1272:            public synchronized Session getSession(String sessionKey)
1273:                    throws SessionException {
1274:                keyGenerator.incrementRandomCounter();
1275:                StandardSession session = (StandardSession) sessionHome
1276:                        .getSession(sessionKey);
1277:                if (session != null) {
1278:                    session.touch();
1279:                } else {
1280:                    sessionUserTable.remove(sessionKey);
1281:                }
1282:                return session;
1283:            }
1284:
1285:            /**
1286:             * Lookup the <code>Session</code> object associated with the specified
1287:             * session key.
1288:             * <P>
1289:             * 
1290:             * Each time a session is returned via this method, the session's last used
1291:             * (referenced) time is updated to the current time.
1292:             * 
1293:             * @param thread
1294:             *            the thread to associate with the session.
1295:             * @param sessionKey
1296:             *            The String used to reference a <code>Session</code> object.
1297:             * @return If the key is associated with an active session, then the
1298:             *         corresponding <code>Session</code> object is returned.
1299:             *         Otherwise <code>null</code> is returned.
1300:             * @see Session
1301:             * @see StandardSession#touch
1302:             * @exception SessionException
1303:             *                If the session cannot be retrieved.
1304:             */
1305:            public synchronized Session getSession(Thread thread,
1306:                    String sessionKey) throws SessionException {
1307:                keyGenerator.incrementRandomCounter();
1308:                StandardSession session = (StandardSession) sessionHome
1309:                        .getSession(thread, sessionKey);
1310:                if (session != null) {
1311:                    session.touch();
1312:                } else {
1313:                    sessionUserTable.remove(sessionKey);
1314:                }
1315:                return session;
1316:            }
1317:
1318:            /**
1319:             * Support for director connector Director connector sets header :affCR: ,
1320:             * in that case we need to delete active session and create new one , with
1321:             * new ipPortToken
1322:             */
1323:            public synchronized Session getSession(Thread thread,
1324:                    String sessionKey, HttpPresentationComms comms)
1325:                    throws SessionException {
1326:
1327:                Session session = getSession(thread, sessionKey);
1328:
1329:                //		String saTokChangeRequest = null;
1330:                /*
1331:                 * try{ saTokChangeRequest = comms.request.getHeader(":affCR:"); } catch
1332:                 * (HttpPresentationException hpe) { saTokChangeRequest=null; }
1333:                 */
1334:                /*if (saTokChangeRequest != null && session != null) {
1335:                	deleteSession(session);
1336:                	return null;
1337:                } else {
1338:                	return session;
1339:                }*/
1340:                return session;
1341:            }
1342:
1343:            /**
1344:             * Lookup the <code>Session</code> object associated with the specified
1345:             * session key.
1346:             * <P>
1347:             * 
1348:             * Each time a session is returned via this method, the session's last used
1349:             * (referenced) time is NOT!!! updated to the current time.
1350:             * 
1351:             * This method is for save reporting without change the last time used.
1352:             * 
1353:             * @param thread
1354:             *            the thread to associate with the session.
1355:             * @param sessionKey
1356:             *            The String used to reference a <code>Session</code> object.
1357:             * @return If the key is associated with an active session, then the
1358:             *         corresponding <code>Session</code> object is returned.
1359:             *         Otherwise <code>null</code> is returned.
1360:             * @see Session
1361:             * @see StandardSession#touch
1362:             * @exception SessionException
1363:             *                If the session cannot be retrieved.
1364:             * @author schubi@die-schubis.de
1365:             */
1366:            public synchronized Session getSaveSession(Thread thread,
1367:                    String sessionKey) throws SessionException {
1368:                keyGenerator.incrementRandomCounter();
1369:                StandardSession session = (StandardSession) sessionHome
1370:                        .getSession(thread, sessionKey);
1371:                if (session != null) {
1372:                    // session.touch();
1373:                } else {
1374:                    sessionUserTable.remove(sessionKey);
1375:                }
1376:                return session;
1377:            }
1378:
1379:            /**
1380:             * Get all of the active sessions.
1381:             * 
1382:             * @return An enumeration of the active sessions.
1383:             * @exception SessionException
1384:             *                If the sessions cannot be retrieved.
1385:             */
1386:            public synchronized Enumeration getSessionKeys()
1387:                    throws SessionException {
1388:                return sessionHome.keys();
1389:            }
1390:
1391:            /**
1392:             * Lookup the keys for the active sessions for a user. A given user may have
1393:             * multiple sessions associated with it (using FTP as an example, the
1394:             * "anonymous" account).
1395:             * 
1396:             * @param user
1397:             *            The user to search for.
1398:             * @return An enumeration containing the session keys of the active sessions
1399:             *         for the user.
1400:             * @exception SessionException
1401:             *                If the sessions cannot be retrieved.
1402:             */
1403:            public synchronized Enumeration getSessionKeys(User user)
1404:                    throws SessionException {
1405:                return sessionUserTable.getSessionKeys(user);
1406:            }
1407:
1408:            /**
1409:             * Gets the number of currently active sessions.
1410:             * 
1411:             * @return The number of currently active sessions.
1412:             * @exception SessionException
1413:             *                If the session cannot be calculated.
1414:             */
1415:            public int activeSessionCount() throws SessionException {
1416:                return sessionHome.size();
1417:            }
1418:
1419:            /**
1420:             * Gets the number of session that are paged to persistent store.
1421:             * 
1422:             * @return The number of currently paged sessions.
1423:             * @exception SessionException
1424:             *                If the session cannot be calculated.
1425:             */
1426:            public int pagedSessionCount() throws SessionException {
1427:                return sessionHome.pagedSize();
1428:            }
1429:
1430:            /**
1431:             * Returns the current mode for the session manager.
1432:             * 
1433:             * @return the mode.
1434:             * @exception SessionException
1435:             *                If the mode cannot be determined.
1436:             * @see #MODE_BASIC
1437:             * @see #MODE_PAGE_TO_DISK
1438:             * @see #MODE_PAGE_TO_DB
1439:             * @see #MODE_CUSTOM
1440:             */
1441:            public int getMode() throws SessionException {
1442:                return mode;
1443:            }
1444:
1445:            /**
1446:             * Gets the maximum number of concurent sessions that existed at any time
1447:             * since this object was created, or <CODE>resetMaxSessionCount()</CODE>
1448:             * was called. This is a historical highwater mark.
1449:             * 
1450:             * @return The highwater mark for number of sessions, or -1.
1451:             */
1452:            public int maxSessionCount() {
1453:                return maxSessions;
1454:            }
1455:
1456:            /**
1457:             * Gets the time when the maximum refered to by <CODE>maxSessionCount()</CODE>
1458:             * occured.
1459:             * 
1460:             * @return The Date of when the maximum number of sessions occured.
1461:             */
1462:            public Date maxSessionCountDate() {
1463:                return maxSessionsDate;
1464:            }
1465:
1466:            /**
1467:             * Reset the maximum session count. See <CODE>maxSessionCount()</CODE>.
1468:             * The highwater mark should be reset to the current number of sessions.
1469:             * 
1470:             * @exception SessionException
1471:             *                if the max session count cannot be reset.
1472:             */
1473:            public void resetMaxSessionCount() throws SessionException {
1474:                maxSessions = sessionHome.size();
1475:                maxSessionsDate = new Date();
1476:            }
1477:
1478:            /**
1479:             * Returns the maximum session life time, in seconds.
1480:             */
1481:            public long getMaxSessionLifeTime() {
1482:                return maxSessionLifeTime;
1483:            }
1484:
1485:            /**
1486:             * Sets the maximum session idle time, in seconds.
1487:             */
1488:            public void setMaxSessionIdleTime(long maxSessionIdleTime) {
1489:                this .maxSessionIdleTime = maxSessionIdleTime;
1490:            }
1491:
1492:            /**
1493:             * Returns the maximum session idle time, in seconds.
1494:             */
1495:            public long getMaxSessionIdleTime() {
1496:                return maxSessionIdleTime;
1497:            }
1498:
1499:            /**
1500:             * Returns the url encoding state. Either <code>Never</code>
1501:             * <code>Always</code> <code>Auto</code>
1502:             */
1503:            public String getEncodeUrlState() {
1504:                return encodeUrlState;
1505:            }
1506:
1507:            /**
1508:             * Returns the url encoding rule for the first application page
1509:             * (true/false).
1510:             * 
1511:             * CFG_ENCODE_URL_STATE must not be set to NEVER for this parameter to take
1512:             * efect
1513:             */
1514:            public boolean getEncodeFirstUrl() {
1515:                return encodeFirstUrl;
1516:            }
1517:
1518:            /**
1519:             * Returns the maximum no-user session idle time, in seconds.
1520:             */
1521:            public long getMaxNoUserSessionIdleTime() {
1522:                return maxNoUserSessionIdleTime;
1523:            }
1524:
1525:            /**
1526:             * Prints debug information under Logger.DEBUG.
1527:             * 
1528:             * @param level
1529:             *            the debug level.
1530:             * @param msg
1531:             *            the message to print.
1532:             */
1533:            protected void debug(int level, String msg) {
1534:                int dbg = Logger.DEBUG;
1535:                switch (level) {
1536:                case 1:
1537:                    dbg = Logger.DEBUG1;
1538:                    break;
1539:                case 2:
1540:                    dbg = Logger.DEBUG2;
1541:                    break;
1542:                case 3:
1543:                    dbg = Logger.DEBUG3;
1544:                    break;
1545:                case 4:
1546:                    dbg = Logger.DEBUG4;
1547:                    break;
1548:                case 5:
1549:                    dbg = Logger.DEBUG5;
1550:                    break;
1551:                case 6:
1552:                    dbg = Logger.DEBUG6;
1553:                    break;
1554:                case 7:
1555:                    dbg = Logger.DEBUG7;
1556:                    break;
1557:                case 8:
1558:                    dbg = Logger.DEBUG8;
1559:                    break;
1560:                case 9:
1561:                    dbg = Logger.DEBUG9;
1562:                    break;
1563:                default:
1564:                    dbg = Logger.DEBUG;
1565:                    break;
1566:                }
1567:                Enhydra.getLogChannel().write(
1568:                        dbg,
1569:                        "PersistentSessionHome("
1570:                                + Thread.currentThread().getName() + "): "
1571:                                + msg);
1572:            }
1573:
1574:            /*
1575:             * (non-Javadoc)
1576:             * @see com.lutris.appserver.server.session.SessionManager#getEmptySessionPath()
1577:             */
1578:            public boolean getEmptySessionPath() {
1579:                return emptySessionPath;
1580:            }
1581:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.