Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2015-05-07 06:23:53 +0000
committerGreg Wilkins2015-05-07 06:24:11 +0000
commit5d041ad54f1796d0640623b06678bc58ce4fec93 (patch)
treeb5676466f79a49469c21a572744e50454da3791e /jetty-xml
parentdbf4b2d72dbedcd61b106e4fde943286adf4580f (diff)
downloadorg.eclipse.jetty.project-5d041ad54f1796d0640623b06678bc58ce4fec93.tar.gz
org.eclipse.jetty.project-5d041ad54f1796d0640623b06678bc58ce4fec93.tar.xz
org.eclipse.jetty.project-5d041ad54f1796d0640623b06678bc58ce4fec93.zip
466645 Allow XmlConfiguration Properties to use Elements or Attributes
Diffstat (limited to 'jetty-xml')
-rw-r--r--jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java372
-rw-r--r--jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd9
-rw-r--r--jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_3.dtd280
-rw-r--r--jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java56
-rw-r--r--jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml2
-rw-r--r--jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml2
6 files changed, 603 insertions, 118 deletions
diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
index f5c404a79c..4cd73c9b30 100644
--- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
+++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
@@ -52,6 +52,7 @@ import java.util.regex.Pattern;
import org.eclipse.jetty.util.ArrayQueue;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
@@ -96,6 +97,7 @@ public class XmlConfiguration
URL config60 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd");
URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd");
URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd");
+ URL config93 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_3.dtd");
parser.redirectEntity("configure.dtd",config90);
parser.redirectEntity("configure_1_0.dtd",config60);
parser.redirectEntity("configure_1_1.dtd",config60);
@@ -104,13 +106,14 @@ public class XmlConfiguration
parser.redirectEntity("configure_6_0.dtd",config60);
parser.redirectEntity("configure_7_6.dtd",config76);
parser.redirectEntity("configure_9_0.dtd",config90);
+ parser.redirectEntity("configure_9_3.dtd",config93);
- parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config90);
- parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config90);
- parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config90);
+ parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config93);
+ parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config93);
+ parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config93);
- parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config90);
- parser.redirectEntity("-//Jetty//Configure//EN",config90);
+ parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config93);
+ parser.redirectEntity("-//Jetty//Configure//EN",config93);
return parser;
}
@@ -270,9 +273,11 @@ public class XmlConfiguration
public void initializeDefaults(Object object)
{
}
+
private static class JettyXmlConfiguration implements ConfigurationProcessor
{
+
private String _url;
XmlParser.Node _root;
XmlConfiguration _configuration;
@@ -429,6 +434,12 @@ public class XmlConfiguration
case "Property":
propertyObj(node);
break;
+ case "SystemProperty":
+ systemPropertyObj(node);
+ break;
+ case "Env":
+ envObj(node);
+ break;
default:
throw new IllegalStateException("Unknown tag: " + tag + " in " + _url);
}
@@ -686,49 +697,36 @@ public class XmlConfiguration
*/
private Object call(Object obj, XmlParser.Node node) throws Exception
{
- String id = node.getAttribute("id");
- Class<?> oClass = nodeClass(node);
- if (oClass != null)
- obj = null;
- else if (obj != null)
- oClass = obj.getClass();
- if (oClass == null)
- throw new IllegalArgumentException(node.toString());
+ AttrOrElementNode aoeNode=new AttrOrElementNode(obj,node,"Id","Name","Class","Arg");
+ String id = aoeNode.getString("Id");
+ String name = aoeNode.getString("Name");
+ String clazz = aoeNode.getString("Class");
+ List<Object> args = aoeNode.getList("Arg");
- int size = 0;
- int argIndex = node.size();
- for (int i = 0; i < node.size(); i++)
+
+ Class<?> oClass;
+ if (clazz!=null)
{
- Object o = node.get(i);
- if (o instanceof String)
- continue;
- if (!((XmlParser.Node)o).getTag().equals("Arg"))
- {
- argIndex = i;
- break;
- }
- size++;
+ // static call
+ oClass=Loader.loadClass(XmlConfiguration.class,clazz);
+ obj=null;
}
-
- Object[] arg = new Object[size];
- for (int i = 0, j = 0; j < size; i++)
+ else if (obj!=null)
{
- Object o = node.get(i);
- if (o instanceof String)
- continue;
- arg[j++] = value(obj,(XmlParser.Node)o);
+ oClass = obj.getClass();
}
-
- String method = node.getAttribute("name");
+ else
+ throw new IllegalArgumentException(node.toString());
+
if (LOG.isDebugEnabled())
- LOG.debug("XML call " + method);
+ LOG.debug("XML call " + name);
try
{
- Object n= TypeUtil.call(oClass,method,obj,arg);
+ Object n= TypeUtil.call(oClass,name,obj,args.toArray(new Object[args.size()]));
if (id != null)
_configuration.getIdMap().put(id,n);
- configure(n,node,argIndex);
+ configure(n,node,aoeNode.getNext());
return n;
}
catch (NoSuchMethodException e)
@@ -943,76 +941,124 @@ public class XmlConfiguration
*/
private Object propertyObj(XmlParser.Node node) throws Exception
{
- String idAttr = node.getAttribute("id");
- String nameAttr = node.getAttribute("name");
- String defaultValue = node.getAttribute("default");
+ AttrOrElementNode aoeNode=new AttrOrElementNode(node,"Id","Name","Deprecated","Default");
+ String id = aoeNode.getString("Id");
+ String name = aoeNode.getString("Name",true);
+ List<Object> deprecated = aoeNode.getList("Deprecated");
+ String dftValue = aoeNode.getString("Default");
- Object value = null;
+ // Look for a value
Map<String,String> properties = _configuration.getProperties();
- if (properties != null && nameAttr != null)
- value = resolve(properties, nameAttr);
-
- if (value == null && defaultValue != null)
- value = interpolate(properties, defaultValue);
-
- if (idAttr != null)
- _configuration.getIdMap().put(idAttr, value);
-
- if (value != null)
- configure(value, node, 0);
+ String value = properties.get(name);
+
+ // Look for a deprecated name value
+ if (value==null && !deprecated.isEmpty())
+ {
+ for (Object d : deprecated)
+ {
+ value = properties.get(StringUtil.valueOf(d));
+ if (value!=null)
+ {
+ LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
+ break;
+ }
+ }
+ }
+
+ // use default value
+ if (value==null)
+ value=dftValue;
+ // Set value if ID set
+ if (id != null)
+ _configuration.getIdMap().put(id, value);
return value;
}
- private String resolve(Map<String, String> properties, String nameAttr)
+ /*
+ * Get a SystemProperty.
+ *
+ * @param node
+ * @return
+ * @exception Exception
+ */
+ private Object systemPropertyObj(XmlParser.Node node) throws Exception
{
- String preferredName = null;
- String[] names = nameAttr.split(",");
- for (String name : names)
+ AttrOrElementNode aoeNode=new AttrOrElementNode(node,"Id","Name","Deprecated","Default");
+ String id = aoeNode.getString("Id");
+ String name = aoeNode.getString("Name",true);
+ List<Object> deprecated = aoeNode.getList("Deprecated");
+ String dftValue = aoeNode.getString("Default");
+
+ // Look for a value
+ String value = System.getProperty(name);
+
+ // Look for a deprecated name value
+ if (value==null && !deprecated.isEmpty())
{
- name = name.trim();
- if (name.length() == 0)
- continue;
- if (preferredName == null)
- preferredName = name;
-
- String value = properties.get(name);
- if (value != null)
+ for (Object d : deprecated)
{
- if (!name.equals(preferredName))
- LOG.warn("Property '{}' is deprecated, use '{}' instead", name, preferredName);
- return value;
+ value = System.getProperty(StringUtil.valueOf(d));
+ if (value!=null)
+ {
+ LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
+ break;
+ }
}
}
- return null;
- }
+
+ // use default value
+ if (value==null)
+ value=dftValue;
+
+ // Set value if ID set
+ if (id != null)
+ _configuration.getIdMap().put(id, value);
- private String interpolate(Map<String, String> properties, String text)
+ return value;
+ }
+
+ /*
+ * Get a Environment Property.
+ *
+ * @param node
+ * @return
+ * @exception Exception
+ */
+ private Object envObj(XmlParser.Node node) throws Exception
{
- StringBuilder result = new StringBuilder();
- Matcher matcher = __propertyPattern.matcher(text);
- int start = 0;
- while (matcher.find(start))
+ AttrOrElementNode aoeNode=new AttrOrElementNode(node,"Id","Name","Deprecated","Default");
+ String id = aoeNode.getString("Id");
+ String name = aoeNode.getString("Name",true);
+ List<Object> deprecated = aoeNode.getList("Deprecated");
+ String dftValue = aoeNode.getString("Default");
+
+ // Look for a value
+ String value = System.getenv(name);
+
+ // Look for a deprecated name value
+ if (value==null && !deprecated.isEmpty())
{
- int match = matcher.start();
- result.append(text.substring(start, match));
- String name = matcher.group(1);
- String dftValue = null;
- int bar = name.indexOf('|');
- if (bar > 0)
+ for (Object d : deprecated)
{
- dftValue = name.substring(bar + 1).trim();
- name = name.substring(0, bar).trim();
+ value = System.getenv(StringUtil.valueOf(d));
+ if (value!=null)
+ {
+ LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
+ break;
+ }
}
- String value = resolve(properties, name);
- if (value == null)
- value = dftValue;
- result.append(value);
- start = matcher.end();
}
- result.append(text.substring(start, text.length()));
- String r = result.toString();
- return r.isEmpty() ? null : r;
+
+ // use default value
+ if (value==null)
+ value=dftValue;
+
+ // Set value if ID set
+ if (id != null)
+ _configuration.getIdMap().put(id, value);
+
+ return value;
}
/*
@@ -1186,21 +1232,146 @@ public class XmlConfiguration
if ("Property".equals(tag))
return propertyObj(node);
if ("SystemProperty".equals(tag))
+ return systemPropertyObj(node);
+ if ("Env".equals(tag))
+ return envObj(node);
+
+ LOG.warn("Unknown value tag: " + node,new Throwable());
+ return null;
+ }
+
+
+ private class AttrOrElementNode
+ {
+ final Object _obj;
+ final XmlParser.Node _node;
+ final Set<String> _elements = new HashSet<>();
+ final int _next;
+
+ AttrOrElementNode(XmlParser.Node node,String... elements )
{
- String name = node.getAttribute("name");
- String defaultValue = node.getAttribute("default");
- return System.getProperty(name,defaultValue);
+ this(null,node,elements);
}
- if ("Env".equals(tag))
+
+ AttrOrElementNode(Object obj, XmlParser.Node node,String... elements )
+ {
+ _obj=obj;
+ _node=node;
+ for (String e:elements)
+ _elements.add(e);
+
+ int next=0;
+ for (Object o: _node)
+ {
+ if (o instanceof String)
+ {
+ if (((String)o).trim().length()==0)
+ {
+ next++;
+ continue;
+ }
+ break;
+ }
+
+ if (!(o instanceof XmlParser.Node))
+ break;
+
+ XmlParser.Node n = (XmlParser.Node)o;
+ if (!_elements.contains(n.getTag()))
+ break;
+
+ next++;
+ }
+ _next=next;
+ }
+
+ public int getNext()
{
- String name = node.getAttribute("name");
- String defaultValue = node.getAttribute("default");
- String value=System.getenv(name);
- return value==null?defaultValue:value;
+ return _next;
}
- LOG.warn("Unknown value tag: " + node,new Throwable());
- return null;
+ public String getString(String elementName) throws Exception
+ {
+ return StringUtil.valueOf(get(elementName,false));
+ }
+
+ public Object get(String elementName) throws Exception
+ {
+ return get(elementName,false);
+ }
+
+ public String getString(String elementName, boolean manditory) throws Exception
+ {
+ return StringUtil.valueOf(get(elementName,manditory));
+ }
+
+
+ public Object get(String elementName, boolean manditory) throws Exception
+ {
+ String attrName=StringUtil.asciiToLowerCase(elementName);
+ String attr = _node.getAttribute(attrName);
+ Object value=attr;
+
+ 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+"'");
+
+ value=value(_obj,n);
+ break;
+ }
+ }
+
+ if (manditory && value==null)
+ throw new IllegalStateException("Must have attr '"+attrName+"' or element '"+elementName+"'");
+
+ return value;
+ }
+
+ public List<Object> getList(String elementName) throws Exception
+ {
+ return getList(elementName,false);
+ }
+
+ public List<Object> getList(String elementName, boolean manditory) throws Exception
+ {
+ String attrName=StringUtil.asciiToLowerCase(elementName);
+ final List<Object> values=new ArrayList<>();
+
+ String attr = _node.getAttribute(attrName);
+ if (attr!=null)
+ {
+ for (String a : attr.split(","))
+ values.add(a);
+ }
+
+ 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(value(_obj,n));
+ }
+ }
+
+ if (manditory && values.isEmpty())
+ throw new IllegalStateException("Must have attr '"+attrName+"' or element '"+elementName+"'");
+
+ return values;
+ }
}
}
@@ -1231,7 +1402,6 @@ public class XmlConfiguration
{
try
{
-
Properties properties = null;
// Look for properties from start.jar
diff --git a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd
index 542bc8c9db..7d6045bfb2 100644
--- a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd
+++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd
@@ -274,15 +274,6 @@ Property Element.
This element allows arbitrary properties to be retrieved by name.
The name attribute specifies the property name and the optional
default argument provides a default value.
-
-A Property element can contain a sequence of elements such as Set, Put, Call, etc.
-which act on the retrieved object:
-
- <Property name="Server">
- <Call id="jdbcIdMgr" name="getAttribute">
- <Arg>jdbcIdMgr</Arg>
- </Call>
- </Property>
-->
<!ELEMENT Property (%CONFIG;)* >
<!ATTLIST Property %NAMEATTR; %DEFAULTATTR; %IDATTR; >
diff --git a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_3.dtd b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_3.dtd
new file mode 100644
index 0000000000..1b0b37f06b
--- /dev/null
+++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_3.dtd
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+This is the document type descriptor for the
+org.eclipse.jetty.xml.XmlConfiguration class. It allows a java object to be
+configured by with a sequence of Set, Put and Call elements. These tags are
+mapped to methods on the object to be configured as follows:
+
+ <Set name="Test">value</Set> == obj.setTest("value");
+ <Put name="Test">value</Put> == obj.put("Test","value");
+ <Call name="test"><Arg>value</Arg></Call> == obj.test("value");
+
+Values themselves may be configured objects that are created with the
+<New> tag or returned from a <Call> tag.
+
+Values are matched to arguments on a best effort approach, but types
+my be specified if a match is not achieved.
+
+-->
+
+<!ENTITY % CONFIG "Set|Get|Put|Call|New|Ref|Array|Map|Property">
+<!ENTITY % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|Env|Property">
+
+<!ENTITY % TYPEATTR "type CDATA #IMPLIED " > <!-- String|Character|Short|Byte|Integer|Long|Boolean|Float|Double|char|short|byte|int|long|boolean|float|double|URL|InetAddress|InetAddrPort| #classname -->
+<!ENTITY % IMPLIEDCLASSATTR "class CDATA #IMPLIED" >
+<!ENTITY % CLASSATTR "class CDATA #REQUIRED" >
+<!ENTITY % NAMEATTR "name CDATA #REQUIRED" >
+<!ENTITY % IMPLIEDNAMEATTR "name CDATA #IMPLIED" >
+<!ENTITY % DEPRECATEDATTR "deprecated CDATA #IMPLIED" >
+<!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" >
+<!ENTITY % IDATTR "id ID #IMPLIED" >
+<!ENTITY % ARGATTR "arg CDATA #IMPLIED" >
+<!ENTITY % REFATTR "refid CDATA #IMPLIED" >
+<!ENTITY % REQUIREDIDATTR "id ID #REQUIRED" >
+
+
+<!--
+Configure Element.
+This is the root element that specifies the class of object that
+can be configured:
+
+ <Configure class="com.acme.MyClass"> ... </Configure>
+-->
+<!ELEMENT Configure (Arg*,(%CONFIG;)*) >
+<!ATTLIST Configure %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Set Element.
+This element maps to a call to a setter method or field on the current object.
+The name and optional type attributes are used to select the setter
+method. If the name given is xxx, then a setXxx method is used, or
+the xxx field is used of setXxx cannot be found.
+A Set element can contain value text and/or the value objects returned
+by other elements such as Call, New, SystemProperty, etc.
+If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+
+A Set with a class attribute is treated as a static set method invocation.
+-->
+<!ELEMENT Set (%VALUE;)* >
+<!ATTLIST Set %NAMEATTR; %TYPEATTR; %IMPLIEDCLASSATTR; >
+
+
+<!--
+Get Element.
+This element maps to a call to a getter method or field on the current object.
+The name attribute is used to select the get method.
+If the name given is xxx, then a getXxx method is used, or
+the xxx field is used if getXxx cannot be found.
+A Get element can contain other elements such as Set, Put, Call, etc.
+which act on the object returned by the get call.
+
+A Get with a class attribute is treated as a static get method or field.
+-->
+<!ELEMENT Get (%CONFIG;)* >
+<!ATTLIST Get %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Put Element.
+This element maps to a call to a put method on the current object,
+which must implement the Map interface. The name attribute is used
+as the put key and the optional type attribute can force the type
+of the value.
+
+A Put element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Put (%VALUE;)* >
+<!ATTLIST Put %NAMEATTR; %TYPEATTR; >
+
+
+<!--
+Call Element.
+This element maps to an arbitrary call to a method on the current object,
+The name attribute and Arg elements are used to select the method.
+
+A Call element can contain a sequence of Arg elements followed by
+a sequence of other elements such as Set, Put, Call, etc. which act on any object
+returned by the original call:
+
+ <Call id="o2" name="test">
+ <Arg>value1</Arg>
+ <Set name="Test">Value2</Set>
+ </Call>
+
+This is equivalent to:
+
+ Object o2 = o1.test("value1");
+ o2.setTest("value2");
+
+A Call with a class attribute is treated as a static call.
+-->
+<!ELEMENT Call (Id?,Name?,Class?,Arg*,(%CONFIG;)*) >
+<!ATTLIST Call %ARGATTR; %IMPLIEDNAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Arg Element.
+This element defines a positional or optional named argument for the
+Call and New elements. The optional type attribute can force the type
+of the value.
+
+An Arg element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Arg (%VALUE;)* >
+<!ATTLIST Arg %TYPEATTR; %IMPLIEDNAMEATTR; >
+
+
+<!--
+New Element.
+This element allows the creation of a new object as part of a
+value for elements such as Set, Put, Arg, etc. The class attribute
+determines the type of the new object and the contained Arg elements
+are used to select the constructor for the new object.
+
+A New element can contain a sequence of Arg elements followed by
+a sequence of elements such as Set, Put, Call, etc. elements
+which act on the new object:
+
+ <New id="o" class="com.acme.MyClass">
+ <Arg>value1</Arg>
+ <Set name="test">Value2</Set>
+ </New>
+
+This is equivalent to:
+
+ Object o = new com.acme.MyClass("value1");
+ o.setTest("Value2");
+-->
+<!ELEMENT New (Arg*,(%CONFIG;)*) >
+<!ATTLIST New %CLASSATTR; %IDATTR;>
+
+
+<!--
+Ref Element.
+This element allows a previously created object to be referenced by id. The
+attribute refid is used to specify the id of another object (the attribute id can
+also be used, but it's use is deprecated).
+A Ref element can contain a sequence of elements such as Set, Put, Call, etc.
+which act on the referenced object.
+
+ <Ref refid="myobject">
+ <Set name="Test">Value2</Set>
+ </New>
+-->
+<!ELEMENT Ref (%CONFIG;)* >
+<!ATTLIST Ref %IDATTR; %REFATTR;>
+
+
+<!--
+Array Element.
+This element allows the creation of a new array as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Array type="java.lang.String">
+ <Item>value0</Item>
+ <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+ </Array>
+
+This is equivalent to:
+ String[] a = new String[] { "value0", new String("value1") };
+-->
+<!ELEMENT Array (Item*) >
+<!ATTLIST Array %TYPEATTR; %IDATTR; >
+
+
+<!--
+Map Element.
+This element allows the creation of a new map as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Map>
+ <Entry>
+ <Item>keyName</Item>
+ <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+ </Entry>
+ </Map>
+
+This is equivalent to:
+ Map m = new HashMap();
+ m.put("keyName", new String("value1"));
+-->
+<!ELEMENT Map (Entry*) >
+<!ATTLIST Map %IDATTR; >
+<!ELEMENT Entry (Item,Item) >
+
+
+<!--
+Item Element.
+This element defines an entry for the Array or Map Entry elements.
+The optional type attribute can force the type of the value.
+
+An Item element can contain value text and/or the value object of
+elements such as Call, New, SystemProperty, etc. If no value type
+is specified, then white space is trimmed out of the value.
+If it contains multiple value elements they are added as strings
+before being converted to any specified type.
+-->
+<!ELEMENT Item (%VALUE;)* >
+<!ATTLIST Item %TYPEATTR; %IDATTR; >
+
+
+<!--
+System Property Element.
+This element allows JVM System properties to be retrieved as
+part of the value of elements such as Set, Put, Arg, etc.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+
+ <SystemProperty name="Test" default="value" />
+
+This is equivalent to:
+
+ System.getProperty("Test","value");
+-->
+<!ELEMENT SystemProperty (Id?,Name?,Deprecated*,Default?) >
+<!ATTLIST SystemProperty %IMPLIEDNAMEATTR; %DEFAULTATTR; %DEPRECATEDATTR; %IDATTR; >
+
+<!--
+Environment variable Element.
+This element allows OS Environment variables to be retrieved as
+part of the value of elements such as Set, Put, Arg, etc.
+The name attribute specifies the env variable name and the optional
+default argument provides a default value.
+
+ <Env name="Test" default="value" />
+
+This is equivalent to:
+
+ String v=System.getEnv("Test");
+ if (v==null) v="value";
+
+-->
+<!ELEMENT Env (Id?,Name?,Deprecated*,Default?) >
+<!ATTLIST Env %IMPLIEDNAMEATTR; %DEFAULTATTR; %DEPRECATEDATTR; %IDATTR; >
+
+
+<!--
+Property Element.
+This element allows arbitrary properties to be retrieved by name.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+-->
+<!ELEMENT Property (Id?,Name?,Deprecated*,Default?) >
+<!ATTLIST Property %IMPLIEDNAMEATTR; %DEFAULTATTR; %DEPRECATEDATTR; %IDATTR; >
diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
index 1cc9a61c83..aeb90ca928 100644
--- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
+++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java
@@ -787,7 +787,7 @@ public class XmlConfigurationTest
String defolt = "baz";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
- " <Set name=\"first\"><Property name=\"foo,bar\" default=\"" + defolt + "\"/></Set> " +
+ " <Set name=\"first\"><Property name=\"wibble\" deprecated=\"foo,bar\" default=\"" + defolt + "\"/></Set> " +
"</Configure>");
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
assertEquals(defolt, config.getFirst());
@@ -800,7 +800,7 @@ public class XmlConfigurationTest
String value = "foo";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
- " <Set name=\"first\"><Property name=\"" + name + ",bar\" default=\"baz\"/></Set> " +
+ " <Set name=\"first\"><Property name=\"" + name + "\" deprecated=\"other,bar\" default=\"baz\"/></Set> " +
"</Configure>");
xmlConfiguration.getProperties().put(name, value);
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
@@ -814,7 +814,42 @@ public class XmlConfigurationTest
String value = "bar";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
- " <Set name=\"first\"><Property name=\"foo," + name + "\" default=\"baz\"/></Set> " +
+ " <Set name=\"first\"><Property name=\"foo\" deprecated=\"" + name + "\" default=\"baz\"/></Set> " +
+ "</Configure>");
+ xmlConfiguration.getProperties().put(name, value);
+ DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
+ assertEquals(value, config.getFirst());
+ }
+
+ @Test
+ public void testWithMultiplePropertyNamesWithDeprecatedThenThirdIsChosen() throws Exception
+ {
+ String name = "bar";
+ String value = "bar";
+ XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
+ "<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
+ " <Set name=\"first\"><Property name=\"foo\" deprecated=\"other," + name + "\" default=\"baz\"/></Set> " +
+ "</Configure>");
+ xmlConfiguration.getProperties().put(name, value);
+ DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
+ assertEquals(value, config.getFirst());
+ }
+
+ @Test
+ public void testWithMultiplePropertyNameElementsWithDeprecatedThenThirdIsChosen() throws Exception
+ {
+ String name = "bar";
+ String value = "bar";
+ XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
+ "<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
+ " <Set name=\"first\">" +
+ " <Property> " +
+ " <Name>foo</Name>" +
+ " <Deprecated>foo</Deprecated>" +
+ " <Deprecated>"+name+"</Deprecated>" +
+ " <Default>baz</Default>" +
+ " </Property> " +
+ " </Set> " +
"</Configure>");
xmlConfiguration.getProperties().put(name, value);
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
@@ -826,11 +861,16 @@ public class XmlConfigurationTest
{
String name = "bar";
String value = "bar";
- String defaultValue = "_${bar}_${bar}_";
+ String defaultValue = "_<Property name=\"bar\"/>_<Property name=\"bar\"/>_";
String expectedValue = "_" + value + "_" + value + "_";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
- " <Set name=\"first\"><Property name=\"not_found\" default=\"" + defaultValue + "\"/></Set> " +
+ " <Set name=\"first\">" +
+ " <Property>" +
+ " <Name>not_found</Name>" +
+ " <Default>" + defaultValue + "</Default>" +
+ " </Property>" +
+ " </Set> " +
"</Configure>");
xmlConfiguration.getProperties().put(name, value);
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
@@ -843,7 +883,11 @@ public class XmlConfigurationTest
String value = "bar";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
- " <Set name=\"first\"><Property name=\"not_found\" default=\"${not_found|" + value + "}\"/></Set> " +
+ " <Set name=\"first\">" +
+ " <Property name=\"not_found\">" +
+ " <Default><Property name=\"also_not_found\" default=\"" + value + "\"/></Default>" +
+ " </Property>" +
+ " </Set> " +
"</Configure>");
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
assertEquals(value, config.getFirst());
diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
index 46c85718cf..29f3de97e1 100644
--- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
+++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/configure.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<!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>
diff --git a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml
index 08e75df181..c8e20cee27 100644
--- a/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml
+++ b/jetty-xml/src/test/resources/org/eclipse/jetty/xml/mortbay.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure_9_0.dtd">
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure_9_3.dtd">
<Configure class="java.lang.Object">
</Configure>

Back to the top