import java.io.*;
import java.util.*;
+import java.lang.reflect.*;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.*;
import javax.xml.parsers.ParserConfigurationException;
* classes as well as the inclusion of a method to
* add parameters (nested tags) that are required.
* (the addRequired method) in the config file.
+ * that part is from tomcat.
+ *
+ * much code is stolen from ant ProjectHelper.java.
*
* @author -mh <heckmann@hbe.ca>
* @version 2001.10.21
private File configFileParent;
private Locator locator;
- //private SaxContext saxContext;
+ private SaxContext saxContext;
+
+ XmlMatch requiredXmlMatch[]=new XmlMatch[256]; //maximum amount of rules
+ int requiredXmlMatchCount=0;
+ boolean matched[] = new boolean[256];
+ int matchedCount=0;
+
+ XmlMatch mustComeFirstMatch[]=new XmlMatch[256]; //maximum amount of rules
+ int comeFirstMatchCount=0;
+
+ Property comesFirstArr[]=new Property[128];
+ int comesFirstCount=0;
+
+ Property propertyArr[]=new Property[128];
+ int propertyCount=0;
+
+ private static XmlConfigurator instance = new XmlConfigurator();
+ public static XmlConfigurator getInstance() { return instance; }
/**
* Configures the Project with the contents of the specified XML file.
*/
- public static void configure(File configFile) throws ConfigException {
- new XmlConfigurator(configFile).parse();
+ public void configure(File configFile) throws ConfigException {
+ setConfigFile(configFile);
+ parse();
}
/**
+ * konstruktor. private so no one calls "new" on us.
+ */
+ private XmlConfigurator() {}
+
+
+ /**
* Constructs a new Ant parser for the specified XML file.
*/
- private XmlConfigurator(File configFile) {
+ private void setConfigFile(File configFile) {
this.configFile = new File(configFile.getAbsolutePath());
configFileParent = new File(this.configFile.getParent());
+ saxContext = new SaxContext();
}
/**
inputSource = new InputSource(inputStream);
inputSource.setSystemId(uri);
saxParser.parse(inputSource, new RootHandler());
- }
+ if(matchedCount < requiredXmlMatchCount) {
+ for( int i=0; i<requiredXmlMatchCount; i++) {
+ if( !matched[i] )
+ throw new ConfigException("Error parsing config file, missing required element: "+requiredXmlMatch[i].toString());
+ }
+ }
+ try {
+ for(int i=0; i<comesFirstCount;i++) {
+ comesFirstArr[i].set();
+ }
+ for(int i=0; i<propertyCount;i++) {
+ propertyArr[i].set();
+ System.out.println("about to set: "+i);
+ }
+ } catch (Exception e) {
+ throw new SAXParseException(e.toString(), locator);
+ }
+}
catch(ParserConfigurationException exc) {
throw new ConfigException("Parser has not been configured correctly", exc);
}
*/
protected void finished() {}
- public void endElement() throws SAXException {
-
+ public void endElement(String uri, String tag, String qName) throws SAXException {
finished();
// Let parent resume handling SAX events
saxParser.getXMLReader().setContentHandler(parentHandler);
locator);
}
+ saxContext.push(tag);
+ matchedCount += checkRequiredTag(saxContext);
+
//MirConfig.setName(name);
}
}
}
+ public void finished() {
+ System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+ saxContext.pop();
+ }
+
private void handleClassdef(String name, Attributes attrs) throws SAXParseException {
(new ClassHandler(this)).init(name, attrs);
}
throw new SAXParseException("class element appears without a \"name\" attribute", locator);
}
+ saxContext.push(tag+":"+name);
+ matchedCount += checkRequiredTag(saxContext);
try {
- classN=Class.forName(name);
+ classN=Class.forName(name, false, this.getClass().getClassLoader());
} catch (ClassNotFoundException e) {
throw new ConfigException("Error invoking class: \""+name+
"\"",e);
}
}
+ public void finished() {
+ System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+ System.out.println("COUNT "+saxContext.getTagCount());
+ saxContext.pop();
+ }
+
private void handleProperties(String name, Attributes attrs) throws SAXParseException {
(new PropertiesHandler(this, classN )).init(name, attrs);
}
if (value == null) {
throw new SAXParseException("property element appears without a \"value\" attribute", locator);
}
- /////
+ saxContext.push(tag+":"+name);
+ matchedCount += checkRequiredTag(saxContext);
+
+ //finally add it to the lists
+ //to be processed later
+ if (checkComesFirstTag(saxContext)) {
+ comesFirstArr[comesFirstCount]=new Property(classN, name, value);
+ comesFirstCount++;
+ } else {
+ propertyArr[propertyCount]=new Property(classN, name, value);
+ propertyCount++;
+ }
}
protected void finished() {
- //do the setting here?
+ System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+ System.out.println("COUNT "+saxContext.getTagCount());
+ saxContext.pop();
}
}
+ public void addComesFirstTag(String xmlPath) {
+ mustComeFirstMatch[comeFirstMatchCount]=new XmlMatch(xmlPath);
+ comeFirstMatchCount++;
+ }
+
+ private boolean checkComesFirstTag(SaxContext ctx) {
+ for( int i=0; i<comeFirstMatchCount; i++ ) {
+ if( mustComeFirstMatch[i].match(ctx) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void addRequiredTag(String xmlPath) {
+ requiredXmlMatch[requiredXmlMatchCount]=new XmlMatch(xmlPath);
+ matched[requiredXmlMatchCount]=false;
+ requiredXmlMatchCount++;
+ }
+
+ private int checkRequiredTag(SaxContext ctx) {
+ int matchCount=0;
+ for( int i=0; i<requiredXmlMatchCount; i++ ) {
+ if( requiredXmlMatch[i].match(ctx) ) {
+ matched[i]=true;
+ matchCount++;
+ }
+ }
+ return matchCount;
+ }
+
+
private static String capitalize(String name) {
if (name == null || name.length() == 0) {
return name;
return new String(chars);
}
+ private class Property {
+ Class classN;
+ String name;
+ String value;
+
+ public Property( Class classN, String name, String value) {
+ this.classN=classN;
+ this.name=name;
+ this.value=value;
+ }
+
+ /** Find a method with the right name
+ * If found, call the method ( if param is int or boolean we'll convert
+ * value to the right type before) - that means you can have setDebug(1).
+ */
+ public void set() throws Exception {
+
+ String setter= "set" +capitalize(name);
+
+ try {
+ Method methods[]=classN.getMethods();
+ Method setPropertyMethod=null;
+
+ // First, the ideal case - a setFoo( String ) method
+ for( int i=0; i< methods.length; i++ ) {
+ Class paramT[]=methods[i].getParameterTypes();
+ if( setter.equals( methods[i].getName() ) &&
+ paramT.length == 1 &&
+ "java.lang.String".equals( paramT[0].getName())) {
+
+ methods[i].invoke( null, new Object[] { value } );
+ return;
+ }
+ } //end for
+
+ // Try a setFoo ( int ), (float) or ( boolean )
+ for( int i=0; i< methods.length; i++ ) {
+ boolean ok=true;
+ if( setter.equals( methods[i].getName() ) &&
+ methods[i].getParameterTypes().length == 1) {
+
+ // match - find the type and invoke it
+ Class paramType=methods[i].getParameterTypes()[0];
+ Object params[]=new Object[1];
+ if ("java.lang.Integer".equals( paramType.getName()) ||
+ "int".equals( paramType.getName())) {
+ try {
+ params[0]=new Integer(value);
+ } catch( NumberFormatException ex ) {ok=false;}
+ } else if ("java.lang.Float".equals( paramType.getName()) ||
+ "float".equals( paramType.getName())) {
+ try {
+ params[0]=new Float(value);
+ } catch( NumberFormatException ex ) {ok=false;}
+ } else if ("java.lang.Boolean".equals( paramType.getName()) ||
+ "boolean".equals( paramType.getName())) {
+ params[0]=new Boolean(value);
+ } else {
+ throw new Exception("Unknown type " + paramType.getName() + "for property \""+name+"\"with value \""+value+"\"");
+ }
+
+ if( ok ) {
+ System.out.println("XXX: " + methods[i] + " " + classN + " " + params[0] );
+ methods[i].invoke( null, params );
+ return;
+ } //end if
+ } //end if setter
+ } //end for
+
+ //if we got this far it means we were not successful in setting the
+ //property
+ throw new Exception("Count not find method \""+setter+"\" in Class \""+classN.getName()+"\" in order to set property \""+name+"\"");
+
+ } catch( SecurityException ex1 ) {
+ throw new Exception("SecurityException for " + classN.getName() + " " + name + "=" + value +")" );
+ //if( ctx.getDebug() > 1 ) ex1.printStackTrace();
+ } catch (IllegalAccessException iae) {
+ throw new Exception("IllegalAccessException for " + classN.getName() + " " + name + "=" + value +")" );
+ //if( ctx.getDebug() > 1 ) iae.printStackTrace();
+ } catch (InvocationTargetException ie) {
+ throw new Exception("InvocationTargetException for " + classN.getName() + " " + name + "=" + value +")" );
+ //if( ctx.getDebug() > 1 ) ie.printStackTrace();
+ }
+ }
+ }
+
}