Fields Summary |
---|
private static com.sun.org.apache.commons.logging.Log | log |
private File | appBaseApp base. |
private File | configBaseConfig base. |
protected String | configClassThe Java class name of the Context configuration class we should use. |
protected String | contextClassThe Java class name of the Context implementation we should use. |
protected int | debugThe debugging detail level for this component. |
protected ArrayList | deployedThe names of applications that we have auto-deployed (to avoid
double deployment attempts). |
protected org.apache.catalina.Host | hostThe Host we are associated with. |
protected static final org.apache.catalina.util.StringManager | smThe string resources for this package. |
private boolean | deployXMLShould we deploy XML Context config files? |
private boolean | unpackWARsShould we unpack WAR files when auto-deploying applications in the
appBase directory? |
private HashMap | webXmlLastModifiedLast modified dates of the web.xml files of the contexts, keyed by
context name. |
private HashMap | contextXmlLastModifiedLast modified dates of the Context xml files of the contexts, keyed by
context name. |
private HashMap | warLastModifiedLast modified dates of the source WAR files, keyed by WAR name. |
private boolean | xmlValidationAttribute value used to turn on/off XML validation |
private boolean | xmlNamespaceAwareAttribute value used to turn on/off XML namespace awarenes. |
Methods Summary |
---|
protected java.io.File | appBase()Return a File object representing the "application root" directory
for our associated Host.
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);
|
protected void | check()Deploy webapps.
if (host.getAutoDeploy()) {
// Deploy apps if the Host allows auto deploying
deployApps();
// Check for web.xml modification
checkContextLastModified();
}
|
protected void | checkContextLastModified()Check deployment descriptors last modified date.
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 = (Long) webXmlLastModified.get(contextName);
if (lastModified == null) {
webXmlLastModified.put
(contextName, Long.valueOf(newLastModified));
} else {
if (lastModified.longValue() != newLastModified) {
if (newLastModified > (webInfLastModified + 5000)) {
webXmlLastModified.remove(contextName);
restartContext(context);
} else {
webXmlLastModified.put
(contextName, Long.valueOf(newLastModified));
}
}
}
} catch (NamingException e) {
; // Ignore
}
Long lastModified = (Long) 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, Long.valueOf(newLastModified));
} else {
if (lastModified.longValue() != 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) {
log.error(sm.getString
("hostConfig.undeployJar.error",
fileName), t);
}
deployApps();
}
}
}
}
}
// Check for WAR modification
if (isUnpackWARs()) {
File appBase = appBase();
if (!appBase.exists() || !appBase.isDirectory())
return;
String files[] = appBase.list();
for (int i = 0; i < files.length; i++) {
if (files[i].endsWith(".war")) {
File dir = new File(appBase, files[i]);
Long lastModified = (Long) warLastModified.get(files[i]);
long dirLastModified = dir.lastModified();
if (lastModified == null) {
warLastModified.put
(files[i], Long.valueOf(dir.lastModified()));
} else if (dirLastModified > lastModified.longValue()) {
// The WAR has been modified: redeploy
String expandedDir = files[i];
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(files[i]);
deployed.remove(expandedDir + ".xml");
if (host.findChild(contextPath) != null) {
((Deployer) host).remove(contextPath,
false);
ExpandWar.deleteDir(expanded);
}
} catch (Throwable t) {
log.error(sm.getString
("hostConfig.undeployJar.error",
files[i]), t);
}
deployApps();
}
// If deployment was successful, reset
// the last modified values
if (host.findChild(contextPath) != null) {
webXmlLastModified.remove(contextPath);
warLastModified.put
(files[i], Long.valueOf(dir.lastModified()));
}
}
}
}
}
|
protected java.io.File | configBase()Return a File object representing the "configuration root" directory
for our associated Host.
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);
|
protected void | deployApps()Deploy applications for any directories or WAR files that are found
in our "application root" directory.
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);
|
protected void | deployDescriptors(java.io.File configBase, java.lang.String[] files)Deploy XML context descriptors.
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().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
log.debug(sm.getString("hostConfig.deployDescriptor", 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) {
log.error(sm.getString("hostConfig.deployDescriptor.error",
files[i]), t);
}
}
}
|
protected void | deployDirectories(java.io.File appBase, java.lang.String[] files)Deploy directories.
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.isDebugEnabled() )
log.debug(sm.getString("hostConfig.deployDir", files[i]));
long t1=System.currentTimeMillis();
try {
URL url = new URL("file", null, dir.getCanonicalPath());
((Deployer) host).install(contextPath, url);
} catch (Throwable t) {
log.error(sm.getString("hostConfig.deployDir.error", files[i]),
t);
}
long t2=System.currentTimeMillis();
if( (t2-t1) > 200 )
log.debug("Deployed " + files[i] + " " + (t2-t1));
}
}
|
protected void | deployWARs(java.io.File appBase, java.lang.String[] files)Deploy WAR 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 (files[i].toLowerCase().endsWith(".war")) {
deployed.add(files[i]);
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i];
int period = contextPath.lastIndexOf(".");
if (period >= 0)
contextPath = contextPath.substring(0, period);
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, files[i].substring
(0, files[i].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 (Exception e) {
// Ignore and continue
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
log.debug(sm.getString("hostConfig.expand", files[i]));
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.warn(sm.getString
("hostConfig.expand.error", files[i]));
continue;
} catch (Throwable t) {
log.error(sm.getString
("hostConfig.expand.error", files[i]), t);
continue;
}
try {
if (path != null) {
url = new URL("file:" + path);
((Deployer) host).install(contextPath, url);
}
} catch (Throwable t) {
log.error(sm.getString
("hostConfig.expand.error", files[i]), t);
}
} else {
// Deploy the application in this WAR file
log.info(sm.getString("hostConfig.deployJar", files[i]));
try {
URL url = new URL("file", null,
dir.getCanonicalPath());
url = new URL("jar:" + url.toString() + "!/");
((Deployer) host).install(contextPath, url);
} catch (Throwable t) {
log.error(sm.getString("hostConfig.deployJar.error",
files[i]), t);
}
}
}
}
|
protected java.lang.String | expand(java.net.URL war)Expand the WAR file found at the specified URL into an unpacked
directory structure, and return the absolute pathname to the expanded
directory.
return ExpandWar.expand(host,war);
|
protected void | expand(java.io.InputStream input, java.io.File docBase, java.lang.String name)Expand the specified input stream into the specified directory, creating
a file named from the specified relative path.
ExpandWar.expand(input,docBase,name);
|
public java.lang.String | getConfigClass()Return the Context configuration class name.
// ------------------------------------------------------------- Properties
return (this.configClass);
|
public java.lang.String | getContextClass()Return the Context implementation class name.
return (this.contextClass);
|
public int | getDebug()Return the debugging detail level for this component.
return (this.debug);
|
public boolean | getXmlNamespaceAware()Get the server.xml attribute's xmlNamespaceAware.
return xmlNamespaceAware;
|
public boolean | getXmlValidation()Get the server.xml attribute's xmlValidation.
return xmlValidation;
|
public boolean | isDeployXML()Return the deploy XML config file flag for this component.
return (this.deployXML);
|
public boolean | isUnpackWARs()Return the unpack WARs flag.
return (this.unpackWARs);
|
public void | lifecycleEvent(org.apache.catalina.LifecycleEvent event)Process the START event for an associated Host.
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) {
log.error(sm.getString("hostConfig.cce", event.getLifecycle()), 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 void | log(java.lang.String message)Log a message on the Logger associated with our Host (if any)
Logger logger = null;
if (host != null)
logger = host.getLogger();
if (logger != null)
logger.log("HostConfig[" + host.getName() + "]: " + message);
else
log.info(message);
|
protected void | log(java.lang.String message, java.lang.Throwable throwable)Log a message on the Logger associated with our Host (if any)
Logger logger = null;
if (host != null)
logger = host.getLogger();
if (logger != null)
logger.log("HostConfig[" + host.getName() + "] "
+ message, throwable);
else {
log.error( message, throwable );
}
|
protected boolean | restartContext(org.apache.catalina.Context context)
boolean result = true;
log.info("restartContext(" + 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 ) {
log.warn("Erorr stopping context " + context.getName() + " " +
ex.toString());
}
// 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) {
log.warn("Error restarting context " + context.getName() + " " +
e.toString());
result = false;
}
return result;
|
public void | setConfigClass(java.lang.String configClass)Set the Context configuration class name.
this.configClass = configClass;
|
public void | setContextClass(java.lang.String contextClass)Set the Context implementation class name.
this.contextClass = contextClass;
|
public void | setDebug(int debug)Set the debugging detail level for this component.
this.debug = debug;
|
public void | setDeployXML(boolean deployXML)Set the deploy XML config file flag for this component.
this.deployXML= deployXML;
|
public void | setUnpackWARs(boolean unpackWARs)Set the unpack WARs flag.
this.unpackWARs = unpackWARs;
|
public void | setXmlNamespaceAware(boolean xmlNamespaceAware)Set the namespace aware feature of the XML parser used when
parsing xml instances.
this.xmlNamespaceAware=xmlNamespaceAware;
|
public void | setXmlValidation(boolean xmlValidation)Set the validation feature of the XML parser used when
parsing xml instances.
this.xmlValidation = xmlValidation;
|
public void | start()Process a "start" event for this Host.
if (log.isDebugEnabled())
log.debug(sm.getString("hostConfig.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);
}
}
|
public void | stop()Process a "stop" event for this Host.
if (log.isDebugEnabled())
log.debug(sm.getString("hostConfig.stop"));
undeployApps();
appBase = null;
configBase = null;
|
protected void | undeployApps()Undeploy all deployed applications.
if (!(host instanceof Deployer))
return;
if (log.isDebugEnabled())
log.debug(sm.getString("hostConfig.undeploying"));
String contextPaths[] = ((Deployer) host).findDeployedApps();
for (int i = 0; i < contextPaths.length; i++) {
if (log.isDebugEnabled())
log.debug(sm.getString("hostConfig.undeploy", contextPaths[i]));
try {
((Deployer) host).remove(contextPaths[i]);
} catch (Throwable t) {
log.error(sm.getString("hostConfig.undeploy.error",
contextPaths[i]), t);
}
}
webXmlLastModified.clear();
deployed.clear();
|