org.apache.catalina.startup.HostConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Portions Copyright [2019] Payara Foundation and/or affiliates
package org.apache.catalina.startup;
import org.apache.catalina.*;
import org.apache.catalina.core.StandardHost;
import org.apache.naming.resources.ResourceAttributes;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import java.io.*;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Startup event listener for a Host that configures the properties
* of that Host, and the associated defined contexts.
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Revision: 1.4 $ $Date: 2006/10/03 20:19:13 $
*/
public class HostConfig
implements LifecycleListener {
private static final Logger log = LogFacade.getLogger();
private static final ResourceBundle rb = log.getResourceBundle();
// ----------------------------------------------------- Instance Variables
/**
* App base.
*/
private File appBase = null;
/**
* Config base.
*/
private File configBase = null;
/**
* The Java class name of the Context configuration class we should use.
*/
protected String configClass = "org.apache.catalina.startup.ContextConfig";
/**
* The Java class name of the Context implementation we should use.
*/
protected String contextClass = "org.apache.catalina.core.StandardContext";
/**
* The debugging detail level for this component.
*/
protected int debug = 0;
/**
* The names of applications that we have auto-deployed (to avoid
* double deployment attempts).
*/
protected List deployed = new ArrayList();
/**
* The Host we are associated with.
*/
protected Host host = null;
/**
* Should we deploy XML Context config files?
*/
private boolean deployXML = false;
/**
* Should we unpack WAR files when auto-deploying applications in the
* appBase
directory?
*/
private boolean unpackWARs = false;
/**
* Last modified dates of the web.xml files of the contexts, keyed by
* context name.
*/
private final Map webXmlLastModified = new HashMap();
/**
* Last modified dates of the Context xml files of the contexts, keyed by
* context name.
*/
private final Map contextXmlLastModified = new HashMap();
/**
* Last modified dates of the source WAR files, keyed by WAR name.
*/
private final HashMap warLastModified = new HashMap();
/**
* Attribute value used to turn on/off XML validation
*/
private boolean xmlValidation = false;
/**
* Attribute value used to turn on/off XML namespace awarenes.
*/
private boolean xmlNamespaceAware = false;
/**
* The list of Wars in the appBase to be ignored because they are invalid
* (e.g. contain /../ sequences).
*/
protected Set invalidWars = new HashSet();
// ------------------------------------------------------------- Properties
/**
* Return the Context configuration class name.
*/
public String getConfigClass() {
return (this.configClass);
}
/**
* Set the Context configuration class name.
*
* @param configClass The new Context configuration class name.
*/
public void setConfigClass(String configClass) {
this.configClass = configClass;
}
/**
* Return the Context implementation class name.
*/
public String getContextClass() {
return (this.contextClass);
}
/**
* Set the Context implementation class name.
*
* @param contextClass The new Context implementation class name.
*/
public void setContextClass(String contextClass) {
this.contextClass = contextClass;
}
/**
* Return the debugging detail level for this component.
*/
public int getDebug() {
return (this.debug);
}
/**
* Set the debugging detail level for this component.
*
* @param debug The new debugging detail level
*/
public void setDebug(int debug) {
this.debug = debug;
}
/**
* Return the deploy XML config file flag for this component.
*/
public boolean isDeployXML() {
return (this.deployXML);
}
/**
* Set the deploy XML config file flag for this component.
*
* @param deployXML The new deploy XML flag
*/
public void setDeployXML(boolean deployXML) {
this.deployXML= deployXML;
}
/**
* Return the unpack WARs flag.
*/
public boolean isUnpackWARs() {
return (this.unpackWARs);
}
/**
* Set the unpack WARs flag.
*
* @param unpackWARs The new unpack WARs flag
*/
public void setUnpackWARs(boolean unpackWARs) {
this.unpackWARs = unpackWARs;
}
/**
* Set the validation feature of the XML parser used when
* parsing xml instances.
* @param xmlValidation true to enable xml instance validation
*/
public void setXmlValidation(boolean xmlValidation){
this.xmlValidation = xmlValidation;
}
/**
* Get the server.xml attribute's xmlValidation.
* @return true if validation is enabled.
*
*/
public boolean getXmlValidation(){
return xmlValidation;
}
/**
* Get the server.xml attribute's xmlNamespaceAware.
* @return true if namespace awarenes is enabled.
*
*/
public boolean getXmlNamespaceAware(){
return xmlNamespaceAware;
}
/**
* Set the namespace aware feature of the XML parser used when
* parsing xml instances.
* @param xmlNamespaceAware true to enable namespace awareness
*/
public void setXmlNamespaceAware(boolean xmlNamespaceAware){
this.xmlNamespaceAware=xmlNamespaceAware;
}
// --------------------------------------------------------- Public Methods
/**
* Process the START event for an associated Host.
*
* @param event The lifecycle event that has occurred
*/
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals("check"))
check();
// Identify the host we are associated with
try {
host = (Host) event.getLifecycle();
if (host instanceof StandardHost) {
int hostDebug = ((StandardHost) host).getDebug();
if (hostDebug > this.debug) {
this.debug = hostDebug;
}
setDeployXML(((StandardHost) host).isDeployXML());
setUnpackWARs(((StandardHost) host).isUnpackWARs());
setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware());
setXmlValidation(((StandardHost) host).getXmlValidation());
}
} catch (ClassCastException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.LIFECYCLE_OBJECT_NOT_HOST_EXCEPTION),
event.getLifecycle());
log.log(Level.SEVERE, msg, e);
return;
}
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT))
start();
else if (event.getType().equals(Lifecycle.STOP_EVENT))
stop();
}
// ------------------------------------------------------ Protected Methods
/**
* Return a File object representing the "application root" directory
* for our associated Host.
*/
protected File appBase() {
if (appBase != null) {
return appBase;
}
File file = new File(host.getAppBase());
if (!file.isAbsolute())
file = new File(System.getProperty("catalina.base"),
host.getAppBase());
try {
appBase = file.getCanonicalFile();
} catch (IOException e) {
appBase = file;
}
return (appBase);
}
/**
* Return a File object representing the "configuration root" directory
* for our associated Host.
*/
protected File configBase() {
if (configBase != null) {
return configBase;
}
File file = new File(System.getProperty("catalina.base"), "conf");
Container parent = host.getParent();
if ((parent != null) && (parent instanceof Engine)) {
file = new File(file, parent.getName());
}
file = new File(file, host.getName());
try {
configBase = file.getCanonicalFile();
} catch (IOException e) {
configBase = file;
}
return (configBase);
}
/**
* Deploy applications for any directories or WAR files that are found
* in our "application root" directory.
*/
protected void deployApps() {
if (!(host instanceof Deployer))
return;
File appBase = appBase();
if (!appBase.exists() || !appBase.isDirectory())
return;
File configBase = configBase();
if (configBase.exists() && configBase.isDirectory()) {
String configFiles[] = configBase.list();
deployDescriptors(configBase, configFiles);
}
String files[] = appBase.list();
deployWARs(appBase, files);
deployDirectories(appBase, files);
}
/**
* Deploy XML context descriptors.
*/
protected void deployDescriptors(File configBase, String[] files) {
if (!deployXML)
return;
for (int i = 0; i < files.length; i++) {
if (files[i].equalsIgnoreCase("META-INF"))
continue;
if (files[i].equalsIgnoreCase("WEB-INF"))
continue;
if (deployed.contains(files[i]))
continue;
File dir = new File(configBase, files[i]);
if (files[i].toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
deployed.add(files[i]);
// Calculate the context path and make sure it is unique
String file = files[i].substring(0, files[i].length() - 4);
String contextPath = "/" + file.replace('_', '/');
if (file.equals("ROOT")) {
contextPath = "";
}
// Assume this is a configuration descriptor and deploy it
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, LogFacade.DEPLOYING_CONFIG_DESCRIPTOR, files[i]);
}
try {
if (host.findChild(contextPath) != null) {
if ((deployed.contains(file))
|| (deployed.contains(file + ".war"))) {
// If this is a newly added context file and
// it overrides a context with a simple path,
// that was previously deployed by the auto
// deployer, undeploy the context
((Deployer) host).remove(contextPath);
} else {
continue;
}
}
URL config =
new URL("file", null, dir.getCanonicalPath());
((Deployer) host).install(config, null);
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_DEPLOYING_CONFIG_DESCRIPTOR_EXCEPTION),
files[i]);
log.log(Level.SEVERE, msg, t);
}
}
}
}
/**
* Deploy WAR files.
*/
protected void deployWARs(File appBase, String[] files) {
for (String file : files) {
if (file.equalsIgnoreCase("META-INF")) {
continue;
}
if (file.equalsIgnoreCase("WEB-INF")) {
continue;
}
if (deployed.contains(file)) {
continue;
}
File dir = new File(appBase, file);
if (file.toLowerCase(Locale.ENGLISH).endsWith(".war") && dir.isFile() && !invalidWars.contains(file)) {
deployed.add(file);
// Calculate the context path and make sure it is unique
String contextPath = "/" + file;
int period = contextPath.lastIndexOf('.');
if (period >= 0)
contextPath = contextPath.substring(0, period);
// Check for WARs with /../ /./ or similar sequences in the name
if (!validateContextPath(appBase, contextPath)) {
log.log(Level.SEVERE, LogFacade.INVALID_WAR_NAME_EXCEPTION, file);
invalidWars.add(file);
continue;
}
if (contextPath.equals("/ROOT"))
contextPath = "";
if (host.findChild(contextPath) != null)
continue;
// Checking for a nested /META-INF/context.xml
JarFile jar = null;
JarEntry entry = null;
InputStream istream = null;
BufferedOutputStream ostream = null;
File xml = new File(configBase, file.substring(0, file.lastIndexOf(".")) + ".xml");
if (!xml.exists()) {
try {
jar = new JarFile(dir);
entry = jar.getJarEntry("META-INF/context.xml");
if (entry != null) {
istream = jar.getInputStream(entry);
ostream =
new BufferedOutputStream
(new FileOutputStream(xml), 1024);
byte buffer[] = new byte[1024];
while (true) {
int n = istream.read(buffer);
if (n < 0) {
break;
}
ostream.write(buffer, 0, n);
}
ostream.flush();
ostream.close();
ostream = null;
istream.close();
istream = null;
entry = null;
jar.close();
jar = null;
deployDescriptors(configBase(), configBase.list());
return;
}
} catch (IOException e) {
// Ignore and continue
} finally {
if (ostream != null) {
try {
ostream.close();
} catch (Throwable t) {
;
}
ostream = null;
}
if (istream != null) {
try {
istream.close();
} catch (Throwable t) {
;
}
istream = null;
}
entry = null;
if (jar != null) {
try {
jar.close();
} catch (Throwable t) {
;
}
jar = null;
}
}
}
if (isUnpackWARs()) {
// Expand and deploy this application as a directory
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, LogFacade.EXPANDING_WEB_APP, file);
}
URL url = null;
String path = null;
try {
url = new URL("jar:file:" +
dir.getCanonicalPath() + "!/");
path = ExpandWar.expand(host, url);
} catch (IOException e) {
// JAR decompression failure
log.log(Level.WARNING, LogFacade.EXPANDING_WEB_APP_EXCEPTION, file);
continue;
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.EXPANDING_WEB_APP_ARCHIVE_EXCEPTION), file);
log.log(Level.SEVERE, msg, t);
continue;
}
try {
if (path != null) {
url = new URL("file:" + path);
((Deployer) host).install(contextPath, url);
}
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.EXPANDING_WEB_APP_ARCHIVE_EXCEPTION), file);
log.log(Level.SEVERE, msg, t);
}
} else {
// Deploy the application in this WAR file
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, LogFacade.DEPLOYING_WEB_APP_ARCHIVE, file);
}
try {
URL url = new URL("file", null,
dir.getCanonicalPath());
url = new URL("jar:" + url.toString() + "!/");
((Deployer) host).install(contextPath, url);
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_DEPLOYING_WEB_APP_ARCHIVE_EXCEPTION), file);
log.log(Level.SEVERE, msg, t);
}
}
}
}
}
/**
* Deploy directories.
*/
protected void deployDirectories(File appBase, String[] files) {
for (int i = 0; i < files.length; i++) {
if (files[i].equalsIgnoreCase("META-INF"))
continue;
if (files[i].equalsIgnoreCase("WEB-INF"))
continue;
if (deployed.contains(files[i]))
continue;
File dir = new File(appBase, files[i]);
if (dir.isDirectory()) {
deployed.add(files[i]);
// Make sure there is an application configuration directory
// This is needed if the Context appBase is the same as the
// web server document root to make sure only web applications
// are deployed and not directories for web space.
File webInf = new File(dir, "/WEB-INF");
if (!webInf.exists() || !webInf.isDirectory() ||
!webInf.canRead())
continue;
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i];
if (files[i].equals("ROOT"))
contextPath = "";
if (host.findChild(contextPath) != null)
continue;
// Deploy the application in this directory
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, LogFacade.DEPLOYING_WEB_APP_DIR, files[i]);
}
long t1=System.currentTimeMillis();
try {
URL url = new URL("file", null, dir.getCanonicalPath());
((Deployer) host).install(contextPath, url);
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_DEPLOYING_WEB_APP_DIR),
files[i]);
log.log(Level.SEVERE, msg, t);
}
long t2=System.currentTimeMillis();
if( (t2-t1) > 200 && log.isLoggable(Level.FINE) )
log.log(Level.FINE, "Deployed {0} {1}", new Object[]{files[i], t2-t1});
}
}
}
private boolean validateContextPath(File appBase, String contextPath) {
// More complicated than the ideal as the canonical path may or may
// not end with File.separator for a directory
StringBuilder docBase;
String canonicalDocBase = null;
try {
String canonicalAppBase = appBase.getCanonicalPath();
docBase = new StringBuilder(canonicalAppBase);
if (canonicalAppBase.endsWith(File.separator)) {
docBase.append(contextPath.substring(1).replace(
'/', File.separatorChar));
} else {
docBase.append(contextPath.replace('/', File.separatorChar));
}
// At this point docBase should be canonical but will not end
// with File.separator
canonicalDocBase =
(new File(docBase.toString())).getCanonicalPath();
// If the canonicalDocBase ends with File.separator, add one to
// docBase before they are compared
if (canonicalDocBase.endsWith(File.separator)) {
docBase.append(File.separator);
}
} catch (IOException ioe) {
return false;
}
// Compare the two. If they are not the same, the contextPath must
// have /../ like sequences in it
return canonicalDocBase.equals(docBase.toString());
}
/**
* Check deployment descriptors last modified date.
*/
protected void checkContextLastModified() {
if (!(host instanceof Deployer))
return;
Deployer deployer = (Deployer) host;
String[] contextNames = deployer.findDeployedApps();
for (int i = 0; i < contextNames.length; i++) {
String contextName = contextNames[i];
Context context = deployer.findDeployedApp(contextName);
if (!(context instanceof Lifecycle))
continue;
try {
DirContext resources = context.getResources();
if (resources == null) {
// This can happen if there was an error initializing
// the context
continue;
}
ResourceAttributes webXmlAttributes =
(ResourceAttributes)
resources.getAttributes("/WEB-INF/web.xml");
ResourceAttributes webInfAttributes =
(ResourceAttributes)
resources.getAttributes("/WEB-INF");
long newLastModified = webXmlAttributes.getLastModified();
long webInfLastModified = webInfAttributes.getLastModified();
Long lastModified = webXmlLastModified.get(contextName);
if (lastModified == null) {
webXmlLastModified.put(contextName, newLastModified);
} else {
if (lastModified != newLastModified) {
if (newLastModified > (webInfLastModified + 5000)) {
webXmlLastModified.remove(contextName);
restartContext(context);
} else {
webXmlLastModified.put (contextName, newLastModified);
}
}
}
} catch (NamingException e) {
; // Ignore
}
Long lastModified = contextXmlLastModified.get(contextName);
String configBase = configBase().getPath();
String configFileName = context.getConfigFile();
if (configFileName != null) {
File configFile = new File(configFileName);
if (!configFile.isAbsolute()) {
configFile = new File(System.getProperty("catalina.base"), configFile.getPath());
}
long newLastModified = configFile.lastModified();
if (lastModified == null) {
contextXmlLastModified.put(contextName, newLastModified);
} else {
if (lastModified != newLastModified) {
contextXmlLastModified.remove(contextName);
String fileName = configFileName;
if (fileName.startsWith(configBase)) {
fileName =
fileName.substring(configBase.length() + 1);
try {
deployed.remove(fileName);
if (host.findChild(contextName) != null) {
((Deployer) host).remove(contextName);
}
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_UNDEPLOYING_JAR_FILE_EXCEPTION),
fileName);
log.log(Level.SEVERE, msg, t);
}
deployApps();
}
}
}
}
}
// Check for WAR modification
if (isUnpackWARs()) {
File appBase = appBase();
if (!appBase.exists() || !appBase.isDirectory())
return;
String files[] = appBase.list();
for (String file : files) {
if (file.endsWith(".war")) {
File dir = new File(appBase, file);
Long lastModified = warLastModified.get(file);
long dirLastModified = dir.lastModified();
if (lastModified == null) {
warLastModified.put(file, dir.lastModified());
} else if (dirLastModified > lastModified) {
// The WAR has been modified: redeploy
String expandedDir = file;
int period = expandedDir.lastIndexOf('.');
if (period >= 0)
expandedDir = expandedDir.substring(0, period);
File expanded = new File(appBase, expandedDir);
String contextPath = "/" + expandedDir;
if (contextPath.equals("/ROOT"))
contextPath = "";
if (dirLastModified > expanded.lastModified()) {
try {
// Undeploy current application
deployed.remove(file);
deployed.remove(expandedDir + ".xml");
if (host.findChild(contextPath) != null) {
((Deployer) host).remove(contextPath,
false);
ExpandWar.deleteDir(expanded);
}
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_UNDEPLOYING_JAR_FILE_EXCEPTION), file);
log.log(Level.SEVERE, msg, t);
}
deployApps();
}
// If deployment was successful, reset
// the last modified values
if (host.findChild(contextPath) != null) {
webXmlLastModified.remove(contextPath);
warLastModified.put(file, dir.lastModified());
}
}
}
}
}
}
protected boolean restartContext(Context context) {
boolean result = true;
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, LogFacade.RESTART_CONTEXT_INFO, context.getName());
}
/*
try {
StandardContext sctx=(StandardContext)context;
sctx.reload();
} catch( Exception ex ) {
log.warn("Erorr stopping context " + context.getName() + " " +
ex.toString());
}
*/
try {
((Lifecycle) context).stop();
} catch( Exception ex ) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_DURING_CONTEXT_STOP_EXCEPTION),
context.getName());
log.log(Level.WARNING, msg, ex);
}
// if the context was not started ( for example an error in web.xml)
// we'll still get to try to start
try {
((Lifecycle) context).start();
} catch (Exception e) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_DURING_CONTEXT_RESTART_EXCEPTION),
context.getName());
log.log(Level.WARNING, msg, e);
result = false;
}
return result;
}
/**
* Expand the WAR file found at the specified URL into an unpacked
* directory structure, and return the absolute pathname to the expanded
* directory.
*
* @param war URL of the web application archive to be expanded
* (must start with "jar:")
*
* @exception IllegalArgumentException if this is not a "jar:" URL
* @exception IOException if an input/output error was encountered
* during expansion
*/
protected String expand(URL war) throws IOException {
return ExpandWar.expand(host,war);
}
/**
* Expand the specified input stream into the specified directory, creating
* a file named from the specified relative path.
*
* @param input InputStream to be copied
* @param docBase Document base directory into which we are expanding
* @param name Relative pathname of the file to be created
*
* @exception IOException if an input/output error occurs
*/
protected void expand(InputStream input, File docBase, String name)
throws IOException {
ExpandWar.expand(input,docBase,name);
}
/**
* Log a message on the Logger associated with our Host (if any)
*
* @param message Message to be logged
*/
protected void log(String message) {
org.apache.catalina.Logger logger = null;
if (host != null)
logger = host.getLogger();
if (logger != null)
logger.log("HostConfig[" + host.getName() + "]: " + message);
else
log.info(message);
}
/**
* Log a message on the Logger associated with our Host (if any)
*
* @param message Message to be logged
* @param throwable Associated exception
*/
protected void log(String message, Throwable throwable) {
org.apache.catalina.Logger logger = null;
if (host != null)
logger = host.getLogger();
if (logger != null)
logger.log("HostConfig[" + host.getName() + "] "
+ message, throwable);
else {
log.log(Level.SEVERE, message, throwable);
}
}
/**
* Process a "start" event for this Host.
*/
public void start() {
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, LogFacade.PROCESSING_START);
if (host.getDeployOnStartup()) {
deployApps();
} else {
// Deploy descriptors anyway (it should be equivalent to being
// part of server.xml)
File configBase = configBase();
if (configBase.exists() && configBase.isDirectory()) {
String configFiles[] = configBase.list();
deployDescriptors(configBase, configFiles);
}
}
}
/**
* Process a "stop" event for this Host.
*/
public void stop() {
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, LogFacade.PROCESSING_STOP);
undeployApps();
appBase = null;
configBase = null;
}
/**
* Undeploy all deployed applications.
*/
protected void undeployApps() {
if (!(host instanceof Deployer))
return;
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, LogFacade.UNDEPLOYING_WEB_APP);
String contextPaths[] = ((Deployer) host).findDeployedApps();
for (String contextPath : contextPaths) {
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, LogFacade.UNDEPLOYING_CONTEXT, contextPath);
}
try {
((Deployer) host).remove(contextPath);
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_UNDEPLOYING_WEB_APP_EXCEPTION), contextPath);
log.log(Level.SEVERE, msg, t);
}
}
webXmlLastModified.clear();
deployed.clear();
}
/**
* Deploy webapps.
*/
protected void check() {
if (host.getAutoDeploy()) {
// Deploy apps if the Host allows auto deploying
deployApps();
// Check for web.xml modification
checkContextLastModified();
}
}
}