Source Code Cross Referenced for PersistentManagerBase.java in  » Sevlet-Container » apache-tomcat-6.0.14 » org » apache » catalina » 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 » Sevlet Container » apache tomcat 6.0.14 » org.apache.catalina.session 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.catalina.session;
0019:
0020:        import java.beans.PropertyChangeEvent;
0021:        import java.beans.PropertyChangeListener;
0022:        import java.io.IOException;
0023:        import java.security.AccessController;
0024:        import java.security.PrivilegedActionException;
0025:        import java.security.PrivilegedExceptionAction;
0026:        import org.apache.catalina.Container;
0027:        import org.apache.catalina.Context;
0028:        import org.apache.catalina.Lifecycle;
0029:        import org.apache.catalina.LifecycleException;
0030:        import org.apache.catalina.LifecycleListener;
0031:        import org.apache.catalina.Session;
0032:        import org.apache.catalina.Store;
0033:        import org.apache.catalina.util.LifecycleSupport;
0034:
0035:        import org.apache.catalina.security.SecurityUtil;
0036:        import org.apache.juli.logging.Log;
0037:        import org.apache.juli.logging.LogFactory;
0038:
0039:        /**
0040:         * Extends the <b>ManagerBase</b> class to implement most of the
0041:         * functionality required by a Manager which supports any kind of
0042:         * persistence, even if onlyfor  restarts.
0043:         * <p>
0044:         * <b>IMPLEMENTATION NOTE</b>:  Correct behavior of session storing and
0045:         * reloading depends upon external calls to the <code>start()</code> and
0046:         * <code>stop()</code> methods of this class at the correct times.
0047:         *
0048:         * @author Craig R. McClanahan
0049:         * @author Jean-Francois Arcand
0050:         * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
0051:         */
0052:
0053:        public abstract class PersistentManagerBase extends ManagerBase
0054:                implements  Lifecycle, PropertyChangeListener {
0055:
0056:            private static Log log = LogFactory
0057:                    .getLog(PersistentManagerBase.class);
0058:
0059:            // ---------------------------------------------------- Security Classes
0060:
0061:            private class PrivilegedStoreClear implements 
0062:                    PrivilegedExceptionAction {
0063:
0064:                PrivilegedStoreClear() {
0065:                }
0066:
0067:                public Object run() throws Exception {
0068:                    store.clear();
0069:                    return null;
0070:                }
0071:            }
0072:
0073:            private class PrivilegedStoreRemove implements 
0074:                    PrivilegedExceptionAction {
0075:
0076:                private String id;
0077:
0078:                PrivilegedStoreRemove(String id) {
0079:                    this .id = id;
0080:                }
0081:
0082:                public Object run() throws Exception {
0083:                    store.remove(id);
0084:                    return null;
0085:                }
0086:            }
0087:
0088:            private class PrivilegedStoreLoad implements 
0089:                    PrivilegedExceptionAction {
0090:
0091:                private String id;
0092:
0093:                PrivilegedStoreLoad(String id) {
0094:                    this .id = id;
0095:                }
0096:
0097:                public Object run() throws Exception {
0098:                    return store.load(id);
0099:                }
0100:            }
0101:
0102:            private class PrivilegedStoreSave implements 
0103:                    PrivilegedExceptionAction {
0104:
0105:                private Session session;
0106:
0107:                PrivilegedStoreSave(Session session) {
0108:                    this .session = session;
0109:                }
0110:
0111:                public Object run() throws Exception {
0112:                    store.save(session);
0113:                    return null;
0114:                }
0115:            }
0116:
0117:            private class PrivilegedStoreKeys implements 
0118:                    PrivilegedExceptionAction {
0119:
0120:                PrivilegedStoreKeys() {
0121:                }
0122:
0123:                public Object run() throws Exception {
0124:                    return store.keys();
0125:                }
0126:            }
0127:
0128:            // ----------------------------------------------------- Instance Variables
0129:
0130:            /**
0131:             * The descriptive information about this implementation.
0132:             */
0133:            private static final String info = "PersistentManagerBase/1.1";
0134:
0135:            /**
0136:             * The lifecycle event support for this component.
0137:             */
0138:            protected LifecycleSupport lifecycle = new LifecycleSupport(this );
0139:
0140:            /**
0141:             * The maximum number of active Sessions allowed, or -1 for no limit.
0142:             */
0143:            protected int maxActiveSessions = -1;
0144:
0145:            /**
0146:             * The descriptive name of this Manager implementation (for logging).
0147:             */
0148:            private static String name = "PersistentManagerBase";
0149:
0150:            /**
0151:             * Has this component been started yet?
0152:             */
0153:            protected boolean started = false;
0154:
0155:            /**
0156:             * Store object which will manage the Session store.
0157:             */
0158:            protected Store store = null;
0159:
0160:            /**
0161:             * Whether to save and reload sessions when the Manager <code>unload</code>
0162:             * and <code>load</code> methods are called.
0163:             */
0164:            protected boolean saveOnRestart = true;
0165:
0166:            /**
0167:             * How long a session must be idle before it should be backed up.
0168:             * -1 means sessions won't be backed up.
0169:             */
0170:            protected int maxIdleBackup = -1;
0171:
0172:            /**
0173:             * Minimum time a session must be idle before it is swapped to disk.
0174:             * This overrides maxActiveSessions, to prevent thrashing if there are lots
0175:             * of active sessions. Setting to -1 means it's ignored.
0176:             */
0177:            protected int minIdleSwap = -1;
0178:
0179:            /**
0180:             * The maximum time a session may be idle before it should be swapped
0181:             * to file just on general principle. Setting this to -1 means sessions
0182:             * should not be forced out.
0183:             */
0184:            protected int maxIdleSwap = -1;
0185:
0186:            /**
0187:             * Number of session creations that failed due to maxActiveSessions.
0188:             */
0189:            protected int rejectedSessions = 0;
0190:
0191:            /**
0192:             * Processing time during session expiration and passivation.
0193:             */
0194:            protected long processingTime = 0;
0195:
0196:            // ------------------------------------------------------------- Properties
0197:
0198:            /**
0199:             * Indicates how many seconds old a session can get, after its last use in a
0200:             * request, before it should be backed up to the store. -1 means sessions
0201:             * are not backed up.
0202:             */
0203:            public int getMaxIdleBackup() {
0204:
0205:                return maxIdleBackup;
0206:
0207:            }
0208:
0209:            /**
0210:             * Sets the option to back sessions up to the Store after they
0211:             * are used in a request. Sessions remain available in memory
0212:             * after being backed up, so they are not passivated as they are
0213:             * when swapped out. The value set indicates how old a session
0214:             * may get (since its last use) before it must be backed up: -1
0215:             * means sessions are not backed up.
0216:             * <p>
0217:             * Note that this is not a hard limit: sessions are checked
0218:             * against this age limit periodically according to <b>processExpiresFrequency</b>.
0219:             * This value should be considered to indicate when a session is
0220:             * ripe for backing up.
0221:             * <p>
0222:             * So it is possible that a session may be idle for maxIdleBackup +
0223:             * processExpiresFrequency * engine.backgroundProcessorDelay seconds, plus the time it takes to handle other
0224:             * session expiration, swapping, etc. tasks.
0225:             *
0226:             * @param backup The number of seconds after their last accessed
0227:             * time when they should be written to the Store.
0228:             */
0229:            public void setMaxIdleBackup(int backup) {
0230:
0231:                if (backup == this .maxIdleBackup)
0232:                    return;
0233:                int oldBackup = this .maxIdleBackup;
0234:                this .maxIdleBackup = backup;
0235:                support.firePropertyChange("maxIdleBackup", new Integer(
0236:                        oldBackup), new Integer(this .maxIdleBackup));
0237:
0238:            }
0239:
0240:            /**
0241:             * The time in seconds after which a session should be swapped out of
0242:             * memory to disk.
0243:             */
0244:            public int getMaxIdleSwap() {
0245:
0246:                return maxIdleSwap;
0247:
0248:            }
0249:
0250:            /**
0251:             * Sets the time in seconds after which a session should be swapped out of
0252:             * memory to disk.
0253:             */
0254:            public void setMaxIdleSwap(int max) {
0255:
0256:                if (max == this .maxIdleSwap)
0257:                    return;
0258:                int oldMaxIdleSwap = this .maxIdleSwap;
0259:                this .maxIdleSwap = max;
0260:                support.firePropertyChange("maxIdleSwap", new Integer(
0261:                        oldMaxIdleSwap), new Integer(this .maxIdleSwap));
0262:
0263:            }
0264:
0265:            /**
0266:             * The minimum time in seconds that a session must be idle before
0267:             * it can be swapped out of memory, or -1 if it can be swapped out
0268:             * at any time.
0269:             */
0270:            public int getMinIdleSwap() {
0271:
0272:                return minIdleSwap;
0273:
0274:            }
0275:
0276:            /**
0277:             * Sets the minimum time in seconds that a session must be idle before
0278:             * it can be swapped out of memory due to maxActiveSession. Set it to -1
0279:             * if it can be swapped out at any time.
0280:             */
0281:            public void setMinIdleSwap(int min) {
0282:
0283:                if (this .minIdleSwap == min)
0284:                    return;
0285:                int oldMinIdleSwap = this .minIdleSwap;
0286:                this .minIdleSwap = min;
0287:                support.firePropertyChange("minIdleSwap", new Integer(
0288:                        oldMinIdleSwap), new Integer(this .minIdleSwap));
0289:
0290:            }
0291:
0292:            /**
0293:             * Set the Container with which this Manager has been associated. If it is a
0294:             * Context (the usual case), listen for changes to the session timeout
0295:             * property.
0296:             * 
0297:             * @param container
0298:             *            The associated Container
0299:             */
0300:            public void setContainer(Container container) {
0301:
0302:                // De-register from the old Container (if any)
0303:                if ((this .container != null)
0304:                        && (this .container instanceof  Context))
0305:                    ((Context) this .container)
0306:                            .removePropertyChangeListener(this );
0307:
0308:                // Default processing provided by our superclass
0309:                super .setContainer(container);
0310:
0311:                // Register with the new Container (if any)
0312:                if ((this .container != null)
0313:                        && (this .container instanceof  Context)) {
0314:                    setMaxInactiveInterval(((Context) this .container)
0315:                            .getSessionTimeout() * 60);
0316:                    ((Context) this .container).addPropertyChangeListener(this );
0317:                }
0318:
0319:            }
0320:
0321:            /**
0322:             * Return descriptive information about this Manager implementation and
0323:             * the corresponding version number, in the format
0324:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0325:             */
0326:            public String getInfo() {
0327:
0328:                return (info);
0329:
0330:            }
0331:
0332:            /**
0333:             * Return true, if the session id is loaded in memory
0334:             * otherwise false is returned
0335:             *
0336:             * @param id The session id for the session to be searched for
0337:             */
0338:            public boolean isLoaded(String id) {
0339:                try {
0340:                    if (super .findSession(id) != null)
0341:                        return true;
0342:                } catch (IOException e) {
0343:                    log.error("checking isLoaded for id, " + id + ", "
0344:                            + e.getMessage(), e);
0345:                }
0346:                return false;
0347:            }
0348:
0349:            /**
0350:             * Return the maximum number of active Sessions allowed, or -1 for
0351:             * no limit.
0352:             */
0353:            public int getMaxActiveSessions() {
0354:
0355:                return (this .maxActiveSessions);
0356:
0357:            }
0358:
0359:            /**
0360:             * Set the maximum number of actives Sessions allowed, or -1 for
0361:             * no limit.
0362:             *
0363:             * @param max The new maximum number of sessions
0364:             */
0365:            public void setMaxActiveSessions(int max) {
0366:
0367:                int oldMaxActiveSessions = this .maxActiveSessions;
0368:                this .maxActiveSessions = max;
0369:                support.firePropertyChange("maxActiveSessions", new Integer(
0370:                        oldMaxActiveSessions), new Integer(
0371:                        this .maxActiveSessions));
0372:
0373:            }
0374:
0375:            /** 
0376:             * Number of session creations that failed due to maxActiveSessions.
0377:             *
0378:             * @return The count
0379:             */
0380:            public int getRejectedSessions() {
0381:                return rejectedSessions;
0382:            }
0383:
0384:            public void setRejectedSessions(int rejectedSessions) {
0385:                this .rejectedSessions = rejectedSessions;
0386:            }
0387:
0388:            /**
0389:             * Return the descriptive short name of this Manager implementation.
0390:             */
0391:            public String getName() {
0392:
0393:                return (name);
0394:
0395:            }
0396:
0397:            /**
0398:             * Get the started status.
0399:             */
0400:            protected boolean isStarted() {
0401:
0402:                return started;
0403:
0404:            }
0405:
0406:            /**
0407:             * Set the started flag
0408:             */
0409:            protected void setStarted(boolean started) {
0410:
0411:                this .started = started;
0412:
0413:            }
0414:
0415:            /**
0416:             * Set the Store object which will manage persistent Session
0417:             * storage for this Manager.
0418:             *
0419:             * @param store the associated Store
0420:             */
0421:            public void setStore(Store store) {
0422:                this .store = store;
0423:                store.setManager(this );
0424:
0425:            }
0426:
0427:            /**
0428:             * Return the Store object which manages persistent Session
0429:             * storage for this Manager.
0430:             */
0431:            public Store getStore() {
0432:
0433:                return (this .store);
0434:
0435:            }
0436:
0437:            /**
0438:             * Indicates whether sessions are saved when the Manager is shut down
0439:             * properly. This requires the unload() method to be called.
0440:             */
0441:            public boolean getSaveOnRestart() {
0442:
0443:                return saveOnRestart;
0444:
0445:            }
0446:
0447:            /**
0448:             * Set the option to save sessions to the Store when the Manager is
0449:             * shut down, then loaded when the Manager starts again. If set to
0450:             * false, any sessions found in the Store may still be picked up when
0451:             * the Manager is started again.
0452:             *
0453:             * @param saveOnRestart true if sessions should be saved on restart, false if
0454:             *     they should be ignored.
0455:             */
0456:            public void setSaveOnRestart(boolean saveOnRestart) {
0457:
0458:                if (saveOnRestart == this .saveOnRestart)
0459:                    return;
0460:
0461:                boolean oldSaveOnRestart = this .saveOnRestart;
0462:                this .saveOnRestart = saveOnRestart;
0463:                support.firePropertyChange("saveOnRestart", new Boolean(
0464:                        oldSaveOnRestart), new Boolean(this .saveOnRestart));
0465:
0466:            }
0467:
0468:            // --------------------------------------------------------- Public Methods
0469:
0470:            /**
0471:             * Clear all sessions from the Store.
0472:             */
0473:            public void clearStore() {
0474:
0475:                if (store == null)
0476:                    return;
0477:
0478:                try {
0479:                    if (SecurityUtil.isPackageProtectionEnabled()) {
0480:                        try {
0481:                            AccessController
0482:                                    .doPrivileged(new PrivilegedStoreClear());
0483:                        } catch (PrivilegedActionException ex) {
0484:                            Exception exception = ex.getException();
0485:                            log.error("Exception clearing the Store: "
0486:                                    + exception);
0487:                            exception.printStackTrace();
0488:                        }
0489:                    } else {
0490:                        store.clear();
0491:                    }
0492:                } catch (IOException e) {
0493:                    log.error("Exception clearing the Store: " + e);
0494:                    e.printStackTrace();
0495:                }
0496:
0497:            }
0498:
0499:            /**
0500:             * Implements the Manager interface, direct call to processExpires and processPersistenceChecks
0501:             */
0502:            public void processExpires() {
0503:
0504:                long timeNow = System.currentTimeMillis();
0505:                Session sessions[] = findSessions();
0506:                int expireHere = 0;
0507:                if (log.isDebugEnabled())
0508:                    log.debug("Start expire sessions " + getName() + " at "
0509:                            + timeNow + " sessioncount " + sessions.length);
0510:                for (int i = 0; i < sessions.length; i++) {
0511:                    if (!sessions[i].isValid()) {
0512:                        expiredSessions++;
0513:                        expireHere++;
0514:                    }
0515:                }
0516:                processPersistenceChecks();
0517:                if ((getStore() != null) && (getStore() instanceof  StoreBase)) {
0518:                    ((StoreBase) getStore()).processExpires();
0519:                }
0520:
0521:                long timeEnd = System.currentTimeMillis();
0522:                if (log.isDebugEnabled())
0523:                    log.debug("End expire sessions " + getName()
0524:                            + " processingTime " + (timeEnd - timeNow)
0525:                            + " expired sessions: " + expireHere);
0526:                processingTime += (timeEnd - timeNow);
0527:
0528:            }
0529:
0530:            /**
0531:             * Called by the background thread after active sessions have been checked
0532:             * for expiration, to allow sessions to be swapped out, backed up, etc.
0533:             */
0534:            public void processPersistenceChecks() {
0535:
0536:                processMaxIdleSwaps();
0537:                processMaxActiveSwaps();
0538:                processMaxIdleBackups();
0539:
0540:            }
0541:
0542:            /**
0543:             * Return the active Session, associated with this Manager, with the
0544:             * specified session id (if any); otherwise return <code>null</code>.
0545:             * This method checks the persistence store if persistence is enabled,
0546:             * otherwise just uses the functionality from ManagerBase.
0547:             *
0548:             * @param id The session id for the session to be returned
0549:             *
0550:             * @exception IllegalStateException if a new session cannot be
0551:             *  instantiated for any reason
0552:             * @exception IOException if an input/output error occurs while
0553:             *  processing this request
0554:             */
0555:            public Session findSession(String id) throws IOException {
0556:
0557:                Session session = super .findSession(id);
0558:                if (session != null)
0559:                    return (session);
0560:
0561:                // See if the Session is in the Store
0562:                session = swapIn(id);
0563:                return (session);
0564:
0565:            }
0566:
0567:            /**
0568:             * Remove this Session from the active Sessions for this Manager,
0569:             * but not from the Store. (Used by the PersistentValve)
0570:             *
0571:             * @param session Session to be removed
0572:             */
0573:            public void removeSuper(Session session) {
0574:                super .remove(session);
0575:            }
0576:
0577:            /**
0578:             * Load all sessions found in the persistence mechanism, assuming
0579:             * they are marked as valid and have not passed their expiration
0580:             * limit. If persistence is not supported, this method returns
0581:             * without doing anything.
0582:             * <p>
0583:             * Note that by default, this method is not called by the MiddleManager
0584:             * class. In order to use it, a subclass must specifically call it,
0585:             * for example in the start() and/or processPersistenceChecks() methods.
0586:             */
0587:            public void load() {
0588:
0589:                // Initialize our internal data structures
0590:                sessions.clear();
0591:
0592:                if (store == null)
0593:                    return;
0594:
0595:                String[] ids = null;
0596:                try {
0597:                    if (SecurityUtil.isPackageProtectionEnabled()) {
0598:                        try {
0599:                            ids = (String[]) AccessController
0600:                                    .doPrivileged(new PrivilegedStoreKeys());
0601:                        } catch (PrivilegedActionException ex) {
0602:                            Exception exception = ex.getException();
0603:                            log.error("Exception in the Store during load: "
0604:                                    + exception);
0605:                            exception.printStackTrace();
0606:                        }
0607:                    } else {
0608:                        ids = store.keys();
0609:                    }
0610:                } catch (IOException e) {
0611:                    log.error("Can't load sessions from store, "
0612:                            + e.getMessage(), e);
0613:                    return;
0614:                }
0615:
0616:                int n = ids.length;
0617:                if (n == 0)
0618:                    return;
0619:
0620:                if (log.isDebugEnabled())
0621:                    log.debug(sm.getString("persistentManager.loading", String
0622:                            .valueOf(n)));
0623:
0624:                for (int i = 0; i < n; i++)
0625:                    try {
0626:                        swapIn(ids[i]);
0627:                    } catch (IOException e) {
0628:                        log.error("Failed load session from store, "
0629:                                + e.getMessage(), e);
0630:                    }
0631:
0632:            }
0633:
0634:            /**
0635:             * Remove this Session from the active Sessions for this Manager,
0636:             * and from the Store.
0637:             *
0638:             * @param session Session to be removed
0639:             */
0640:            public void remove(Session session) {
0641:
0642:                super .remove(session);
0643:
0644:                if (store != null) {
0645:                    removeSession(session.getIdInternal());
0646:                }
0647:            }
0648:
0649:            /**
0650:             * Remove this Session from the active Sessions for this Manager,
0651:             * and from the Store.
0652:             *
0653:             * @param id Session's id to be removed
0654:             */
0655:            protected void removeSession(String id) {
0656:                try {
0657:                    if (SecurityUtil.isPackageProtectionEnabled()) {
0658:                        try {
0659:                            AccessController
0660:                                    .doPrivileged(new PrivilegedStoreRemove(id));
0661:                        } catch (PrivilegedActionException ex) {
0662:                            Exception exception = ex.getException();
0663:                            log
0664:                                    .error("Exception in the Store during removeSession: "
0665:                                            + exception);
0666:                            exception.printStackTrace();
0667:                        }
0668:                    } else {
0669:                        store.remove(id);
0670:                    }
0671:                } catch (IOException e) {
0672:                    log.error("Exception removing session  " + e.getMessage());
0673:                    e.printStackTrace();
0674:                }
0675:            }
0676:
0677:            /**
0678:             * Save all currently active sessions in the appropriate persistence
0679:             * mechanism, if any.  If persistence is not supported, this method
0680:             * returns without doing anything.
0681:             * <p>
0682:             * Note that by default, this method is not called by the MiddleManager
0683:             * class. In order to use it, a subclass must specifically call it,
0684:             * for example in the stop() and/or processPersistenceChecks() methods.
0685:             */
0686:            public void unload() {
0687:
0688:                if (store == null)
0689:                    return;
0690:
0691:                Session sessions[] = findSessions();
0692:                int n = sessions.length;
0693:                if (n == 0)
0694:                    return;
0695:
0696:                if (log.isDebugEnabled())
0697:                    log.debug(sm.getString("persistentManager.unloading",
0698:                            String.valueOf(n)));
0699:
0700:                for (int i = 0; i < n; i++)
0701:                    try {
0702:                        swapOut(sessions[i]);
0703:                    } catch (IOException e) {
0704:                        ; // This is logged in writeSession()
0705:                    }
0706:
0707:            }
0708:
0709:            // ------------------------------------------------------ Protected Methods
0710:
0711:            /**
0712:             * Look for a session in the Store and, if found, restore
0713:             * it in the Manager's list of active sessions if appropriate.
0714:             * The session will be removed from the Store after swapping
0715:             * in, but will not be added to the active session list if it
0716:             * is invalid or past its expiration.
0717:             */
0718:            protected Session swapIn(String id) throws IOException {
0719:
0720:                if (store == null)
0721:                    return null;
0722:
0723:                Session session = null;
0724:                try {
0725:                    if (SecurityUtil.isPackageProtectionEnabled()) {
0726:                        try {
0727:                            session = (Session) AccessController
0728:                                    .doPrivileged(new PrivilegedStoreLoad(id));
0729:                        } catch (PrivilegedActionException ex) {
0730:                            Exception exception = ex.getException();
0731:                            log.error("Exception in the Store during swapIn: "
0732:                                    + exception);
0733:                            if (exception instanceof  IOException) {
0734:                                throw (IOException) exception;
0735:                            } else if (exception instanceof  ClassNotFoundException) {
0736:                                throw (ClassNotFoundException) exception;
0737:                            }
0738:                        }
0739:                    } else {
0740:                        session = store.load(id);
0741:                    }
0742:                } catch (ClassNotFoundException e) {
0743:                    log.error(sm.getString(
0744:                            "persistentManager.deserializeError", id, e));
0745:                    throw new IllegalStateException(sm.getString(
0746:                            "persistentManager.deserializeError", id, e));
0747:                }
0748:
0749:                if (session == null)
0750:                    return (null);
0751:
0752:                if (!session.isValid()) {
0753:                    log.error("session swapped in is invalid or expired");
0754:                    session.expire();
0755:                    removeSession(id);
0756:                    return (null);
0757:                }
0758:
0759:                if (log.isDebugEnabled())
0760:                    log.debug(sm.getString("persistentManager.swapIn", id));
0761:
0762:                session.setManager(this );
0763:                // make sure the listeners know about it.
0764:                ((StandardSession) session).tellNew();
0765:                add(session);
0766:                ((StandardSession) session).activate();
0767:                session.endAccess();
0768:
0769:                return (session);
0770:
0771:            }
0772:
0773:            /**
0774:             * Remove the session from the Manager's list of active
0775:             * sessions and write it out to the Store. If the session
0776:             * is past its expiration or invalid, this method does
0777:             * nothing.
0778:             *
0779:             * @param session The Session to write out.
0780:             */
0781:            protected void swapOut(Session session) throws IOException {
0782:
0783:                if (store == null || !session.isValid()) {
0784:                    return;
0785:                }
0786:
0787:                ((StandardSession) session).passivate();
0788:                writeSession(session);
0789:                super .remove(session);
0790:                session.recycle();
0791:
0792:            }
0793:
0794:            /**
0795:             * Write the provided session to the Store without modifying
0796:             * the copy in memory or triggering passivation events. Does
0797:             * nothing if the session is invalid or past its expiration.
0798:             */
0799:            protected void writeSession(Session session) throws IOException {
0800:
0801:                if (store == null || !session.isValid()) {
0802:                    return;
0803:                }
0804:
0805:                try {
0806:                    if (SecurityUtil.isPackageProtectionEnabled()) {
0807:                        try {
0808:                            AccessController
0809:                                    .doPrivileged(new PrivilegedStoreSave(
0810:                                            session));
0811:                        } catch (PrivilegedActionException ex) {
0812:                            Exception exception = ex.getException();
0813:                            log
0814:                                    .error("Exception in the Store during writeSession: "
0815:                                            + exception);
0816:                            exception.printStackTrace();
0817:                        }
0818:                    } else {
0819:                        store.save(session);
0820:                    }
0821:                } catch (IOException e) {
0822:                    log.error(sm.getString("persistentManager.serializeError",
0823:                            session.getIdInternal(), e));
0824:                    throw e;
0825:                }
0826:
0827:            }
0828:
0829:            // ------------------------------------------------------ Lifecycle Methods
0830:
0831:            /**
0832:             * Add a lifecycle event listener to this component.
0833:             *
0834:             * @param listener The listener to add
0835:             */
0836:            public void addLifecycleListener(LifecycleListener listener) {
0837:
0838:                lifecycle.addLifecycleListener(listener);
0839:
0840:            }
0841:
0842:            /**
0843:             * Get the lifecycle listeners associated with this lifecycle. If this 
0844:             * Lifecycle has no listeners registered, a zero-length array is returned.
0845:             */
0846:            public LifecycleListener[] findLifecycleListeners() {
0847:
0848:                return lifecycle.findLifecycleListeners();
0849:
0850:            }
0851:
0852:            /**
0853:             * Remove a lifecycle event listener from this component.
0854:             *
0855:             * @param listener The listener to remove
0856:             */
0857:            public void removeLifecycleListener(LifecycleListener listener) {
0858:
0859:                lifecycle.removeLifecycleListener(listener);
0860:
0861:            }
0862:
0863:            /**
0864:             * Prepare for the beginning of active use of the public methods of this
0865:             * component.  This method should be called after <code>configure()</code>,
0866:             * and before any of the public methods of the component are utilized.
0867:             *
0868:             * @exception LifecycleException if this component detects a fatal error
0869:             *  that prevents this component from being used
0870:             */
0871:            public void start() throws LifecycleException {
0872:
0873:                // Validate and update our current component state
0874:                if (started) {
0875:                    log.info(sm.getString("standardManager.alreadyStarted"));
0876:                    return;
0877:                }
0878:                if (!initialized)
0879:                    init();
0880:
0881:                lifecycle.fireLifecycleEvent(START_EVENT, null);
0882:                started = true;
0883:
0884:                // Force initialization of the random number generator
0885:                if (log.isDebugEnabled())
0886:                    log.debug("Force random number initialization starting");
0887:                String dummy = generateSessionId();
0888:                if (log.isDebugEnabled())
0889:                    log.debug("Force random number initialization completed");
0890:
0891:                if (store == null)
0892:                    log.error("No Store configured, persistence disabled");
0893:                else if (store instanceof  Lifecycle)
0894:                    ((Lifecycle) store).start();
0895:
0896:            }
0897:
0898:            /**
0899:             * Gracefully terminate the active use of the public methods of this
0900:             * component.  This method should be the last one called on a given
0901:             * instance of this component.
0902:             *
0903:             * @exception LifecycleException if this component detects a fatal error
0904:             *  that needs to be reported
0905:             */
0906:            public void stop() throws LifecycleException {
0907:
0908:                if (log.isDebugEnabled())
0909:                    log.debug("Stopping");
0910:
0911:                // Validate and update our current component state
0912:                if (!isStarted()) {
0913:                    log.info(sm.getString("standardManager.notStarted"));
0914:                    return;
0915:                }
0916:
0917:                lifecycle.fireLifecycleEvent(STOP_EVENT, null);
0918:                setStarted(false);
0919:
0920:                if (getStore() != null && saveOnRestart) {
0921:                    unload();
0922:                } else {
0923:                    // Expire all active sessions
0924:                    Session sessions[] = findSessions();
0925:                    for (int i = 0; i < sessions.length; i++) {
0926:                        StandardSession session = (StandardSession) sessions[i];
0927:                        if (!session.isValid())
0928:                            continue;
0929:                        session.expire();
0930:                    }
0931:                }
0932:
0933:                if (getStore() != null && getStore() instanceof  Lifecycle)
0934:                    ((Lifecycle) getStore()).stop();
0935:
0936:                // Require a new random number generator if we are restarted
0937:                this .random = null;
0938:
0939:                if (initialized)
0940:                    destroy();
0941:
0942:            }
0943:
0944:            // ----------------------------------------- PropertyChangeListener Methods
0945:
0946:            /**
0947:             * Process property change events from our associated Context.
0948:             *
0949:             * @param event The property change event that has occurred
0950:             */
0951:            public void propertyChange(PropertyChangeEvent event) {
0952:
0953:                // Validate the source of this event
0954:                if (!(event.getSource() instanceof  Context))
0955:                    return;
0956:                Context context = (Context) event.getSource();
0957:
0958:                // Process a relevant property change
0959:                if (event.getPropertyName().equals("sessionTimeout")) {
0960:                    try {
0961:                        setMaxInactiveInterval(((Integer) event.getNewValue())
0962:                                .intValue() * 60);
0963:                    } catch (NumberFormatException e) {
0964:                        log.error(sm.getString(
0965:                                "standardManager.sessionTimeout", event
0966:                                        .getNewValue().toString()));
0967:                    }
0968:                }
0969:
0970:            }
0971:
0972:            // ------------------------------------------------------ Protected Methods
0973:
0974:            /**
0975:             * Swap idle sessions out to Store if they are idle too long.
0976:             */
0977:            protected void processMaxIdleSwaps() {
0978:
0979:                if (!isStarted() || maxIdleSwap < 0)
0980:                    return;
0981:
0982:                Session sessions[] = findSessions();
0983:                long timeNow = System.currentTimeMillis();
0984:
0985:                // Swap out all sessions idle longer than maxIdleSwap
0986:                // FIXME: What's preventing us from mangling a session during
0987:                // a request?
0988:                if (maxIdleSwap >= 0) {
0989:                    for (int i = 0; i < sessions.length; i++) {
0990:                        StandardSession session = (StandardSession) sessions[i];
0991:                        if (!session.isValid())
0992:                            continue;
0993:                        int timeIdle = // Truncate, do not round up
0994:                        (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
0995:                        if (timeIdle > maxIdleSwap && timeIdle > minIdleSwap) {
0996:                            if (log.isDebugEnabled())
0997:                                log.debug(sm.getString(
0998:                                        "persistentManager.swapMaxIdle",
0999:                                        session.getIdInternal(), new Integer(
1000:                                                timeIdle)));
1001:                            try {
1002:                                swapOut(session);
1003:                            } catch (IOException e) {
1004:                                ; // This is logged in writeSession()
1005:                            }
1006:                        }
1007:                    }
1008:                }
1009:
1010:            }
1011:
1012:            /**
1013:             * Swap idle sessions out to Store if too many are active
1014:             */
1015:            protected void processMaxActiveSwaps() {
1016:
1017:                if (!isStarted() || getMaxActiveSessions() < 0)
1018:                    return;
1019:
1020:                Session sessions[] = findSessions();
1021:
1022:                // FIXME: Smarter algorithm (LRU)
1023:                if (getMaxActiveSessions() >= sessions.length)
1024:                    return;
1025:
1026:                if (log.isDebugEnabled())
1027:                    log.debug(sm.getString("persistentManager.tooManyActive",
1028:                            new Integer(sessions.length)));
1029:
1030:                int toswap = sessions.length - getMaxActiveSessions();
1031:                long timeNow = System.currentTimeMillis();
1032:
1033:                for (int i = 0; i < sessions.length && toswap > 0; i++) {
1034:                    int timeIdle = // Truncate, do not round up
1035:                    (int) ((timeNow - sessions[i].getLastAccessedTime()) / 1000L);
1036:                    if (timeIdle > minIdleSwap) {
1037:                        if (log.isDebugEnabled())
1038:                            log.debug(sm.getString(
1039:                                    "persistentManager.swapTooManyActive",
1040:                                    sessions[i].getIdInternal(), new Integer(
1041:                                            timeIdle)));
1042:                        try {
1043:                            swapOut(sessions[i]);
1044:                        } catch (IOException e) {
1045:                            ; // This is logged in writeSession()
1046:                        }
1047:                        toswap--;
1048:                    }
1049:                }
1050:
1051:            }
1052:
1053:            /**
1054:             * Back up idle sessions.
1055:             */
1056:            protected void processMaxIdleBackups() {
1057:
1058:                if (!isStarted() || maxIdleBackup < 0)
1059:                    return;
1060:
1061:                Session sessions[] = findSessions();
1062:                long timeNow = System.currentTimeMillis();
1063:
1064:                // Back up all sessions idle longer than maxIdleBackup
1065:                if (maxIdleBackup >= 0) {
1066:                    for (int i = 0; i < sessions.length; i++) {
1067:                        StandardSession session = (StandardSession) sessions[i];
1068:                        if (!session.isValid())
1069:                            continue;
1070:                        int timeIdle = // Truncate, do not round up
1071:                        (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
1072:                        if (timeIdle > maxIdleBackup) {
1073:                            if (log.isDebugEnabled())
1074:                                log.debug(sm.getString(
1075:                                        "persistentManager.backupMaxIdle",
1076:                                        session.getIdInternal(), new Integer(
1077:                                                timeIdle)));
1078:
1079:                            try {
1080:                                writeSession(session);
1081:                            } catch (IOException e) {
1082:                                ; // This is logged in writeSession()
1083:                            }
1084:                        }
1085:                    }
1086:                }
1087:
1088:            }
1089:
1090:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.