|
What this is
Other links
The source code
/*
* Copyright 1999-2004 The Apache Sofware 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.
*/
package org.apache.tomcat.modules.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import org.apache.tomcat.core.BaseInterceptor;
import org.apache.tomcat.core.Context;
import org.apache.tomcat.core.ContextManager;
import org.apache.tomcat.core.TomcatException;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.hooks.Hooks;
import org.apache.tomcat.util.io.FileUtil;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.xml.SaxContext;
import org.apache.tomcat.util.xml.XmlAction;
import org.apache.tomcat.util.xml.XmlMapper;
import org.xml.sax.AttributeList;
/**
* This is a configuration module that will read a server.xml file
* and dynamically configure the server by adding modules and interceptors.
*
* Tomcat can be configured ( and auto-configured ) in many ways, and
* a configuration module will have access to all server events, and will
* be able to update it's state, etc.
*
* @author Costin Manolache
*/
public class ServerXmlReader extends BaseInterceptor {
private static StringManager sm =
StringManager.getManager("org.apache.tomcat.resources");
public ServerXmlReader() {
}
// -------------------- Properties --------------------
String configFile=null;
String moduleFile=null;
static final String DEFAULT_CONFIG="conf/server.xml";
static final String DEFAULT_MODULES="conf/modules.xml";
boolean useCachedModules=true;// can roll back
public void setConfig( String s ) {
configFile=s;
}
public void setHome( String h ) {
System.getProperties().put("tomcat.home", h);
}
public void setModuleConfig( String f ) {
moduleFile=f;
}
// -------------------- Hooks --------------------
/** When this module is added, it'll automatically load
* a configuration file and add all global modules.
*/
public void addInterceptor(ContextManager cm, Context ctx,
BaseInterceptor module)
throws TomcatException
{
// checkHooks(cm, ctx, module);
if( this != module ) return;
setupHookFinder();
XmlMapper xh=new XmlMapper();
xh.setDebug( debug );
xh.addRule( "ContextManager", xh.setProperties() );
setPropertiesRules( cm, xh );
setTagRules( xh );
addDefaultTags(cm, xh);
//addTagRules( cm, xh );
setBackward( xh );
// load the config file(s)
File f = null;
if (configFile == null) {
f=new File( cm.getHome(), DEFAULT_CONFIG);
} else {
// All other paths are relative to TOMCAT_HOME, except this one.
// The user will either type an absolute path or a path relative
// to his working dir ( relative to TOMCAT_HOME is counterintuitive)
f=new File(configFile);
}
if( f.exists() ){
f=new File( f.getAbsolutePath());
cm.setNote( "configFile", f.getAbsolutePath());
loadConfigFile(xh,f,cm);
String s=f.getAbsolutePath();
if( s.startsWith( cm.getHome()))
s="$TOMCAT_HOME" + s.substring( cm.getHome().length());
log( "Config=" + s);
// load server-*.xml
Vector v = getUserConfigFiles(f);
for (Enumeration e = v.elements();
e.hasMoreElements() ; ) {
f = (File)e.nextElement();
loadConfigFile(xh,f,cm);
cm.log(sm.getString("tomcat.loading") + " " + f);
}
}
else
log("Warning: Server configuration file " + f + " was not found!");
}
// -------------------- Xml reading details --------------------
public static void loadConfigFile(XmlMapper xh, File f, Object cm)
throws TomcatException
{
try {
xh.readXml(f,cm);
} catch( Exception ex ) {
ex.printStackTrace();
// cm.log( sm.getString("tomcat.fatalconfigerror"), ex );
throw new TomcatException(ex);
}
}
static class CMPropertySource
implements IntrospectionUtils.PropertySource
{
ContextManager cm;
CMPropertySource( ContextManager cm ) {
this.cm=cm;
}
public String getProperty( String key ) {
if( "tomcat.home".equals( key ) ) {
return cm.getHome();
}
if( "tomcat.install".equals( key ) ) {
return cm.getInstallDir();
}
// XXX add other "predefined" properties
String s=cm.getProperty( key );
if( s==null )
s=System.getProperty(key);
return s;
}
}
public static void setPropertiesRules( ContextManager cm, XmlMapper xh )
throws TomcatException
{
CMPropertySource propS=new CMPropertySource( cm );
xh.setPropertySource( propS );
// add the "correct" first-letter-capitalized version
xh.addRule( "ContextManager/Property", new XmlAction() {
public void start(SaxContext ctx ) throws Exception {
AttributeList attributes = ctx.getCurrentAttributes();
String name=attributes.getValue("name");
String value=attributes.getValue("value");
if( name==null || value==null ) return;
XmlMapper xm=ctx.getMapper();
ContextManager cm1=(ContextManager)ctx.currentObject();
// replace ${foo} in value
value=xm.replaceProperties( value );
if( cm1.getDebug() > 0 )
cm1.log("Setting " + name + "=" + value);
cm1.setProperty( name, value );
}
});
// for backward compatibility, keep old version
xh.addRule( "ContextManager/property", new XmlAction() {
public void start(SaxContext ctx ) throws Exception {
AttributeList attributes = ctx.getCurrentAttributes();
String name=attributes.getValue("name");
String value=attributes.getValue("value");
if( name==null || value==null ) return;
XmlMapper xm=ctx.getMapper();
ContextManager cm1=(ContextManager)ctx.currentObject();
// replace ${foo} in value
value=xm.replaceProperties( value );
if( cm1.getDebug() > 0 )
cm1.log("Setting " + name + "=" + value);
cm1.setProperty( name, value );
}
});
}
public static void addTagRules( ContextManager cm, XmlMapper xh )
throws TomcatException
{
Hashtable modules=(Hashtable)cm.getNote("modules");
if( modules==null) return;
Enumeration keys=modules.keys();
while( keys.hasMoreElements() ) {
String tag=(String)keys.nextElement();
String classN=(String)modules.get( tag );
addTagRule( xh, tag, classN );
}
}
public static void addTagRule( XmlMapper xh, String tag, String classN ) {
xh.addRule( tag ,
xh.objectCreate( classN, null ));
xh.addRule( tag ,
xh.setProperties());
xh.addRule( tag,
xh.addChild( "addInterceptor",
"org.apache.tomcat.core.BaseInterceptor"));
}
public static void setTagRules( XmlMapper xh ) {
xh.addRule( "module", new XmlAction() {
public void start(SaxContext ctx ) throws Exception {
Object elem=ctx.currentObject();
AttributeList attributes = ctx.getCurrentAttributes();
String name=attributes.getValue("name");
String classN=attributes.getValue("javaClass");
if( name==null || classN==null ) return;
ContextManager cm=(ContextManager)ctx.currentObject();
Hashtable modules=(Hashtable)cm.getNote("modules");
modules.put( name, classN );
addTagRule( ctx.getMapper(), name, classN );
if( ctx.getDebug() > 0 ) ctx.log("Adding " + name + " " + classN );
}
});
}
// read modules.xml, if any, and load taskdefs
public void addDefaultTags( ContextManager cm, XmlMapper xh)
throws TomcatException
{
if( cm.getNote( "modules" ) != null )
return;
if( moduleFile==null ) moduleFile=DEFAULT_MODULES;
File f=new File(moduleFile);
if ( !f.isAbsolute())
f=new File( cm.getHome(), moduleFile );
if( f.exists() ) {
// try cached value
File cachedM=new File( cm.getWorkDir() );
if( !cachedM.isAbsolute())
cachedM=new File( cm.getHome(), cm.getWorkDir());
cachedM=new File( cachedM, "modules.properties");
Properties modules=new Properties();
cm.setNote( "modules", modules );
if( useCachedModules &&
cachedM.exists() &&
cachedM.lastModified() > f.lastModified() ) {
// XXX check the other modules-foo.xml
loadCachedModules(cachedM, modules );
addTagRules( cm, xh );
return;
} else {
loadConfigFile( xh, f, cm );
// load module-*.xml
Vector v = getUserConfigFiles(f);
for (Enumeration e = v.elements();
e.hasMoreElements() ; ) {
f = (File)e.nextElement();
loadConfigFile(xh,f,cm);
}
saveCachedModules(cachedM, modules);
}
}
else
log("Warning: Modules configuration file " + f + " was not found!");
}
void loadCachedModules( File f, Properties mods ) {
try {
FileInputStream pos=new FileInputStream( f );
mods.load( pos );
} catch(IOException ex ) {
log("Error loading modules ", ex );
}
}
void saveCachedModules( File f, Properties mods ) {
try {
FileOutputStream pos=new FileOutputStream( f );
mods.save( pos, "Auto-generated cache file");
} catch(IOException ex ) {
//log("Error saving modules ", ex );
}
}
void setupHookFinder() {
Hooks.setHookFinder( new IntrospectionHookFinder() );
}
static class IntrospectionHookFinder implements Hooks.HookFinder {
public boolean hasHook( Object o, String hook ) {
return IntrospectionUtils.hasHook( o, hook );
}
}
// -------------------- File utils --------------------
// get additional files
public static Vector getUserConfigFiles(File master) {
File dir = new File(master.getParent());
String[] names = dir.list();
// System.out.println("getUserConfigFiles " + dir );
String masterName=master.getAbsolutePath();
String base=FileUtil.getBase(masterName) + "-";
String ext=FileUtil.getExtension( masterName );
Vector v = new Vector();
if( names==null ) return v;
for (int i=0; i
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.