Source Code Cross Referenced for ManagerBase.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.PropertyChangeListener;
0021:        import java.beans.PropertyChangeSupport;
0022:        import java.io.DataInputStream;
0023:        import java.io.File;
0024:        import java.io.FileInputStream;
0025:        import java.io.IOException;
0026:        import java.lang.reflect.Method;
0027:        import java.security.AccessController;
0028:        import java.security.MessageDigest;
0029:        import java.security.NoSuchAlgorithmException;
0030:        import java.security.PrivilegedAction;
0031:        import java.util.Date;
0032:        import java.util.Enumeration;
0033:        import java.util.HashMap;
0034:        import java.util.Iterator;
0035:        import java.util.Map;
0036:        import java.util.Random;
0037:        import java.util.concurrent.ConcurrentHashMap;
0038:
0039:        import javax.management.MBeanRegistration;
0040:        import javax.management.MBeanServer;
0041:        import javax.management.ObjectName;
0042:
0043:        import org.apache.catalina.Container;
0044:        import org.apache.catalina.Engine;
0045:        import org.apache.catalina.Globals;
0046:        import org.apache.catalina.Manager;
0047:        import org.apache.catalina.Session;
0048:        import org.apache.catalina.core.StandardContext;
0049:        import org.apache.catalina.core.StandardHost;
0050:        import org.apache.catalina.util.StringManager;
0051:        import org.apache.juli.logging.Log;
0052:        import org.apache.juli.logging.LogFactory;
0053:        import org.apache.tomcat.util.modeler.Registry;
0054:
0055:        /**
0056:         * Minimal implementation of the <b>Manager</b> interface that supports
0057:         * no session persistence or distributable capabilities.  This class may
0058:         * be subclassed to create more sophisticated Manager implementations.
0059:         *
0060:         * @author Craig R. McClanahan
0061:         * @version $Revision: 531901 $ $Date: 2007-04-24 14:24:34 +0200 (mar., 24 avr. 2007) $
0062:         */
0063:
0064:        public abstract class ManagerBase implements  Manager, MBeanRegistration {
0065:            protected Log log = LogFactory.getLog(ManagerBase.class);
0066:
0067:            // ----------------------------------------------------- Instance Variables
0068:
0069:            protected DataInputStream randomIS = null;
0070:            protected String devRandomSource = "/dev/urandom";
0071:
0072:            /**
0073:             * The default message digest algorithm to use if we cannot use
0074:             * the requested one.
0075:             */
0076:            protected static final String DEFAULT_ALGORITHM = "MD5";
0077:
0078:            /**
0079:             * The message digest algorithm to be used when generating session
0080:             * identifiers.  This must be an algorithm supported by the
0081:             * <code>java.security.MessageDigest</code> class on your platform.
0082:             */
0083:            protected String algorithm = DEFAULT_ALGORITHM;
0084:
0085:            /**
0086:             * The Container with which this Manager is associated.
0087:             */
0088:            protected Container container;
0089:
0090:            /**
0091:             * Return the MessageDigest implementation to be used when
0092:             * creating session identifiers.
0093:             */
0094:            protected MessageDigest digest = null;
0095:
0096:            /**
0097:             * The distributable flag for Sessions created by this Manager.  If this
0098:             * flag is set to <code>true</code>, any user attributes added to a
0099:             * session controlled by this Manager must be Serializable.
0100:             */
0101:            protected boolean distributable;
0102:
0103:            /**
0104:             * A String initialization parameter used to increase the entropy of
0105:             * the initialization of our random number generator.
0106:             */
0107:            protected String entropy = null;
0108:
0109:            /**
0110:             * The descriptive information string for this implementation.
0111:             */
0112:            private static final String info = "ManagerBase/1.0";
0113:
0114:            /**
0115:             * The default maximum inactive interval for Sessions created by
0116:             * this Manager.
0117:             */
0118:            protected int maxInactiveInterval = 60;
0119:
0120:            /**
0121:             * The session id length of Sessions created by this Manager.
0122:             */
0123:            protected int sessionIdLength = 16;
0124:
0125:            /**
0126:             * The descriptive name of this Manager implementation (for logging).
0127:             */
0128:            protected static String name = "ManagerBase";
0129:
0130:            /**
0131:             * A random number generator to use when generating session identifiers.
0132:             */
0133:            protected Random random = null;
0134:
0135:            /**
0136:             * The Java class name of the random number generator class to be used
0137:             * when generating session identifiers.
0138:             */
0139:            protected String randomClass = "java.security.SecureRandom";
0140:
0141:            /**
0142:             * The longest time (in seconds) that an expired session had been alive.
0143:             */
0144:            protected int sessionMaxAliveTime;
0145:
0146:            /**
0147:             * Average time (in seconds) that expired sessions had been alive.
0148:             */
0149:            protected int sessionAverageAliveTime;
0150:
0151:            /**
0152:             * Number of sessions that have expired.
0153:             */
0154:            protected int expiredSessions = 0;
0155:
0156:            /**
0157:             * The set of currently active Sessions for this Manager, keyed by
0158:             * session identifier.
0159:             */
0160:            protected Map sessions = new ConcurrentHashMap();
0161:
0162:            // Number of sessions created by this manager
0163:            protected int sessionCounter = 0;
0164:
0165:            protected int maxActive = 0;
0166:
0167:            // number of duplicated session ids - anything >0 means we have problems
0168:            protected int duplicates = 0;
0169:
0170:            protected boolean initialized = false;
0171:
0172:            /**
0173:             * Processing time during session expiration.
0174:             */
0175:            protected long processingTime = 0;
0176:
0177:            /**
0178:             * Iteration count for background processing.
0179:             */
0180:            private int count = 0;
0181:
0182:            /**
0183:             * Frequency of the session expiration, and related manager operations.
0184:             * Manager operations will be done once for the specified amount of
0185:             * backgrondProcess calls (ie, the lower the amount, the most often the
0186:             * checks will occur).
0187:             */
0188:            protected int processExpiresFrequency = 6;
0189:
0190:            /**
0191:             * The string manager for this package.
0192:             */
0193:            protected static StringManager sm = StringManager
0194:                    .getManager(Constants.Package);
0195:
0196:            /**
0197:             * The property change support for this component.
0198:             */
0199:            protected PropertyChangeSupport support = new PropertyChangeSupport(
0200:                    this );
0201:
0202:            // ------------------------------------------------------------- Security classes
0203:
0204:            private class PrivilegedSetRandomFile implements  PrivilegedAction {
0205:
0206:                public Object run() {
0207:                    try {
0208:                        File f = new File(devRandomSource);
0209:                        if (!f.exists())
0210:                            return null;
0211:                        randomIS = new DataInputStream(new FileInputStream(f));
0212:                        randomIS.readLong();
0213:                        if (log.isDebugEnabled())
0214:                            log.debug("Opening " + devRandomSource);
0215:                        return randomIS;
0216:                    } catch (IOException ex) {
0217:                        return null;
0218:                    }
0219:                }
0220:            }
0221:
0222:            // ------------------------------------------------------------- Properties
0223:
0224:            /**
0225:             * Return the message digest algorithm for this Manager.
0226:             */
0227:            public String getAlgorithm() {
0228:
0229:                return (this .algorithm);
0230:
0231:            }
0232:
0233:            /**
0234:             * Set the message digest algorithm for this Manager.
0235:             *
0236:             * @param algorithm The new message digest algorithm
0237:             */
0238:            public void setAlgorithm(String algorithm) {
0239:
0240:                String oldAlgorithm = this .algorithm;
0241:                this .algorithm = algorithm;
0242:                support.firePropertyChange("algorithm", oldAlgorithm,
0243:                        this .algorithm);
0244:
0245:            }
0246:
0247:            /**
0248:             * Return the Container with which this Manager is associated.
0249:             */
0250:            public Container getContainer() {
0251:
0252:                return (this .container);
0253:
0254:            }
0255:
0256:            /**
0257:             * Set the Container with which this Manager is associated.
0258:             *
0259:             * @param container The newly associated Container
0260:             */
0261:            public void setContainer(Container container) {
0262:
0263:                Container oldContainer = this .container;
0264:                this .container = container;
0265:                support.firePropertyChange("container", oldContainer,
0266:                        this .container);
0267:            }
0268:
0269:            /** Returns the name of the implementation class.
0270:             */
0271:            public String getClassName() {
0272:                return this .getClass().getName();
0273:            }
0274:
0275:            /**
0276:             * Return the MessageDigest object to be used for calculating
0277:             * session identifiers.  If none has been created yet, initialize
0278:             * one the first time this method is called.
0279:             */
0280:            public synchronized MessageDigest getDigest() {
0281:
0282:                if (this .digest == null) {
0283:                    long t1 = System.currentTimeMillis();
0284:                    if (log.isDebugEnabled())
0285:                        log.debug(sm
0286:                                .getString("managerBase.getting", algorithm));
0287:                    try {
0288:                        this .digest = MessageDigest.getInstance(algorithm);
0289:                    } catch (NoSuchAlgorithmException e) {
0290:                        log.error(
0291:                                sm.getString("managerBase.digest", algorithm),
0292:                                e);
0293:                        try {
0294:                            this .digest = MessageDigest
0295:                                    .getInstance(DEFAULT_ALGORITHM);
0296:                        } catch (NoSuchAlgorithmException f) {
0297:                            log.error(sm.getString("managerBase.digest",
0298:                                    DEFAULT_ALGORITHM), e);
0299:                            this .digest = null;
0300:                        }
0301:                    }
0302:                    if (log.isDebugEnabled())
0303:                        log.debug(sm.getString("managerBase.gotten"));
0304:                    long t2 = System.currentTimeMillis();
0305:                    if (log.isDebugEnabled())
0306:                        log.debug("getDigest() " + (t2 - t1));
0307:                }
0308:
0309:                return (this .digest);
0310:
0311:            }
0312:
0313:            /**
0314:             * Return the distributable flag for the sessions supported by
0315:             * this Manager.
0316:             */
0317:            public boolean getDistributable() {
0318:
0319:                return (this .distributable);
0320:
0321:            }
0322:
0323:            /**
0324:             * Set the distributable flag for the sessions supported by this
0325:             * Manager.  If this flag is set, all user data objects added to
0326:             * sessions associated with this manager must implement Serializable.
0327:             *
0328:             * @param distributable The new distributable flag
0329:             */
0330:            public void setDistributable(boolean distributable) {
0331:
0332:                boolean oldDistributable = this .distributable;
0333:                this .distributable = distributable;
0334:                support.firePropertyChange("distributable", new Boolean(
0335:                        oldDistributable), new Boolean(this .distributable));
0336:
0337:            }
0338:
0339:            /**
0340:             * Return the entropy increaser value, or compute a semi-useful value
0341:             * if this String has not yet been set.
0342:             */
0343:            public String getEntropy() {
0344:
0345:                // Calculate a semi-useful value if this has not been set
0346:                if (this .entropy == null) {
0347:                    // Use APR to get a crypto secure entropy value
0348:                    byte[] result = new byte[32];
0349:                    boolean apr = false;
0350:                    try {
0351:                        String methodName = "random";
0352:                        Class paramTypes[] = new Class[2];
0353:                        paramTypes[0] = result.getClass();
0354:                        paramTypes[1] = int.class;
0355:                        Object paramValues[] = new Object[2];
0356:                        paramValues[0] = result;
0357:                        paramValues[1] = new Integer(32);
0358:                        Method method = Class.forName(
0359:                                "org.apache.tomcat.jni.OS").getMethod(
0360:                                methodName, paramTypes);
0361:                        method.invoke(null, paramValues);
0362:                        apr = true;
0363:                    } catch (Throwable t) {
0364:                        // Ignore
0365:                    }
0366:                    if (apr) {
0367:                        setEntropy(new String(result));
0368:                    } else {
0369:                        setEntropy(this .toString());
0370:                    }
0371:                }
0372:
0373:                return (this .entropy);
0374:
0375:            }
0376:
0377:            /**
0378:             * Set the entropy increaser value.
0379:             *
0380:             * @param entropy The new entropy increaser value
0381:             */
0382:            public void setEntropy(String entropy) {
0383:
0384:                String oldEntropy = entropy;
0385:                this .entropy = entropy;
0386:                support.firePropertyChange("entropy", oldEntropy, this .entropy);
0387:
0388:            }
0389:
0390:            /**
0391:             * Return descriptive information about this Manager implementation and
0392:             * the corresponding version number, in the format
0393:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0394:             */
0395:            public String getInfo() {
0396:
0397:                return (info);
0398:
0399:            }
0400:
0401:            /**
0402:             * Return the default maximum inactive interval (in seconds)
0403:             * for Sessions created by this Manager.
0404:             */
0405:            public int getMaxInactiveInterval() {
0406:
0407:                return (this .maxInactiveInterval);
0408:
0409:            }
0410:
0411:            /**
0412:             * Set the default maximum inactive interval (in seconds)
0413:             * for Sessions created by this Manager.
0414:             *
0415:             * @param interval The new default value
0416:             */
0417:            public void setMaxInactiveInterval(int interval) {
0418:
0419:                int oldMaxInactiveInterval = this .maxInactiveInterval;
0420:                this .maxInactiveInterval = interval;
0421:                support.firePropertyChange("maxInactiveInterval", new Integer(
0422:                        oldMaxInactiveInterval), new Integer(
0423:                        this .maxInactiveInterval));
0424:
0425:            }
0426:
0427:            /**
0428:             * Gets the session id length (in bytes) of Sessions created by
0429:             * this Manager.
0430:             *
0431:             * @return The session id length
0432:             */
0433:            public int getSessionIdLength() {
0434:
0435:                return (this .sessionIdLength);
0436:
0437:            }
0438:
0439:            /**
0440:             * Sets the session id length (in bytes) for Sessions created by this
0441:             * Manager.
0442:             *
0443:             * @param idLength The session id length
0444:             */
0445:            public void setSessionIdLength(int idLength) {
0446:
0447:                int oldSessionIdLength = this .sessionIdLength;
0448:                this .sessionIdLength = idLength;
0449:                support.firePropertyChange("sessionIdLength", new Integer(
0450:                        oldSessionIdLength), new Integer(this .sessionIdLength));
0451:
0452:            }
0453:
0454:            /**
0455:             * Return the descriptive short name of this Manager implementation.
0456:             */
0457:            public String getName() {
0458:
0459:                return (name);
0460:
0461:            }
0462:
0463:            /** 
0464:             * Use /dev/random-type special device. This is new code, but may reduce
0465:             * the big delay in generating the random.
0466:             *
0467:             *  You must specify a path to a random generator file. Use /dev/urandom
0468:             *  for linux ( or similar ) systems. Use /dev/random for maximum security
0469:             *  ( it may block if not enough "random" exist ). You can also use
0470:             *  a pipe that generates random.
0471:             *
0472:             *  The code will check if the file exists, and default to java Random
0473:             *  if not found. There is a significant performance difference, very
0474:             *  visible on the first call to getSession ( like in the first JSP )
0475:             *  - so use it if available.
0476:             */
0477:            public void setRandomFile(String s) {
0478:                // as a hack, you can use a static file - and genarate the same
0479:                // session ids ( good for strange debugging )
0480:                if (Globals.IS_SECURITY_ENABLED) {
0481:                    randomIS = (DataInputStream) AccessController
0482:                            .doPrivileged(new PrivilegedSetRandomFile());
0483:                } else {
0484:                    try {
0485:                        devRandomSource = s;
0486:                        File f = new File(devRandomSource);
0487:                        if (!f.exists())
0488:                            return;
0489:                        randomIS = new DataInputStream(new FileInputStream(f));
0490:                        randomIS.readLong();
0491:                        if (log.isDebugEnabled())
0492:                            log.debug("Opening " + devRandomSource);
0493:                    } catch (IOException ex) {
0494:                        try {
0495:                            randomIS.close();
0496:                        } catch (Exception e) {
0497:                            log.warn("Failed to close randomIS.");
0498:                        }
0499:
0500:                        randomIS = null;
0501:                    }
0502:                }
0503:            }
0504:
0505:            public String getRandomFile() {
0506:                return devRandomSource;
0507:            }
0508:
0509:            /**
0510:             * Return the random number generator instance we should use for
0511:             * generating session identifiers.  If there is no such generator
0512:             * currently defined, construct and seed a new one.
0513:             */
0514:            public Random getRandom() {
0515:                if (this .random == null) {
0516:                    // Calculate the new random number generator seed
0517:                    long seed = System.currentTimeMillis();
0518:                    long t1 = seed;
0519:                    char entropy[] = getEntropy().toCharArray();
0520:                    for (int i = 0; i < entropy.length; i++) {
0521:                        long update = ((byte) entropy[i]) << ((i % 8) * 8);
0522:                        seed ^= update;
0523:                    }
0524:                    try {
0525:                        // Construct and seed a new random number generator
0526:                        Class clazz = Class.forName(randomClass);
0527:                        this .random = (Random) clazz.newInstance();
0528:                        this .random.setSeed(seed);
0529:                    } catch (Exception e) {
0530:                        // Fall back to the simple case
0531:                        log.error(sm.getString("managerBase.random",
0532:                                randomClass), e);
0533:                        this .random = new java.util.Random();
0534:                        this .random.setSeed(seed);
0535:                    }
0536:                    if (log.isDebugEnabled()) {
0537:                        long t2 = System.currentTimeMillis();
0538:                        if ((t2 - t1) > 100)
0539:                            log.debug(sm.getString("managerBase.seeding",
0540:                                    randomClass)
0541:                                    + " " + (t2 - t1));
0542:                    }
0543:                }
0544:
0545:                return (this .random);
0546:
0547:            }
0548:
0549:            /**
0550:             * Return the random number generator class name.
0551:             */
0552:            public String getRandomClass() {
0553:
0554:                return (this .randomClass);
0555:
0556:            }
0557:
0558:            /**
0559:             * Set the random number generator class name.
0560:             *
0561:             * @param randomClass The new random number generator class name
0562:             */
0563:            public void setRandomClass(String randomClass) {
0564:
0565:                String oldRandomClass = this .randomClass;
0566:                this .randomClass = randomClass;
0567:                support.firePropertyChange("randomClass", oldRandomClass,
0568:                        this .randomClass);
0569:
0570:            }
0571:
0572:            /**
0573:             * Gets the number of sessions that have expired.
0574:             *
0575:             * @return Number of sessions that have expired
0576:             */
0577:            public int getExpiredSessions() {
0578:                return expiredSessions;
0579:            }
0580:
0581:            /**
0582:             * Sets the number of sessions that have expired.
0583:             *
0584:             * @param expiredSessions Number of sessions that have expired
0585:             */
0586:            public void setExpiredSessions(int expiredSessions) {
0587:                this .expiredSessions = expiredSessions;
0588:            }
0589:
0590:            public long getProcessingTime() {
0591:                return processingTime;
0592:            }
0593:
0594:            public void setProcessingTime(long processingTime) {
0595:                this .processingTime = processingTime;
0596:            }
0597:
0598:            /**
0599:             * Return the frequency of manager checks.
0600:             */
0601:            public int getProcessExpiresFrequency() {
0602:
0603:                return (this .processExpiresFrequency);
0604:
0605:            }
0606:
0607:            /**
0608:             * Set the manager checks frequency.
0609:             *
0610:             * @param processExpiresFrequency the new manager checks frequency
0611:             */
0612:            public void setProcessExpiresFrequency(int processExpiresFrequency) {
0613:
0614:                if (processExpiresFrequency <= 0) {
0615:                    return;
0616:                }
0617:
0618:                int oldProcessExpiresFrequency = this .processExpiresFrequency;
0619:                this .processExpiresFrequency = processExpiresFrequency;
0620:                support.firePropertyChange("processExpiresFrequency",
0621:                        new Integer(oldProcessExpiresFrequency), new Integer(
0622:                                this .processExpiresFrequency));
0623:
0624:            }
0625:
0626:            // --------------------------------------------------------- Public Methods
0627:
0628:            /**
0629:             * Implements the Manager interface, direct call to processExpires
0630:             */
0631:            public void backgroundProcess() {
0632:                count = (count + 1) % processExpiresFrequency;
0633:                if (count == 0)
0634:                    processExpires();
0635:            }
0636:
0637:            /**
0638:             * Invalidate all sessions that have expired.
0639:             */
0640:            public void processExpires() {
0641:
0642:                long timeNow = System.currentTimeMillis();
0643:                Session sessions[] = findSessions();
0644:                int expireHere = 0;
0645:
0646:                if (log.isDebugEnabled())
0647:                    log.debug("Start expire sessions " + getName() + " at "
0648:                            + timeNow + " sessioncount " + sessions.length);
0649:                for (int i = 0; i < sessions.length; i++) {
0650:                    if (!sessions[i].isValid()) {
0651:                        expireHere++;
0652:                    }
0653:                }
0654:                long timeEnd = System.currentTimeMillis();
0655:                if (log.isDebugEnabled())
0656:                    log.debug("End expire sessions " + getName()
0657:                            + " processingTime " + (timeEnd - timeNow)
0658:                            + " expired sessions: " + expireHere);
0659:                processingTime += (timeEnd - timeNow);
0660:
0661:            }
0662:
0663:            public void destroy() {
0664:                if (oname != null)
0665:                    Registry.getRegistry(null, null).unregisterComponent(oname);
0666:                initialized = false;
0667:                oname = null;
0668:            }
0669:
0670:            public void init() {
0671:                if (initialized)
0672:                    return;
0673:                initialized = true;
0674:
0675:                log = LogFactory.getLog(ManagerBase.class);
0676:
0677:                if (oname == null) {
0678:                    try {
0679:                        StandardContext ctx = (StandardContext) this 
0680:                                .getContainer();
0681:                        Engine eng = (Engine) ctx.getParent().getParent();
0682:                        domain = ctx.getEngineName();
0683:                        distributable = ctx.getDistributable();
0684:                        StandardHost hst = (StandardHost) ctx.getParent();
0685:                        String path = ctx.getPath();
0686:                        if (path.equals("")) {
0687:                            path = "/";
0688:                        }
0689:                        oname = new ObjectName(domain + ":type=Manager,path="
0690:                                + path + ",host=" + hst.getName());
0691:                        Registry.getRegistry(null, null).registerComponent(
0692:                                this , oname, null);
0693:                    } catch (Exception e) {
0694:                        log.error("Error registering ", e);
0695:                    }
0696:                }
0697:
0698:                // Initialize random number generation
0699:                getRandomBytes(new byte[16]);
0700:
0701:                if (log.isDebugEnabled())
0702:                    log.debug("Registering " + oname);
0703:
0704:            }
0705:
0706:            /**
0707:             * Add this Session to the set of active Sessions for this Manager.
0708:             *
0709:             * @param session Session to be added
0710:             */
0711:            public void add(Session session) {
0712:
0713:                sessions.put(session.getIdInternal(), session);
0714:                int size = sessions.size();
0715:                if (size > maxActive) {
0716:                    maxActive = size;
0717:                }
0718:            }
0719:
0720:            /**
0721:             * Add a property change listener to this component.
0722:             *
0723:             * @param listener The listener to add
0724:             */
0725:            public void addPropertyChangeListener(
0726:                    PropertyChangeListener listener) {
0727:
0728:                support.addPropertyChangeListener(listener);
0729:
0730:            }
0731:
0732:            /**
0733:             * Construct and return a new session object, based on the default
0734:             * settings specified by this Manager's properties.  The session
0735:             * id will be assigned by this method, and available via the getId()
0736:             * method of the returned session.  If a new session cannot be created
0737:             * for any reason, return <code>null</code>.
0738:             * 
0739:             * @exception IllegalStateException if a new session cannot be
0740:             *  instantiated for any reason
0741:             * @deprecated
0742:             */
0743:            public Session createSession() {
0744:                return createSession(null);
0745:            }
0746:
0747:            /**
0748:             * Construct and return a new session object, based on the default
0749:             * settings specified by this Manager's properties.  The session
0750:             * id specified will be used as the session id.  
0751:             * If a new session cannot be created for any reason, return 
0752:             * <code>null</code>.
0753:             * 
0754:             * @param sessionId The session id which should be used to create the
0755:             *  new session; if <code>null</code>, a new session id will be
0756:             *  generated
0757:             * @exception IllegalStateException if a new session cannot be
0758:             *  instantiated for any reason
0759:             */
0760:            public Session createSession(String sessionId) {
0761:
0762:                // Recycle or create a Session instance
0763:                Session session = createEmptySession();
0764:
0765:                // Initialize the properties of the new session and return it
0766:                session.setNew(true);
0767:                session.setValid(true);
0768:                session.setCreationTime(System.currentTimeMillis());
0769:                session.setMaxInactiveInterval(this .maxInactiveInterval);
0770:                if (sessionId == null) {
0771:                    sessionId = generateSessionId();
0772:                    // FIXME WHy we need no duplication check?
0773:                    /*         
0774:                         synchronized (sessions) {
0775:                            while (sessions.get(sessionId) != null) { // Guarantee
0776:                                // uniqueness
0777:                                duplicates++;
0778:                                sessionId = generateSessionId();
0779:                            }
0780:                        }
0781:                     */
0782:
0783:                    // FIXME: Code to be used in case route replacement is needed
0784:                    /*
0785:                    } else {
0786:                    String jvmRoute = getJvmRoute();
0787:                    if (getJvmRoute() != null) {
0788:                        String requestJvmRoute = null;
0789:                        int index = sessionId.indexOf(".");
0790:                        if (index > 0) {
0791:                            requestJvmRoute = sessionId
0792:                                    .substring(index + 1, sessionId.length());
0793:                        }
0794:                        if (requestJvmRoute != null && !requestJvmRoute.equals(jvmRoute)) {
0795:                            sessionId = sessionId.substring(0, index) + "." + jvmRoute;
0796:                        }
0797:                    }
0798:                     */
0799:                }
0800:                session.setId(sessionId);
0801:                sessionCounter++;
0802:
0803:                return (session);
0804:
0805:            }
0806:
0807:            /**
0808:             * Get a session from the recycled ones or create a new empty one.
0809:             * The PersistentManager manager does not need to create session data
0810:             * because it reads it from the Store.
0811:             */
0812:            public Session createEmptySession() {
0813:                return (getNewSession());
0814:            }
0815:
0816:            /**
0817:             * Return the active Session, associated with this Manager, with the
0818:             * specified session id (if any); otherwise return <code>null</code>.
0819:             *
0820:             * @param id The session id for the session to be returned
0821:             *
0822:             * @exception IllegalStateException if a new session cannot be
0823:             *  instantiated for any reason
0824:             * @exception IOException if an input/output error occurs while
0825:             *  processing this request
0826:             */
0827:            public Session findSession(String id) throws IOException {
0828:
0829:                if (id == null)
0830:                    return (null);
0831:                return (Session) sessions.get(id);
0832:
0833:            }
0834:
0835:            /**
0836:             * Return the set of active Sessions associated with this Manager.
0837:             * If this Manager has no active Sessions, a zero-length array is returned.
0838:             */
0839:            public Session[] findSessions() {
0840:
0841:                Session results[] = null;
0842:                synchronized (sessions) {
0843:                    results = new Session[sessions.size()];
0844:                    results = (Session[]) sessions.values().toArray(results);
0845:                }
0846:                return (results);
0847:
0848:            }
0849:
0850:            /**
0851:             * Remove this Session from the active Sessions for this Manager.
0852:             *
0853:             * @param session Session to be removed
0854:             */
0855:            public void remove(Session session) {
0856:
0857:                sessions.remove(session.getIdInternal());
0858:
0859:            }
0860:
0861:            /**
0862:             * Remove a property change listener from this component.
0863:             *
0864:             * @param listener The listener to remove
0865:             */
0866:            public void removePropertyChangeListener(
0867:                    PropertyChangeListener listener) {
0868:
0869:                support.removePropertyChangeListener(listener);
0870:
0871:            }
0872:
0873:            // ------------------------------------------------------ Protected Methods
0874:
0875:            /**
0876:             * Get new session class to be used in the doLoad() method.
0877:             */
0878:            protected StandardSession getNewSession() {
0879:                return new StandardSession(this );
0880:            }
0881:
0882:            protected void getRandomBytes(byte bytes[]) {
0883:                // Generate a byte array containing a session identifier
0884:                if (devRandomSource != null && randomIS == null) {
0885:                    setRandomFile(devRandomSource);
0886:                }
0887:                if (randomIS != null) {
0888:                    try {
0889:                        int len = randomIS.read(bytes);
0890:                        if (len == bytes.length) {
0891:                            return;
0892:                        }
0893:                        if (log.isDebugEnabled())
0894:                            log.debug("Got " + len + " " + bytes.length);
0895:                    } catch (Exception ex) {
0896:                        // Ignore
0897:                    }
0898:                    devRandomSource = null;
0899:
0900:                    try {
0901:                        randomIS.close();
0902:                    } catch (Exception e) {
0903:                        log.warn("Failed to close randomIS.");
0904:                    }
0905:
0906:                    randomIS = null;
0907:                }
0908:                getRandom().nextBytes(bytes);
0909:            }
0910:
0911:            /**
0912:             * Generate and return a new session identifier.
0913:             */
0914:            protected synchronized String generateSessionId() {
0915:
0916:                byte random[] = new byte[16];
0917:                String jvmRoute = getJvmRoute();
0918:                String result = null;
0919:
0920:                // Render the result as a String of hexadecimal digits
0921:                StringBuffer buffer = new StringBuffer();
0922:                do {
0923:                    int resultLenBytes = 0;
0924:                    if (result != null) {
0925:                        buffer = new StringBuffer();
0926:                        duplicates++;
0927:                    }
0928:
0929:                    while (resultLenBytes < this .sessionIdLength) {
0930:                        getRandomBytes(random);
0931:                        random = getDigest().digest(random);
0932:                        for (int j = 0; j < random.length
0933:                                && resultLenBytes < this .sessionIdLength; j++) {
0934:                            byte b1 = (byte) ((random[j] & 0xf0) >> 4);
0935:                            byte b2 = (byte) (random[j] & 0x0f);
0936:                            if (b1 < 10)
0937:                                buffer.append((char) ('0' + b1));
0938:                            else
0939:                                buffer.append((char) ('A' + (b1 - 10)));
0940:                            if (b2 < 10)
0941:                                buffer.append((char) ('0' + b2));
0942:                            else
0943:                                buffer.append((char) ('A' + (b2 - 10)));
0944:                            resultLenBytes++;
0945:                        }
0946:                    }
0947:                    if (jvmRoute != null) {
0948:                        buffer.append('.').append(jvmRoute);
0949:                    }
0950:                    result = buffer.toString();
0951:                } while (sessions.containsKey(result));
0952:                return (result);
0953:
0954:            }
0955:
0956:            // ------------------------------------------------------ Protected Methods
0957:
0958:            /**
0959:             * Retrieve the enclosing Engine for this Manager.
0960:             *
0961:             * @return an Engine object (or null).
0962:             */
0963:            public Engine getEngine() {
0964:                Engine e = null;
0965:                for (Container c = getContainer(); e == null && c != null; c = c
0966:                        .getParent()) {
0967:                    if (c != null && c instanceof  Engine) {
0968:                        e = (Engine) c;
0969:                    }
0970:                }
0971:                return e;
0972:            }
0973:
0974:            /**
0975:             * Retrieve the JvmRoute for the enclosing Engine.
0976:             * @return the JvmRoute or null.
0977:             */
0978:            public String getJvmRoute() {
0979:                Engine e = getEngine();
0980:                return e == null ? null : e.getJvmRoute();
0981:            }
0982:
0983:            // -------------------------------------------------------- Package Methods
0984:
0985:            public void setSessionCounter(int sessionCounter) {
0986:                this .sessionCounter = sessionCounter;
0987:            }
0988:
0989:            /** 
0990:             * Total sessions created by this manager.
0991:             *
0992:             * @return sessions created
0993:             */
0994:            public int getSessionCounter() {
0995:                return sessionCounter;
0996:            }
0997:
0998:            /** 
0999:             * Number of duplicated session IDs generated by the random source.
1000:             * Anything bigger than 0 means problems.
1001:             *
1002:             * @return The count of duplicates
1003:             */
1004:            public int getDuplicates() {
1005:                return duplicates;
1006:            }
1007:
1008:            public void setDuplicates(int duplicates) {
1009:                this .duplicates = duplicates;
1010:            }
1011:
1012:            /** 
1013:             * Returns the number of active sessions
1014:             *
1015:             * @return number of sessions active
1016:             */
1017:            public int getActiveSessions() {
1018:                return sessions.size();
1019:            }
1020:
1021:            /**
1022:             * Max number of concurrent active sessions
1023:             *
1024:             * @return The highest number of concurrent active sessions
1025:             */
1026:            public int getMaxActive() {
1027:                return maxActive;
1028:            }
1029:
1030:            public void setMaxActive(int maxActive) {
1031:                this .maxActive = maxActive;
1032:            }
1033:
1034:            /**
1035:             * Gets the longest time (in seconds) that an expired session had been
1036:             * alive.
1037:             *
1038:             * @return Longest time (in seconds) that an expired session had been
1039:             * alive.
1040:             */
1041:            public int getSessionMaxAliveTime() {
1042:                return sessionMaxAliveTime;
1043:            }
1044:
1045:            /**
1046:             * Sets the longest time (in seconds) that an expired session had been
1047:             * alive.
1048:             *
1049:             * @param sessionMaxAliveTime Longest time (in seconds) that an expired
1050:             * session had been alive.
1051:             */
1052:            public void setSessionMaxAliveTime(int sessionMaxAliveTime) {
1053:                this .sessionMaxAliveTime = sessionMaxAliveTime;
1054:            }
1055:
1056:            /**
1057:             * Gets the average time (in seconds) that expired sessions had been
1058:             * alive.
1059:             *
1060:             * @return Average time (in seconds) that expired sessions had been
1061:             * alive.
1062:             */
1063:            public int getSessionAverageAliveTime() {
1064:                return sessionAverageAliveTime;
1065:            }
1066:
1067:            /**
1068:             * Sets the average time (in seconds) that expired sessions had been
1069:             * alive.
1070:             *
1071:             * @param sessionAverageAliveTime Average time (in seconds) that expired
1072:             * sessions had been alive.
1073:             */
1074:            public void setSessionAverageAliveTime(int sessionAverageAliveTime) {
1075:                this .sessionAverageAliveTime = sessionAverageAliveTime;
1076:            }
1077:
1078:            /** 
1079:             * For debugging: return a list of all session ids currently active
1080:             *
1081:             */
1082:            public String listSessionIds() {
1083:                StringBuffer sb = new StringBuffer();
1084:                Iterator keys = sessions.keySet().iterator();
1085:                while (keys.hasNext()) {
1086:                    sb.append(keys.next()).append(" ");
1087:                }
1088:                return sb.toString();
1089:            }
1090:
1091:            /** 
1092:             * For debugging: get a session attribute
1093:             *
1094:             * @param sessionId
1095:             * @param key
1096:             * @return The attribute value, if found, null otherwise
1097:             */
1098:            public String getSessionAttribute(String sessionId, String key) {
1099:                Session s = (Session) sessions.get(sessionId);
1100:                if (s == null) {
1101:                    if (log.isInfoEnabled())
1102:                        log.info("Session not found " + sessionId);
1103:                    return null;
1104:                }
1105:                Object o = s.getSession().getAttribute(key);
1106:                if (o == null)
1107:                    return null;
1108:                return o.toString();
1109:            }
1110:
1111:            /**
1112:             * Returns information about the session with the given session id.
1113:             * 
1114:             * <p>The session information is organized as a HashMap, mapping 
1115:             * session attribute names to the String representation of their values.
1116:             *
1117:             * @param sessionId Session id
1118:             * 
1119:             * @return HashMap mapping session attribute names to the String
1120:             * representation of their values, or null if no session with the
1121:             * specified id exists, or if the session does not have any attributes
1122:             */
1123:            public HashMap getSession(String sessionId) {
1124:                Session s = (Session) sessions.get(sessionId);
1125:                if (s == null) {
1126:                    if (log.isInfoEnabled()) {
1127:                        log.info("Session not found " + sessionId);
1128:                    }
1129:                    return null;
1130:                }
1131:
1132:                Enumeration ee = s.getSession().getAttributeNames();
1133:                if (ee == null || !ee.hasMoreElements()) {
1134:                    return null;
1135:                }
1136:
1137:                HashMap map = new HashMap();
1138:                while (ee.hasMoreElements()) {
1139:                    String attrName = (String) ee.nextElement();
1140:                    map.put(attrName, getSessionAttribute(sessionId, attrName));
1141:                }
1142:
1143:                return map;
1144:            }
1145:
1146:            public void expireSession(String sessionId) {
1147:                Session s = (Session) sessions.get(sessionId);
1148:                if (s == null) {
1149:                    if (log.isInfoEnabled())
1150:                        log.info("Session not found " + sessionId);
1151:                    return;
1152:                }
1153:                s.expire();
1154:            }
1155:
1156:            public String getLastAccessedTime(String sessionId) {
1157:                Session s = (Session) sessions.get(sessionId);
1158:                if (s == null) {
1159:                    log.info("Session not found " + sessionId);
1160:                    return "";
1161:                }
1162:                return new Date(s.getLastAccessedTime()).toString();
1163:            }
1164:
1165:            // -------------------- JMX and Registration  --------------------
1166:            protected String domain;
1167:            protected ObjectName oname;
1168:            protected MBeanServer mserver;
1169:
1170:            public ObjectName getObjectName() {
1171:                return oname;
1172:            }
1173:
1174:            public String getDomain() {
1175:                return domain;
1176:            }
1177:
1178:            public ObjectName preRegister(MBeanServer server, ObjectName name)
1179:                    throws Exception {
1180:                oname = name;
1181:                mserver = server;
1182:                domain = name.getDomain();
1183:                return name;
1184:            }
1185:
1186:            public void postRegister(Boolean registrationDone) {
1187:            }
1188:
1189:            public void preDeregister() throws Exception {
1190:            }
1191:
1192:            public void postDeregister() {
1193:            }
1194:
1195:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.