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


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