Source Code Cross Referenced for SessionManager.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » server » session » 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 » EJB Server resin 3.1.5 » resin » com.caucho.server.session 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Scott Ferguson
0028:         */
0029:
0030:        package com.caucho.server.session;
0031:
0032:        import com.caucho.config.Config;
0033:        import com.caucho.config.ConfigException;
0034:        import com.caucho.config.types.JndiBuilder;
0035:        import com.caucho.config.types.Period;
0036:        import com.caucho.hessian.io.*;
0037:        import com.caucho.management.server.SessionManagerMXBean;
0038:        import com.caucho.server.cluster.Cluster;
0039:        import com.caucho.server.cluster.ClusterObject;
0040:        import com.caucho.server.cluster.ClusterServer;
0041:        import com.caucho.server.cluster.ObjectManager;
0042:        import com.caucho.server.cluster.Store;
0043:        import com.caucho.server.cluster.StoreManager;
0044:        import com.caucho.server.dispatch.DispatchServer;
0045:        import com.caucho.server.dispatch.InvocationDecoder;
0046:        import com.caucho.server.security.ServletAuthenticator;
0047:        import com.caucho.server.webapp.WebApp;
0048:        import com.caucho.util.Alarm;
0049:        import com.caucho.util.AlarmListener;
0050:        import com.caucho.util.L10N;
0051:        import com.caucho.util.LruCache;
0052:        import com.caucho.util.RandomUtil;
0053:        import com.caucho.vfs.Path;
0054:        import com.caucho.vfs.Vfs;
0055:
0056:        import javax.naming.Context;
0057:        import javax.naming.InitialContext;
0058:        import javax.servlet.http.HttpServletRequest;
0059:        import javax.servlet.http.HttpSessionActivationListener;
0060:        import javax.servlet.http.HttpSessionAttributeListener;
0061:        import javax.servlet.http.HttpSessionEvent;
0062:        import javax.servlet.http.HttpSessionListener;
0063:        import java.io.*;
0064:        import java.util.ArrayList;
0065:        import java.util.Iterator;
0066:        import java.util.logging.Level;
0067:        import java.util.logging.Logger;
0068:
0069:        // import com.caucho.server.http.ServletServer;
0070:        // import com.caucho.server.http.VirtualHost;
0071:
0072:        /**
0073:         * Manages sessions in a web-app.
0074:         */
0075:        public final class SessionManager implements  ObjectManager,
0076:                AlarmListener {
0077:            static protected final L10N L = new L10N(SessionManager.class);
0078:            static protected final Logger log = Logger
0079:                    .getLogger(SessionManager.class.getName());
0080:
0081:            private static final int FALSE = 0;
0082:            private static final int COOKIE = 1;
0083:            private static final int TRUE = 2;
0084:
0085:            private static final int UNSET = 0;
0086:            private static final int SET_TRUE = 1;
0087:            private static final int SET_FALSE = 2;
0088:
0089:            private static final int SAVE_BEFORE_HEADERS = 0x1;
0090:            private static final int SAVE_BEFORE_FLUSH = 0x2;
0091:            private static final int SAVE_AFTER_REQUEST = 0x4;
0092:            private static final int SAVE_ON_SHUTDOWN = 0x8;
0093:
0094:            private static final int DECODE[];
0095:
0096:            private WebApp _webApp;
0097:            private final SessionManagerAdmin _admin;
0098:
0099:            // factory for creating sessions
0100:            // private SessionFactory _sessionFactory;
0101:
0102:            // active sessions
0103:            private LruCache<String, SessionImpl> _sessions;
0104:            // total sessions
0105:            private int _totalSessions;
0106:
0107:            // iterator to purge sessions (to reduce gc)
0108:            private Iterator<SessionImpl> _sessionIter;
0109:            // array list for session timeout
0110:            private ArrayList<SessionImpl> _sessionList = new ArrayList<SessionImpl>();
0111:            // generate cookies
0112:            private boolean _enableSessionCookies = true;
0113:            // allow session rewriting
0114:            private boolean _enableSessionUrls = true;
0115:
0116:            private boolean _isModuloSessionId = false;
0117:            private boolean _isAppendServerIndex = false;
0118:            private boolean _isTwoDigitSessionIndex = false;
0119:
0120:            // invalidate the session after the listeners have been called
0121:            private boolean _isInvalidateAfterListener;
0122:
0123:            // maximum number of sessions
0124:            private int _sessionMax = 8192;
0125:            // how long a session will be inactive before it times out
0126:            private long _sessionTimeout = 30 * 60 * 1000;
0127:
0128:            private String _cookieName = "JSESSIONID";
0129:            private String _sslCookieName;
0130:
0131:            // Rewriting strings.
0132:            private String _sessionSuffix = ";jsessionid=";
0133:            private String _sessionPrefix;
0134:
0135:            // default cookie version
0136:            private int _cookieVersion;
0137:            private String _cookieDomain;
0138:            private long _cookieMaxAge;
0139:            private boolean _cookieSecure;
0140:            private int _isCookieHttpOnly;
0141:            private String _cookiePort;
0142:            private int _reuseSessionId = COOKIE;
0143:            private int _cookieLength = 21;
0144:
0145:            private int _sessionSaveMode = SAVE_AFTER_REQUEST;
0146:
0147:            //private SessionStore sessionStore;
0148:            private StoreManager _storeManager;
0149:
0150:            // If true, serialization errors should not be logged
0151:            // XXX: changed for JSF
0152:            private boolean _ignoreSerializationErrors = true;
0153:            private boolean _isHessianSerialization = false;
0154:
0155:            // List of the HttpSessionListeners from the configuration file
0156:            private ArrayList<HttpSessionListener> _listeners;
0157:
0158:            // List of the HttpSessionListeners from the configuration file
0159:            private ArrayList<HttpSessionActivationListener> _activationListeners;
0160:
0161:            // List of the HttpSessionAttributeListeners from the configuration file
0162:            private ArrayList<HttpSessionAttributeListener> _attributeListeners;
0163:
0164:            //
0165:            // Compatibility fields
0166:            //
0167:
0168:            private boolean _isWebAppStore; // i.e. for old-style compatibility
0169:            private Store _sessionStore;
0170:            private int _alwaysLoadSession;
0171:            private int _alwaysSaveSession;
0172:
0173:            private boolean _distributedRing;
0174:            private Path _persistentPath;
0175:
0176:            private boolean _isClosed;
0177:
0178:            private String _distributionId;
0179:            private Cluster _cluster;
0180:            private ClusterServer _selfServer;
0181:            private ClusterServer[] _srunGroup = new ClusterServer[0];
0182:
0183:            private int _srunIndex;
0184:            private int _srunLength;
0185:            private int _machineLength;
0186:
0187:            private Alarm _alarm = new Alarm(this );
0188:
0189:            // statistics
0190:            private Object _statisticsLock = new Object();
0191:            private long _sessionCreateCount;
0192:            private long _sessionTimeoutCount;
0193:            private long _sessionInvalidateCount;
0194:
0195:            /**
0196:             * Creates and initializes a new session manager
0197:             *
0198:             * @param app the web-app webApp
0199:             * @param registry the web-app configuration node
0200:             */
0201:            public SessionManager(WebApp app) throws Exception {
0202:                _webApp = app;
0203:
0204:                DispatchServer server = app.getDispatchServer();
0205:                if (server != null) {
0206:                    InvocationDecoder decoder = server.getInvocationDecoder();
0207:
0208:                    _sessionSuffix = decoder.getSessionURLPrefix();
0209:                    _sessionPrefix = decoder.getAlternateSessionURLPrefix();
0210:
0211:                    _cookieName = decoder.getSessionCookie();
0212:                    _sslCookieName = decoder.getSSLSessionCookie();
0213:                }
0214:
0215:                // this.server = app.getVirtualHost().getServer();
0216:                // this.srunIndex = server.getSrunIndex();
0217:
0218:                String hostName = app.getHostName();
0219:                String contextPath = app.getContextPath();
0220:
0221:                if (hostName == null || hostName.equals(""))
0222:                    hostName = "default";
0223:
0224:                String name = hostName + contextPath;
0225:
0226:                if (_distributionId == null)
0227:                    _distributionId = name;
0228:
0229:                _persistentPath = Vfs.lookup("WEB-INF/sessions");
0230:
0231:                _admin = new SessionManagerAdmin(this );
0232:            }
0233:
0234:            /**
0235:             * Returns the admin.
0236:             */
0237:            public SessionManagerMXBean getAdmin() {
0238:                return _admin;
0239:            }
0240:
0241:            /**
0242:             * Gets the cluster.
0243:             */
0244:            protected Cluster getCluster() {
0245:                synchronized (this ) {
0246:                    if (_cluster == null) {
0247:                        _cluster = Cluster.getLocal();
0248:                        ClusterServer selfServer = null;
0249:
0250:                        if (_cluster != null) {
0251:                            _machineLength = _cluster.getMachineList().size();
0252:                            _srunLength = _cluster.getServerList().length;
0253:
0254:                            selfServer = _cluster.getSelfServer();
0255:                            _selfServer = selfServer;
0256:
0257:                            if (selfServer != null) {
0258:                                _srunGroup = _cluster.getServerList();
0259:                                _srunIndex = selfServer.getIndex();
0260:                            }
0261:                        }
0262:                    }
0263:                }
0264:
0265:                return _cluster;
0266:            }
0267:
0268:            /**
0269:             * Returns the session prefix, ie.. ";jsessionid=".
0270:             */
0271:            public String getSessionPrefix() {
0272:                return _sessionSuffix;
0273:            }
0274:
0275:            /**
0276:             * Returns the alternate session prefix, before the URL for wap.
0277:             */
0278:            public String getAlternateSessionPrefix() {
0279:                return _sessionPrefix;
0280:            }
0281:
0282:            /**
0283:             * Returns the cookie version.
0284:             */
0285:            public int getCookieVersion() {
0286:                return _cookieVersion;
0287:            }
0288:
0289:            /**
0290:             * Sets the cookie version.
0291:             */
0292:            public void setCookieVersion(int cookieVersion) {
0293:                _cookieVersion = cookieVersion;
0294:            }
0295:
0296:            /**
0297:             * Sets the cookie ports.
0298:             */
0299:            public void setCookiePort(String port) {
0300:                _cookiePort = port;
0301:            }
0302:
0303:            /**
0304:             * Gets the cookie ports.
0305:             */
0306:            public String getCookiePort() {
0307:                return _cookiePort;
0308:            }
0309:
0310:            /**
0311:             * Returns the debug log
0312:             */
0313:            public Logger getDebug() {
0314:                return log;
0315:            }
0316:
0317:            /**
0318:             * Returns the SessionManager's webApp
0319:             */
0320:            WebApp getWebApp() {
0321:                return _webApp;
0322:            }
0323:
0324:            /**
0325:             * Returns the SessionManager's authenticator
0326:             */
0327:            ServletAuthenticator getAuthenticator() {
0328:                return _webApp.getAuthenticator();
0329:            }
0330:
0331:            /**
0332:             * Sets the persistent store.
0333:             */
0334:            public void setPersistentStore(JndiBuilder store)
0335:                    throws javax.naming.NamingException, ConfigException {
0336:                _storeManager = (StoreManager) store.getObject();
0337:
0338:                if (_storeManager == null)
0339:                    throw new ConfigException(L.l(
0340:                            "{0} is an unknown persistent store.", store
0341:                                    .getJndiName()));
0342:            }
0343:
0344:            /**
0345:             * True if sessions should always be loadd.
0346:             */
0347:            boolean getAlwaysLoadSession() {
0348:                return _alwaysLoadSession == SET_TRUE;
0349:            }
0350:
0351:            /**
0352:             * True if sessions should always be loadd.
0353:             */
0354:            public void setAlwaysLoadSession(boolean load) {
0355:                _alwaysLoadSession = load ? SET_TRUE : SET_FALSE;
0356:            }
0357:
0358:            /**
0359:             * True if sessions should always be saved.
0360:             */
0361:            boolean getAlwaysSaveSession() {
0362:                return _alwaysSaveSession == SET_TRUE;
0363:            }
0364:
0365:            /**
0366:             * True if sessions should always be saved.
0367:             */
0368:            public void setAlwaysSaveSession(boolean save) {
0369:                _alwaysSaveSession = save ? SET_TRUE : SET_FALSE;
0370:            }
0371:
0372:            /**
0373:             * True if sessions should be saved on shutdown.
0374:             */
0375:            public boolean isSaveOnShutdown() {
0376:                return (_sessionSaveMode & SAVE_ON_SHUTDOWN) != 0;
0377:            }
0378:
0379:            /**
0380:             * True if sessions should only be saved on shutdown.
0381:             */
0382:            public boolean isSaveOnlyOnShutdown() {
0383:                return (_sessionSaveMode & SAVE_ON_SHUTDOWN) == SAVE_ON_SHUTDOWN;
0384:            }
0385:
0386:            /**
0387:             * True if sessions should be saved before the HTTP headers.
0388:             */
0389:            public boolean isSaveBeforeHeaders() {
0390:                return (_sessionSaveMode & SAVE_BEFORE_HEADERS) != 0;
0391:            }
0392:
0393:            /**
0394:             * True if sessions should be saved before each flush.
0395:             */
0396:            public boolean isSaveBeforeFlush() {
0397:                return (_sessionSaveMode & SAVE_BEFORE_FLUSH) != 0;
0398:            }
0399:
0400:            /**
0401:             * True if sessions should be saved after the request.
0402:             */
0403:            public boolean isSaveAfterRequest() {
0404:                return (_sessionSaveMode & SAVE_AFTER_REQUEST) != 0;
0405:            }
0406:
0407:            /**
0408:             * Sets the save-mode: before-flush, before-headers, after-request,
0409:             * on-shutdown
0410:             */
0411:            public void setSaveMode(String mode) throws ConfigException {
0412:                /* XXX: probably don't want to implement this.
0413:                if ("before-flush".equals(mode)) {
0414:                  _sessionSaveMode = (SAVE_BEFORE_FLUSH|
0415:                		  SAVE_BEFORE_HEADERS|
0416:                		  SAVE_AFTER_REQUEST|
0417:                		  SAVE_ON_SHUTDOWN);
0418:                }
0419:                else
0420:                 */
0421:
0422:                if ("before-headers".equals(mode)) {
0423:                    _sessionSaveMode = (SAVE_BEFORE_HEADERS
0424:                            | SAVE_AFTER_REQUEST | SAVE_ON_SHUTDOWN);
0425:                } else if ("after-request".equals(mode)) {
0426:                    _sessionSaveMode = (SAVE_AFTER_REQUEST | SAVE_ON_SHUTDOWN);
0427:                } else if ("on-shutdown".equals(mode)) {
0428:                    _sessionSaveMode = (SAVE_ON_SHUTDOWN);
0429:                } else
0430:                    throw new ConfigException(
0431:                            L
0432:                                    .l(
0433:                                            "'{0}' is an unknown session save-mode.  Values are: before-headers, after-request, and on-shutdown.",
0434:                                            mode));
0435:
0436:            }
0437:
0438:            /**
0439:             * Returns the string value of the save-mode.
0440:             */
0441:            public String getSaveMode() {
0442:                if (isSaveBeforeFlush())
0443:                    return "before-flush";
0444:                else if (isSaveBeforeHeaders())
0445:                    return "before-headers";
0446:                else if (isSaveAfterRequest())
0447:                    return "after-request";
0448:                else if (isSaveOnShutdown())
0449:                    return "on-shutdown";
0450:                else
0451:                    return "unknown";
0452:            }
0453:
0454:            /**
0455:             * True if sessions should only be saved on shutdown.
0456:             */
0457:            public void setSaveOnlyOnShutdown(boolean save) {
0458:                log
0459:                        .warning("<save-only-on-shutdown> is deprecated.  Use <save-mode>on-shutdown</save-mode> instead");
0460:
0461:                if (save)
0462:                    _sessionSaveMode = SAVE_ON_SHUTDOWN;
0463:            }
0464:
0465:            /**
0466:             * True if sessions should only be saved on shutdown.
0467:             */
0468:            public void setSaveOnShutdown(boolean save) {
0469:                log
0470:                        .warning("<save-on-shutdown> is deprecated.  Use <save-only-on-shutdown> instead");
0471:
0472:                setSaveOnlyOnShutdown(save);
0473:            }
0474:
0475:            /**
0476:             * Sets the serialization type.
0477:             */
0478:            public void setSerializationType(String type) {
0479:                if ("hessian".equals(type))
0480:                    _isHessianSerialization = true;
0481:                else if ("java".equals(type))
0482:                    _isHessianSerialization = false;
0483:                else
0484:                    throw new ConfigException(
0485:                            L
0486:                                    .l(
0487:                                            "'{0}' is an unknown valud for serialization-type.  The valid types are 'hessian' and 'java'.",
0488:                                            type));
0489:            }
0490:
0491:            /**
0492:             * Returns true for Hessian serialization.
0493:             */
0494:            public boolean isHessianSerialization() {
0495:                return _isHessianSerialization;
0496:            }
0497:
0498:            /**
0499:             * True if the session should be invalidated after the listener.
0500:             */
0501:            public void setInvalidateAfterListener(boolean inv) {
0502:                _isInvalidateAfterListener = inv;
0503:            }
0504:
0505:            /**
0506:             * True if the session should be invalidated after the listener.
0507:             */
0508:            public boolean isInvalidateAfterListener() {
0509:                return _isInvalidateAfterListener;
0510:            }
0511:
0512:            /**
0513:             * Returns the current number of active sessions.
0514:             */
0515:            public int getActiveSessionCount() {
0516:                if (_sessions == null)
0517:                    return -1;
0518:                else
0519:                    return _sessions.size();
0520:            }
0521:
0522:            /**
0523:             * Returns the active sessions.
0524:             */
0525:            public int getSessionActiveCount() {
0526:                return getActiveSessionCount();
0527:            }
0528:
0529:            /**
0530:             * Returns the created sessions.
0531:             */
0532:            public long getSessionCreateCount() {
0533:                return _sessionCreateCount;
0534:            }
0535:
0536:            /**
0537:             * Returns the timeout sessions.
0538:             */
0539:            public long getSessionTimeoutCount() {
0540:                return _sessionTimeoutCount;
0541:            }
0542:
0543:            /**
0544:             * Returns the invalidate sessions.
0545:             */
0546:            public long getSessionInvalidateCount() {
0547:                return _sessionInvalidateCount;
0548:            }
0549:
0550:            /**
0551:             * Adds a new HttpSessionListener.
0552:             */
0553:            public void addListener(HttpSessionListener listener) {
0554:                if (_listeners == null)
0555:                    _listeners = new ArrayList<HttpSessionListener>();
0556:
0557:                _listeners.add(listener);
0558:            }
0559:
0560:            /**
0561:             * Adds a new HttpSessionListener.
0562:             */
0563:            ArrayList<HttpSessionListener> getListeners() {
0564:                return _listeners;
0565:            }
0566:
0567:            /**
0568:             * Adds a new HttpSessionActivationListener.
0569:             */
0570:            public void addActivationListener(
0571:                    HttpSessionActivationListener listener) {
0572:                if (_activationListeners == null)
0573:                    _activationListeners = new ArrayList<HttpSessionActivationListener>();
0574:
0575:                _activationListeners.add(listener);
0576:            }
0577:
0578:            /**
0579:             * Returns the activation listeners.
0580:             */
0581:            ArrayList<HttpSessionActivationListener> getActivationListeners() {
0582:                return _activationListeners;
0583:            }
0584:
0585:            /**
0586:             * Adds a new HttpSessionAttributeListener.
0587:             */
0588:            public void addAttributeListener(
0589:                    HttpSessionAttributeListener listener) {
0590:                if (_attributeListeners == null)
0591:                    _attributeListeners = new ArrayList<HttpSessionAttributeListener>();
0592:
0593:                _attributeListeners.add(listener);
0594:            }
0595:
0596:            /**
0597:             * Gets the HttpSessionAttributeListener.
0598:             */
0599:            ArrayList<HttpSessionAttributeListener> getAttributeListeners() {
0600:                return _attributeListeners;
0601:            }
0602:
0603:            /**
0604:             * True if serialization errors should just fail silently.
0605:             */
0606:            boolean getIgnoreSerializationErrors() {
0607:                return _ignoreSerializationErrors;
0608:            }
0609:
0610:            /**
0611:             * True if serialization errors should just fail silently.
0612:             */
0613:            public void setIgnoreSerializationErrors(boolean ignore) {
0614:                _ignoreSerializationErrors = ignore;
0615:            }
0616:
0617:            /**
0618:             * True if the server should reuse the current session id if the
0619:             * session doesn't exist.
0620:             */
0621:            public int getReuseSessionId() {
0622:                return _reuseSessionId;
0623:            }
0624:
0625:            /**
0626:             * True if the server should reuse the current session id if the
0627:             * session doesn't exist.
0628:             */
0629:            public boolean reuseSessionId(boolean fromCookie) {
0630:                int reuseSessionId = _reuseSessionId;
0631:
0632:                return reuseSessionId == TRUE || fromCookie
0633:                        && reuseSessionId == COOKIE;
0634:            }
0635:
0636:            /**
0637:             * True if the server should reuse the current session id if the
0638:             * session doesn't exist.
0639:             */
0640:            public void setReuseSessionId(String reuse) throws ConfigException {
0641:                if (reuse == null)
0642:                    _reuseSessionId = COOKIE;
0643:                else if (reuse.equalsIgnoreCase("true")
0644:                        || reuse.equalsIgnoreCase("yes")
0645:                        || reuse.equalsIgnoreCase("cookie"))
0646:                    _reuseSessionId = COOKIE;
0647:                else if (reuse.equalsIgnoreCase("false")
0648:                        || reuse.equalsIgnoreCase("no"))
0649:                    _reuseSessionId = FALSE;
0650:                else if (reuse.equalsIgnoreCase("all"))
0651:                    _reuseSessionId = TRUE;
0652:                else
0653:                    throw new ConfigException(
0654:                            L
0655:                                    .l(
0656:                                            "'{0}' is an invalid value for reuse-session-id.  'true' or 'false' are the allowed values.",
0657:                                            reuse));
0658:            }
0659:
0660:            /**
0661:             * Returns the owning server.
0662:             */
0663:            ClusterServer getServer(int index) {
0664:                Cluster cluster = getCluster();
0665:
0666:                if (cluster != null)
0667:                    return cluster.getServer(index);
0668:                else
0669:                    return null;
0670:            }
0671:
0672:            /**
0673:             * Returns the index of this JVM in the ring.
0674:             */
0675:            public int getSrunIndex() {
0676:                return _srunIndex;
0677:            }
0678:
0679:            /**
0680:             * Returns the number of sruns in the cluster
0681:             */
0682:            public int getSrunLength() {
0683:                return _srunLength;
0684:            }
0685:
0686:            /**
0687:             * Returns true if the sessions are closed.
0688:             */
0689:            public boolean isClosed() {
0690:                return _isClosed;
0691:            }
0692:
0693:            /**
0694:             * Sets the file store.
0695:             */
0696:            public StoreManager createFileStore() throws ConfigException {
0697:                Cluster cluster = getCluster();
0698:
0699:                if (cluster == null)
0700:                    throw new ConfigException(L
0701:                            .l("<file-store> needs a defined <cluster>."));
0702:
0703:                if (cluster.getStore() != null)
0704:                    throw new ConfigException(
0705:                            L
0706:                                    .l("<file-store> may not be used with a defined <persistent-store>.  Use <use-persistent-store> instead."));
0707:
0708:                StoreManager fileStore = cluster.createPrivateFileStore();
0709:
0710:                _storeManager = fileStore;
0711:
0712:                _isWebAppStore = true;
0713:
0714:                return fileStore;
0715:            }
0716:
0717:            /**
0718:             * Sets the jdbc store.
0719:             */
0720:            public StoreManager createJdbcStore() throws ConfigException {
0721:                Cluster cluster = getCluster();
0722:
0723:                if (cluster == null)
0724:                    throw new ConfigException(L
0725:                            .l("<jdbc-store> needs a defined <cluster>."));
0726:
0727:                if (cluster.getStore() != null)
0728:                    throw new ConfigException(
0729:                            L
0730:                                    .l("<jdbc-store> may not be used with a defined <persistent-store>.  Use <use-persistent-store> instead."));
0731:
0732:                _storeManager = cluster.createJdbcStore();
0733:
0734:                _isWebAppStore = true;
0735:
0736:                return _storeManager;
0737:            }
0738:
0739:            /**
0740:             * Sets the tcp store.
0741:             */
0742:            public void setTcpStore(boolean isEnable) throws Exception {
0743:                setClusterStore(isEnable);
0744:            }
0745:
0746:            /**
0747:             * Sets the cluster store.
0748:             */
0749:            public void setClusterStore(boolean isEnable) throws Exception {
0750:                if (!isEnable)
0751:                    return;
0752:
0753:                Cluster cluster = getCluster();
0754:
0755:                if (cluster == null)
0756:                    throw new ConfigException(L
0757:                            .l("<cluster-store> needs a defined <cluster>."));
0758:
0759:                StoreManager store = cluster.getStore();
0760:
0761:                if (store == null)
0762:                    throw new ConfigException(
0763:                            L
0764:                                    .l("cluster-store in <session-config> requires a configured cluster-store in the <cluster>"));
0765:
0766:                _storeManager = store;
0767:            }
0768:
0769:            /**
0770:             * Sets the cluster store.
0771:             */
0772:            public void setUsePersistentStore(boolean enable) throws Exception {
0773:                if (!enable)
0774:                    return;
0775:
0776:                Cluster cluster = getCluster();
0777:
0778:                if (cluster == null)
0779:                    throw new ConfigException(
0780:                            L
0781:                                    .l("<use-persistent-store> needs a defined <cluster>."));
0782:
0783:                StoreManager store = cluster.getStore();
0784:
0785:                if (store == null) {
0786:                    try {
0787:                        Context ic = new InitialContext();
0788:                        store = (StoreManager) ic
0789:                                .lookup("java:comp/env/caucho/persistent-store");
0790:                    } catch (Throwable e) {
0791:                        log.log(Level.FINER, e.toString(), e);
0792:                    }
0793:                }
0794:
0795:                if (store != null) {
0796:                } else if (!Config.evalBoolean("${resin.isProfessional()}")) {
0797:                    throw new ConfigException(
0798:                            L
0799:                                    .l("use-persistent-store in <session-config> requires Resin professional."));
0800:                } else
0801:                    throw new ConfigException(
0802:                            L
0803:                                    .l("use-persistent-store in <session-config> requires a configured <persistent-store> in the <server>"));
0804:
0805:                if (_isWebAppStore)
0806:                    throw new ConfigException(
0807:                            L
0808:                                    .l("use-persistent-store may not be used with <jdbc-store> or <file-store>."));
0809:
0810:                _storeManager = store;
0811:            }
0812:
0813:            /**
0814:             * Returns the session factory.
0815:             */
0816:            public void setPersistentPath(Path path) {
0817:                _persistentPath = path;
0818:            }
0819:
0820:            public String getDistributionId() {
0821:                return _distributionId;
0822:            }
0823:
0824:            public void setDistributionId(String distributionId) {
0825:                _distributionId = distributionId;
0826:            }
0827:
0828:            /**
0829:             * Returns the default session timeout in milliseconds.
0830:             */
0831:            public long getSessionTimeout() {
0832:                return _sessionTimeout;
0833:            }
0834:
0835:            /**
0836:             * Set the default session timeout in minutes
0837:             */
0838:            public void setSessionTimeout(long timeout) {
0839:                if (timeout <= 0 || Integer.MAX_VALUE / 2 < timeout)
0840:                    _sessionTimeout = Long.MAX_VALUE / 2;
0841:                else
0842:                    _sessionTimeout = 60000L * timeout;
0843:            }
0844:
0845:            /**
0846:             * Returns the idle time.
0847:             */
0848:            public long getMaxIdleTime() {
0849:                return _sessionTimeout;
0850:            }
0851:
0852:            /**
0853:             * Returns the maximum number of sessions.
0854:             */
0855:            public int getSessionMax() {
0856:                return _sessionMax;
0857:            }
0858:
0859:            /**
0860:             * Returns the maximum number of sessions.
0861:             */
0862:            public void setSessionMax(int max) {
0863:                if (max < 1)
0864:                    throw new ConfigException(
0865:                            L
0866:                                    .l(
0867:                                            "session-max '{0}' is too small.  session-max must be a positive number",
0868:                                            max));
0869:
0870:                _sessionMax = max;
0871:            }
0872:
0873:            /**
0874:             * Returns true if sessions use the cookie header.
0875:             */
0876:            public boolean enableSessionCookies() {
0877:                return _enableSessionCookies;
0878:            }
0879:
0880:            /**
0881:             * Returns true if sessions use the cookie header.
0882:             */
0883:            public void setEnableCookies(boolean enableCookies) {
0884:                _enableSessionCookies = enableCookies;
0885:            }
0886:
0887:            /**
0888:             * Returns true if sessions can use the session rewriting.
0889:             */
0890:            public boolean enableSessionUrls() {
0891:                return _enableSessionUrls;
0892:            }
0893:
0894:            /**
0895:             * Returns true if sessions can use the session rewriting.
0896:             */
0897:            public void setEnableUrlRewriting(boolean enableUrls) {
0898:                _enableSessionUrls = enableUrls;
0899:            }
0900:
0901:            /**
0902:             * Returns the default cookie name.
0903:             */
0904:            public String getCookieName() {
0905:                return _cookieName;
0906:            }
0907:
0908:            /**
0909:             * Returns the SSL cookie name.
0910:             */
0911:            public String getSSLCookieName() {
0912:                if (_sslCookieName != null)
0913:                    return _sslCookieName;
0914:                else
0915:                    return _cookieName;
0916:            }
0917:
0918:            /**
0919:             * Returns the default session cookie domain.
0920:             */
0921:            public String getCookieDomain() {
0922:                return _cookieDomain;
0923:            }
0924:
0925:            /**
0926:             * Sets the default session cookie domain.
0927:             */
0928:            public void setCookieDomain(String domain) {
0929:                _cookieDomain = domain;
0930:            }
0931:
0932:            /**
0933:             * Returns the max-age of the session cookie.
0934:             */
0935:            public long getCookieMaxAge() {
0936:                return _cookieMaxAge;
0937:            }
0938:
0939:            /**
0940:             * Sets the max-age of the session cookie.
0941:             */
0942:            public void setCookieMaxAge(Period maxAge) {
0943:                _cookieMaxAge = maxAge.getPeriod();
0944:            }
0945:
0946:            /**
0947:             * Returns the secure of the session cookie.
0948:             */
0949:            public boolean getCookieSecure() {
0950:                if (_cookieSecure)
0951:                    return true;
0952:                else
0953:                    return !_cookieName.equals(_sslCookieName);
0954:            }
0955:
0956:            /**
0957:             * Sets the secure of the session cookie.
0958:             */
0959:            public void setCookieSecure(boolean secure) {
0960:                _cookieSecure = secure;
0961:            }
0962:
0963:            /**
0964:             * Returns the http-only of the session cookie.
0965:             */
0966:            public boolean isCookieHttpOnly() {
0967:                if (_isCookieHttpOnly == SET_TRUE)
0968:                    return true;
0969:                else if (_isCookieHttpOnly == SET_FALSE)
0970:                    return true;
0971:                else
0972:                    return getWebApp().getCookieHttpOnly();
0973:            }
0974:
0975:            /**
0976:             * Sets the http-only of the session cookie.
0977:             */
0978:            public void setCookieHttpOnly(boolean httpOnly) {
0979:                _isCookieHttpOnly = httpOnly ? SET_TRUE : SET_FALSE;
0980:            }
0981:
0982:            /**
0983:             * Sets the cookie length
0984:             */
0985:            public void setCookieLength(int cookieLength) {
0986:                if (cookieLength < 7)
0987:                    cookieLength = 7;
0988:
0989:                _cookieLength = cookieLength;
0990:            }
0991:
0992:            /**
0993:             * Returns the cookie length.
0994:             */
0995:            public long getCookieLength() {
0996:                return _cookieLength;
0997:            }
0998:
0999:            /**
1000:             * Sets module session id generation.
1001:             */
1002:            public void setCookieModuloCluster(boolean isModulo) {
1003:                _isModuloSessionId = isModulo;
1004:            }
1005:
1006:            /**
1007:             * Sets module session id generation.
1008:             */
1009:            public void setCookieAppendServerIndex(boolean isAppend) {
1010:                _isAppendServerIndex = isAppend;
1011:            }
1012:
1013:            /**
1014:             * Sets module session id generation.
1015:             */
1016:            public boolean isCookieAppendServerIndex() {
1017:                return _isAppendServerIndex;
1018:            }
1019:
1020:            public void init() {
1021:                if (_sessionSaveMode == SAVE_ON_SHUTDOWN
1022:                        && (_alwaysSaveSession == SET_TRUE || _alwaysLoadSession == SET_TRUE))
1023:                    throw new ConfigException(
1024:                            L
1025:                                    .l("save-mode='on-shutdown' cannot be used with <always-save-session/> or <always-load-session/>"));
1026:            }
1027:
1028:            public void start() throws Exception {
1029:                _sessions = new LruCache<String, SessionImpl>(_sessionMax);
1030:                _sessionIter = _sessions.values();
1031:
1032:                if (_cluster == null)
1033:                    getCluster();
1034:
1035:                if (_isWebAppStore) {
1036:                    // for backward compatibility
1037:
1038:                    if (_alwaysLoadSession == SET_TRUE)
1039:                        _storeManager.setAlwaysLoad(true);
1040:                    else if (_alwaysLoadSession == SET_FALSE)
1041:                        _storeManager.setAlwaysLoad(false);
1042:
1043:                    if (_alwaysSaveSession == SET_TRUE)
1044:                        _storeManager.setAlwaysSave(true);
1045:                    else if (_alwaysSaveSession == SET_FALSE)
1046:                        _storeManager.setAlwaysSave(false);
1047:
1048:                    _storeManager.init();
1049:
1050:                    _storeManager.updateIdleCheckInterval(_sessionTimeout);
1051:                }
1052:
1053:                if (_storeManager != null) {
1054:                    _sessionStore = _storeManager.createStore(_distributionId,
1055:                            this );
1056:                    _sessionStore.setMaxIdleTime(_sessionTimeout);
1057:
1058:                    if (_alwaysLoadSession == SET_TRUE)
1059:                        _sessionStore.setAlwaysLoad(true);
1060:                    else if (_alwaysLoadSession == SET_FALSE)
1061:                        _sessionStore.setAlwaysLoad(false);
1062:
1063:                    if (_alwaysSaveSession == SET_TRUE)
1064:                        _sessionStore.setAlwaysSave(true);
1065:                    else if (_alwaysSaveSession == SET_FALSE)
1066:                        _sessionStore.setAlwaysSave(false);
1067:                }
1068:
1069:                _alarm.queue(60000);
1070:            }
1071:
1072:            /**
1073:             * Returns the session store.
1074:             */
1075:            public Store getSessionStore() {
1076:                return _sessionStore;
1077:            }
1078:
1079:            /**
1080:             * Returns true if the session exists in this manager.
1081:             */
1082:            public boolean containsSession(String id) {
1083:                return _sessions.get(id) != null;
1084:            }
1085:
1086:            /**
1087:             * Create a new session.
1088:             *
1089:             * @param oldId the id passed to the request.  Reuse if possible.
1090:             * @param now the current date
1091:             * @param sessionGroup the srun index for this machine
1092:             */
1093:            public SessionImpl createSession(String oldId, long now,
1094:                    HttpServletRequest request, boolean fromCookie) {
1095:                String id = oldId;
1096:
1097:                if (id == null || id.length() < 4 || !isInSessionGroup(id)
1098:                        || !reuseSessionId(fromCookie)) {
1099:                    id = createSessionId(request, true);
1100:                }
1101:
1102:                SessionImpl session = create(id, now, true);
1103:
1104:                if (session == null)
1105:                    return null;
1106:
1107:                session.addUse();
1108:
1109:                synchronized (_statisticsLock) {
1110:                    _sessionCreateCount++;
1111:                }
1112:
1113:                synchronized (session) {
1114:                    if (_sessionStore != null && id.equals(oldId))
1115:                        load(session, now);
1116:                    else
1117:                        session.create(now);
1118:                }
1119:
1120:                // after load so a reset doesn't clear any setting
1121:                handleCreateListeners(session);
1122:
1123:                return session;
1124:            }
1125:
1126:            /**
1127:             * Creates a pseudo-random session id.  If there's an old id and the
1128:             * group matches, then use it because different webApps on the
1129:             * same matchine should use the same cookie.
1130:             *
1131:             * @param sessionGroup possibly assigned by the web server
1132:             */
1133:            public String createSessionId(HttpServletRequest request) {
1134:                return createSessionId(request, false);
1135:            }
1136:
1137:            /**
1138:             * Creates a pseudo-random session id.  If there's an old id and the
1139:             * group matches, then use it because different webApps on the
1140:             * same machine should use the same cookie.
1141:             *
1142:             * @param sessionGroup possibly assigned by the web server
1143:             */
1144:            public String createSessionId(HttpServletRequest request,
1145:                    boolean create) {
1146:                String id;
1147:
1148:                do {
1149:                    id = createSessionIdImpl(request);
1150:                } while (create && getSession(id, 0, create, true) != null);
1151:
1152:                if (id == null || id.equals(""))
1153:                    throw new RuntimeException();
1154:
1155:                return id;
1156:            }
1157:
1158:            public String createSessionIdImpl(HttpServletRequest request) {
1159:                StringBuffer cb = new StringBuffer();
1160:                // this section is the host specific session index
1161:                // the most random bit is the high bit
1162:                int index = _srunIndex;
1163:
1164:                // look at caucho.session-server-id for a hint of the owner
1165:                Object owner = request.getAttribute("caucho.session-server-id");
1166:                if (owner == null) {
1167:                } else if (owner instanceof  Number) {
1168:                    index = ((Number) owner).intValue();
1169:                    if (_srunLength <= index)
1170:                        index = _srunIndex;
1171:                } else if (owner instanceof  String) {
1172:                    ClusterServer server = _cluster.getServer((String) owner);
1173:
1174:                    if (server != null)
1175:                        index = server.getIndex();
1176:                }
1177:
1178:                if (index < 0)
1179:                    index = 0;
1180:
1181:                int length = _cookieLength;
1182:
1183:                addBackup(cb, index);
1184:
1185:                length -= cb.length();
1186:
1187:                long random = RandomUtil.getRandomLong();
1188:
1189:                for (int i = 0; i < 11 && length-- > 0; i++) {
1190:                    cb.append(convert(random));
1191:                    random = random >> 6;
1192:                }
1193:
1194:                if (length > 0) {
1195:                    long time = Alarm.getCurrentTime();
1196:                    for (int i = 0; i < 7 && length-- > 0; i++) {
1197:                        cb.append(convert(time));
1198:                        time = time >> 6;
1199:                    }
1200:                }
1201:
1202:                while (length > 0) {
1203:                    random = RandomUtil.getRandomLong();
1204:                    for (int i = 0; i < 11 && length-- > 0; i++) {
1205:                        cb.append(convert(random));
1206:                        random = random >> 6;
1207:                    }
1208:                }
1209:
1210:                if (_isAppendServerIndex) {
1211:                    cb.append('.');
1212:                    cb.append((index + 1));
1213:                }
1214:
1215:                return cb.toString();
1216:            }
1217:
1218:            /**
1219:             * Adds the primary/backup/third digits to the session id.
1220:             */
1221:            private void addBackup(StringBuffer cb, int index) {
1222:                long backupCode;
1223:
1224:                if (_selfServer != null)
1225:                    backupCode = _selfServer.getCluster().generateBackupCode(
1226:                            index);
1227:                else
1228:                    backupCode = 0x000200010000L;
1229:
1230:                addDigit(cb, (int) (backupCode & 0xffff));
1231:                addDigit(cb, (int) ((backupCode >> 16) & 0xffff));
1232:                addDigit(cb, (int) ((backupCode >> 32) & 0xffff));
1233:            }
1234:
1235:            private void addDigit(StringBuffer cb, int digit) {
1236:                if (_srunLength <= 64 && !_isTwoDigitSessionIndex)
1237:                    cb.append(convert(digit));
1238:                else {
1239:                    cb.append(convert(digit / 64));
1240:                    cb.append(convert(digit));
1241:                }
1242:            }
1243:
1244:            /**
1245:             * Returns a session from the session store, returning null if there's
1246:             * no cached session.
1247:             *
1248:             * @param key the session id
1249:             * @param now the time in milliseconds
1250:             *
1251:             * @return the cached session.
1252:             */
1253:            public SessionImpl getSession(String key, long now, boolean create,
1254:                    boolean fromCookie) {
1255:                SessionImpl session;
1256:                boolean isNew = false;
1257:                boolean killSession = false;
1258:
1259:                if (_sessions == null)
1260:                    return null;
1261:
1262:                session = _sessions.get(key);
1263:
1264:                if (session != null && !session.getId().equals(key))
1265:                    throw new IllegalStateException(key + " != "
1266:                            + session.getId());
1267:
1268:                if (now <= 0) // just generating id
1269:                    return session;
1270:
1271:                if (session != null && !session.addUse()) {
1272:                    session = null;
1273:                }
1274:
1275:                if (session == null && _sessionStore != null) {
1276:                    if (!isInSessionGroup(key))
1277:                        return null;
1278:
1279:                    session = create(key, now, create);
1280:
1281:                    if (!session.addUse())
1282:                        session = null;
1283:                    isNew = true;
1284:                }
1285:
1286:                if (session == null)
1287:                    return null;
1288:
1289:                if (isNew) {
1290:                    killSession = !load(session, now);
1291:                    isNew = killSession;
1292:                } else if (!session.load()) {
1293:                    // if the load failed, then the session died out from underneath
1294:                    session.reset(now);
1295:                    isNew = true;
1296:                }
1297:
1298:                if (killSession && (!create || !reuseSessionId(fromCookie))) {
1299:                    // XXX: session.setClosed();
1300:                    session.endUse();
1301:                    _sessions.remove(key);
1302:                    // XXX:
1303:                    session._isValid = false;
1304:
1305:                    return null;
1306:                } else if (isNew)
1307:                    handleCreateListeners(session);
1308:                else
1309:                    session.setAccess(now);
1310:
1311:                return session;
1312:            }
1313:
1314:            public boolean isInSessionGroup(String id) {
1315:                if (_srunLength == 0 || _srunGroup.length == 0)
1316:                    return true;
1317:
1318:                int group = decode(id.charAt(0)) % _srunLength;
1319:
1320:                for (int i = _srunGroup.length - 1; i >= 0; i--) {
1321:                    ClusterServer server = _srunGroup[i];
1322:
1323:                    if (server != null && group == server.getIndex())
1324:                        return true;
1325:                }
1326:
1327:                return false;
1328:            }
1329:
1330:            /**
1331:             * Creates a session.  It's already been established that the
1332:             * key does not currently have a session.
1333:             */
1334:            private SessionImpl create(String key, long now, boolean isCreate) {
1335:                SessionImpl session = new SessionImpl(this , key, now);
1336:
1337:                // If another thread has created and stored a new session,
1338:                // putIfNew will return the old session
1339:                session = _sessions.putIfNew(key, session);
1340:
1341:                if (!key.equals(session.getId()))
1342:                    throw new IllegalStateException(key + " != "
1343:                            + session.getId());
1344:
1345:                Store sessionStore = _sessionStore;
1346:                if (sessionStore != null) {
1347:                    ClusterObject clusterObject = sessionStore
1348:                            .createClusterObject(key);
1349:                    session.setClusterObject(clusterObject);
1350:                }
1351:
1352:                return session;
1353:            }
1354:
1355:            /**
1356:             * Notification from the cluster.
1357:             */
1358:            public void notifyRemove(String id) {
1359:                SessionImpl session = _sessions.remove(id);
1360:
1361:                if (session != null)
1362:                    session.invalidateLru();
1363:            }
1364:
1365:            /**
1366:             * Notification from the cluster.
1367:             */
1368:            public void notifyUpdate(String id) {
1369:            }
1370:
1371:            /**
1372:             * Converts an integer to a printable character
1373:             */
1374:            private static char convert(long code) {
1375:                code = code & 0x3f;
1376:
1377:                if (code < 26)
1378:                    return (char) ('a' + code);
1379:                else if (code < 52)
1380:                    return (char) ('A' + code - 26);
1381:                else if (code < 62)
1382:                    return (char) ('0' + code - 52);
1383:                else if (code == 62)
1384:                    return '_';
1385:                else
1386:                    return '-';
1387:            }
1388:
1389:            public static int decode(int code) {
1390:                return DECODE[code & 0x7f];
1391:            }
1392:
1393:            private void handleCreateListeners(SessionImpl session) {
1394:                if (_listeners != null) {
1395:                    HttpSessionEvent event = new HttpSessionEvent(session);
1396:
1397:                    for (int i = 0; i < _listeners.size(); i++) {
1398:                        HttpSessionListener listener = _listeners.get(i);
1399:
1400:                        listener.sessionCreated(event);
1401:                    }
1402:                }
1403:            }
1404:
1405:            /**
1406:             * Loads the session from the backing store.  The caller must synchronize
1407:             * the session.
1408:             *
1409:             * @param session the session to load.
1410:             * @param now current time in milliseconds.
1411:             */
1412:            private boolean load(SessionImpl session, long now) {
1413:                try {
1414:                    // XXX: session.setNeedsLoad(false);
1415:
1416:                    /*
1417:                    if (session.getUseCount() > 1) {
1418:                    // if used by more than just us, 
1419:                    return true;
1420:                    }
1421:                    else*/if (now <= 0) {
1422:                        return false;
1423:                    } else if (session.load()) {
1424:                        session.setAccess(now);
1425:                        return true;
1426:                    } else {
1427:                        session.create(now);
1428:                    }
1429:                } catch (Exception e) {
1430:                    log.log(Level.FINE, e.toString(), e);
1431:                    session.reset(now);
1432:                }
1433:
1434:                return false;
1435:            }
1436:
1437:            /**
1438:             * Adds a session from the cache.
1439:             */
1440:            void addSession(SessionImpl session) {
1441:                _sessions.put(session.getId(), session);
1442:            }
1443:
1444:            /**
1445:             * Removes a session from the cache.
1446:             */
1447:            void removeSession(SessionImpl session) {
1448:                _sessions.remove(session.getId());
1449:            }
1450:
1451:            /**
1452:             * Loads the session.
1453:             *
1454:             * @param in the input stream containing the serialized session
1455:             * @param obj the session object to be deserialized
1456:             */
1457:            public void load(InputStream is, Object obj) throws IOException {
1458:                SessionImpl session = (SessionImpl) obj;
1459:
1460:                if (_isHessianSerialization) {
1461:                    Hessian2Input in = new Hessian2Input(is);
1462:
1463:                    session.load(in);
1464:
1465:                    in.close();
1466:                } else {
1467:                    ObjectInputStream in = new DistributedObjectInputStream(is);
1468:
1469:                    session.load(in);
1470:
1471:                    in.close();
1472:                }
1473:            }
1474:
1475:            /**
1476:             * Checks if the session is empty.
1477:             */
1478:            public boolean isEmpty(Object obj) {
1479:                SessionImpl session = (SessionImpl) obj;
1480:
1481:                return session.isEmpty();
1482:            }
1483:
1484:            /**
1485:             * Saves the session.
1486:             */
1487:            public void store(OutputStream os, Object obj) throws IOException {
1488:                SessionImpl session = (SessionImpl) obj;
1489:
1490:                if (_isHessianSerialization) {
1491:                    Hessian2Output out = new Hessian2Output(os);
1492:
1493:                    session.store(out);
1494:
1495:                    out.close();
1496:                } else {
1497:                    ObjectOutputStream out = new ObjectOutputStream(os);
1498:
1499:                    session.store(out);
1500:
1501:                    out.close();
1502:                }
1503:            }
1504:
1505:            /**
1506:             * Timeout for reaping old sessions
1507:             *
1508:             * @return number of live sessions for stats
1509:             */
1510:            public void handleAlarm(Alarm alarm) {
1511:                try {
1512:                    _sessionList.clear();
1513:
1514:                    int liveSessions = 0;
1515:
1516:                    if (_isClosed)
1517:                        return;
1518:
1519:                    long now = Alarm.getCurrentTime();
1520:                    long accessWindow = 0;
1521:
1522:                    if (_sessionStore != null)
1523:                        accessWindow = _sessionStore.getAccessWindowTime();
1524:
1525:                    synchronized (_sessions) {
1526:                        _sessionIter = _sessions.values(_sessionIter);
1527:                        while (_sessionIter.hasNext()) {
1528:                            SessionImpl session = _sessionIter.next();
1529:
1530:                            long maxIdleTime = session._maxInactiveInterval
1531:                                    + accessWindow;
1532:
1533:                            if (session.inUse())
1534:                                liveSessions++;
1535:                            else if (session._accessTime + maxIdleTime < now)
1536:                                _sessionList.add(session);
1537:                            else
1538:                                liveSessions++;
1539:                        }
1540:                    }
1541:
1542:                    synchronized (_statisticsLock) {
1543:                        _sessionTimeoutCount += _sessionList.size();
1544:                    }
1545:
1546:                    for (int i = 0; i < _sessionList.size(); i++) {
1547:                        SessionImpl session = _sessionList.get(i);
1548:
1549:                        try {
1550:                            if (!session.isValid())
1551:                                continue;
1552:
1553:                            if (_storeManager == null) {
1554:                                // if no persistent store then invalidate
1555:                                // XXX: server/12cg - single signon shouldn't logout
1556:                                session.invalidateTimeout();
1557:                            } else if (session.getSrunIndex() != _srunIndex
1558:                                    && _srunIndex >= 0) {
1559:                                if (log.isLoggable(Level.FINE))
1560:                                    log.fine(session + " timeout (backup)");
1561:
1562:                                // if not the owner, then just remove
1563:                                _sessions.remove(session.getId());
1564:                            } else {
1565:                                session.invalidateTimeout();
1566:                            }
1567:                        } catch (Throwable e) {
1568:                            log.log(Level.FINE, e.toString(), e);
1569:                        }
1570:                    }
1571:                } finally {
1572:                    if (!_isClosed)
1573:                        _alarm.queue(60000);
1574:                }
1575:            }
1576:
1577:            /**
1578:             * Cleans up the sessions when the WebApp shuts down gracefully.
1579:             */
1580:            public void close() {
1581:                synchronized (this ) {
1582:                    if (_isClosed)
1583:                        return;
1584:                    _isClosed = true;
1585:                }
1586:
1587:                if (_sessions == null)
1588:                    return;
1589:
1590:                _alarm.dequeue();
1591:
1592:                ArrayList<SessionImpl> list = new ArrayList<SessionImpl>();
1593:
1594:                boolean isError = false;
1595:                // XXX: messy way of dealing with saveOnlyOnShutdown
1596:                synchronized (_sessions) {
1597:                    _sessionIter = _sessions.values(_sessionIter);
1598:                    while (_sessionIter.hasNext()) {
1599:                        SessionImpl session = _sessionIter.next();
1600:
1601:                        if (session.isValid())
1602:                            list.add(session);
1603:                    }
1604:
1605:                    // XXX: if cleared here, will remove the session
1606:                    // _sessions.clear();
1607:                }
1608:
1609:                for (int i = list.size() - 1; i >= 0; i--) {
1610:                    SessionImpl session = list.get(i);
1611:
1612:                    if (log.isLoggable(Level.FINE))
1613:                        log.fine("close session " + session.getId());
1614:
1615:                    try {
1616:                        if (session.isValid()) {
1617:                            synchronized (session) {
1618:                                // server/016i, server/018x
1619:                                if (!session.isEmpty())
1620:                                    session.saveOnShutdown();
1621:                            }
1622:                        }
1623:
1624:                        _sessions.remove(session.getId());
1625:                    } catch (Exception e) {
1626:                        if (!isError)
1627:                            log.log(Level.WARNING, "Can't store session: " + e,
1628:                                    e);
1629:                        isError = true;
1630:                    }
1631:                }
1632:
1633:                if (_admin != null)
1634:                    _admin.unregister();
1635:
1636:                _sessionList = null;
1637:
1638:                /*
1639:                if (_clusterManager != null)
1640:                  _clusterManager.removeContext(_distributionId);
1641:                 */
1642:            }
1643:
1644:            @Override
1645:            public String toString() {
1646:                if (_webApp != null)
1647:                    return "SessionManager[" + _webApp.getContextPath() + "]";
1648:                else
1649:                    return "SessionManager[]";
1650:            }
1651:
1652:            static class DistributedObjectInputStream extends ObjectInputStream {
1653:                private ClassLoader _loader;
1654:
1655:                DistributedObjectInputStream(InputStream is) throws IOException {
1656:                    super (is);
1657:
1658:                    Thread thread = Thread.currentThread();
1659:                    _loader = thread.getContextClassLoader();
1660:                }
1661:
1662:                @Override
1663:                protected Class resolveClass(ObjectStreamClass v)
1664:                        throws IOException, ClassNotFoundException {
1665:                    String name = v.getName();
1666:
1667:                    return Class.forName(name, false, _loader);
1668:                }
1669:            }
1670:
1671:            static {
1672:                DECODE = new int[128];
1673:                for (int i = 0; i < 64; i++)
1674:                    DECODE[(int) convert(i)] = i;
1675:            }
1676:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.