Source Code Cross Referenced for HostConfig.java in  » Sevlet-Container » apache-tomcat-6.0.14 » org » apache » catalina » startup » 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.startup 
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.startup;
0019:
0020:        import java.io.BufferedOutputStream;
0021:        import java.io.File;
0022:        import java.io.FileOutputStream;
0023:        import java.io.IOException;
0024:        import java.io.InputStream;
0025:        import java.util.ArrayList;
0026:        import java.util.HashMap;
0027:        import java.util.LinkedHashMap;
0028:        import java.util.jar.JarEntry;
0029:        import java.util.jar.JarFile;
0030:
0031:        import javax.management.ObjectName;
0032:
0033:        import org.apache.catalina.Container;
0034:        import org.apache.catalina.Context;
0035:        import org.apache.catalina.Engine;
0036:        import org.apache.catalina.Host;
0037:        import org.apache.catalina.Lifecycle;
0038:        import org.apache.catalina.LifecycleEvent;
0039:        import org.apache.catalina.LifecycleListener;
0040:        import org.apache.catalina.core.ContainerBase;
0041:        import org.apache.catalina.core.StandardHost;
0042:        import org.apache.catalina.util.StringManager;
0043:        import org.apache.tomcat.util.digester.Digester;
0044:        import org.apache.tomcat.util.modeler.Registry;
0045:
0046:        /**
0047:         * Startup event listener for a <b>Host</b> that configures the properties
0048:         * of that Host, and the associated defined contexts.
0049:         *
0050:         * @author Craig R. McClanahan
0051:         * @author Remy Maucherat
0052:         * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
0053:         */
0054:        public class HostConfig implements  LifecycleListener {
0055:
0056:            protected static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
0057:                    .getLog(HostConfig.class);
0058:
0059:            // ----------------------------------------------------- Instance Variables
0060:
0061:            /**
0062:             * App base.
0063:             */
0064:            protected File appBase = null;
0065:
0066:            /**
0067:             * Config base.
0068:             */
0069:            protected File configBase = null;
0070:
0071:            /**
0072:             * The Java class name of the Context configuration class we should use.
0073:             */
0074:            protected String configClass = "org.apache.catalina.startup.ContextConfig";
0075:
0076:            /**
0077:             * The Java class name of the Context implementation we should use.
0078:             */
0079:            protected String contextClass = "org.apache.catalina.core.StandardContext";
0080:
0081:            /**
0082:             * The Host we are associated with.
0083:             */
0084:            protected Host host = null;
0085:
0086:            /**
0087:             * The JMX ObjectName of this component.
0088:             */
0089:            protected ObjectName oname = null;
0090:
0091:            /**
0092:             * The string resources for this package.
0093:             */
0094:            protected static final StringManager sm = StringManager
0095:                    .getManager(Constants.Package);
0096:
0097:            /**
0098:             * Should we deploy XML Context config files?
0099:             */
0100:            protected boolean deployXML = false;
0101:
0102:            /**
0103:             * Should we unpack WAR files when auto-deploying applications in the
0104:             * <code>appBase</code> directory?
0105:             */
0106:            protected boolean unpackWARs = false;
0107:
0108:            /**
0109:             * Map of deployed applications.
0110:             */
0111:            protected HashMap deployed = new HashMap();
0112:
0113:            /**
0114:             * List of applications which are being serviced, and shouldn't be 
0115:             * deployed/undeployed/redeployed at the moment.
0116:             */
0117:            protected ArrayList serviced = new ArrayList();
0118:
0119:            /**
0120:             * Attribute value used to turn on/off XML validation
0121:             */
0122:            protected boolean xmlValidation = false;
0123:
0124:            /**
0125:             * Attribute value used to turn on/off XML namespace awarenes.
0126:             */
0127:            protected boolean xmlNamespaceAware = false;
0128:
0129:            /**
0130:             * The <code>Digester</code> instance used to parse context descriptors.
0131:             */
0132:            protected static Digester digester = createDigester();
0133:
0134:            // ------------------------------------------------------------- Properties
0135:
0136:            /**
0137:             * Return the Context configuration class name.
0138:             */
0139:            public String getConfigClass() {
0140:
0141:                return (this .configClass);
0142:
0143:            }
0144:
0145:            /**
0146:             * Set the Context configuration class name.
0147:             *
0148:             * @param configClass The new Context configuration class name.
0149:             */
0150:            public void setConfigClass(String configClass) {
0151:
0152:                this .configClass = configClass;
0153:
0154:            }
0155:
0156:            /**
0157:             * Return the Context implementation class name.
0158:             */
0159:            public String getContextClass() {
0160:
0161:                return (this .contextClass);
0162:
0163:            }
0164:
0165:            /**
0166:             * Set the Context implementation class name.
0167:             *
0168:             * @param contextClass The new Context implementation class name.
0169:             */
0170:            public void setContextClass(String contextClass) {
0171:
0172:                this .contextClass = contextClass;
0173:
0174:            }
0175:
0176:            /**
0177:             * Return the deploy XML config file flag for this component.
0178:             */
0179:            public boolean isDeployXML() {
0180:
0181:                return (this .deployXML);
0182:
0183:            }
0184:
0185:            /**
0186:             * Set the deploy XML config file flag for this component.
0187:             *
0188:             * @param deployXML The new deploy XML flag
0189:             */
0190:            public void setDeployXML(boolean deployXML) {
0191:
0192:                this .deployXML = deployXML;
0193:
0194:            }
0195:
0196:            /**
0197:             * Return the unpack WARs flag.
0198:             */
0199:            public boolean isUnpackWARs() {
0200:
0201:                return (this .unpackWARs);
0202:
0203:            }
0204:
0205:            /**
0206:             * Set the unpack WARs flag.
0207:             *
0208:             * @param unpackWARs The new unpack WARs flag
0209:             */
0210:            public void setUnpackWARs(boolean unpackWARs) {
0211:
0212:                this .unpackWARs = unpackWARs;
0213:
0214:            }
0215:
0216:            /**
0217:             * Set the validation feature of the XML parser used when
0218:             * parsing xml instances.
0219:             * @param xmlValidation true to enable xml instance validation
0220:             */
0221:            public void setXmlValidation(boolean xmlValidation) {
0222:                this .xmlValidation = xmlValidation;
0223:            }
0224:
0225:            /**
0226:             * Get the server.xml <host> attribute's xmlValidation.
0227:             * @return true if validation is enabled.
0228:             *
0229:             */
0230:            public boolean getXmlValidation() {
0231:                return xmlValidation;
0232:            }
0233:
0234:            /**
0235:             * Get the server.xml <host> attribute's xmlNamespaceAware.
0236:             * @return true if namespace awarenes is enabled.
0237:             *
0238:             */
0239:            public boolean getXmlNamespaceAware() {
0240:                return xmlNamespaceAware;
0241:            }
0242:
0243:            /**
0244:             * Set the namespace aware feature of the XML parser used when
0245:             * parsing xml instances.
0246:             * @param xmlNamespaceAware true to enable namespace awareness
0247:             */
0248:            public void setXmlNamespaceAware(boolean xmlNamespaceAware) {
0249:                this .xmlNamespaceAware = xmlNamespaceAware;
0250:            }
0251:
0252:            // --------------------------------------------------------- Public Methods
0253:
0254:            /**
0255:             * Process the START event for an associated Host.
0256:             *
0257:             * @param event The lifecycle event that has occurred
0258:             */
0259:            public void lifecycleEvent(LifecycleEvent event) {
0260:
0261:                if (event.getType().equals(Lifecycle.PERIODIC_EVENT))
0262:                    check();
0263:
0264:                // Identify the host we are associated with
0265:                try {
0266:                    host = (Host) event.getLifecycle();
0267:                    if (host instanceof  StandardHost) {
0268:                        setDeployXML(((StandardHost) host).isDeployXML());
0269:                        setUnpackWARs(((StandardHost) host).isUnpackWARs());
0270:                        setXmlNamespaceAware(((StandardHost) host)
0271:                                .getXmlNamespaceAware());
0272:                        setXmlValidation(((StandardHost) host)
0273:                                .getXmlValidation());
0274:                    }
0275:                } catch (ClassCastException e) {
0276:                    log.error(sm.getString("hostConfig.cce", event
0277:                            .getLifecycle()), e);
0278:                    return;
0279:                }
0280:
0281:                // Process the event that has occurred
0282:                if (event.getType().equals(Lifecycle.START_EVENT))
0283:                    start();
0284:                else if (event.getType().equals(Lifecycle.STOP_EVENT))
0285:                    stop();
0286:
0287:            }
0288:
0289:            /**
0290:             * Add a serviced application to the list.
0291:             */
0292:            public synchronized void addServiced(String name) {
0293:                serviced.add(name);
0294:            }
0295:
0296:            /**
0297:             * Is application serviced ?
0298:             * @return state of the application
0299:             */
0300:            public synchronized boolean isServiced(String name) {
0301:                return (serviced.contains(name));
0302:            }
0303:
0304:            /**
0305:             * Removed a serviced application from the list.
0306:             */
0307:            public synchronized void removeServiced(String name) {
0308:                serviced.remove(name);
0309:            }
0310:
0311:            /**
0312:             * Get the instant where an application was deployed.
0313:             * @return 0L if no application with that name is deployed, or the instant
0314:             * on which the application was deployed
0315:             */
0316:            public long getDeploymentTime(String name) {
0317:                DeployedApplication app = (DeployedApplication) deployed
0318:                        .get(name);
0319:                if (app == null) {
0320:                    return 0L;
0321:                } else {
0322:                    return app.timestamp;
0323:                }
0324:            }
0325:
0326:            /**
0327:             * Has the specified application been deployed? Note applications defined
0328:             * in server.xml will not have been deployed.
0329:             * @return <code>true</code> if the application has been deployed and
0330:             * <code>false</code> if the applciation has not been deployed or does not
0331:             * exist
0332:             */
0333:            public boolean isDeployed(String name) {
0334:                DeployedApplication app = (DeployedApplication) deployed
0335:                        .get(name);
0336:                if (app == null) {
0337:                    return false;
0338:                } else {
0339:                    return true;
0340:                }
0341:            }
0342:
0343:            // ------------------------------------------------------ Protected Methods
0344:
0345:            /**
0346:             * Create the digester which will be used to parse context config files.
0347:             */
0348:            protected static Digester createDigester() {
0349:                Digester digester = new Digester();
0350:                digester.setValidating(false);
0351:                // Add object creation rule
0352:                digester
0353:                        .addObjectCreate("Context",
0354:                                "org.apache.catalina.core.StandardContext",
0355:                                "className");
0356:                // Set the properties on that object (it doesn't matter if extra 
0357:                // properties are set)
0358:                digester.addSetProperties("Context");
0359:                return (digester);
0360:            }
0361:
0362:            /**
0363:             * Return a File object representing the "application root" directory
0364:             * for our associated Host.
0365:             */
0366:            protected File appBase() {
0367:
0368:                if (appBase != null) {
0369:                    return appBase;
0370:                }
0371:
0372:                File file = new File(host.getAppBase());
0373:                if (!file.isAbsolute())
0374:                    file = new File(System.getProperty("catalina.base"), host
0375:                            .getAppBase());
0376:                try {
0377:                    appBase = file.getCanonicalFile();
0378:                } catch (IOException e) {
0379:                    appBase = file;
0380:                }
0381:                return (appBase);
0382:
0383:            }
0384:
0385:            /**
0386:             * Return a File object representing the "configuration root" directory
0387:             * for our associated Host.
0388:             */
0389:            protected File configBase() {
0390:
0391:                if (configBase != null) {
0392:                    return configBase;
0393:                }
0394:
0395:                File file = new File(System.getProperty("catalina.base"),
0396:                        "conf");
0397:                Container parent = host.getParent();
0398:                if ((parent != null) && (parent instanceof  Engine)) {
0399:                    file = new File(file, parent.getName());
0400:                }
0401:                file = new File(file, host.getName());
0402:                try {
0403:                    configBase = file.getCanonicalFile();
0404:                } catch (IOException e) {
0405:                    configBase = file;
0406:                }
0407:                return (configBase);
0408:
0409:            }
0410:
0411:            /**
0412:             * Get the name of the configBase.
0413:             * For use with JMX management.
0414:             */
0415:            public String getConfigBaseName() {
0416:                return configBase().getAbsolutePath();
0417:            }
0418:
0419:            /**
0420:             * Given a context path, get the config file name.
0421:             */
0422:            protected String getConfigFile(String path) {
0423:                String basename = null;
0424:                if (path.equals("")) {
0425:                    basename = "ROOT";
0426:                } else {
0427:                    basename = path.substring(1).replace('/', '#');
0428:                }
0429:                return (basename);
0430:            }
0431:
0432:            /**
0433:             * Given a context path, get the config file name.
0434:             */
0435:            protected String getDocBase(String path) {
0436:                String basename = null;
0437:                if (path.equals("")) {
0438:                    basename = "ROOT";
0439:                } else {
0440:                    basename = path.substring(1);
0441:                }
0442:                return (basename);
0443:            }
0444:
0445:            /**
0446:             * Deploy applications for any directories or WAR files that are found
0447:             * in our "application root" directory.
0448:             */
0449:            protected void deployApps() {
0450:
0451:                File appBase = appBase();
0452:                File configBase = configBase();
0453:                // Deploy XML descriptors from configBase
0454:                deployDescriptors(configBase, configBase.list());
0455:                // Deploy WARs, and loop if additional descriptors are found
0456:                deployWARs(appBase, appBase.list());
0457:                // Deploy expanded folders
0458:                deployDirectories(appBase, appBase.list());
0459:
0460:            }
0461:
0462:            /**
0463:             * Deploy applications for any directories or WAR files that are found
0464:             * in our "application root" directory.
0465:             */
0466:            protected void deployApps(String name) {
0467:
0468:                File appBase = appBase();
0469:                File configBase = configBase();
0470:                String baseName = getConfigFile(name);
0471:                String docBase = getConfigFile(name);
0472:
0473:                // Deploy XML descriptors from configBase
0474:                File xml = new File(configBase, baseName + ".xml");
0475:                if (xml.exists())
0476:                    deployDescriptor(name, xml, baseName + ".xml");
0477:                // Deploy WARs, and loop if additional descriptors are found
0478:                File war = new File(appBase, docBase + ".war");
0479:                if (war.exists())
0480:                    deployWAR(name, war, docBase + ".war");
0481:                // Deploy expanded folders
0482:                File dir = new File(appBase, docBase);
0483:                if (dir.exists())
0484:                    deployDirectory(name, dir, docBase);
0485:
0486:            }
0487:
0488:            /**
0489:             * Deploy XML context descriptors.
0490:             */
0491:            protected void deployDescriptors(File configBase, String[] files) {
0492:
0493:                if (files == null)
0494:                    return;
0495:
0496:                for (int i = 0; i < files.length; i++) {
0497:
0498:                    if (files[i].equalsIgnoreCase("META-INF"))
0499:                        continue;
0500:                    if (files[i].equalsIgnoreCase("WEB-INF"))
0501:                        continue;
0502:                    File contextXml = new File(configBase, files[i]);
0503:                    if (files[i].toLowerCase().endsWith(".xml")) {
0504:
0505:                        // Calculate the context path and make sure it is unique
0506:                        String nameTmp = files[i].substring(0, files[i]
0507:                                .length() - 4);
0508:                        String contextPath = "/" + nameTmp.replace('#', '/');
0509:                        if (nameTmp.equals("ROOT")) {
0510:                            contextPath = "";
0511:                        }
0512:
0513:                        if (isServiced(contextPath))
0514:                            continue;
0515:
0516:                        String file = files[i];
0517:
0518:                        deployDescriptor(contextPath, contextXml, file);
0519:
0520:                    }
0521:
0522:                }
0523:
0524:            }
0525:
0526:            /**
0527:             * @param contextPath
0528:             * @param contextXml
0529:             * @param file
0530:             */
0531:            protected void deployDescriptor(String contextPath,
0532:                    File contextXml, String file) {
0533:                if (deploymentExists(contextPath)) {
0534:                    return;
0535:                }
0536:
0537:                DeployedApplication deployedApp = new DeployedApplication(
0538:                        contextPath);
0539:
0540:                // Assume this is a configuration descriptor and deploy it
0541:                if (log.isDebugEnabled()) {
0542:                    log
0543:                            .debug(sm.getString("hostConfig.deployDescriptor",
0544:                                    file));
0545:                }
0546:
0547:                Context context = null;
0548:                try {
0549:                    synchronized (digester) {
0550:                        try {
0551:                            context = (Context) digester.parse(contextXml);
0552:                            if (context == null) {
0553:                                log.error(sm.getString(
0554:                                        "hostConfig.deployDescriptor.error",
0555:                                        file));
0556:                                return;
0557:                            }
0558:                        } finally {
0559:                            digester.reset();
0560:                        }
0561:                    }
0562:                    if (context instanceof  Lifecycle) {
0563:                        Class clazz = Class.forName(host.getConfigClass());
0564:                        LifecycleListener listener = (LifecycleListener) clazz
0565:                                .newInstance();
0566:                        ((Lifecycle) context).addLifecycleListener(listener);
0567:                    }
0568:                    context.setConfigFile(contextXml.getAbsolutePath());
0569:                    context.setPath(contextPath);
0570:                    // Add the associated docBase to the redeployed list if it's a WAR
0571:                    boolean isWar = false;
0572:                    boolean isExternal = false;
0573:                    if (context.getDocBase() != null) {
0574:                        File docBase = new File(context.getDocBase());
0575:                        if (!docBase.isAbsolute()) {
0576:                            docBase = new File(appBase(), context.getDocBase());
0577:                        }
0578:                        // If external docBase, register .xml as redeploy first
0579:                        if (!docBase.getCanonicalPath().startsWith(
0580:                                appBase().getAbsolutePath())) {
0581:                            isExternal = true;
0582:                            deployedApp.redeployResources.put(contextXml
0583:                                    .getAbsolutePath(), new Long(contextXml
0584:                                    .lastModified()));
0585:                            deployedApp.redeployResources.put(docBase
0586:                                    .getAbsolutePath(), new Long(docBase
0587:                                    .lastModified()));
0588:                            if (docBase.getAbsolutePath().toLowerCase()
0589:                                    .endsWith(".war")) {
0590:                                isWar = true;
0591:                            }
0592:                        } else {
0593:                            log
0594:                                    .warn(sm
0595:                                            .getString(
0596:                                                    "hostConfig.deployDescriptor.localDocBaseSpecified",
0597:                                                    docBase));
0598:                            // Ignore specified docBase
0599:                            context.setDocBase(null);
0600:                        }
0601:                    }
0602:                    host.addChild(context);
0603:                    // Get paths for WAR and expanded WAR in appBase
0604:                    String name = null;
0605:                    String path = context.getPath();
0606:                    if (path.equals("")) {
0607:                        name = "ROOT";
0608:                    } else {
0609:                        if (path.startsWith("/")) {
0610:                            name = path.substring(1);
0611:                        } else {
0612:                            name = path;
0613:                        }
0614:                    }
0615:                    File expandedDocBase = new File(name);
0616:                    File warDocBase = new File(name + ".war");
0617:                    if (!expandedDocBase.isAbsolute()) {
0618:                        expandedDocBase = new File(appBase(), name);
0619:                        warDocBase = new File(appBase(), name + ".war");
0620:                    }
0621:                    // Add the eventual unpacked WAR and all the resources which will be
0622:                    // watched inside it
0623:                    if (isWar && unpackWARs) {
0624:                        deployedApp.redeployResources.put(expandedDocBase
0625:                                .getAbsolutePath(), new Long(expandedDocBase
0626:                                .lastModified()));
0627:                        deployedApp.redeployResources.put(contextXml
0628:                                .getAbsolutePath(), new Long(contextXml
0629:                                .lastModified()));
0630:                        addWatchedResources(deployedApp, expandedDocBase
0631:                                .getAbsolutePath(), context);
0632:                    } else {
0633:                        // Find an existing matching war and expanded folder
0634:                        if (warDocBase.exists()) {
0635:                            deployedApp.redeployResources.put(warDocBase
0636:                                    .getAbsolutePath(), new Long(warDocBase
0637:                                    .lastModified()));
0638:                        }
0639:                        if (expandedDocBase.exists()) {
0640:                            deployedApp.redeployResources.put(expandedDocBase
0641:                                    .getAbsolutePath(), new Long(
0642:                                    expandedDocBase.lastModified()));
0643:                            addWatchedResources(deployedApp, expandedDocBase
0644:                                    .getAbsolutePath(), context);
0645:                        } else {
0646:                            addWatchedResources(deployedApp, null, context);
0647:                        }
0648:                        // Add the context XML to the list of files which should trigger a redeployment
0649:                        if (!isExternal) {
0650:                            deployedApp.redeployResources.put(contextXml
0651:                                    .getAbsolutePath(), new Long(contextXml
0652:                                    .lastModified()));
0653:                        }
0654:                    }
0655:                } catch (Throwable t) {
0656:                    log.error(sm.getString("hostConfig.deployDescriptor.error",
0657:                            file), t);
0658:                }
0659:
0660:                if (context != null
0661:                        && host.findChild(context.getName()) != null) {
0662:                    deployed.put(contextPath, deployedApp);
0663:                }
0664:            }
0665:
0666:            /**
0667:             * Deploy WAR files.
0668:             */
0669:            protected void deployWARs(File appBase, String[] files) {
0670:
0671:                if (files == null)
0672:                    return;
0673:
0674:                for (int i = 0; i < files.length; i++) {
0675:
0676:                    if (files[i].equalsIgnoreCase("META-INF"))
0677:                        continue;
0678:                    if (files[i].equalsIgnoreCase("WEB-INF"))
0679:                        continue;
0680:                    File dir = new File(appBase, files[i]);
0681:                    if (files[i].toLowerCase().endsWith(".war")) {
0682:
0683:                        // Calculate the context path and make sure it is unique
0684:                        String contextPath = "/" + files[i];
0685:                        int period = contextPath.lastIndexOf(".");
0686:                        if (period >= 0)
0687:                            contextPath = contextPath.substring(0, period);
0688:                        if (contextPath.equals("/ROOT"))
0689:                            contextPath = "";
0690:
0691:                        if (isServiced(contextPath))
0692:                            continue;
0693:
0694:                        String file = files[i];
0695:
0696:                        deployWAR(contextPath, dir, file);
0697:
0698:                    }
0699:
0700:                }
0701:
0702:            }
0703:
0704:            /**
0705:             * @param contextPath
0706:             * @param dir
0707:             * @param file
0708:             */
0709:            protected void deployWAR(String contextPath, File dir, String file) {
0710:
0711:                if (deploymentExists(contextPath))
0712:                    return;
0713:
0714:                // Checking for a nested /META-INF/context.xml
0715:                JarFile jar = null;
0716:                JarEntry entry = null;
0717:                InputStream istream = null;
0718:                BufferedOutputStream ostream = null;
0719:                File xml = new File(configBase, file.substring(0, file
0720:                        .lastIndexOf("."))
0721:                        + ".xml");
0722:                if (deployXML && !xml.exists()) {
0723:                    try {
0724:                        jar = new JarFile(dir);
0725:                        entry = jar
0726:                                .getJarEntry(Constants.ApplicationContextXml);
0727:                        if (entry != null) {
0728:                            istream = jar.getInputStream(entry);
0729:
0730:                            configBase.mkdirs();
0731:
0732:                            ostream = new BufferedOutputStream(
0733:                                    new FileOutputStream(xml), 1024);
0734:                            byte buffer[] = new byte[1024];
0735:                            while (true) {
0736:                                int n = istream.read(buffer);
0737:                                if (n < 0) {
0738:                                    break;
0739:                                }
0740:                                ostream.write(buffer, 0, n);
0741:                            }
0742:                            ostream.flush();
0743:                            ostream.close();
0744:                            ostream = null;
0745:                            istream.close();
0746:                            istream = null;
0747:                            entry = null;
0748:                            jar.close();
0749:                            jar = null;
0750:                        }
0751:                    } catch (Exception e) {
0752:                        // Ignore and continue
0753:                        if (ostream != null) {
0754:                            try {
0755:                                ostream.close();
0756:                            } catch (Throwable t) {
0757:                                ;
0758:                            }
0759:                            ostream = null;
0760:                        }
0761:                        if (istream != null) {
0762:                            try {
0763:                                istream.close();
0764:                            } catch (Throwable t) {
0765:                                ;
0766:                            }
0767:                            istream = null;
0768:                        }
0769:                    } finally {
0770:                        entry = null;
0771:                        if (jar != null) {
0772:                            try {
0773:                                jar.close();
0774:                            } catch (Throwable t) {
0775:                                ;
0776:                            }
0777:                            jar = null;
0778:                        }
0779:                    }
0780:                }
0781:
0782:                DeployedApplication deployedApp = new DeployedApplication(
0783:                        contextPath);
0784:
0785:                // Deploy the application in this WAR file
0786:                if (log.isInfoEnabled())
0787:                    log.info(sm.getString("hostConfig.deployJar", file));
0788:
0789:                // Populate redeploy resources with the WAR file
0790:                deployedApp.redeployResources.put(dir.getAbsolutePath(),
0791:                        new Long(dir.lastModified()));
0792:
0793:                try {
0794:                    Context context = (Context) Class.forName(contextClass)
0795:                            .newInstance();
0796:                    if (context instanceof  Lifecycle) {
0797:                        Class clazz = Class.forName(host.getConfigClass());
0798:                        LifecycleListener listener = (LifecycleListener) clazz
0799:                                .newInstance();
0800:                        ((Lifecycle) context).addLifecycleListener(listener);
0801:                    }
0802:                    context.setPath(contextPath);
0803:                    context.setDocBase(file);
0804:                    if (xml.exists()) {
0805:                        context.setConfigFile(xml.getAbsolutePath());
0806:                        deployedApp.redeployResources.put(
0807:                                xml.getAbsolutePath(), new Long(xml
0808:                                        .lastModified()));
0809:                    }
0810:                    host.addChild(context);
0811:                    // If we're unpacking WARs, the docBase will be mutated after
0812:                    // starting the context
0813:                    if (unpackWARs && (context.getDocBase() != null)) {
0814:                        String name = null;
0815:                        String path = context.getPath();
0816:                        if (path.equals("")) {
0817:                            name = "ROOT";
0818:                        } else {
0819:                            if (path.startsWith("/")) {
0820:                                name = path.substring(1);
0821:                            } else {
0822:                                name = path;
0823:                            }
0824:                        }
0825:                        File docBase = new File(name);
0826:                        if (!docBase.isAbsolute()) {
0827:                            docBase = new File(appBase(), name);
0828:                        }
0829:                        deployedApp.redeployResources.put(docBase
0830:                                .getAbsolutePath(), new Long(docBase
0831:                                .lastModified()));
0832:                        addWatchedResources(deployedApp, docBase
0833:                                .getAbsolutePath(), context);
0834:                    } else {
0835:                        addWatchedResources(deployedApp, null, context);
0836:                    }
0837:                } catch (Throwable t) {
0838:                    log.error(sm.getString("hostConfig.deployJar.error", file),
0839:                            t);
0840:                }
0841:
0842:                deployed.put(contextPath, deployedApp);
0843:            }
0844:
0845:            /**
0846:             * Deploy directories.
0847:             */
0848:            protected void deployDirectories(File appBase, String[] files) {
0849:
0850:                if (files == null)
0851:                    return;
0852:
0853:                for (int i = 0; i < files.length; i++) {
0854:
0855:                    if (files[i].equalsIgnoreCase("META-INF"))
0856:                        continue;
0857:                    if (files[i].equalsIgnoreCase("WEB-INF"))
0858:                        continue;
0859:                    File dir = new File(appBase, files[i]);
0860:                    if (dir.isDirectory()) {
0861:
0862:                        // Calculate the context path and make sure it is unique
0863:                        String contextPath = "/" + files[i];
0864:                        if (files[i].equals("ROOT"))
0865:                            contextPath = "";
0866:
0867:                        if (isServiced(contextPath))
0868:                            continue;
0869:
0870:                        deployDirectory(contextPath, dir, files[i]);
0871:
0872:                    }
0873:
0874:                }
0875:
0876:            }
0877:
0878:            /**
0879:             * @param contextPath
0880:             * @param dir
0881:             * @param file
0882:             */
0883:            protected void deployDirectory(String contextPath, File dir,
0884:                    String file) {
0885:                DeployedApplication deployedApp = new DeployedApplication(
0886:                        contextPath);
0887:
0888:                if (deploymentExists(contextPath))
0889:                    return;
0890:
0891:                // Deploy the application in this directory
0892:                if (log.isDebugEnabled())
0893:                    log.debug(sm.getString("hostConfig.deployDir", file));
0894:                try {
0895:                    Context context = (Context) Class.forName(contextClass)
0896:                            .newInstance();
0897:                    if (context instanceof  Lifecycle) {
0898:                        Class clazz = Class.forName(host.getConfigClass());
0899:                        LifecycleListener listener = (LifecycleListener) clazz
0900:                                .newInstance();
0901:                        ((Lifecycle) context).addLifecycleListener(listener);
0902:                    }
0903:                    context.setPath(contextPath);
0904:                    context.setDocBase(file);
0905:                    File configFile = new File(dir,
0906:                            Constants.ApplicationContextXml);
0907:                    if (deployXML) {
0908:                        context.setConfigFile(configFile.getAbsolutePath());
0909:                    }
0910:                    host.addChild(context);
0911:                    deployedApp.redeployResources.put(dir.getAbsolutePath(),
0912:                            new Long(dir.lastModified()));
0913:                    if (deployXML) {
0914:                        deployedApp.redeployResources.put(configFile
0915:                                .getAbsolutePath(), new Long(configFile
0916:                                .lastModified()));
0917:                    }
0918:                    addWatchedResources(deployedApp, dir.getAbsolutePath(),
0919:                            context);
0920:                } catch (Throwable t) {
0921:                    log.error(sm.getString("hostConfig.deployDir.error", file),
0922:                            t);
0923:                }
0924:
0925:                deployed.put(contextPath, deployedApp);
0926:            }
0927:
0928:            /**
0929:             * Check if a webapp is already deployed in this host.
0930:             * 
0931:             * @param contextPath of the context which will be checked
0932:             */
0933:            protected boolean deploymentExists(String contextPath) {
0934:                return (deployed.containsKey(contextPath) || (host
0935:                        .findChild(contextPath) != null));
0936:            }
0937:
0938:            /**
0939:             * Add watched resources to the specified Context.
0940:             * @param app HostConfig deployed app
0941:             * @param docBase web app docBase
0942:             * @param context web application context
0943:             */
0944:            protected void addWatchedResources(DeployedApplication app,
0945:                    String docBase, Context context) {
0946:                // FIXME: Feature idea. Add support for patterns (ex: WEB-INF/*, WEB-INF/*.xml), where
0947:                //        we would only check if at least one resource is newer than app.timestamp
0948:                File docBaseFile = null;
0949:                if (docBase != null) {
0950:                    docBaseFile = new File(docBase);
0951:                    if (!docBaseFile.isAbsolute()) {
0952:                        docBaseFile = new File(appBase(), docBase);
0953:                    }
0954:                }
0955:                String[] watchedResources = context.findWatchedResources();
0956:                for (int i = 0; i < watchedResources.length; i++) {
0957:                    File resource = new File(watchedResources[i]);
0958:                    if (!resource.isAbsolute()) {
0959:                        if (docBase != null) {
0960:                            resource = new File(docBaseFile,
0961:                                    watchedResources[i]);
0962:                        } else {
0963:                            continue;
0964:                        }
0965:                    }
0966:                    app.reloadResources.put(resource.getAbsolutePath(),
0967:                            new Long(resource.lastModified()));
0968:                }
0969:            }
0970:
0971:            /**
0972:             * Check resources for redeployment and reloading.
0973:             */
0974:            protected synchronized void checkResources(DeployedApplication app) {
0975:                String[] resources = (String[]) app.redeployResources.keySet()
0976:                        .toArray(new String[0]);
0977:                for (int i = 0; i < resources.length; i++) {
0978:                    File resource = new File(resources[i]);
0979:                    if (log.isDebugEnabled())
0980:                        log.debug("Checking context[" + app.name
0981:                                + "] redeploy resource " + resource);
0982:                    if (resource.exists()) {
0983:                        long lastModified = ((Long) app.redeployResources
0984:                                .get(resources[i])).longValue();
0985:                        if ((!resource.isDirectory())
0986:                                && resource.lastModified() > lastModified) {
0987:                            // Undeploy application
0988:                            if (log.isInfoEnabled())
0989:                                log.info(sm.getString("hostConfig.undeploy",
0990:                                        app.name));
0991:                            ContainerBase context = (ContainerBase) host
0992:                                    .findChild(app.name);
0993:                            try {
0994:                                host.removeChild(context);
0995:                            } catch (Throwable t) {
0996:                                log.warn(sm.getString(
0997:                                        "hostConfig.context.remove", app.name),
0998:                                        t);
0999:                            }
1000:                            try {
1001:                                context.destroy();
1002:                            } catch (Throwable t) {
1003:                                log.warn(
1004:                                        sm.getString(
1005:                                                "hostConfig.context.destroy",
1006:                                                app.name), t);
1007:                            }
1008:                            // Delete other redeploy resources
1009:                            for (int j = i + 1; j < resources.length; j++) {
1010:                                try {
1011:                                    File current = new File(resources[j]);
1012:                                    current = current.getCanonicalFile();
1013:                                    if ((current.getAbsolutePath()
1014:                                            .startsWith(appBase()
1015:                                                    .getAbsolutePath()))
1016:                                            || (current.getAbsolutePath()
1017:                                                    .startsWith(configBase()
1018:                                                            .getAbsolutePath()))) {
1019:                                        if (log.isDebugEnabled())
1020:                                            log.debug("Delete " + current);
1021:                                        ExpandWar.delete(current);
1022:                                    }
1023:                                } catch (IOException e) {
1024:                                    log.warn(sm.getString(
1025:                                            "hostConfig.canonicalizing",
1026:                                            app.name), e);
1027:                                }
1028:                            }
1029:                            deployed.remove(app.name);
1030:                            return;
1031:                        }
1032:                    } else {
1033:                        long lastModified = ((Long) app.redeployResources
1034:                                .get(resources[i])).longValue();
1035:                        if (lastModified == 0L) {
1036:                            continue;
1037:                        }
1038:                        // Undeploy application
1039:                        if (log.isInfoEnabled())
1040:                            log.info(sm.getString("hostConfig.undeploy",
1041:                                    app.name));
1042:                        ContainerBase context = (ContainerBase) host
1043:                                .findChild(app.name);
1044:                        try {
1045:                            host.removeChild(context);
1046:                        } catch (Throwable t) {
1047:                            log.warn(sm.getString("hostConfig.context.remove",
1048:                                    app.name), t);
1049:                        }
1050:                        try {
1051:                            context.destroy();
1052:                        } catch (Throwable t) {
1053:                            log.warn(sm.getString("hostConfig.context.destroy",
1054:                                    app.name), t);
1055:                        }
1056:                        // Delete all redeploy resources
1057:                        for (int j = i + 1; j < resources.length; j++) {
1058:                            try {
1059:                                File current = new File(resources[j]);
1060:                                current = current.getCanonicalFile();
1061:                                if ((current.getAbsolutePath()
1062:                                        .startsWith(appBase().getAbsolutePath()))
1063:                                        || (current.getAbsolutePath()
1064:                                                .startsWith(configBase()
1065:                                                        .getAbsolutePath()))) {
1066:                                    if (log.isDebugEnabled())
1067:                                        log.debug("Delete " + current);
1068:                                    ExpandWar.delete(current);
1069:                                }
1070:                            } catch (IOException e) {
1071:                                log.warn(sm.getString(
1072:                                        "hostConfig.canonicalizing", app.name),
1073:                                        e);
1074:                            }
1075:                        }
1076:                        // Delete reload resources as well (to remove any remaining .xml descriptor)
1077:                        String[] resources2 = (String[]) app.reloadResources
1078:                                .keySet().toArray(new String[0]);
1079:                        for (int j = 0; j < resources2.length; j++) {
1080:                            try {
1081:                                File current = new File(resources2[j]);
1082:                                current = current.getCanonicalFile();
1083:                                if ((current.getAbsolutePath()
1084:                                        .startsWith(appBase().getAbsolutePath()))
1085:                                        || ((current
1086:                                                .getAbsolutePath()
1087:                                                .startsWith(
1088:                                                        configBase()
1089:                                                                .getAbsolutePath()) && (current
1090:                                                .getAbsolutePath()
1091:                                                .endsWith(".xml"))))) {
1092:                                    if (log.isDebugEnabled())
1093:                                        log.debug("Delete " + current);
1094:                                    ExpandWar.delete(current);
1095:                                }
1096:                            } catch (IOException e) {
1097:                                log.warn(sm.getString(
1098:                                        "hostConfig.canonicalizing", app.name),
1099:                                        e);
1100:                            }
1101:                        }
1102:                        deployed.remove(app.name);
1103:                        return;
1104:                    }
1105:                }
1106:                resources = (String[]) app.reloadResources.keySet().toArray(
1107:                        new String[0]);
1108:                for (int i = 0; i < resources.length; i++) {
1109:                    File resource = new File(resources[i]);
1110:                    if (log.isDebugEnabled())
1111:                        log.debug("Checking context[" + app.name
1112:                                + "] reload resource " + resource);
1113:                    long lastModified = ((Long) app.reloadResources
1114:                            .get(resources[i])).longValue();
1115:                    if ((!resource.exists() && lastModified != 0L)
1116:                            || (resource.lastModified() != lastModified)) {
1117:                        // Reload application
1118:                        if (log.isInfoEnabled())
1119:                            log.info(sm
1120:                                    .getString("hostConfig.reload", app.name));
1121:                        Container context = host.findChild(app.name);
1122:                        try {
1123:                            ((Lifecycle) context).stop();
1124:                        } catch (Exception e) {
1125:                            log.warn(sm.getString("hostConfig.context.restart",
1126:                                    app.name), e);
1127:                        }
1128:                        // If the context was not started (for example an error 
1129:                        // in web.xml) we'll still get to try to start
1130:                        try {
1131:                            ((Lifecycle) context).start();
1132:                        } catch (Exception e) {
1133:                            log.warn(sm.getString("hostConfig.context.restart",
1134:                                    app.name), e);
1135:                        }
1136:                        // Update times
1137:                        app.reloadResources.put(resources[i], new Long(resource
1138:                                .lastModified()));
1139:                        app.timestamp = System.currentTimeMillis();
1140:                        return;
1141:                    }
1142:                }
1143:            }
1144:
1145:            /**
1146:             * Process a "start" event for this Host.
1147:             */
1148:            public void start() {
1149:
1150:                if (log.isDebugEnabled())
1151:                    log.debug(sm.getString("hostConfig.start"));
1152:
1153:                try {
1154:                    ObjectName hostON = new ObjectName(host.getObjectName());
1155:                    oname = new ObjectName(hostON.getDomain()
1156:                            + ":type=Deployer,host=" + host.getName());
1157:                    Registry.getRegistry(null, null).registerComponent(this ,
1158:                            oname, this .getClass().getName());
1159:                } catch (Exception e) {
1160:                    log
1161:                            .error(sm.getString("hostConfig.jmx.register",
1162:                                    oname), e);
1163:                }
1164:
1165:                if (host.getDeployOnStartup())
1166:                    deployApps();
1167:
1168:            }
1169:
1170:            /**
1171:             * Process a "stop" event for this Host.
1172:             */
1173:            public void stop() {
1174:
1175:                if (log.isDebugEnabled())
1176:                    log.debug(sm.getString("hostConfig.stop"));
1177:
1178:                undeployApps();
1179:
1180:                if (oname != null) {
1181:                    try {
1182:                        Registry.getRegistry(null, null).unregisterComponent(
1183:                                oname);
1184:                    } catch (Exception e) {
1185:                        log.error(sm.getString("hostConfig.jmx.unregister",
1186:                                oname), e);
1187:                    }
1188:                }
1189:                oname = null;
1190:                appBase = null;
1191:                configBase = null;
1192:
1193:            }
1194:
1195:            /**
1196:             * Undeploy all deployed applications.
1197:             */
1198:            protected void undeployApps() {
1199:
1200:                if (log.isDebugEnabled())
1201:                    log.debug(sm.getString("hostConfig.undeploying"));
1202:
1203:                // Soft undeploy all contexts we have deployed
1204:                DeployedApplication[] apps = (DeployedApplication[]) deployed
1205:                        .values().toArray(new DeployedApplication[0]);
1206:                for (int i = 0; i < apps.length; i++) {
1207:                    try {
1208:                        host.removeChild(host.findChild(apps[i].name));
1209:                    } catch (Throwable t) {
1210:                        log.warn(sm.getString("hostConfig.context.remove",
1211:                                apps[i].name), t);
1212:                    }
1213:                }
1214:
1215:                deployed.clear();
1216:
1217:            }
1218:
1219:            /**
1220:             * Check status of all webapps.
1221:             */
1222:            protected void check() {
1223:
1224:                if (host.getAutoDeploy()) {
1225:                    // Check for resources modification to trigger redeployment
1226:                    DeployedApplication[] apps = (DeployedApplication[]) deployed
1227:                            .values().toArray(new DeployedApplication[0]);
1228:                    for (int i = 0; i < apps.length; i++) {
1229:                        if (!isServiced(apps[i].name))
1230:                            checkResources(apps[i]);
1231:                    }
1232:                    // Hotdeploy applications
1233:                    deployApps();
1234:                }
1235:
1236:            }
1237:
1238:            /**
1239:             * Check status of a specific webapp, for use with stuff like management webapps.
1240:             */
1241:            public void check(String name) {
1242:                DeployedApplication app = (DeployedApplication) deployed
1243:                        .get(name);
1244:                if (app != null) {
1245:                    checkResources(app);
1246:                } else {
1247:                    deployApps(name);
1248:                }
1249:            }
1250:
1251:            /**
1252:             * Add a new Context to be managed by us.
1253:             * Entry point for the admin webapp, and other JMX Context controlers.
1254:             */
1255:            public void manageApp(Context context) {
1256:
1257:                String contextPath = context.getPath();
1258:
1259:                if (deployed.containsKey(contextPath))
1260:                    return;
1261:
1262:                DeployedApplication deployedApp = new DeployedApplication(
1263:                        contextPath);
1264:
1265:                // Add the associated docBase to the redeployed list if it's a WAR
1266:                boolean isWar = false;
1267:                if (context.getDocBase() != null) {
1268:                    File docBase = new File(context.getDocBase());
1269:                    if (!docBase.isAbsolute()) {
1270:                        docBase = new File(appBase(), context.getDocBase());
1271:                    }
1272:                    deployedApp.redeployResources.put(
1273:                            docBase.getAbsolutePath(), new Long(docBase
1274:                                    .lastModified()));
1275:                    if (docBase.getAbsolutePath().toLowerCase()
1276:                            .endsWith(".war")) {
1277:                        isWar = true;
1278:                    }
1279:                }
1280:                host.addChild(context);
1281:                // Add the eventual unpacked WAR and all the resources which will be
1282:                // watched inside it
1283:                if (isWar && unpackWARs) {
1284:                    String name = null;
1285:                    String path = context.getPath();
1286:                    if (path.equals("")) {
1287:                        name = "ROOT";
1288:                    } else {
1289:                        if (path.startsWith("/")) {
1290:                            name = path.substring(1);
1291:                        } else {
1292:                            name = path;
1293:                        }
1294:                    }
1295:                    File docBase = new File(name);
1296:                    if (!docBase.isAbsolute()) {
1297:                        docBase = new File(appBase(), name);
1298:                    }
1299:                    deployedApp.redeployResources.put(
1300:                            docBase.getAbsolutePath(), new Long(docBase
1301:                                    .lastModified()));
1302:                    addWatchedResources(deployedApp, docBase.getAbsolutePath(),
1303:                            context);
1304:                } else {
1305:                    addWatchedResources(deployedApp, null, context);
1306:                }
1307:                deployed.put(contextPath, deployedApp);
1308:            }
1309:
1310:            /**
1311:             * Remove a webapp from our control.
1312:             * Entry point for the admin webapp, and other JMX Context controlers.
1313:             */
1314:            public void unmanageApp(String contextPath) {
1315:                if (isServiced(contextPath)) {
1316:                    deployed.remove(contextPath);
1317:                    host.removeChild(host.findChild(contextPath));
1318:                }
1319:            }
1320:
1321:            // ----------------------------------------------------- Instance Variables
1322:
1323:            /**
1324:             * This class represents the state of a deployed application, as well as 
1325:             * the monitored resources.
1326:             */
1327:            protected class DeployedApplication {
1328:                public DeployedApplication(String name) {
1329:                    this .name = name;
1330:                }
1331:
1332:                /**
1333:                 * Application context path. The assertion is that 
1334:                 * (host.getChild(name) != null).
1335:                 */
1336:                public String name;
1337:
1338:                /**
1339:                 * Any modification of the specified (static) resources will cause a 
1340:                 * redeployment of the application. If any of the specified resources is
1341:                 * removed, the application will be undeployed. Typically, this will
1342:                 * contain resources like the context.xml file, a compressed WAR path.
1343:                 * The value is the last modification time.
1344:                 */
1345:                public LinkedHashMap redeployResources = new LinkedHashMap();
1346:
1347:                /**
1348:                 * Any modification of the specified (static) resources will cause a 
1349:                 * reload of the application. This will typically contain resources
1350:                 * such as the web.xml of a webapp, but can be configured to contain
1351:                 * additional descriptors.
1352:                 * The value is the last modification time.
1353:                 */
1354:                public HashMap reloadResources = new HashMap();
1355:
1356:                /**
1357:                 * Instant where the application was last put in service.
1358:                 */
1359:                public long timestamp = System.currentTimeMillis();
1360:            }
1361:
1362:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.