466645 Allow XmlConfiguration Properties to use Elements or Attributes

implemented for New element
This commit is contained in:
Greg Wilkins 2015-05-07 17:58:37 +10:00
parent 532b0019cc
commit e580f57d6e
6 changed files with 368 additions and 214 deletions

View File

@ -298,6 +298,9 @@ public class XmlConfiguration
String loaders = (oClass.getClassLoader()==obj.getClass().getClassLoader())?"":"Object Class and type Class are from different loaders.";
throw new IllegalArgumentException("Object of class '"+obj.getClass().getCanonicalName()+"' is not of type '" + oClass.getCanonicalName()+"'. "+loaders+" in "+_url);
}
String id=_root.getAttribute("id");
if (id!=null)
_configuration.getIdMap().put(id,obj);
configure(obj,_root,0);
return obj;
}
@ -352,8 +355,10 @@ public class XmlConfiguration
throw new IllegalStateException(String.format("No constructor %s(%s,%s) in %s",oClass,arguments,namedArgMap,_url));
}
}
_configuration.initializeDefaults(obj);
if (id!=null)
_configuration.getIdMap().put(id,obj);
_configuration.initializeDefaults(obj);
configure(obj, _root, index);
return obj;
}
@ -378,10 +383,6 @@ public class XmlConfiguration
*/
public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception
{
String id = cfg.getAttribute("id");
if (id != null)
_configuration.getIdMap().put(id,obj);
// Object already constructed so skip any arguments
for (; i < cfg.size(); i++)
{
@ -668,6 +669,8 @@ public class XmlConfiguration
// try calling a getXxx method.
Method method = oClass.getMethod("get" + name.substring(0,1).toUpperCase(Locale.ENGLISH) + name.substring(1),(java.lang.Class[])null);
obj = method.invoke(obj,(java.lang.Object[])null);
if (id!=null)
_configuration.getIdMap().put(id,obj);
configure(obj,node,0);
}
catch (NoSuchMethodException nsme)
@ -683,8 +686,6 @@ public class XmlConfiguration
throw nsme;
}
}
if (id != null)
_configuration.getIdMap().put(id, obj);
return obj;
}
@ -723,11 +724,11 @@ public class XmlConfiguration
try
{
Object n= TypeUtil.call(oClass,name,obj,args.toArray(new Object[args.size()]));
Object nobj= TypeUtil.call(oClass,name,obj,args.toArray(new Object[args.size()]));
if (id != null)
_configuration.getIdMap().put(id,n);
configure(n,node,aoeNode.getNext());
return n;
_configuration.getIdMap().put(id,nobj);
configure(nobj,node,aoeNode.getNext());
return nobj;
}
catch (NoSuchMethodException e)
{
@ -747,59 +748,44 @@ public class XmlConfiguration
*/
private Object newObj(Object obj, XmlParser.Node node) throws Exception
{
Class<?> oClass = nodeClass(node);
int argIndex = node.size();
Map<String, Object> namedArgMap = new HashMap<>();
List<Object> arguments = new LinkedList<>();
XmlParser.Node child;
// Find the <Arg> elements
for (int i = 0; i < node.size(); i++)
{
Object o = node.get(i);
if (o instanceof String)
{
// Skip raw String nodes
continue;
}
child = (XmlParser.Node)o;
if(child.getTag().equals("Arg"))
{
String namedAttribute = child.getAttribute("name");
Object value=value(obj,child);
if (namedAttribute != null)
{
// named arguments
namedArgMap.put(namedAttribute,value);
}
// raw arguments
arguments.add(value);
} else {
// The first non <Arg> child is the start of
// elements that configure the class, such as
// <Set> and <Call> nodes
argIndex = i;
break;
}
}
AttrOrElementNode aoeNode=new AttrOrElementNode(obj,node,"Id","Class","Arg");
String id = aoeNode.getString("Id");
String clazz = aoeNode.getString("Class");
List<XmlParser.Node> argNodes = aoeNode.getNodes("Arg");
if (LOG.isDebugEnabled())
LOG.debug("XML new " + oClass);
LOG.debug("XML new " + clazz);
Object n;
Class<?> oClass = Loader.loadClass(XmlConfiguration.class,clazz);
// Find the <Arg> elements
Map<String, Object> namedArgMap = new HashMap<>();
List<Object> arguments = new LinkedList<>();
for (XmlParser.Node child : argNodes)
{
String namedAttribute = child.getAttribute("name");
Object value=value(obj,child);
if (namedAttribute != null)
{
// named arguments
namedArgMap.put(namedAttribute,value);
}
// raw arguments
arguments.add(value);
}
Object nobj;
try
{
if (namedArgMap.size() > 0)
{
LOG.debug("using named mapping");
n = TypeUtil.construct(oClass, arguments.toArray(), namedArgMap);
nobj = TypeUtil.construct(oClass, arguments.toArray(), namedArgMap);
}
else
{
LOG.debug("using normal mapping");
n = TypeUtil.construct(oClass, arguments.toArray());
nobj = TypeUtil.construct(oClass, arguments.toArray());
}
}
catch (NoSuchMethodException e)
@ -807,9 +793,12 @@ public class XmlConfiguration
throw new IllegalStateException("No suitable constructor: " + node + " on " + obj);
}
_configuration.initializeDefaults(n);
configure(n,node,argIndex);
return n;
if (id != null)
_configuration.getIdMap().put(id, nobj);
_configuration.initializeDefaults(nobj);
configure(nobj,node,aoeNode.getNext());
return nobj;
}
/*
@ -1372,6 +1361,42 @@ public class XmlConfiguration
return values;
}
public List<XmlParser.Node> getNodes(String elementName) throws Exception
{
String attrName=StringUtil.asciiToLowerCase(elementName);
final List<XmlParser.Node> values=new ArrayList<>();
String attr = _node.getAttribute(attrName);
if (attr!=null)
{
for (String a : attr.split(","))
{
// create a fake node
XmlParser.Node n = new XmlParser.Node(null,elementName,null);
n.add(a);
values.add(n);
}
}
for (int i=0;i<_next;i++)
{
Object o = _node.get(i);
if (!(o instanceof XmlParser.Node))
continue;
XmlParser.Node n = (XmlParser.Node)o;
if (elementName.equals(n.getTag()))
{
if (attr!=null)
throw new IllegalStateException("Cannot have attr '"+attrName+"' and element '"+elementName+"'");
values.add(n);
}
}
return values;
}
}
}

View File

@ -158,9 +158,8 @@ This is equivalent to:
Object o = new com.acme.MyClass("value1");
o.setTest("Value2");
-->
<!ELEMENT New (Arg*,(%CONFIG;)*) >
<!ATTLIST New %CLASSATTR; %IDATTR;>
<!ELEMENT New (Id?,Name?,Class?,Arg*,(%CONFIG;)*) >
<!ATTLIST New %IDATTR; %IMPLIEDCLASSATTR; %ARGATTR; >
<!--
Ref Element.

View File

@ -38,7 +38,7 @@ import static org.junit.Assert.assertTrue;
public class XmlConfigurationTest
{
protected String _configure="org/eclipse/jetty/xml/configure.xml";
protected String[] _configure=new String [] {"org/eclipse/jetty/xml/configureWithAttr.xml","org/eclipse/jetty/xml/configureWithElements.xml"};
private static final String STRING_ARRAY_XML = "<Array type=\"String\"><Item type=\"String\">String1</Item><Item type=\"String\">String2</Item></Array>";
private static final String INT_ARRAY_XML = "<Array type=\"int\"><Item type=\"int\">1</Item><Item type=\"int\">2</Item></Array>";
@ -54,161 +54,167 @@ public class XmlConfigurationTest
@Test
public void testPassedObject() throws Exception
{
TestConfiguration.VALUE=77;
Map<String,String> properties = new HashMap<>();
properties.put("whatever", "xxx");
URL url = XmlConfigurationTest.class.getClassLoader().getResource(_configure);
XmlConfiguration configuration = new XmlConfiguration(url);
TestConfiguration tc = new TestConfiguration("tc");
configuration.getProperties().putAll(properties);
configuration.configure(tc);
for (String configure : _configure)
{
Map<String,String> properties = new HashMap<>();
properties.put("whatever", "xxx");
TestConfiguration.VALUE=77;
URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure);
XmlConfiguration configuration = new XmlConfiguration(url);
TestConfiguration tc = new TestConfiguration("tc");
configuration.getProperties().putAll(properties);
configuration.configure(tc);
assertEquals("Set String","SetValue",tc.testObject);
assertEquals("Set Type",2,tc.testInt);
assertEquals("Set String","SetValue",tc.testObject);
assertEquals("Set Type",2,tc.testInt);
assertEquals(18080, tc.propValue);
assertEquals(18080, tc.propValue);
assertEquals("Put","PutValue",tc.get("Test"));
assertEquals("Put dft","2",tc.get("TestDft"));
assertEquals("Put type",2,tc.get("TestInt"));
assertEquals("Put","PutValue",tc.get("Test"));
assertEquals("Put dft","2",tc.get("TestDft"));
assertEquals("Put type",2,tc.get("TestInt"));
assertEquals("Trim","PutValue",tc.get("Trim"));
assertEquals("Null",null,tc.get("Null"));
assertEquals("NullTrim",null,tc.get("NullTrim"));
assertEquals("Trim","PutValue",tc.get("Trim"));
assertEquals("Null",null,tc.get("Null"));
assertEquals("NullTrim",null,tc.get("NullTrim"));
assertEquals("ObjectTrim",1.2345,tc.get("ObjectTrim"));
assertEquals("Objects","-1String",tc.get("Objects"));
assertEquals( "ObjectsTrim", "-1String",tc.get("ObjectsTrim"));
assertEquals( "String", "\n PutValue\n ",tc.get("String"));
assertEquals( "NullString", "",tc.get("NullString"));
assertEquals( "WhiteSpace", "\n ",tc.get("WhiteSpace"));
assertEquals( "ObjectString", "\n 1.2345\n ",tc.get("ObjectString"));
assertEquals( "ObjectsString", "-1String",tc.get("ObjectsString"));
assertEquals( "ObjectsWhiteString", "-1\n String",tc.get("ObjectsWhiteString"));
assertEquals("ObjectTrim",1.2345,tc.get("ObjectTrim"));
assertEquals("Objects","-1String",tc.get("Objects"));
assertEquals( "ObjectsTrim", "-1String",tc.get("ObjectsTrim"));
assertEquals( "String", "\n PutValue\n ",tc.get("String"));
assertEquals( "NullString", "",tc.get("NullString"));
assertEquals( "WhiteSpace", "\n ",tc.get("WhiteSpace"));
assertEquals( "ObjectString", "\n 1.2345\n ",tc.get("ObjectString"));
assertEquals( "ObjectsString", "-1String",tc.get("ObjectsString"));
assertEquals( "ObjectsWhiteString", "-1\n String",tc.get("ObjectsWhiteString"));
assertEquals( "SystemProperty", System.getProperty("user.dir")+"/stuff",tc.get("SystemProperty"));
assertEquals( "Env", System.getenv("HOME"),tc.get("Env"));
assertEquals( "SystemProperty", System.getProperty("user.dir")+"/stuff",tc.get("SystemProperty"));
assertEquals( "Env", System.getenv("HOME"),tc.get("Env"));
assertEquals( "Property", "xxx", tc.get("Property"));
assertEquals( "Property", "xxx", tc.get("Property"));
assertEquals( "Called", "Yes",tc.get("Called"));
assertEquals( "Called", "Yes",tc.get("Called"));
assertTrue(TestConfiguration.called);
assertTrue(TestConfiguration.called);
assertEquals("oa[0]","Blah",tc.oa[0]);
assertEquals("oa[1]","1.2.3.4:5678",tc.oa[1]);
assertEquals("oa[2]",1.2345,tc.oa[2]);
assertEquals("oa[3]",null,tc.oa[3]);
assertEquals("oa[0]","Blah",tc.oa[0]);
assertEquals("oa[1]","1.2.3.4:5678",tc.oa[1]);
assertEquals("oa[2]",1.2345,tc.oa[2]);
assertEquals("oa[3]",null,tc.oa[3]);
assertEquals("ia[0]",1,tc.ia[0]);
assertEquals("ia[1]",2,tc.ia[1]);
assertEquals("ia[2]",3,tc.ia[2]);
assertEquals("ia[3]",0,tc.ia[3]);
assertEquals("ia[0]",1,tc.ia[0]);
assertEquals("ia[1]",2,tc.ia[1]);
assertEquals("ia[2]",3,tc.ia[2]);
assertEquals("ia[3]",0,tc.ia[3]);
TestConfiguration tc2=tc.nested;
assertTrue(tc2!=null);
assertEquals( "Called(bool)",true,tc2.get("Arg"));
TestConfiguration tc2=tc.nested;
assertTrue(tc2!=null);
assertEquals( "Called(bool)",true,tc2.get("Arg"));
assertEquals("nested config",null,tc.get("Arg"));
assertEquals("nested config",true,tc2.get("Arg"));
assertEquals("nested config",null,tc.get("Arg"));
assertEquals("nested config",true,tc2.get("Arg"));
assertEquals("nested config","Call1",tc2.testObject);
assertEquals("nested config",4,tc2.testInt);
assertEquals( "nested call", "http://www.eclipse.com/",tc2.url.toString());
assertEquals("nested config","Call1",tc2.testObject);
assertEquals("nested config",4,tc2.testInt);
assertEquals( "nested call", "http://www.eclipse.com/",tc2.url.toString());
assertEquals("static to field",tc.testField1,77);
assertEquals("field to field",tc.testField2,2);
assertEquals("literal to static",TestConfiguration.VALUE,42);
assertEquals("static to field",tc.testField1,77);
assertEquals("field to field",tc.testField2,2);
assertEquals("literal to static",TestConfiguration.VALUE,42);
}
}
@Test
public void testNewObject() throws Exception
{
TestConfiguration.VALUE=71;
Map<String,String> properties = new HashMap<>();
properties.put("whatever", "xxx");
URL url = XmlConfigurationTest.class.getClassLoader().getResource(_configure);
final AtomicInteger count = new AtomicInteger(0);
XmlConfiguration configuration = new XmlConfiguration(url)
for (String configure : _configure)
{
@Override
public void initializeDefaults(Object object)
TestConfiguration.VALUE=71;
Map<String,String> properties = new HashMap<>();
properties.put("whatever", "xxx");
URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure);
final AtomicInteger count = new AtomicInteger(0);
XmlConfiguration configuration = new XmlConfiguration(url)
{
if (object instanceof TestConfiguration)
@Override
public void initializeDefaults(Object object)
{
count.incrementAndGet();
((TestConfiguration)object).setNested(null);
((TestConfiguration)object).setTestString("NEW DEFAULT");
if (object instanceof TestConfiguration)
{
count.incrementAndGet();
((TestConfiguration)object).setNested(null);
((TestConfiguration)object).setTestString("NEW DEFAULT");
}
}
}
};
configuration.getProperties().putAll(properties);
TestConfiguration tc = (TestConfiguration)configuration.configure();
};
configuration.getProperties().putAll(properties);
TestConfiguration tc = (TestConfiguration)configuration.configure();
assertEquals(3,count.get());
assertEquals(3,count.get());
assertEquals("NEW DEFAULT",tc.getTestString());
assertEquals("nested",tc.getNested().getTestString());
assertEquals("NEW DEFAULT",tc.getNested().getNested().getTestString());
assertEquals("NEW DEFAULT",tc.getTestString());
assertEquals("nested",tc.getNested().getTestString());
assertEquals("NEW DEFAULT",tc.getNested().getNested().getTestString());
assertEquals("Set String","SetValue",tc.testObject);
assertEquals("Set Type",2,tc.testInt);
assertEquals("Set String","SetValue",tc.testObject);
assertEquals("Set Type",2,tc.testInt);
assertEquals(18080, tc.propValue);
assertEquals(18080, tc.propValue);
assertEquals("Put","PutValue",tc.get("Test"));
assertEquals("Put dft","2",tc.get("TestDft"));
assertEquals("Put type",2,tc.get("TestInt"));
assertEquals("Put","PutValue",tc.get("Test"));
assertEquals("Put dft","2",tc.get("TestDft"));
assertEquals("Put type",2,tc.get("TestInt"));
assertEquals("Trim","PutValue",tc.get("Trim"));
assertEquals("Null",null,tc.get("Null"));
assertEquals("NullTrim",null,tc.get("NullTrim"));
assertEquals("Trim","PutValue",tc.get("Trim"));
assertEquals("Null",null,tc.get("Null"));
assertEquals("NullTrim",null,tc.get("NullTrim"));
assertEquals("ObjectTrim",1.2345,tc.get("ObjectTrim"));
assertEquals("Objects","-1String",tc.get("Objects"));
assertEquals( "ObjectsTrim", "-1String",tc.get("ObjectsTrim"));
assertEquals( "String", "\n PutValue\n ",tc.get("String"));
assertEquals( "NullString", "",tc.get("NullString"));
assertEquals( "WhiteSpace", "\n ",tc.get("WhiteSpace"));
assertEquals( "ObjectString", "\n 1.2345\n ",tc.get("ObjectString"));
assertEquals( "ObjectsString", "-1String",tc.get("ObjectsString"));
assertEquals( "ObjectsWhiteString", "-1\n String",tc.get("ObjectsWhiteString"));
assertEquals("ObjectTrim",1.2345,tc.get("ObjectTrim"));
assertEquals("Objects","-1String",tc.get("Objects"));
assertEquals( "ObjectsTrim", "-1String",tc.get("ObjectsTrim"));
assertEquals( "String", "\n PutValue\n ",tc.get("String"));
assertEquals( "NullString", "",tc.get("NullString"));
assertEquals( "WhiteSpace", "\n ",tc.get("WhiteSpace"));
assertEquals( "ObjectString", "\n 1.2345\n ",tc.get("ObjectString"));
assertEquals( "ObjectsString", "-1String",tc.get("ObjectsString"));
assertEquals( "ObjectsWhiteString", "-1\n String",tc.get("ObjectsWhiteString"));
assertEquals( "SystemProperty", System.getProperty("user.dir")+"/stuff",tc.get("SystemProperty"));
assertEquals( "Property", "xxx", tc.get("Property"));
assertEquals( "SystemProperty", System.getProperty("user.dir")+"/stuff",tc.get("SystemProperty"));
assertEquals( "Property", "xxx", tc.get("Property"));
assertEquals( "Called", "Yes",tc.get("Called"));
assertEquals( "Called", "Yes",tc.get("Called"));
assertTrue(TestConfiguration.called);
assertTrue(TestConfiguration.called);
assertEquals("oa[0]","Blah",tc.oa[0]);
assertEquals("oa[1]","1.2.3.4:5678",tc.oa[1]);
assertEquals("oa[2]",1.2345,tc.oa[2]);
assertEquals("oa[3]",null,tc.oa[3]);
assertEquals("oa[0]","Blah",tc.oa[0]);
assertEquals("oa[1]","1.2.3.4:5678",tc.oa[1]);
assertEquals("oa[2]",1.2345,tc.oa[2]);
assertEquals("oa[3]",null,tc.oa[3]);
assertEquals("ia[0]",1,tc.ia[0]);
assertEquals("ia[1]",2,tc.ia[1]);
assertEquals("ia[2]",3,tc.ia[2]);
assertEquals("ia[3]",0,tc.ia[3]);
assertEquals("ia[0]",1,tc.ia[0]);
assertEquals("ia[1]",2,tc.ia[1]);
assertEquals("ia[2]",3,tc.ia[2]);
assertEquals("ia[3]",0,tc.ia[3]);
TestConfiguration tc2=tc.nested;
assertTrue(tc2!=null);
assertEquals( "Called(bool)",true,tc2.get("Arg"));
TestConfiguration tc2=tc.nested;
assertTrue(tc2!=null);
assertEquals( "Called(bool)",true,tc2.get("Arg"));
assertEquals("nested config",null,tc.get("Arg"));
assertEquals("nested config",true,tc2.get("Arg"));
assertEquals("nested config",null,tc.get("Arg"));
assertEquals("nested config",true,tc2.get("Arg"));
assertEquals("nested config","Call1",tc2.testObject);
assertEquals("nested config",4,tc2.testInt);
assertEquals( "nested call", "http://www.eclipse.com/",tc2.url.toString());
assertEquals("nested config","Call1",tc2.testObject);
assertEquals("nested config",4,tc2.testInt);
assertEquals( "nested call", "http://www.eclipse.com/",tc2.url.toString());
assertEquals("static to field",71,tc.testField1);
assertEquals("field to field",2,tc.testField2);
assertEquals("literal to static",42,TestConfiguration.VALUE);
assertEquals("static to field",71,tc.testField1);
assertEquals("field to field",2,tc.testField2);
assertEquals("literal to static",42,TestConfiguration.VALUE);
}
}

View File

@ -31,24 +31,12 @@ public class XmlParserTest
{
XmlParser parser = new XmlParser();
URL configURL = XmlConfiguration.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure_6_0.dtd");
URL configURL = XmlConfiguration.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure_9_3.dtd");
parser.redirectEntity("configure.dtd", configURL);
parser.redirectEntity("configure_1_3.dtd", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure_1_3.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.3//EN", configURL);
parser.redirectEntity("configure_1_2.dtd", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure_1_2.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.2//EN", configURL);
parser.redirectEntity("configure_1_1.dtd", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure_1_1.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.1//EN", configURL);
parser.redirectEntity("configure_1_0.dtd", configURL);
parser.redirectEntity("http://jetty.eclipse.org/configure_1_0.dtd", configURL);
parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.0//EN", configURL);
URL url = XmlParserTest.class.getClassLoader().getResource("org/eclipse/jetty/xml/configure.xml");
URL url = XmlParserTest.class.getClassLoader().getResource("org/eclipse/jetty/xml/configureWithAttr.xml");
XmlParser.Node testDoc = parser.parse(url.toString());
String testDocStr = testDoc.toString().trim();

View File

@ -22,31 +22,19 @@
<Put name="NullTrim">
</Put>
<Put name="Object"><New class="java.lang.Double">
<Arg>1.2345</Arg>
</New></Put>
<Put name="Object"><New class="java.lang.Double" arg="1.2345"/></Put>
<Put name="ObjectTrim">
<New class="java.lang.Double">
<Arg>1.2345</Arg>
</New>
<New class="java.lang.Double" arg="1.2345"/>
</Put>
<Put name="Objects"><New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New class="java.lang.String">
<Arg>String</Arg>
</New></Put>
<Put name="Objects"><New class="java.lang.Integer" arg="-1"/><New class="java.lang.String" arg="String"/></Put>
<Put name="ObjectsTrim">
<New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New class="java.lang.String">
<Arg>String</Arg>
<New class="java.lang.Integer" arg="-1">
</New><New class="java.lang.String" arg="String">
</New></Put>
<Put name="String" type="String">
PutValue
</Put>
@ -62,19 +50,12 @@
</New>
</Put>
<Put name="ObjectsString" type="String"><New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New class="java.lang.String">
<Arg>String</Arg>
</New></Put>
<Put name="ObjectsString" type="String"><New class="java.lang.Integer" arg="-1"/><New class="java.lang.String" arg="String"/></Put>
<Put name="ObjectsWhiteString">
<New class="java.lang.Integer">
<Arg>-1</Arg>
<New class="java.lang.Integer" arg="-1">
</New>
<New class="java.lang.String">
<Arg>String</Arg>
<New class="java.lang.String" arg="String">
</New></Put>
<Put name="SystemProperty" ><SystemProperty name="user.dir"/>/stuff</Put>

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.xml.TestConfiguration">
<Arg name="name">name</Arg>
<Set name="Test">SetValue</Set>
<Set name="Test" type="int"><Property><Name>does.not.exist</Name><Default>2</Default></Property></Set>
<Set name="PropertyTest"><Property><Name>anIntegerNoActualPropDefined</Name><Default>18080</Default></Property></Set>
<Put name="Test">PutValue</Put>
<Put name="TestDft">2</Put>
<Put name="TestInt" type="int">2</Put>
<Put name="Trim">
PutValue
</Put>
<Put name="Null"></Put>
<Put name="NullTrim">
</Put>
<Put name="Object"><New class="java.lang.Double">
<Arg>1.2345</Arg>
</New></Put>
<Put name="ObjectTrim">
<New class="java.lang.Double">
<Arg>1.2345</Arg>
</New>
</Put>
<Put name="Objects"><New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New class="java.lang.String">
<Arg>String</Arg>
</New></Put>
<Put name="ObjectsTrim">
<New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New class="java.lang.String">
<Arg>String</Arg>
</New></Put>
<Put name="String" type="String">
PutValue
</Put>
<Put name="NullString" type="String"></Put>
<Put name="WhiteSpace" type="String">
</Put>
<Put name="ObjectString" type="String">
<New class="java.lang.Double">
<Arg>1.2345</Arg>
</New>
</Put>
<Put name="ObjectsString" type="String"><New class="java.lang.Integer">
<Arg>-1</Arg>
</New><New>
<Class>java.lang.String</Class>
<Arg>String</Arg>
</New></Put>
<Put name="ObjectsWhiteString">
<New>
<Class>java.lang.Integer</Class>
<Arg>-1</Arg>
</New>
<New>
<Class>java.lang.String</Class>
<Arg>String</Arg>
</New></Put>
<Put name="SystemProperty" ><SystemProperty><Name>user.dir</Name></SystemProperty>/stuff</Put>
<Put name="Property"><Property><Name>whatever</Name><Default>xxx</Default></Property></Put>
<Put name="SomethingElse"><SystemProperty name="floople" default="xxx"/></Put>
<Put name="Boolean" type="Boolean">True</Put>
<Put name="Float" type="Float">2.3</Put>
<Put name="Env"><Env name="HOME"/></Put>
<Set name="nested">
<New>
<Class>org.eclipse.jetty.xml.TestConfiguration</Class>
<Set name="testString">nested</Set>
<Set name="nested">
<New class="org.eclipse.jetty.xml.TestConfiguration">
</New>
</Set>
</New>
</Set>
<Call name="call">
</Call>
<Call name="call">
<Arg type="boolean">false</Arg>
</Call>
<Call name="call">
<Arg type="boolean">true</Arg>
<Put name="nested">put</Put>
<Set name="Test">Call1</Set>
<Set name="Test" type="int">4</Set>
<Call>
<Name>call</Name>
<Arg type="URL">http://www.eclipse.com/</Arg>
<Arg type="boolean">false</Arg>
</Call>
</Call>
<Get name="String">
<Call name="toString"/>
</Get>
<Call>
<Name>callStatic</Name>
<Class>org.eclipse.jetty.xml.TestConfiguration</Class>
</Call>
<Call>
<Name>call</Name>
<Arg><Array type="java.lang.Object">
<Item>Blah</Item>
<Item type="String">1.2.3.4:5678</Item>
<Item><New class="java.lang.Double"><Arg>1.2345</Arg></New></Item>
<Item></Item>
</Array></Arg>
</Call>
<Call>
<Name>call</Name>
<Arg><Array type="int">
<Item type="int">1</Item>
<Item type="int">2</Item>
<Item type="int">3</Item>
<Item></Item>
</Array></Arg>
</Call>
<Set name="testField1"><Get class="org.eclipse.jetty.xml.TestConfiguration" name="VALUE"/></Set>
<Set name="testField2"><Get name="testInt"/></Set>
<Set name="VALUE" type="int">42</Set>
</Configure>