103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.xml; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.InputStream; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.StringReader; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Array; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Constructor; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Field; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.InvocationTargetException; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Method; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Modifier; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.InetAddress; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.MalformedURLException; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URL; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.UnknownHostException; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.security.AccessController; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.security.PrivilegedAction; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ArrayList; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Enumeration; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Locale; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map; 4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Properties; 4503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Queue; 4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.atomic.AtomicReference; 4803928aee4356845252ac6b662d5c72c29903813eJake Slack 4903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.ArrayQueue; 5003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.LazyList; 5103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Loader; 5203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.TypeUtil; 5303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.component.LifeCycle; 5403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 5503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 5603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource; 5703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.xml.XmlParser.Node; 5803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.xml.sax.InputSource; 5903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.xml.sax.SAXException; 6003928aee4356845252ac6b662d5c72c29903813eJake Slack 6103928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 6203928aee4356845252ac6b662d5c72c29903813eJake Slack/** 6303928aee4356845252ac6b662d5c72c29903813eJake Slack * Configure Objects from XML. This class reads an XML file conforming to the configure.dtd DTD and uses it to configure and object by calling set, put or other 6403928aee4356845252ac6b662d5c72c29903813eJake Slack * methods on the object. 6503928aee4356845252ac6b662d5c72c29903813eJake Slack * 6603928aee4356845252ac6b662d5c72c29903813eJake Slack * <p> 6703928aee4356845252ac6b662d5c72c29903813eJake Slack * The actual XML file format may be changed (eg to spring XML) by implementing the {@link ConfigurationProcessorFactory} interfaces to be found by the 6803928aee4356845252ac6b662d5c72c29903813eJake Slack * <code>ServiceLoader</code> by using the DTD and first tag element in the file. Note that DTD will be null if validation is off. 6903928aee4356845252ac6b662d5c72c29903813eJake Slack * 7003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 7103928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class XmlConfiguration 7203928aee4356845252ac6b662d5c72c29903813eJake Slack{ 7303928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(XmlConfiguration.class); 7403928aee4356845252ac6b662d5c72c29903813eJake Slack 7503928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Class<?>[] __primitives = 7603928aee4356845252ac6b662d5c72c29903813eJake Slack { Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE }; 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Class<?>[] __primitiveHolders = 7903928aee4356845252ac6b662d5c72c29903813eJake Slack { Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class }; 8003928aee4356845252ac6b662d5c72c29903813eJake Slack 8103928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Class<?>[] __supportedCollections = 8203928aee4356845252ac6b662d5c72c29903813eJake Slack { ArrayList.class,ArrayQueue.class,HashSet.class,Queue.class,List.class,Set.class,Collection.class,}; 8303928aee4356845252ac6b662d5c72c29903813eJake Slack 8403928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Iterable<?> __factoryLoader; 8503928aee4356845252ac6b662d5c72c29903813eJake Slack 8603928aee4356845252ac6b662d5c72c29903813eJake Slack private static final XmlParser __parser = initParser(); 8703928aee4356845252ac6b662d5c72c29903813eJake Slack 8803928aee4356845252ac6b662d5c72c29903813eJake Slack static 8903928aee4356845252ac6b662d5c72c29903813eJake Slack { 9003928aee4356845252ac6b662d5c72c29903813eJake Slack Iterable<?> loader=null; 9103928aee4356845252ac6b662d5c72c29903813eJake Slack try 9203928aee4356845252ac6b662d5c72c29903813eJake Slack { 9303928aee4356845252ac6b662d5c72c29903813eJake Slack // Use reflection to look up 1.6 service loader 9403928aee4356845252ac6b662d5c72c29903813eJake Slack // loader=ServiceLoader.load(ConfigurationProcessorFactory.class); 9503928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> slc = ClassLoader.getSystemClassLoader().loadClass("java.util.ServiceLoader"); 9603928aee4356845252ac6b662d5c72c29903813eJake Slack Method load = slc.getMethod("load",Class.class); 9703928aee4356845252ac6b662d5c72c29903813eJake Slack loader=(Iterable<?>)load.invoke(null,ConfigurationProcessorFactory.class); 9803928aee4356845252ac6b662d5c72c29903813eJake Slack } 9903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 10003928aee4356845252ac6b662d5c72c29903813eJake Slack { 10103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 10203928aee4356845252ac6b662d5c72c29903813eJake Slack } 10303928aee4356845252ac6b662d5c72c29903813eJake Slack finally 10403928aee4356845252ac6b662d5c72c29903813eJake Slack { 10503928aee4356845252ac6b662d5c72c29903813eJake Slack __factoryLoader=loader; 10603928aee4356845252ac6b662d5c72c29903813eJake Slack } 10703928aee4356845252ac6b662d5c72c29903813eJake Slack } 10803928aee4356845252ac6b662d5c72c29903813eJake Slack 10903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11003928aee4356845252ac6b662d5c72c29903813eJake Slack private URL _url; 11103928aee4356845252ac6b662d5c72c29903813eJake Slack private String _dtd; 11203928aee4356845252ac6b662d5c72c29903813eJake Slack private ConfigurationProcessor _processor; 11303928aee4356845252ac6b662d5c72c29903813eJake Slack private final Map<String, Object> _idMap = new HashMap<String, Object>(); 11403928aee4356845252ac6b662d5c72c29903813eJake Slack private final Map<String, String> _propertyMap = new HashMap<String, String>(); 11503928aee4356845252ac6b662d5c72c29903813eJake Slack 11603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11703928aee4356845252ac6b662d5c72c29903813eJake Slack private synchronized static XmlParser initParser() 11803928aee4356845252ac6b662d5c72c29903813eJake Slack { 11903928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser parser = new XmlParser(); 12003928aee4356845252ac6b662d5c72c29903813eJake Slack URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true); 12103928aee4356845252ac6b662d5c72c29903813eJake Slack URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true); 12203928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure.dtd",config76); 12303928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_1_0.dtd",config60); 12403928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_1_1.dtd",config60); 12503928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_1_2.dtd",config60); 12603928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_1_3.dtd",config60); 12703928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_6_0.dtd",config60); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("configure_7_6.dtd",config76); 12903928aee4356845252ac6b662d5c72c29903813eJake Slack 13003928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config76); 13103928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config76); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config76); 13303928aee4356845252ac6b662d5c72c29903813eJake Slack 13403928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config76); 13503928aee4356845252ac6b662d5c72c29903813eJake Slack parser.redirectEntity("-//Jetty//Configure//EN",config76); 13603928aee4356845252ac6b662d5c72c29903813eJake Slack 13703928aee4356845252ac6b662d5c72c29903813eJake Slack return parser; 13803928aee4356845252ac6b662d5c72c29903813eJake Slack } 13903928aee4356845252ac6b662d5c72c29903813eJake Slack 14003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 14103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 14203928aee4356845252ac6b662d5c72c29903813eJake Slack * Reads and parses the XML configuration file. 14303928aee4356845252ac6b662d5c72c29903813eJake Slack * 14403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param configuration the URL of the XML configuration 14503928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws IOException if the configuration could not be read 14603928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws SAXException if the configuration could not be parsed 14703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 14803928aee4356845252ac6b662d5c72c29903813eJake Slack public XmlConfiguration(URL configuration) throws SAXException, IOException 14903928aee4356845252ac6b662d5c72c29903813eJake Slack { 15003928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (__parser) 15103928aee4356845252ac6b662d5c72c29903813eJake Slack { 15203928aee4356845252ac6b662d5c72c29903813eJake Slack _url=configuration; 15303928aee4356845252ac6b662d5c72c29903813eJake Slack setConfig(__parser.parse(configuration.toString())); 15403928aee4356845252ac6b662d5c72c29903813eJake Slack _dtd=__parser.getDTD(); 15503928aee4356845252ac6b662d5c72c29903813eJake Slack } 15603928aee4356845252ac6b662d5c72c29903813eJake Slack } 15703928aee4356845252ac6b662d5c72c29903813eJake Slack 15803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 15903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 16003928aee4356845252ac6b662d5c72c29903813eJake Slack * Reads and parses the XML configuration string. 16103928aee4356845252ac6b662d5c72c29903813eJake Slack * 16203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param configuration String of XML configuration commands excluding the normal XML preamble. 16303928aee4356845252ac6b662d5c72c29903813eJake Slack * The String should start with a "<Configure ....>" element. 16403928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws IOException if the configuration could not be read 16503928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws SAXException if the configuration could not be parsed 16603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 16703928aee4356845252ac6b662d5c72c29903813eJake Slack public XmlConfiguration(String configuration) throws SAXException, IOException 16803928aee4356845252ac6b662d5c72c29903813eJake Slack { 16903928aee4356845252ac6b662d5c72c29903813eJake Slack configuration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Mort Bay Consulting//DTD Configure 1.2//EN\" \"http://jetty.eclipse.org/configure_1_2.dtd\">" 17003928aee4356845252ac6b662d5c72c29903813eJake Slack + configuration; 17103928aee4356845252ac6b662d5c72c29903813eJake Slack InputSource source = new InputSource(new StringReader(configuration)); 17203928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (__parser) 17303928aee4356845252ac6b662d5c72c29903813eJake Slack { 17403928aee4356845252ac6b662d5c72c29903813eJake Slack setConfig( __parser.parse(source)); 17503928aee4356845252ac6b662d5c72c29903813eJake Slack _dtd=__parser.getDTD(); 17603928aee4356845252ac6b662d5c72c29903813eJake Slack } 17703928aee4356845252ac6b662d5c72c29903813eJake Slack } 17803928aee4356845252ac6b662d5c72c29903813eJake Slack 17903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 18103928aee4356845252ac6b662d5c72c29903813eJake Slack * Reads and parses the XML configuration stream. 18203928aee4356845252ac6b662d5c72c29903813eJake Slack * 18303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param configuration An input stream containing a complete configuration file 18403928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws IOException if the configuration could not be read 18503928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws SAXException if the configuration could not be parsed 18603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 18703928aee4356845252ac6b662d5c72c29903813eJake Slack public XmlConfiguration(InputStream configuration) throws SAXException, IOException 18803928aee4356845252ac6b662d5c72c29903813eJake Slack { 18903928aee4356845252ac6b662d5c72c29903813eJake Slack InputSource source = new InputSource(configuration); 19003928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (__parser) 19103928aee4356845252ac6b662d5c72c29903813eJake Slack { 19203928aee4356845252ac6b662d5c72c29903813eJake Slack setConfig(__parser.parse(source)); 19303928aee4356845252ac6b662d5c72c29903813eJake Slack _dtd=__parser.getDTD(); 19403928aee4356845252ac6b662d5c72c29903813eJake Slack } 19503928aee4356845252ac6b662d5c72c29903813eJake Slack } 19603928aee4356845252ac6b662d5c72c29903813eJake Slack 19703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 19803928aee4356845252ac6b662d5c72c29903813eJake Slack private void setConfig(XmlParser.Node config) 19903928aee4356845252ac6b662d5c72c29903813eJake Slack { 20003928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Configure".equals(config.getTag())) 20103928aee4356845252ac6b662d5c72c29903813eJake Slack { 20203928aee4356845252ac6b662d5c72c29903813eJake Slack _processor=new JettyXmlConfiguration(); 20303928aee4356845252ac6b662d5c72c29903813eJake Slack } 20403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (__factoryLoader!=null) 20503928aee4356845252ac6b662d5c72c29903813eJake Slack { 20603928aee4356845252ac6b662d5c72c29903813eJake Slack for ( Object factory : __factoryLoader) 20703928aee4356845252ac6b662d5c72c29903813eJake Slack { 20803928aee4356845252ac6b662d5c72c29903813eJake Slack // use reflection to get 1.6 methods 20903928aee4356845252ac6b662d5c72c29903813eJake Slack Method gcp; 21003928aee4356845252ac6b662d5c72c29903813eJake Slack try 21103928aee4356845252ac6b662d5c72c29903813eJake Slack { 21203928aee4356845252ac6b662d5c72c29903813eJake Slack gcp = factory.getClass().getMethod("getConfigurationProcessor",String.class,String.class); 21303928aee4356845252ac6b662d5c72c29903813eJake Slack _processor = (ConfigurationProcessor) gcp.invoke(factory,_dtd,config.getTag()); 21403928aee4356845252ac6b662d5c72c29903813eJake Slack } 21503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 21603928aee4356845252ac6b662d5c72c29903813eJake Slack { 21703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack } 21903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_processor!=null) 22003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 22103928aee4356845252ac6b662d5c72c29903813eJake Slack } 22203928aee4356845252ac6b662d5c72c29903813eJake Slack 22303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_processor==null) 22403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Unknown configuration type: "+config.getTag()+" in "+this); 22503928aee4356845252ac6b662d5c72c29903813eJake Slack } 22603928aee4356845252ac6b662d5c72c29903813eJake Slack else 22703928aee4356845252ac6b662d5c72c29903813eJake Slack { 22803928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException("Unknown XML tag:"+config.getTag()); 22903928aee4356845252ac6b662d5c72c29903813eJake Slack } 23003928aee4356845252ac6b662d5c72c29903813eJake Slack _processor.init(_url,config,this); 23103928aee4356845252ac6b662d5c72c29903813eJake Slack } 23203928aee4356845252ac6b662d5c72c29903813eJake Slack 23303928aee4356845252ac6b662d5c72c29903813eJake Slack 23403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 23503928aee4356845252ac6b662d5c72c29903813eJake Slack public Map<String, Object> getIdMap() 23603928aee4356845252ac6b662d5c72c29903813eJake Slack { 23703928aee4356845252ac6b662d5c72c29903813eJake Slack return _idMap; 23803928aee4356845252ac6b662d5c72c29903813eJake Slack } 23903928aee4356845252ac6b662d5c72c29903813eJake Slack 24003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 24203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param map the ID map 24303928aee4356845252ac6b662d5c72c29903813eJake Slack * @deprecated use {@link #getIdMap()}.put(...) 24403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 24503928aee4356845252ac6b662d5c72c29903813eJake Slack @Deprecated 24603928aee4356845252ac6b662d5c72c29903813eJake Slack public void setIdMap(Map<String, Object> map) 24703928aee4356845252ac6b662d5c72c29903813eJake Slack { 24803928aee4356845252ac6b662d5c72c29903813eJake Slack _idMap.clear(); 24903928aee4356845252ac6b662d5c72c29903813eJake Slack _idMap.putAll(map); 25003928aee4356845252ac6b662d5c72c29903813eJake Slack } 25103928aee4356845252ac6b662d5c72c29903813eJake Slack 25203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 25303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 25403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param map the properties map 25503928aee4356845252ac6b662d5c72c29903813eJake Slack * @deprecated use {@link #getProperties()}.putAll(...) 25603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 25703928aee4356845252ac6b662d5c72c29903813eJake Slack @Deprecated 25803928aee4356845252ac6b662d5c72c29903813eJake Slack public void setProperties(Map<String, String> map) 25903928aee4356845252ac6b662d5c72c29903813eJake Slack { 26003928aee4356845252ac6b662d5c72c29903813eJake Slack _propertyMap.clear(); 26103928aee4356845252ac6b662d5c72c29903813eJake Slack _propertyMap.putAll(map); 26203928aee4356845252ac6b662d5c72c29903813eJake Slack } 26303928aee4356845252ac6b662d5c72c29903813eJake Slack 26403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 26503928aee4356845252ac6b662d5c72c29903813eJake Slack public Map<String, String> getProperties() 26603928aee4356845252ac6b662d5c72c29903813eJake Slack { 26703928aee4356845252ac6b662d5c72c29903813eJake Slack return _propertyMap; 26803928aee4356845252ac6b662d5c72c29903813eJake Slack } 26903928aee4356845252ac6b662d5c72c29903813eJake Slack 27003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 27103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 27203928aee4356845252ac6b662d5c72c29903813eJake Slack * Applies the XML configuration script to the given object. 27303928aee4356845252ac6b662d5c72c29903813eJake Slack * 27403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param obj The object to be configured, which must be of a type or super type 27503928aee4356845252ac6b662d5c72c29903813eJake Slack * of the class attribute of the <Configure> element. 27603928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception if the configuration fails 27703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the configured object 27803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 27903928aee4356845252ac6b662d5c72c29903813eJake Slack public Object configure(Object obj) throws Exception 28003928aee4356845252ac6b662d5c72c29903813eJake Slack { 28103928aee4356845252ac6b662d5c72c29903813eJake Slack return _processor.configure(obj); 28203928aee4356845252ac6b662d5c72c29903813eJake Slack } 28303928aee4356845252ac6b662d5c72c29903813eJake Slack 28403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 28503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 28603928aee4356845252ac6b662d5c72c29903813eJake Slack * Applies the XML configuration script. 28703928aee4356845252ac6b662d5c72c29903813eJake Slack * If the root element of the configuration has an ID, an object is looked up by ID and its type checked 28803928aee4356845252ac6b662d5c72c29903813eJake Slack * against the root element's type. 28903928aee4356845252ac6b662d5c72c29903813eJake Slack * Otherwise a new object of the type specified by the root element is created. 29003928aee4356845252ac6b662d5c72c29903813eJake Slack * 29103928aee4356845252ac6b662d5c72c29903813eJake Slack * @return The newly created configured object. 29203928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception if the configuration fails 29303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 29403928aee4356845252ac6b662d5c72c29903813eJake Slack public Object configure() throws Exception 29503928aee4356845252ac6b662d5c72c29903813eJake Slack { 29603928aee4356845252ac6b662d5c72c29903813eJake Slack return _processor.configure(); 29703928aee4356845252ac6b662d5c72c29903813eJake Slack } 29803928aee4356845252ac6b662d5c72c29903813eJake Slack 29903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 30003928aee4356845252ac6b662d5c72c29903813eJake Slack /** Initialize a new Object defaults. 30103928aee4356845252ac6b662d5c72c29903813eJake Slack * <p>This method must be called by any {@link ConfigurationProcessor} when it 30203928aee4356845252ac6b662d5c72c29903813eJake Slack * creates a new instance of an object before configuring it, so that a derived 30303928aee4356845252ac6b662d5c72c29903813eJake Slack * XmlConfiguration class may inject default values. 30403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param object 30503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 30603928aee4356845252ac6b662d5c72c29903813eJake Slack public void initializeDefaults(Object object) 30703928aee4356845252ac6b662d5c72c29903813eJake Slack { 30803928aee4356845252ac6b662d5c72c29903813eJake Slack } 30903928aee4356845252ac6b662d5c72c29903813eJake Slack 31003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 31103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 31203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 31303928aee4356845252ac6b662d5c72c29903813eJake Slack private static class JettyXmlConfiguration implements ConfigurationProcessor 31403928aee4356845252ac6b662d5c72c29903813eJake Slack { 31503928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node _root; 31603928aee4356845252ac6b662d5c72c29903813eJake Slack XmlConfiguration _configuration; 31703928aee4356845252ac6b662d5c72c29903813eJake Slack 31803928aee4356845252ac6b662d5c72c29903813eJake Slack public void init(URL url, XmlParser.Node root, XmlConfiguration configuration) 31903928aee4356845252ac6b662d5c72c29903813eJake Slack { 32003928aee4356845252ac6b662d5c72c29903813eJake Slack _root=root; 32103928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration=configuration; 32203928aee4356845252ac6b662d5c72c29903813eJake Slack } 32303928aee4356845252ac6b662d5c72c29903813eJake Slack 32403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 32503928aee4356845252ac6b662d5c72c29903813eJake Slack public Object configure(Object obj) throws Exception 32603928aee4356845252ac6b662d5c72c29903813eJake Slack { 32703928aee4356845252ac6b662d5c72c29903813eJake Slack // Check the class of the object 32803928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(_root); 32903928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass != null && !oClass.isInstance(obj)) 33003928aee4356845252ac6b662d5c72c29903813eJake Slack { 33103928aee4356845252ac6b662d5c72c29903813eJake Slack String loaders = (oClass.getClassLoader()==obj.getClass().getClassLoader())?"":"Object Class and type Class are from different loaders."; 33203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException("Object of class '"+obj.getClass().getCanonicalName()+"' is not of type '" + oClass.getCanonicalName()+"'. "+loaders); 33303928aee4356845252ac6b662d5c72c29903813eJake Slack } 33403928aee4356845252ac6b662d5c72c29903813eJake Slack configure(obj,_root,0); 33503928aee4356845252ac6b662d5c72c29903813eJake Slack return obj; 33603928aee4356845252ac6b662d5c72c29903813eJake Slack } 33703928aee4356845252ac6b662d5c72c29903813eJake Slack 33803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 33903928aee4356845252ac6b662d5c72c29903813eJake Slack public Object configure() throws Exception 34003928aee4356845252ac6b662d5c72c29903813eJake Slack { 34103928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(_root); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack 34303928aee4356845252ac6b662d5c72c29903813eJake Slack String id = _root.getAttribute("id"); 34403928aee4356845252ac6b662d5c72c29903813eJake Slack Object obj = id == null?null:_configuration.getIdMap().get(id); 34503928aee4356845252ac6b662d5c72c29903813eJake Slack 34603928aee4356845252ac6b662d5c72c29903813eJake Slack if (obj == null && oClass != null) 34703928aee4356845252ac6b662d5c72c29903813eJake Slack { 34803928aee4356845252ac6b662d5c72c29903813eJake Slack obj = oClass.newInstance(); 34903928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.initializeDefaults(obj); 35003928aee4356845252ac6b662d5c72c29903813eJake Slack } 35103928aee4356845252ac6b662d5c72c29903813eJake Slack 35203928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass != null && !oClass.isInstance(obj)) 35303928aee4356845252ac6b662d5c72c29903813eJake Slack throw new ClassCastException(oClass.toString()); 35403928aee4356845252ac6b662d5c72c29903813eJake Slack 35503928aee4356845252ac6b662d5c72c29903813eJake Slack configure(obj,_root,0); 35603928aee4356845252ac6b662d5c72c29903813eJake Slack return obj; 35703928aee4356845252ac6b662d5c72c29903813eJake Slack } 35803928aee4356845252ac6b662d5c72c29903813eJake Slack 35903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 36003928aee4356845252ac6b662d5c72c29903813eJake Slack private static Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException 36103928aee4356845252ac6b662d5c72c29903813eJake Slack { 36203928aee4356845252ac6b662d5c72c29903813eJake Slack String className = node.getAttribute("class"); 36303928aee4356845252ac6b662d5c72c29903813eJake Slack if (className == null) 36403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 36503928aee4356845252ac6b662d5c72c29903813eJake Slack 36603928aee4356845252ac6b662d5c72c29903813eJake Slack return Loader.loadClass(XmlConfiguration.class,className,true); 36703928aee4356845252ac6b662d5c72c29903813eJake Slack } 36803928aee4356845252ac6b662d5c72c29903813eJake Slack 36903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 37003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 37103928aee4356845252ac6b662d5c72c29903813eJake Slack * Recursive configuration routine. 37203928aee4356845252ac6b662d5c72c29903813eJake Slack * This method applies the nested Set, Put, Call, etc. elements to the given object. 37303928aee4356845252ac6b662d5c72c29903813eJake Slack * 37403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param obj the object to configure 37503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param cfg the XML nodes of the configuration 37603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param i the index of the XML nodes 37703928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception if the configuration fails 37803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 37903928aee4356845252ac6b662d5c72c29903813eJake Slack public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception 38003928aee4356845252ac6b662d5c72c29903813eJake Slack { 38103928aee4356845252ac6b662d5c72c29903813eJake Slack String id = cfg.getAttribute("id"); 38203928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 38303928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,obj); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack 38503928aee4356845252ac6b662d5c72c29903813eJake Slack for (; i < cfg.size(); i++) 38603928aee4356845252ac6b662d5c72c29903813eJake Slack { 38703928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = cfg.get(i); 38803928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 38903928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 39003928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node node = (XmlParser.Node)o; 39103928aee4356845252ac6b662d5c72c29903813eJake Slack 39203928aee4356845252ac6b662d5c72c29903813eJake Slack try 39303928aee4356845252ac6b662d5c72c29903813eJake Slack { 39403928aee4356845252ac6b662d5c72c29903813eJake Slack String tag = node.getTag(); 39503928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Set".equals(tag)) 39603928aee4356845252ac6b662d5c72c29903813eJake Slack set(obj,node); 39703928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Put".equals(tag)) 39803928aee4356845252ac6b662d5c72c29903813eJake Slack put(obj,node); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Call".equals(tag)) 40003928aee4356845252ac6b662d5c72c29903813eJake Slack call(obj,node); 40103928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Get".equals(tag)) 40203928aee4356845252ac6b662d5c72c29903813eJake Slack get(obj,node); 40303928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("New".equals(tag)) 40403928aee4356845252ac6b662d5c72c29903813eJake Slack newObj(obj,node); 40503928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Array".equals(tag)) 40603928aee4356845252ac6b662d5c72c29903813eJake Slack newArray(obj,node); 40703928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Ref".equals(tag)) 40803928aee4356845252ac6b662d5c72c29903813eJake Slack refObj(obj,node); 40903928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("Property".equals(tag)) 41003928aee4356845252ac6b662d5c72c29903813eJake Slack propertyObj(node); 41103928aee4356845252ac6b662d5c72c29903813eJake Slack else 41203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Unknown tag: " + tag); 41303928aee4356845252ac6b662d5c72c29903813eJake Slack } 41403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 41503928aee4356845252ac6b662d5c72c29903813eJake Slack { 41603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Config error at " + node,e.toString()); 41703928aee4356845252ac6b662d5c72c29903813eJake Slack throw e; 41803928aee4356845252ac6b662d5c72c29903813eJake Slack } 41903928aee4356845252ac6b662d5c72c29903813eJake Slack } 42003928aee4356845252ac6b662d5c72c29903813eJake Slack } 42103928aee4356845252ac6b662d5c72c29903813eJake Slack 42203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 42303928aee4356845252ac6b662d5c72c29903813eJake Slack /* 42403928aee4356845252ac6b662d5c72c29903813eJake Slack * Call a set method. This method makes a best effort to find a matching set method. The type of the value is used to find a suitable set method by 1. 42503928aee4356845252ac6b662d5c72c29903813eJake Slack * Trying for a trivial type match. 2. Looking for a native type match. 3. Trying all correctly named methods for an auto conversion. 4. Attempting to 42603928aee4356845252ac6b662d5c72c29903813eJake Slack * construct a suitable value from original value. @param obj 42703928aee4356845252ac6b662d5c72c29903813eJake Slack * 42803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param node 42903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 43003928aee4356845252ac6b662d5c72c29903813eJake Slack private void set(Object obj, XmlParser.Node node) throws Exception 43103928aee4356845252ac6b662d5c72c29903813eJake Slack { 43203928aee4356845252ac6b662d5c72c29903813eJake Slack String attr = node.getAttribute("name"); 43303928aee4356845252ac6b662d5c72c29903813eJake Slack String name = "set" + attr.substring(0,1).toUpperCase(Locale.ENGLISH) + attr.substring(1); 43403928aee4356845252ac6b662d5c72c29903813eJake Slack Object value = value(obj,node); 43503928aee4356845252ac6b662d5c72c29903813eJake Slack Object[] arg = 43603928aee4356845252ac6b662d5c72c29903813eJake Slack { value }; 43703928aee4356845252ac6b662d5c72c29903813eJake Slack 43803928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(node); 43903928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass != null) 44003928aee4356845252ac6b662d5c72c29903813eJake Slack obj = null; 44103928aee4356845252ac6b662d5c72c29903813eJake Slack else 44203928aee4356845252ac6b662d5c72c29903813eJake Slack oClass = obj.getClass(); 44303928aee4356845252ac6b662d5c72c29903813eJake Slack 44403928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?>[] vClass = 44503928aee4356845252ac6b662d5c72c29903813eJake Slack { Object.class }; 44603928aee4356845252ac6b662d5c72c29903813eJake Slack if (value != null) 44703928aee4356845252ac6b662d5c72c29903813eJake Slack vClass[0] = value.getClass(); 44803928aee4356845252ac6b662d5c72c29903813eJake Slack 44903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 45003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("XML " + (obj != null?obj.toString():oClass.getName()) + "." + name + "(" + value + ")"); 45103928aee4356845252ac6b662d5c72c29903813eJake Slack 45203928aee4356845252ac6b662d5c72c29903813eJake Slack // Try for trivial match 45303928aee4356845252ac6b662d5c72c29903813eJake Slack try 45403928aee4356845252ac6b662d5c72c29903813eJake Slack { 45503928aee4356845252ac6b662d5c72c29903813eJake Slack Method set = oClass.getMethod(name,vClass); 45603928aee4356845252ac6b662d5c72c29903813eJake Slack set.invoke(obj,arg); 45703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 45803928aee4356845252ac6b662d5c72c29903813eJake Slack } 45903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalArgumentException e) 46003928aee4356845252ac6b662d5c72c29903813eJake Slack { 46103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 46203928aee4356845252ac6b662d5c72c29903813eJake Slack } 46303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 46403928aee4356845252ac6b662d5c72c29903813eJake Slack { 46503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 46603928aee4356845252ac6b662d5c72c29903813eJake Slack } 46703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException e) 46803928aee4356845252ac6b662d5c72c29903813eJake Slack { 46903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 47003928aee4356845252ac6b662d5c72c29903813eJake Slack } 47103928aee4356845252ac6b662d5c72c29903813eJake Slack 47203928aee4356845252ac6b662d5c72c29903813eJake Slack // Try for native match 47303928aee4356845252ac6b662d5c72c29903813eJake Slack try 47403928aee4356845252ac6b662d5c72c29903813eJake Slack { 47503928aee4356845252ac6b662d5c72c29903813eJake Slack Field type = vClass[0].getField("TYPE"); 47603928aee4356845252ac6b662d5c72c29903813eJake Slack vClass[0] = (Class<?>)type.get(null); 47703928aee4356845252ac6b662d5c72c29903813eJake Slack Method set = oClass.getMethod(name,vClass); 47803928aee4356845252ac6b662d5c72c29903813eJake Slack set.invoke(obj,arg); 47903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 48003928aee4356845252ac6b662d5c72c29903813eJake Slack } 48103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchFieldException e) 48203928aee4356845252ac6b662d5c72c29903813eJake Slack { 48303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 48403928aee4356845252ac6b662d5c72c29903813eJake Slack } 48503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalArgumentException e) 48603928aee4356845252ac6b662d5c72c29903813eJake Slack { 48703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 48803928aee4356845252ac6b662d5c72c29903813eJake Slack } 48903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 49003928aee4356845252ac6b662d5c72c29903813eJake Slack { 49103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 49203928aee4356845252ac6b662d5c72c29903813eJake Slack } 49303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException e) 49403928aee4356845252ac6b662d5c72c29903813eJake Slack { 49503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 49603928aee4356845252ac6b662d5c72c29903813eJake Slack } 49703928aee4356845252ac6b662d5c72c29903813eJake Slack 49803928aee4356845252ac6b662d5c72c29903813eJake Slack // Try a field 49903928aee4356845252ac6b662d5c72c29903813eJake Slack try 50003928aee4356845252ac6b662d5c72c29903813eJake Slack { 50103928aee4356845252ac6b662d5c72c29903813eJake Slack Field field = oClass.getField(attr); 50203928aee4356845252ac6b662d5c72c29903813eJake Slack if (Modifier.isPublic(field.getModifiers())) 50303928aee4356845252ac6b662d5c72c29903813eJake Slack { 50403928aee4356845252ac6b662d5c72c29903813eJake Slack field.set(obj,value); 50503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 50603928aee4356845252ac6b662d5c72c29903813eJake Slack } 50703928aee4356845252ac6b662d5c72c29903813eJake Slack } 50803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchFieldException e) 50903928aee4356845252ac6b662d5c72c29903813eJake Slack { 51003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 51103928aee4356845252ac6b662d5c72c29903813eJake Slack } 51203928aee4356845252ac6b662d5c72c29903813eJake Slack 51303928aee4356845252ac6b662d5c72c29903813eJake Slack // Search for a match by trying all the set methods 51403928aee4356845252ac6b662d5c72c29903813eJake Slack Method[] sets = oClass.getMethods(); 51503928aee4356845252ac6b662d5c72c29903813eJake Slack Method set = null; 51603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int s = 0; sets != null && s < sets.length; s++) 51703928aee4356845252ac6b662d5c72c29903813eJake Slack { 51803928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?>[] paramTypes = sets[s].getParameterTypes(); 51903928aee4356845252ac6b662d5c72c29903813eJake Slack if (name.equals(sets[s].getName()) && paramTypes.length == 1) 52003928aee4356845252ac6b662d5c72c29903813eJake Slack { 52103928aee4356845252ac6b662d5c72c29903813eJake Slack 52203928aee4356845252ac6b662d5c72c29903813eJake Slack // lets try it 52303928aee4356845252ac6b662d5c72c29903813eJake Slack try 52403928aee4356845252ac6b662d5c72c29903813eJake Slack { 52503928aee4356845252ac6b662d5c72c29903813eJake Slack set = sets[s]; 52603928aee4356845252ac6b662d5c72c29903813eJake Slack sets[s].invoke(obj,arg); 52703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 52803928aee4356845252ac6b662d5c72c29903813eJake Slack } 52903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalArgumentException e) 53003928aee4356845252ac6b662d5c72c29903813eJake Slack { 53103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 53203928aee4356845252ac6b662d5c72c29903813eJake Slack } 53303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 53403928aee4356845252ac6b662d5c72c29903813eJake Slack { 53503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 53603928aee4356845252ac6b662d5c72c29903813eJake Slack } 53703928aee4356845252ac6b662d5c72c29903813eJake Slack 53803928aee4356845252ac6b662d5c72c29903813eJake Slack try 53903928aee4356845252ac6b662d5c72c29903813eJake Slack { 54003928aee4356845252ac6b662d5c72c29903813eJake Slack for (Class<?> c : __supportedCollections) 54103928aee4356845252ac6b662d5c72c29903813eJake Slack if (paramTypes[0].isAssignableFrom(c)) 54203928aee4356845252ac6b662d5c72c29903813eJake Slack { 54303928aee4356845252ac6b662d5c72c29903813eJake Slack sets[s].invoke(obj,convertArrayToCollection(value,c)); 54403928aee4356845252ac6b662d5c72c29903813eJake Slack return; 54503928aee4356845252ac6b662d5c72c29903813eJake Slack } 54603928aee4356845252ac6b662d5c72c29903813eJake Slack } 54703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 54803928aee4356845252ac6b662d5c72c29903813eJake Slack { 54903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 55003928aee4356845252ac6b662d5c72c29903813eJake Slack } 55103928aee4356845252ac6b662d5c72c29903813eJake Slack } 55203928aee4356845252ac6b662d5c72c29903813eJake Slack } 55303928aee4356845252ac6b662d5c72c29903813eJake Slack 55403928aee4356845252ac6b662d5c72c29903813eJake Slack // Try converting the arg to the last set found. 55503928aee4356845252ac6b662d5c72c29903813eJake Slack if (set != null) 55603928aee4356845252ac6b662d5c72c29903813eJake Slack { 55703928aee4356845252ac6b662d5c72c29903813eJake Slack try 55803928aee4356845252ac6b662d5c72c29903813eJake Slack { 55903928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> sClass = set.getParameterTypes()[0]; 56003928aee4356845252ac6b662d5c72c29903813eJake Slack if (sClass.isPrimitive()) 56103928aee4356845252ac6b662d5c72c29903813eJake Slack { 56203928aee4356845252ac6b662d5c72c29903813eJake Slack for (int t = 0; t < __primitives.length; t++) 56303928aee4356845252ac6b662d5c72c29903813eJake Slack { 56403928aee4356845252ac6b662d5c72c29903813eJake Slack if (sClass.equals(__primitives[t])) 56503928aee4356845252ac6b662d5c72c29903813eJake Slack { 56603928aee4356845252ac6b662d5c72c29903813eJake Slack sClass = __primitiveHolders[t]; 56703928aee4356845252ac6b662d5c72c29903813eJake Slack break; 56803928aee4356845252ac6b662d5c72c29903813eJake Slack } 56903928aee4356845252ac6b662d5c72c29903813eJake Slack } 57003928aee4356845252ac6b662d5c72c29903813eJake Slack } 57103928aee4356845252ac6b662d5c72c29903813eJake Slack Constructor<?> cons = sClass.getConstructor(vClass); 57203928aee4356845252ac6b662d5c72c29903813eJake Slack arg[0] = cons.newInstance(arg); 57303928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.initializeDefaults(arg[0]); 57403928aee4356845252ac6b662d5c72c29903813eJake Slack set.invoke(obj,arg); 57503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 57603928aee4356845252ac6b662d5c72c29903813eJake Slack } 57703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException e) 57803928aee4356845252ac6b662d5c72c29903813eJake Slack { 57903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 58003928aee4356845252ac6b662d5c72c29903813eJake Slack } 58103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 58203928aee4356845252ac6b662d5c72c29903813eJake Slack { 58303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 58403928aee4356845252ac6b662d5c72c29903813eJake Slack } 58503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (InstantiationException e) 58603928aee4356845252ac6b662d5c72c29903813eJake Slack { 58703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 58803928aee4356845252ac6b662d5c72c29903813eJake Slack } 58903928aee4356845252ac6b662d5c72c29903813eJake Slack } 59003928aee4356845252ac6b662d5c72c29903813eJake Slack 59103928aee4356845252ac6b662d5c72c29903813eJake Slack // No Joy 59203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new NoSuchMethodException(oClass + "." + name + "(" + vClass[0] + ")"); 59303928aee4356845252ac6b662d5c72c29903813eJake Slack } 59403928aee4356845252ac6b662d5c72c29903813eJake Slack 59503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 59603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param array the array to convert 59703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param collectionType the desired collection type 59803928aee4356845252ac6b662d5c72c29903813eJake Slack * @return a collection of the desired type if the array can be converted 59903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 60003928aee4356845252ac6b662d5c72c29903813eJake Slack private static Collection<?> convertArrayToCollection(Object array, Class<?> collectionType) 60103928aee4356845252ac6b662d5c72c29903813eJake Slack { 60203928aee4356845252ac6b662d5c72c29903813eJake Slack Collection<?> collection = null; 60303928aee4356845252ac6b662d5c72c29903813eJake Slack if (array.getClass().isArray()) 60403928aee4356845252ac6b662d5c72c29903813eJake Slack { 60503928aee4356845252ac6b662d5c72c29903813eJake Slack if (collectionType.isAssignableFrom(ArrayList.class)) 60603928aee4356845252ac6b662d5c72c29903813eJake Slack collection = convertArrayToArrayList(array); 60703928aee4356845252ac6b662d5c72c29903813eJake Slack else if (collectionType.isAssignableFrom(HashSet.class)) 60803928aee4356845252ac6b662d5c72c29903813eJake Slack collection = new HashSet<Object>(convertArrayToArrayList(array)); 60903928aee4356845252ac6b662d5c72c29903813eJake Slack else if (collectionType.isAssignableFrom(ArrayQueue.class)) 61003928aee4356845252ac6b662d5c72c29903813eJake Slack { 61103928aee4356845252ac6b662d5c72c29903813eJake Slack ArrayQueue<Object> q= new ArrayQueue<Object>(); 61203928aee4356845252ac6b662d5c72c29903813eJake Slack q.addAll(convertArrayToArrayList(array)); 61303928aee4356845252ac6b662d5c72c29903813eJake Slack collection=q; 61403928aee4356845252ac6b662d5c72c29903813eJake Slack } 61503928aee4356845252ac6b662d5c72c29903813eJake Slack } 61603928aee4356845252ac6b662d5c72c29903813eJake Slack if (collection==null) 61703928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException("Can't convert \"" + array.getClass() + "\" to " + collectionType); 61803928aee4356845252ac6b662d5c72c29903813eJake Slack return collection; 61903928aee4356845252ac6b662d5c72c29903813eJake Slack } 62003928aee4356845252ac6b662d5c72c29903813eJake Slack 62103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 62203928aee4356845252ac6b662d5c72c29903813eJake Slack private static ArrayList<Object> convertArrayToArrayList(Object array) 62303928aee4356845252ac6b662d5c72c29903813eJake Slack { 62403928aee4356845252ac6b662d5c72c29903813eJake Slack int length = Array.getLength(array); 62503928aee4356845252ac6b662d5c72c29903813eJake Slack ArrayList<Object> list = new ArrayList<Object>(length); 62603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < length; i++) 62703928aee4356845252ac6b662d5c72c29903813eJake Slack list.add(Array.get(array,i)); 62803928aee4356845252ac6b662d5c72c29903813eJake Slack return list; 62903928aee4356845252ac6b662d5c72c29903813eJake Slack } 63003928aee4356845252ac6b662d5c72c29903813eJake Slack 63103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 63203928aee4356845252ac6b662d5c72c29903813eJake Slack /* 63303928aee4356845252ac6b662d5c72c29903813eJake Slack * Call a put method. 63403928aee4356845252ac6b662d5c72c29903813eJake Slack * 63503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param obj @param node 63603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 63703928aee4356845252ac6b662d5c72c29903813eJake Slack private void put(Object obj, XmlParser.Node node) throws Exception 63803928aee4356845252ac6b662d5c72c29903813eJake Slack { 63903928aee4356845252ac6b662d5c72c29903813eJake Slack if (!(obj instanceof Map)) 64003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException("Object for put is not a Map: " + obj); 64103928aee4356845252ac6b662d5c72c29903813eJake Slack @SuppressWarnings("unchecked") 64203928aee4356845252ac6b662d5c72c29903813eJake Slack Map<Object, Object> map = (Map<Object, Object>)obj; 64303928aee4356845252ac6b662d5c72c29903813eJake Slack 64403928aee4356845252ac6b662d5c72c29903813eJake Slack String name = node.getAttribute("name"); 64503928aee4356845252ac6b662d5c72c29903813eJake Slack Object value = value(obj,node); 64603928aee4356845252ac6b662d5c72c29903813eJake Slack map.put(name,value); 64703928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 64803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("XML " + obj + ".put(" + name + "," + value + ")"); 64903928aee4356845252ac6b662d5c72c29903813eJake Slack } 65003928aee4356845252ac6b662d5c72c29903813eJake Slack 65103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 65203928aee4356845252ac6b662d5c72c29903813eJake Slack /* 65303928aee4356845252ac6b662d5c72c29903813eJake Slack * Call a get method. Any object returned from the call is passed to the configure method to consume the remaining elements. @param obj @param node 65403928aee4356845252ac6b662d5c72c29903813eJake Slack * 65503928aee4356845252ac6b662d5c72c29903813eJake Slack * @return @exception Exception 65603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 65703928aee4356845252ac6b662d5c72c29903813eJake Slack private Object get(Object obj, XmlParser.Node node) throws Exception 65803928aee4356845252ac6b662d5c72c29903813eJake Slack { 65903928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(node); 66003928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass != null) 66103928aee4356845252ac6b662d5c72c29903813eJake Slack obj = null; 66203928aee4356845252ac6b662d5c72c29903813eJake Slack else 66303928aee4356845252ac6b662d5c72c29903813eJake Slack oClass = obj.getClass(); 66403928aee4356845252ac6b662d5c72c29903813eJake Slack 66503928aee4356845252ac6b662d5c72c29903813eJake Slack String name = node.getAttribute("name"); 66603928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 66703928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 66803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("XML get " + name); 66903928aee4356845252ac6b662d5c72c29903813eJake Slack 67003928aee4356845252ac6b662d5c72c29903813eJake Slack try 67103928aee4356845252ac6b662d5c72c29903813eJake Slack { 67203928aee4356845252ac6b662d5c72c29903813eJake Slack // try calling a getXxx method. 67303928aee4356845252ac6b662d5c72c29903813eJake Slack Method method = oClass.getMethod("get" + name.substring(0,1).toUpperCase(Locale.ENGLISH) + name.substring(1),(java.lang.Class[])null); 67403928aee4356845252ac6b662d5c72c29903813eJake Slack obj = method.invoke(obj,(java.lang.Object[])null); 67503928aee4356845252ac6b662d5c72c29903813eJake Slack configure(obj,node,0); 67603928aee4356845252ac6b662d5c72c29903813eJake Slack } 67703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException nsme) 67803928aee4356845252ac6b662d5c72c29903813eJake Slack { 67903928aee4356845252ac6b662d5c72c29903813eJake Slack try 68003928aee4356845252ac6b662d5c72c29903813eJake Slack { 68103928aee4356845252ac6b662d5c72c29903813eJake Slack Field field = oClass.getField(name); 68203928aee4356845252ac6b662d5c72c29903813eJake Slack obj = field.get(obj); 68303928aee4356845252ac6b662d5c72c29903813eJake Slack configure(obj,node,0); 68403928aee4356845252ac6b662d5c72c29903813eJake Slack } 68503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchFieldException nsfe) 68603928aee4356845252ac6b662d5c72c29903813eJake Slack { 68703928aee4356845252ac6b662d5c72c29903813eJake Slack throw nsme; 68803928aee4356845252ac6b662d5c72c29903813eJake Slack } 68903928aee4356845252ac6b662d5c72c29903813eJake Slack } 69003928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 69103928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,obj); 69203928aee4356845252ac6b662d5c72c29903813eJake Slack return obj; 69303928aee4356845252ac6b662d5c72c29903813eJake Slack } 69403928aee4356845252ac6b662d5c72c29903813eJake Slack 69503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 69603928aee4356845252ac6b662d5c72c29903813eJake Slack /* 69703928aee4356845252ac6b662d5c72c29903813eJake Slack * Call a method. A method is selected by trying all methods with matching names and number of arguments. Any object returned from the call is passed to 69803928aee4356845252ac6b662d5c72c29903813eJake Slack * the configure method to consume the remaining elements. Note that if this is a static call we consider only methods declared directly in the given 69903928aee4356845252ac6b662d5c72c29903813eJake Slack * class. i.e. we ignore any static methods in superclasses. @param obj 70003928aee4356845252ac6b662d5c72c29903813eJake Slack * 70103928aee4356845252ac6b662d5c72c29903813eJake Slack * @param node @return @exception Exception 70203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 70303928aee4356845252ac6b662d5c72c29903813eJake Slack private Object call(Object obj, XmlParser.Node node) throws Exception 70403928aee4356845252ac6b662d5c72c29903813eJake Slack { 70503928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 70603928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(node); 70703928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass != null) 70803928aee4356845252ac6b662d5c72c29903813eJake Slack obj = null; 70903928aee4356845252ac6b662d5c72c29903813eJake Slack else if (obj != null) 71003928aee4356845252ac6b662d5c72c29903813eJake Slack oClass = obj.getClass(); 71103928aee4356845252ac6b662d5c72c29903813eJake Slack if (oClass == null) 71203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalArgumentException(node.toString()); 71303928aee4356845252ac6b662d5c72c29903813eJake Slack 71403928aee4356845252ac6b662d5c72c29903813eJake Slack int size = 0; 71503928aee4356845252ac6b662d5c72c29903813eJake Slack int argi = node.size(); 71603928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < node.size(); i++) 71703928aee4356845252ac6b662d5c72c29903813eJake Slack { 71803928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = node.get(i); 71903928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 72003928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 72103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!((XmlParser.Node)o).getTag().equals("Arg")) 72203928aee4356845252ac6b662d5c72c29903813eJake Slack { 72303928aee4356845252ac6b662d5c72c29903813eJake Slack argi = i; 72403928aee4356845252ac6b662d5c72c29903813eJake Slack break; 72503928aee4356845252ac6b662d5c72c29903813eJake Slack } 72603928aee4356845252ac6b662d5c72c29903813eJake Slack size++; 72703928aee4356845252ac6b662d5c72c29903813eJake Slack } 72803928aee4356845252ac6b662d5c72c29903813eJake Slack 72903928aee4356845252ac6b662d5c72c29903813eJake Slack Object[] arg = new Object[size]; 73003928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0, j = 0; j < size; i++) 73103928aee4356845252ac6b662d5c72c29903813eJake Slack { 73203928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = node.get(i); 73303928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 73403928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 73503928aee4356845252ac6b662d5c72c29903813eJake Slack arg[j++] = value(obj,(XmlParser.Node)o); 73603928aee4356845252ac6b662d5c72c29903813eJake Slack } 73703928aee4356845252ac6b662d5c72c29903813eJake Slack 73803928aee4356845252ac6b662d5c72c29903813eJake Slack String method = node.getAttribute("name"); 73903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 74003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("XML call " + method); 74103928aee4356845252ac6b662d5c72c29903813eJake Slack 74203928aee4356845252ac6b662d5c72c29903813eJake Slack try 74303928aee4356845252ac6b662d5c72c29903813eJake Slack { 74403928aee4356845252ac6b662d5c72c29903813eJake Slack Object n= TypeUtil.call(oClass,method,obj,arg); 74503928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 74603928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,n); 74703928aee4356845252ac6b662d5c72c29903813eJake Slack configure(n,node,argi); 74803928aee4356845252ac6b662d5c72c29903813eJake Slack return n; 74903928aee4356845252ac6b662d5c72c29903813eJake Slack } 75003928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoSuchMethodException e) 75103928aee4356845252ac6b662d5c72c29903813eJake Slack { 75203928aee4356845252ac6b662d5c72c29903813eJake Slack IllegalStateException ise = new IllegalStateException("No Method: " + node + " on " + oClass); 75303928aee4356845252ac6b662d5c72c29903813eJake Slack ise.initCause(e); 75403928aee4356845252ac6b662d5c72c29903813eJake Slack throw ise; 75503928aee4356845252ac6b662d5c72c29903813eJake Slack } 75603928aee4356845252ac6b662d5c72c29903813eJake Slack 75703928aee4356845252ac6b662d5c72c29903813eJake Slack } 75803928aee4356845252ac6b662d5c72c29903813eJake Slack 75903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 76003928aee4356845252ac6b662d5c72c29903813eJake Slack /* 76103928aee4356845252ac6b662d5c72c29903813eJake Slack * Create a new value object. 76203928aee4356845252ac6b662d5c72c29903813eJake Slack * 76303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param obj @param node @return @exception Exception 76403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 76503928aee4356845252ac6b662d5c72c29903813eJake Slack private Object newObj(Object obj, XmlParser.Node node) throws Exception 76603928aee4356845252ac6b662d5c72c29903813eJake Slack { 76703928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> oClass = nodeClass(node); 76803928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 76903928aee4356845252ac6b662d5c72c29903813eJake Slack int size = 0; 77003928aee4356845252ac6b662d5c72c29903813eJake Slack int argi = node.size(); 77103928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < node.size(); i++) 77203928aee4356845252ac6b662d5c72c29903813eJake Slack { 77303928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = node.get(i); 77403928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 77503928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 77603928aee4356845252ac6b662d5c72c29903813eJake Slack if (!((XmlParser.Node)o).getTag().equals("Arg")) 77703928aee4356845252ac6b662d5c72c29903813eJake Slack { 77803928aee4356845252ac6b662d5c72c29903813eJake Slack argi = i; 77903928aee4356845252ac6b662d5c72c29903813eJake Slack break; 78003928aee4356845252ac6b662d5c72c29903813eJake Slack } 78103928aee4356845252ac6b662d5c72c29903813eJake Slack size++; 78203928aee4356845252ac6b662d5c72c29903813eJake Slack } 78303928aee4356845252ac6b662d5c72c29903813eJake Slack 78403928aee4356845252ac6b662d5c72c29903813eJake Slack Object[] arg = new Object[size]; 78503928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0, j = 0; j < size; i++) 78603928aee4356845252ac6b662d5c72c29903813eJake Slack { 78703928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = node.get(i); 78803928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 78903928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 79003928aee4356845252ac6b662d5c72c29903813eJake Slack arg[j++] = value(obj,(XmlParser.Node)o); 79103928aee4356845252ac6b662d5c72c29903813eJake Slack } 79203928aee4356845252ac6b662d5c72c29903813eJake Slack 79303928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 79403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("XML new " + oClass); 79503928aee4356845252ac6b662d5c72c29903813eJake Slack 79603928aee4356845252ac6b662d5c72c29903813eJake Slack // Lets just try all constructors for now 79703928aee4356845252ac6b662d5c72c29903813eJake Slack Constructor<?>[] constructors = oClass.getConstructors(); 79803928aee4356845252ac6b662d5c72c29903813eJake Slack for (int c = 0; constructors != null && c < constructors.length; c++) 79903928aee4356845252ac6b662d5c72c29903813eJake Slack { 80003928aee4356845252ac6b662d5c72c29903813eJake Slack if (constructors[c].getParameterTypes().length != size) 80103928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 80203928aee4356845252ac6b662d5c72c29903813eJake Slack 80303928aee4356845252ac6b662d5c72c29903813eJake Slack Object n = null; 80403928aee4356845252ac6b662d5c72c29903813eJake Slack boolean called = false; 80503928aee4356845252ac6b662d5c72c29903813eJake Slack try 80603928aee4356845252ac6b662d5c72c29903813eJake Slack { 80703928aee4356845252ac6b662d5c72c29903813eJake Slack n = constructors[c].newInstance(arg); 80803928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.initializeDefaults(n); 80903928aee4356845252ac6b662d5c72c29903813eJake Slack called = true; 81003928aee4356845252ac6b662d5c72c29903813eJake Slack } 81103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalAccessException e) 81203928aee4356845252ac6b662d5c72c29903813eJake Slack { 81303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 81403928aee4356845252ac6b662d5c72c29903813eJake Slack } 81503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (InstantiationException e) 81603928aee4356845252ac6b662d5c72c29903813eJake Slack { 81703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 81803928aee4356845252ac6b662d5c72c29903813eJake Slack } 81903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IllegalArgumentException e) 82003928aee4356845252ac6b662d5c72c29903813eJake Slack { 82103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 82203928aee4356845252ac6b662d5c72c29903813eJake Slack } 82303928aee4356845252ac6b662d5c72c29903813eJake Slack if (called) 82403928aee4356845252ac6b662d5c72c29903813eJake Slack { 82503928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 82603928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,n); 82703928aee4356845252ac6b662d5c72c29903813eJake Slack configure(n,node,argi); 82803928aee4356845252ac6b662d5c72c29903813eJake Slack return n; 82903928aee4356845252ac6b662d5c72c29903813eJake Slack } 83003928aee4356845252ac6b662d5c72c29903813eJake Slack } 83103928aee4356845252ac6b662d5c72c29903813eJake Slack 83203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("No Constructor: " + node + " on " + obj); 83303928aee4356845252ac6b662d5c72c29903813eJake Slack } 83403928aee4356845252ac6b662d5c72c29903813eJake Slack 83503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 83603928aee4356845252ac6b662d5c72c29903813eJake Slack /* 83703928aee4356845252ac6b662d5c72c29903813eJake Slack * Reference an id value object. 83803928aee4356845252ac6b662d5c72c29903813eJake Slack * 83903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param obj @param node @return @exception NoSuchMethodException @exception ClassNotFoundException @exception InvocationTargetException 84003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 84103928aee4356845252ac6b662d5c72c29903813eJake Slack private Object refObj(Object obj, XmlParser.Node node) throws Exception 84203928aee4356845252ac6b662d5c72c29903813eJake Slack { 84303928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 84403928aee4356845252ac6b662d5c72c29903813eJake Slack obj = _configuration.getIdMap().get(id); 84503928aee4356845252ac6b662d5c72c29903813eJake Slack if (obj == null) 84603928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("No object for id=" + id); 84703928aee4356845252ac6b662d5c72c29903813eJake Slack configure(obj,node,0); 84803928aee4356845252ac6b662d5c72c29903813eJake Slack return obj; 84903928aee4356845252ac6b662d5c72c29903813eJake Slack } 85003928aee4356845252ac6b662d5c72c29903813eJake Slack 85103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 85203928aee4356845252ac6b662d5c72c29903813eJake Slack /* 85303928aee4356845252ac6b662d5c72c29903813eJake Slack * Create a new array object. 85403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 85503928aee4356845252ac6b662d5c72c29903813eJake Slack private Object newArray(Object obj, XmlParser.Node node) throws Exception 85603928aee4356845252ac6b662d5c72c29903813eJake Slack { 85703928aee4356845252ac6b662d5c72c29903813eJake Slack 85803928aee4356845252ac6b662d5c72c29903813eJake Slack // Get the type 85903928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> aClass = java.lang.Object.class; 86003928aee4356845252ac6b662d5c72c29903813eJake Slack String type = node.getAttribute("type"); 86103928aee4356845252ac6b662d5c72c29903813eJake Slack final String id = node.getAttribute("id"); 86203928aee4356845252ac6b662d5c72c29903813eJake Slack if (type != null) 86303928aee4356845252ac6b662d5c72c29903813eJake Slack { 86403928aee4356845252ac6b662d5c72c29903813eJake Slack aClass = TypeUtil.fromName(type); 86503928aee4356845252ac6b662d5c72c29903813eJake Slack if (aClass == null) 86603928aee4356845252ac6b662d5c72c29903813eJake Slack { 86703928aee4356845252ac6b662d5c72c29903813eJake Slack if ("String".equals(type)) 86803928aee4356845252ac6b662d5c72c29903813eJake Slack aClass = java.lang.String.class; 86903928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("URL".equals(type)) 87003928aee4356845252ac6b662d5c72c29903813eJake Slack aClass = java.net.URL.class; 87103928aee4356845252ac6b662d5c72c29903813eJake Slack else if ("InetAddress".equals(type)) 87203928aee4356845252ac6b662d5c72c29903813eJake Slack aClass = java.net.InetAddress.class; 87303928aee4356845252ac6b662d5c72c29903813eJake Slack else 87403928aee4356845252ac6b662d5c72c29903813eJake Slack aClass = Loader.loadClass(XmlConfiguration.class,type,true); 87503928aee4356845252ac6b662d5c72c29903813eJake Slack } 87603928aee4356845252ac6b662d5c72c29903813eJake Slack } 87703928aee4356845252ac6b662d5c72c29903813eJake Slack 87803928aee4356845252ac6b662d5c72c29903813eJake Slack Object al = null; 87903928aee4356845252ac6b662d5c72c29903813eJake Slack 88003928aee4356845252ac6b662d5c72c29903813eJake Slack for (Object nodeObject : node) 88103928aee4356845252ac6b662d5c72c29903813eJake Slack { 88203928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node item = (Node)nodeObject; 88303928aee4356845252ac6b662d5c72c29903813eJake Slack String nid = item.getAttribute("id"); 88403928aee4356845252ac6b662d5c72c29903813eJake Slack Object v = value(obj,item); 88503928aee4356845252ac6b662d5c72c29903813eJake Slack al = LazyList.add(al,(v == null && aClass.isPrimitive())?0:v); 88603928aee4356845252ac6b662d5c72c29903813eJake Slack if (nid != null) 88703928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(nid,v); 88803928aee4356845252ac6b662d5c72c29903813eJake Slack } 88903928aee4356845252ac6b662d5c72c29903813eJake Slack 89003928aee4356845252ac6b662d5c72c29903813eJake Slack Object array = LazyList.toArray(al,aClass); 89103928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 89203928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,array); 89303928aee4356845252ac6b662d5c72c29903813eJake Slack return array; 89403928aee4356845252ac6b662d5c72c29903813eJake Slack } 89503928aee4356845252ac6b662d5c72c29903813eJake Slack 89603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 89703928aee4356845252ac6b662d5c72c29903813eJake Slack /* 89803928aee4356845252ac6b662d5c72c29903813eJake Slack * Create a new map object. 89903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 90003928aee4356845252ac6b662d5c72c29903813eJake Slack private Object newMap(Object obj, XmlParser.Node node) throws Exception 90103928aee4356845252ac6b662d5c72c29903813eJake Slack { 90203928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 90303928aee4356845252ac6b662d5c72c29903813eJake Slack 90403928aee4356845252ac6b662d5c72c29903813eJake Slack Map<Object, Object> map = new HashMap<Object, Object>(); 90503928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 90603928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,map); 90703928aee4356845252ac6b662d5c72c29903813eJake Slack 90803928aee4356845252ac6b662d5c72c29903813eJake Slack for (Object o : node) 90903928aee4356845252ac6b662d5c72c29903813eJake Slack { 91003928aee4356845252ac6b662d5c72c29903813eJake Slack if (o instanceof String) 91103928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 91203928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node entry = (XmlParser.Node)o; 91303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!entry.getTag().equals("Entry")) 91403928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Not an Entry"); 91503928aee4356845252ac6b662d5c72c29903813eJake Slack 91603928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node key = null; 91703928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node value = null; 91803928aee4356845252ac6b662d5c72c29903813eJake Slack 91903928aee4356845252ac6b662d5c72c29903813eJake Slack for (Object object : entry) 92003928aee4356845252ac6b662d5c72c29903813eJake Slack { 92103928aee4356845252ac6b662d5c72c29903813eJake Slack if (object instanceof String) 92203928aee4356845252ac6b662d5c72c29903813eJake Slack continue; 92303928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node item = (XmlParser.Node)object; 92403928aee4356845252ac6b662d5c72c29903813eJake Slack if (!item.getTag().equals("Item")) 92503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Not an Item"); 92603928aee4356845252ac6b662d5c72c29903813eJake Slack if (key == null) 92703928aee4356845252ac6b662d5c72c29903813eJake Slack key = item; 92803928aee4356845252ac6b662d5c72c29903813eJake Slack else 92903928aee4356845252ac6b662d5c72c29903813eJake Slack value = item; 93003928aee4356845252ac6b662d5c72c29903813eJake Slack } 93103928aee4356845252ac6b662d5c72c29903813eJake Slack 93203928aee4356845252ac6b662d5c72c29903813eJake Slack if (key == null || value == null) 93303928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Missing Item in Entry"); 93403928aee4356845252ac6b662d5c72c29903813eJake Slack String kid = key.getAttribute("id"); 93503928aee4356845252ac6b662d5c72c29903813eJake Slack String vid = value.getAttribute("id"); 93603928aee4356845252ac6b662d5c72c29903813eJake Slack 93703928aee4356845252ac6b662d5c72c29903813eJake Slack Object k = value(obj,key); 93803928aee4356845252ac6b662d5c72c29903813eJake Slack Object v = value(obj,value); 93903928aee4356845252ac6b662d5c72c29903813eJake Slack map.put(k,v); 94003928aee4356845252ac6b662d5c72c29903813eJake Slack 94103928aee4356845252ac6b662d5c72c29903813eJake Slack if (kid != null) 94203928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(kid,k); 94303928aee4356845252ac6b662d5c72c29903813eJake Slack if (vid != null) 94403928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(vid,v); 94503928aee4356845252ac6b662d5c72c29903813eJake Slack } 94603928aee4356845252ac6b662d5c72c29903813eJake Slack 94703928aee4356845252ac6b662d5c72c29903813eJake Slack return map; 94803928aee4356845252ac6b662d5c72c29903813eJake Slack } 94903928aee4356845252ac6b662d5c72c29903813eJake Slack 95003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 95103928aee4356845252ac6b662d5c72c29903813eJake Slack /* 95203928aee4356845252ac6b662d5c72c29903813eJake Slack * Get a Property. 95303928aee4356845252ac6b662d5c72c29903813eJake Slack * 95403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param node 95503928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 95603928aee4356845252ac6b662d5c72c29903813eJake Slack * @exception Exception 95703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 95803928aee4356845252ac6b662d5c72c29903813eJake Slack private Object propertyObj(XmlParser.Node node) throws Exception 95903928aee4356845252ac6b662d5c72c29903813eJake Slack { 96003928aee4356845252ac6b662d5c72c29903813eJake Slack String id = node.getAttribute("id"); 96103928aee4356845252ac6b662d5c72c29903813eJake Slack String name = node.getAttribute("name"); 96203928aee4356845252ac6b662d5c72c29903813eJake Slack String defaultValue = node.getAttribute("default"); 96303928aee4356845252ac6b662d5c72c29903813eJake Slack Object prop; 96403928aee4356845252ac6b662d5c72c29903813eJake Slack Map<String,String> property_map=_configuration.getProperties(); 96503928aee4356845252ac6b662d5c72c29903813eJake Slack if (property_map != null && property_map.containsKey(name)) 96603928aee4356845252ac6b662d5c72c29903813eJake Slack prop = property_map.get(name); 96703928aee4356845252ac6b662d5c72c29903813eJake Slack else 96803928aee4356845252ac6b662d5c72c29903813eJake Slack prop = defaultValue; 96903928aee4356845252ac6b662d5c72c29903813eJake Slack if (id != null) 97003928aee4356845252ac6b662d5c72c29903813eJake Slack _configuration.getIdMap().put(id,prop); 97103928aee4356845252ac6b662d5c72c29903813eJake Slack if (prop != null) 97203928aee4356845252ac6b662d5c72c29903813eJake Slack configure(prop,node,0); 97303928aee4356845252ac6b662d5c72c29903813eJake Slack return prop; 97403928aee4356845252ac6b662d5c72c29903813eJake Slack } 97503928aee4356845252ac6b662d5c72c29903813eJake Slack 97603928aee4356845252ac6b662d5c72c29903813eJake Slack 97703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 97803928aee4356845252ac6b662d5c72c29903813eJake Slack /* 97903928aee4356845252ac6b662d5c72c29903813eJake Slack * Get the value of an element. If no value type is specified, then white space is trimmed out of the value. If it contains multiple value elements they 98003928aee4356845252ac6b662d5c72c29903813eJake Slack * are added as strings before being converted to any specified type. @param node 98103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 98203928aee4356845252ac6b662d5c72c29903813eJake Slack private Object value(Object obj, XmlParser.Node node) throws Exception 98303928aee4356845252ac6b662d5c72c29903813eJake Slack { 98403928aee4356845252ac6b662d5c72c29903813eJake Slack Object value; 98503928aee4356845252ac6b662d5c72c29903813eJake Slack 98603928aee4356845252ac6b662d5c72c29903813eJake Slack // Get the type 98703928aee4356845252ac6b662d5c72c29903813eJake Slack String type = node.getAttribute("type"); 98803928aee4356845252ac6b662d5c72c29903813eJake Slack 98903928aee4356845252ac6b662d5c72c29903813eJake Slack // Try a ref lookup 99003928aee4356845252ac6b662d5c72c29903813eJake Slack String ref = node.getAttribute("ref"); 99103928aee4356845252ac6b662d5c72c29903813eJake Slack if (ref != null) 99203928aee4356845252ac6b662d5c72c29903813eJake Slack { 99303928aee4356845252ac6b662d5c72c29903813eJake Slack value = _configuration.getIdMap().get(ref); 99403928aee4356845252ac6b662d5c72c29903813eJake Slack } 99503928aee4356845252ac6b662d5c72c29903813eJake Slack else 99603928aee4356845252ac6b662d5c72c29903813eJake Slack { 99703928aee4356845252ac6b662d5c72c29903813eJake Slack // handle trivial case 99803928aee4356845252ac6b662d5c72c29903813eJake Slack if (node.size() == 0) 99903928aee4356845252ac6b662d5c72c29903813eJake Slack { 100003928aee4356845252ac6b662d5c72c29903813eJake Slack if ("String".equals(type)) 100103928aee4356845252ac6b662d5c72c29903813eJake Slack return ""; 100203928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 100303928aee4356845252ac6b662d5c72c29903813eJake Slack } 100403928aee4356845252ac6b662d5c72c29903813eJake Slack 100503928aee4356845252ac6b662d5c72c29903813eJake Slack // Trim values 100603928aee4356845252ac6b662d5c72c29903813eJake Slack int first = 0; 100703928aee4356845252ac6b662d5c72c29903813eJake Slack int last = node.size() - 1; 100803928aee4356845252ac6b662d5c72c29903813eJake Slack 100903928aee4356845252ac6b662d5c72c29903813eJake Slack // Handle default trim type 101003928aee4356845252ac6b662d5c72c29903813eJake Slack if (type == null || !"String".equals(type)) 101103928aee4356845252ac6b662d5c72c29903813eJake Slack { 101203928aee4356845252ac6b662d5c72c29903813eJake Slack // Skip leading white 101303928aee4356845252ac6b662d5c72c29903813eJake Slack Object item; 101403928aee4356845252ac6b662d5c72c29903813eJake Slack while (first <= last) 101503928aee4356845252ac6b662d5c72c29903813eJake Slack { 101603928aee4356845252ac6b662d5c72c29903813eJake Slack item = node.get(first); 101703928aee4356845252ac6b662d5c72c29903813eJake Slack if (!(item instanceof String)) 101803928aee4356845252ac6b662d5c72c29903813eJake Slack break; 101903928aee4356845252ac6b662d5c72c29903813eJake Slack item = ((String)item).trim(); 102003928aee4356845252ac6b662d5c72c29903813eJake Slack if (((String)item).length() > 0) 102103928aee4356845252ac6b662d5c72c29903813eJake Slack break; 102203928aee4356845252ac6b662d5c72c29903813eJake Slack first++; 102303928aee4356845252ac6b662d5c72c29903813eJake Slack } 102403928aee4356845252ac6b662d5c72c29903813eJake Slack 102503928aee4356845252ac6b662d5c72c29903813eJake Slack // Skip trailing white 102603928aee4356845252ac6b662d5c72c29903813eJake Slack while (first < last) 102703928aee4356845252ac6b662d5c72c29903813eJake Slack { 102803928aee4356845252ac6b662d5c72c29903813eJake Slack item = node.get(last); 102903928aee4356845252ac6b662d5c72c29903813eJake Slack if (!(item instanceof String)) 103003928aee4356845252ac6b662d5c72c29903813eJake Slack break; 103103928aee4356845252ac6b662d5c72c29903813eJake Slack item = ((String)item).trim(); 103203928aee4356845252ac6b662d5c72c29903813eJake Slack if (((String)item).length() > 0) 103303928aee4356845252ac6b662d5c72c29903813eJake Slack break; 103403928aee4356845252ac6b662d5c72c29903813eJake Slack last--; 103503928aee4356845252ac6b662d5c72c29903813eJake Slack } 103603928aee4356845252ac6b662d5c72c29903813eJake Slack 103703928aee4356845252ac6b662d5c72c29903813eJake Slack // All white, so return null 103803928aee4356845252ac6b662d5c72c29903813eJake Slack if (first > last) 103903928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 104003928aee4356845252ac6b662d5c72c29903813eJake Slack } 104103928aee4356845252ac6b662d5c72c29903813eJake Slack 104203928aee4356845252ac6b662d5c72c29903813eJake Slack if (first == last) 104303928aee4356845252ac6b662d5c72c29903813eJake Slack // Single Item value 104403928aee4356845252ac6b662d5c72c29903813eJake Slack value = itemValue(obj,node.get(first)); 104503928aee4356845252ac6b662d5c72c29903813eJake Slack else 104603928aee4356845252ac6b662d5c72c29903813eJake Slack { 104703928aee4356845252ac6b662d5c72c29903813eJake Slack // Get the multiple items as a single string 104803928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder buf = new StringBuilder(); 104903928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = first; i <= last; i++) 105003928aee4356845252ac6b662d5c72c29903813eJake Slack { 105103928aee4356845252ac6b662d5c72c29903813eJake Slack Object item = node.get(i); 105203928aee4356845252ac6b662d5c72c29903813eJake Slack buf.append(itemValue(obj,item)); 105303928aee4356845252ac6b662d5c72c29903813eJake Slack } 105403928aee4356845252ac6b662d5c72c29903813eJake Slack value = buf.toString(); 105503928aee4356845252ac6b662d5c72c29903813eJake Slack } 105603928aee4356845252ac6b662d5c72c29903813eJake Slack } 105703928aee4356845252ac6b662d5c72c29903813eJake Slack 105803928aee4356845252ac6b662d5c72c29903813eJake Slack // Untyped or unknown 105903928aee4356845252ac6b662d5c72c29903813eJake Slack if (value == null) 106003928aee4356845252ac6b662d5c72c29903813eJake Slack { 106103928aee4356845252ac6b662d5c72c29903813eJake Slack if ("String".equals(type)) 106203928aee4356845252ac6b662d5c72c29903813eJake Slack return ""; 106303928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 106403928aee4356845252ac6b662d5c72c29903813eJake Slack } 106503928aee4356845252ac6b662d5c72c29903813eJake Slack 106603928aee4356845252ac6b662d5c72c29903813eJake Slack // Try to type the object 106703928aee4356845252ac6b662d5c72c29903813eJake Slack if (type == null) 106803928aee4356845252ac6b662d5c72c29903813eJake Slack { 106903928aee4356845252ac6b662d5c72c29903813eJake Slack if (value instanceof String) 107003928aee4356845252ac6b662d5c72c29903813eJake Slack return ((String)value).trim(); 107103928aee4356845252ac6b662d5c72c29903813eJake Slack return value; 107203928aee4356845252ac6b662d5c72c29903813eJake Slack } 107303928aee4356845252ac6b662d5c72c29903813eJake Slack 107403928aee4356845252ac6b662d5c72c29903813eJake Slack if (isTypeMatchingClass(type,String.class)) 107503928aee4356845252ac6b662d5c72c29903813eJake Slack return value.toString(); 107603928aee4356845252ac6b662d5c72c29903813eJake Slack 107703928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> pClass = TypeUtil.fromName(type); 107803928aee4356845252ac6b662d5c72c29903813eJake Slack if (pClass != null) 107903928aee4356845252ac6b662d5c72c29903813eJake Slack return TypeUtil.valueOf(pClass,value.toString()); 108003928aee4356845252ac6b662d5c72c29903813eJake Slack 108103928aee4356845252ac6b662d5c72c29903813eJake Slack if (isTypeMatchingClass(type,URL.class)) 108203928aee4356845252ac6b662d5c72c29903813eJake Slack { 108303928aee4356845252ac6b662d5c72c29903813eJake Slack if (value instanceof URL) 108403928aee4356845252ac6b662d5c72c29903813eJake Slack return value; 108503928aee4356845252ac6b662d5c72c29903813eJake Slack try 108603928aee4356845252ac6b662d5c72c29903813eJake Slack { 108703928aee4356845252ac6b662d5c72c29903813eJake Slack return new URL(value.toString()); 108803928aee4356845252ac6b662d5c72c29903813eJake Slack } 108903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (MalformedURLException e) 109003928aee4356845252ac6b662d5c72c29903813eJake Slack { 109103928aee4356845252ac6b662d5c72c29903813eJake Slack throw new InvocationTargetException(e); 109203928aee4356845252ac6b662d5c72c29903813eJake Slack } 109303928aee4356845252ac6b662d5c72c29903813eJake Slack } 109403928aee4356845252ac6b662d5c72c29903813eJake Slack 109503928aee4356845252ac6b662d5c72c29903813eJake Slack if (isTypeMatchingClass(type,InetAddress.class)) 109603928aee4356845252ac6b662d5c72c29903813eJake Slack { 109703928aee4356845252ac6b662d5c72c29903813eJake Slack if (value instanceof InetAddress) 109803928aee4356845252ac6b662d5c72c29903813eJake Slack return value; 109903928aee4356845252ac6b662d5c72c29903813eJake Slack try 110003928aee4356845252ac6b662d5c72c29903813eJake Slack { 110103928aee4356845252ac6b662d5c72c29903813eJake Slack return InetAddress.getByName(value.toString()); 110203928aee4356845252ac6b662d5c72c29903813eJake Slack } 110303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (UnknownHostException e) 110403928aee4356845252ac6b662d5c72c29903813eJake Slack { 110503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new InvocationTargetException(e); 110603928aee4356845252ac6b662d5c72c29903813eJake Slack } 110703928aee4356845252ac6b662d5c72c29903813eJake Slack } 110803928aee4356845252ac6b662d5c72c29903813eJake Slack 110903928aee4356845252ac6b662d5c72c29903813eJake Slack for (Class<?> collectionClass : __supportedCollections) 111003928aee4356845252ac6b662d5c72c29903813eJake Slack { 111103928aee4356845252ac6b662d5c72c29903813eJake Slack if (isTypeMatchingClass(type,collectionClass)) 111203928aee4356845252ac6b662d5c72c29903813eJake Slack return convertArrayToCollection(value,collectionClass); 111303928aee4356845252ac6b662d5c72c29903813eJake Slack } 111403928aee4356845252ac6b662d5c72c29903813eJake Slack 111503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Unknown type " + type); 111603928aee4356845252ac6b662d5c72c29903813eJake Slack } 111703928aee4356845252ac6b662d5c72c29903813eJake Slack 111803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 111903928aee4356845252ac6b662d5c72c29903813eJake Slack private static boolean isTypeMatchingClass(String type, Class<?> classToMatch) 112003928aee4356845252ac6b662d5c72c29903813eJake Slack { 112103928aee4356845252ac6b662d5c72c29903813eJake Slack return classToMatch.getSimpleName().equalsIgnoreCase(type) || classToMatch.getName().equals(type); 112203928aee4356845252ac6b662d5c72c29903813eJake Slack } 112303928aee4356845252ac6b662d5c72c29903813eJake Slack 112403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 112503928aee4356845252ac6b662d5c72c29903813eJake Slack /* 112603928aee4356845252ac6b662d5c72c29903813eJake Slack * Get the value of a single element. @param obj @param item @return @exception Exception 112703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 112803928aee4356845252ac6b662d5c72c29903813eJake Slack private Object itemValue(Object obj, Object item) throws Exception 112903928aee4356845252ac6b662d5c72c29903813eJake Slack { 113003928aee4356845252ac6b662d5c72c29903813eJake Slack // String value 113103928aee4356845252ac6b662d5c72c29903813eJake Slack if (item instanceof String) 113203928aee4356845252ac6b662d5c72c29903813eJake Slack return item; 113303928aee4356845252ac6b662d5c72c29903813eJake Slack 113403928aee4356845252ac6b662d5c72c29903813eJake Slack XmlParser.Node node = (XmlParser.Node)item; 113503928aee4356845252ac6b662d5c72c29903813eJake Slack String tag = node.getTag(); 113603928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Call".equals(tag)) 113703928aee4356845252ac6b662d5c72c29903813eJake Slack return call(obj,node); 113803928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Get".equals(tag)) 113903928aee4356845252ac6b662d5c72c29903813eJake Slack return get(obj,node); 114003928aee4356845252ac6b662d5c72c29903813eJake Slack if ("New".equals(tag)) 114103928aee4356845252ac6b662d5c72c29903813eJake Slack return newObj(obj,node); 114203928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Ref".equals(tag)) 114303928aee4356845252ac6b662d5c72c29903813eJake Slack return refObj(obj,node); 114403928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Array".equals(tag)) 114503928aee4356845252ac6b662d5c72c29903813eJake Slack return newArray(obj,node); 114603928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Map".equals(tag)) 114703928aee4356845252ac6b662d5c72c29903813eJake Slack return newMap(obj,node); 114803928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Property".equals(tag)) 114903928aee4356845252ac6b662d5c72c29903813eJake Slack return propertyObj(node); 115003928aee4356845252ac6b662d5c72c29903813eJake Slack 115103928aee4356845252ac6b662d5c72c29903813eJake Slack if ("SystemProperty".equals(tag)) 115203928aee4356845252ac6b662d5c72c29903813eJake Slack { 115303928aee4356845252ac6b662d5c72c29903813eJake Slack String name = node.getAttribute("name"); 115403928aee4356845252ac6b662d5c72c29903813eJake Slack String defaultValue = node.getAttribute("default"); 115503928aee4356845252ac6b662d5c72c29903813eJake Slack return System.getProperty(name,defaultValue); 115603928aee4356845252ac6b662d5c72c29903813eJake Slack } 115703928aee4356845252ac6b662d5c72c29903813eJake Slack 115803928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Env".equals(tag)) 115903928aee4356845252ac6b662d5c72c29903813eJake Slack { 116003928aee4356845252ac6b662d5c72c29903813eJake Slack String name = node.getAttribute("name"); 116103928aee4356845252ac6b662d5c72c29903813eJake Slack String defaultValue = node.getAttribute("default"); 116203928aee4356845252ac6b662d5c72c29903813eJake Slack String value=System.getenv(name); 116303928aee4356845252ac6b662d5c72c29903813eJake Slack return value==null?defaultValue:value; 116403928aee4356845252ac6b662d5c72c29903813eJake Slack } 116503928aee4356845252ac6b662d5c72c29903813eJake Slack 116603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unknown value tag: " + node,new Throwable()); 116703928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 116803928aee4356845252ac6b662d5c72c29903813eJake Slack } 116903928aee4356845252ac6b662d5c72c29903813eJake Slack } 117003928aee4356845252ac6b662d5c72c29903813eJake Slack 117103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 117203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 117303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 117403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 117503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 117603928aee4356845252ac6b662d5c72c29903813eJake Slack * Run the XML configurations as a main application. The command line is used to obtain properties files (must be named '*.properties') and XmlConfiguration 117703928aee4356845252ac6b662d5c72c29903813eJake Slack * files. 117803928aee4356845252ac6b662d5c72c29903813eJake Slack * <p> 117903928aee4356845252ac6b662d5c72c29903813eJake Slack * Any property file on the command line is added to a combined Property instance that is passed to each configuration file via 118003928aee4356845252ac6b662d5c72c29903813eJake Slack * {@link XmlConfiguration#setProperties(Map)}. 118103928aee4356845252ac6b662d5c72c29903813eJake Slack * <p> 118203928aee4356845252ac6b662d5c72c29903813eJake Slack * Each configuration file on the command line is used to create a new XmlConfiguration instance and the {@link XmlConfiguration#configure()} method is used 118303928aee4356845252ac6b662d5c72c29903813eJake Slack * to create the configured object. If the resulting object is an instance of {@link LifeCycle}, then it is started. 118403928aee4356845252ac6b662d5c72c29903813eJake Slack * <p> 118503928aee4356845252ac6b662d5c72c29903813eJake Slack * Any IDs created in a configuration are passed to the next configuration file on the command line using {@link #getIdMap()} and {@link #setIdMap(Map)} . 118603928aee4356845252ac6b662d5c72c29903813eJake Slack * This allows objects with IDs created in one config file to be referenced in subsequent config files on the command line. 118703928aee4356845252ac6b662d5c72c29903813eJake Slack * 118803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param args 118903928aee4356845252ac6b662d5c72c29903813eJake Slack * array of property and xml configuration filenames or {@link Resource}s. 119003928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception if the XML configurations cannot be run 119103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 119203928aee4356845252ac6b662d5c72c29903813eJake Slack public static void main(final String[] args) throws Exception 119303928aee4356845252ac6b662d5c72c29903813eJake Slack { 119403928aee4356845252ac6b662d5c72c29903813eJake Slack 119503928aee4356845252ac6b662d5c72c29903813eJake Slack final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); 119603928aee4356845252ac6b662d5c72c29903813eJake Slack 119703928aee4356845252ac6b662d5c72c29903813eJake Slack AccessController.doPrivileged(new PrivilegedAction<Object>() 119803928aee4356845252ac6b662d5c72c29903813eJake Slack { 119903928aee4356845252ac6b662d5c72c29903813eJake Slack public Object run() 120003928aee4356845252ac6b662d5c72c29903813eJake Slack { 120103928aee4356845252ac6b662d5c72c29903813eJake Slack try 120203928aee4356845252ac6b662d5c72c29903813eJake Slack { 120303928aee4356845252ac6b662d5c72c29903813eJake Slack 120403928aee4356845252ac6b662d5c72c29903813eJake Slack Properties properties = null; 120503928aee4356845252ac6b662d5c72c29903813eJake Slack 120603928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for properties from start.jar 120703928aee4356845252ac6b662d5c72c29903813eJake Slack try 120803928aee4356845252ac6b662d5c72c29903813eJake Slack { 120903928aee4356845252ac6b662d5c72c29903813eJake Slack Class<?> config = XmlConfiguration.class.getClassLoader().loadClass("org.eclipse.jetty.start.Config"); 121003928aee4356845252ac6b662d5c72c29903813eJake Slack properties = (Properties)config.getMethod("getProperties").invoke(null); 121103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("org.eclipse.jetty.start.Config properties = {}",properties); 121203928aee4356845252ac6b662d5c72c29903813eJake Slack } 121303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (NoClassDefFoundError e) 121403928aee4356845252ac6b662d5c72c29903813eJake Slack { 121503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 121603928aee4356845252ac6b662d5c72c29903813eJake Slack } 121703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (ClassNotFoundException e) 121803928aee4356845252ac6b662d5c72c29903813eJake Slack { 121903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 122003928aee4356845252ac6b662d5c72c29903813eJake Slack } 122103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 122203928aee4356845252ac6b662d5c72c29903813eJake Slack { 122303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 122403928aee4356845252ac6b662d5c72c29903813eJake Slack } 122503928aee4356845252ac6b662d5c72c29903813eJake Slack 122603928aee4356845252ac6b662d5c72c29903813eJake Slack // If no start.config properties, use clean slate 122703928aee4356845252ac6b662d5c72c29903813eJake Slack if (properties == null) 122803928aee4356845252ac6b662d5c72c29903813eJake Slack { 122903928aee4356845252ac6b662d5c72c29903813eJake Slack properties = new Properties(); 123003928aee4356845252ac6b662d5c72c29903813eJake Slack // Add System Properties 123103928aee4356845252ac6b662d5c72c29903813eJake Slack Enumeration<?> ensysprop = System.getProperties().propertyNames(); 123203928aee4356845252ac6b662d5c72c29903813eJake Slack while (ensysprop.hasMoreElements()) 123303928aee4356845252ac6b662d5c72c29903813eJake Slack { 123403928aee4356845252ac6b662d5c72c29903813eJake Slack String name = (String)ensysprop.nextElement(); 123503928aee4356845252ac6b662d5c72c29903813eJake Slack properties.put(name,System.getProperty(name)); 123603928aee4356845252ac6b662d5c72c29903813eJake Slack } 123703928aee4356845252ac6b662d5c72c29903813eJake Slack } 123803928aee4356845252ac6b662d5c72c29903813eJake Slack 123903928aee4356845252ac6b662d5c72c29903813eJake Slack // For all arguments, load properties or parse XMLs 124003928aee4356845252ac6b662d5c72c29903813eJake Slack XmlConfiguration last = null; 124103928aee4356845252ac6b662d5c72c29903813eJake Slack Object[] obj = new Object[args.length]; 124203928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < args.length; i++) 124303928aee4356845252ac6b662d5c72c29903813eJake Slack { 124403928aee4356845252ac6b662d5c72c29903813eJake Slack if (args[i].toLowerCase(Locale.ENGLISH).endsWith(".properties")) 124503928aee4356845252ac6b662d5c72c29903813eJake Slack { 124603928aee4356845252ac6b662d5c72c29903813eJake Slack properties.load(Resource.newResource(args[i]).getInputStream()); 124703928aee4356845252ac6b662d5c72c29903813eJake Slack } 124803928aee4356845252ac6b662d5c72c29903813eJake Slack else 124903928aee4356845252ac6b662d5c72c29903813eJake Slack { 125003928aee4356845252ac6b662d5c72c29903813eJake Slack XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL()); 125103928aee4356845252ac6b662d5c72c29903813eJake Slack if (last != null) 125203928aee4356845252ac6b662d5c72c29903813eJake Slack configuration.getIdMap().putAll(last.getIdMap()); 125303928aee4356845252ac6b662d5c72c29903813eJake Slack if (properties.size() > 0) 125403928aee4356845252ac6b662d5c72c29903813eJake Slack { 125503928aee4356845252ac6b662d5c72c29903813eJake Slack Map<String, String> props = new HashMap<String, String>(); 125603928aee4356845252ac6b662d5c72c29903813eJake Slack for (Object key : properties.keySet()) 125703928aee4356845252ac6b662d5c72c29903813eJake Slack { 125803928aee4356845252ac6b662d5c72c29903813eJake Slack props.put(key.toString(),String.valueOf(properties.get(key))); 125903928aee4356845252ac6b662d5c72c29903813eJake Slack } 126003928aee4356845252ac6b662d5c72c29903813eJake Slack configuration.getProperties().putAll(props); 126103928aee4356845252ac6b662d5c72c29903813eJake Slack } 126203928aee4356845252ac6b662d5c72c29903813eJake Slack obj[i] = configuration.configure(); 126303928aee4356845252ac6b662d5c72c29903813eJake Slack last = configuration; 126403928aee4356845252ac6b662d5c72c29903813eJake Slack } 126503928aee4356845252ac6b662d5c72c29903813eJake Slack } 126603928aee4356845252ac6b662d5c72c29903813eJake Slack 126703928aee4356845252ac6b662d5c72c29903813eJake Slack // For all objects created by XmlConfigurations, start them if they are lifecycles. 126803928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i = 0; i < args.length; i++) 126903928aee4356845252ac6b662d5c72c29903813eJake Slack { 127003928aee4356845252ac6b662d5c72c29903813eJake Slack if (obj[i] instanceof LifeCycle) 127103928aee4356845252ac6b662d5c72c29903813eJake Slack { 127203928aee4356845252ac6b662d5c72c29903813eJake Slack LifeCycle lc = (LifeCycle)obj[i]; 127303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!lc.isRunning()) 127403928aee4356845252ac6b662d5c72c29903813eJake Slack lc.start(); 127503928aee4356845252ac6b662d5c72c29903813eJake Slack } 127603928aee4356845252ac6b662d5c72c29903813eJake Slack } 127703928aee4356845252ac6b662d5c72c29903813eJake Slack } 127803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 127903928aee4356845252ac6b662d5c72c29903813eJake Slack { 128003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(Log.EXCEPTION,e); 128103928aee4356845252ac6b662d5c72c29903813eJake Slack exception.set(e); 128203928aee4356845252ac6b662d5c72c29903813eJake Slack } 128303928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 128403928aee4356845252ac6b662d5c72c29903813eJake Slack } 128503928aee4356845252ac6b662d5c72c29903813eJake Slack }); 128603928aee4356845252ac6b662d5c72c29903813eJake Slack 128703928aee4356845252ac6b662d5c72c29903813eJake Slack Throwable th = exception.get(); 128803928aee4356845252ac6b662d5c72c29903813eJake Slack if (th != null) 128903928aee4356845252ac6b662d5c72c29903813eJake Slack { 129003928aee4356845252ac6b662d5c72c29903813eJake Slack if (th instanceof RuntimeException) 129103928aee4356845252ac6b662d5c72c29903813eJake Slack throw (RuntimeException)th; 129203928aee4356845252ac6b662d5c72c29903813eJake Slack else if (th instanceof Exception) 129303928aee4356845252ac6b662d5c72c29903813eJake Slack throw (Exception)th; 129403928aee4356845252ac6b662d5c72c29903813eJake Slack else if (th instanceof Error) 129503928aee4356845252ac6b662d5c72c29903813eJake Slack throw (Error)th; 129603928aee4356845252ac6b662d5c72c29903813eJake Slack throw new Error(th); 129703928aee4356845252ac6b662d5c72c29903813eJake Slack } 129803928aee4356845252ac6b662d5c72c29903813eJake Slack } 129903928aee4356845252ac6b662d5c72c29903813eJake Slack} 1300