382343 - Jetty XML support for Map is broken.

This commit is contained in:
Simone Bordet 2012-06-12 13:12:17 +02:00
parent bb3fa1cd7a
commit 1aebddfaf7
3 changed files with 100 additions and 58 deletions

View File

@ -71,7 +71,6 @@ public class XmlConfiguration
private static final Class<?>[] __primitiveHolders = private static final Class<?>[] __primitiveHolders =
{ Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class }; { Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class };
private static final Integer ZERO = new Integer(0);
private static final Class<?>[] __supportedCollections = private static final Class<?>[] __supportedCollections =
{ ArrayList.class,ArrayQueue.class,HashSet.class,Queue.class,List.class,Set.class,Collection.class,}; { ArrayList.class,ArrayQueue.class,HashSet.class,Queue.class,List.class,Set.class,Collection.class,};
@ -141,9 +140,11 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Constructor. Reads the XML configuration file. * Reads and parses the XML configuration file.
* *
* @param configuration * @param configuration the URL of the XML configuration
* @throws IOException if the configuration could not be read
* @throws SAXException if the configuration could not be parsed
*/ */
public XmlConfiguration(URL configuration) throws SAXException, IOException public XmlConfiguration(URL configuration) throws SAXException, IOException
{ {
@ -157,12 +158,12 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Constructor. * Reads and parses the XML configuration string.
* *
* @param configuration * @param configuration String of XML configuration commands excluding the normal XML preamble.
* String of XML configuration commands excluding the normal XML preamble. The String should start with a " <Configure ...." element. * The String should start with a "&lt;Configure ....&gt;" element.
* @exception SAXException * @throws IOException if the configuration could not be read
* @exception IOException * @throws SAXException if the configuration could not be parsed
*/ */
public XmlConfiguration(String configuration) throws SAXException, IOException public XmlConfiguration(String configuration) throws SAXException, IOException
{ {
@ -178,12 +179,11 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Constructor. * Reads and parses the XML configuration stream.
* *
* @param configuration * @param configuration An input stream containing a complete configuration file
* An input stream containing a complete e.g. configuration file * @throws IOException if the configuration could not be read
* @exception SAXException * @throws SAXException if the configuration could not be parsed
* @exception IOException
*/ */
public XmlConfiguration(InputStream configuration) throws SAXException, IOException public XmlConfiguration(InputStream configuration) throws SAXException, IOException
{ {
@ -240,6 +240,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param map the ID map
* @deprecated use {@link #getIdMap()}.put(...) * @deprecated use {@link #getIdMap()}.put(...)
*/ */
@Deprecated @Deprecated
@ -251,6 +252,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param map the properties map
* @deprecated use {@link #getProperties()}.putAll(...) * @deprecated use {@link #getProperties()}.putAll(...)
*/ */
@Deprecated @Deprecated
@ -268,13 +270,12 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Configure an object. * Applies the XML configuration script to the given object.
* *
* <p>Apply the XML configuration script to the passed object.</p> * @param obj The object to be configured, which must be of a type or super type
* * of the class attribute of the &lt;Configure&gt; element.
* @param obj * @throws Exception if the configuration fails
* The object to be configured, which must be of a type or super type of the class attribute of the Configure element. * @return the configured object
* @exception Exception
*/ */
public Object configure(Object obj) throws Exception public Object configure(Object obj) throws Exception
{ {
@ -283,10 +284,13 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Configure an object. If the configuration has an ID, an object is looked up by ID and it's type check. Otherwise a new object is created. * Applies the XML configuration script.
* If the root element of the configuration has an ID, an object is looked up by ID and its type checked
* against the root element's type.
* Otherwise a new object of the type specified by the root element is created.
* *
* @return The newly created configured object. * @return The newly created configured object.
* @exception Exception * @throws Exception if the configuration fails
*/ */
public Object configure() throws Exception public Object configure() throws Exception
{ {
@ -353,12 +357,13 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Recursive configuration step. This method applies the remaining Set, Put and Call elements to the current object. * Recursive configuration routine.
* This method applies the nested Set, Put, Call, etc. elements to the given object.
* *
* @param obj * @param obj the object to configure
* @param cfg * @param cfg the XML nodes of the configuration
* @param i * @param i the index of the XML nodes
* @exception Exception * @throws Exception if the configuration fails
*/ */
public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception
{ {
@ -576,7 +581,9 @@ public class XmlConfiguration
} }
/** /**
* @return a collection if compareValueToClass is a Set or List. null if that's not the case or value can't be converted to a Collection * @param array the array to convert
* @param collectionType the desired collection type
* @return a collection of the desired type if the array can be converted
*/ */
private static Collection<?> convertArrayToCollection(Object array, Class<?> collectionType) private static Collection<?> convertArrayToCollection(Object array, Class<?> collectionType)
{ {
@ -862,7 +869,7 @@ public class XmlConfiguration
XmlParser.Node item = (Node)nodeObject; XmlParser.Node item = (Node)nodeObject;
String nid = item.getAttribute("id"); String nid = item.getAttribute("id");
Object v = value(obj,item); Object v = value(obj,item);
al = LazyList.add(al,(v == null && aClass.isPrimitive())?ZERO:v); al = LazyList.add(al,(v == null && aClass.isPrimitive())?0:v);
if (nid != null) if (nid != null)
_idMap.put(nid,v); _idMap.put(nid,v);
} }
@ -896,7 +903,7 @@ public class XmlConfiguration
XmlParser.Node key = null; XmlParser.Node key = null;
XmlParser.Node value = null; XmlParser.Node value = null;
for (Object object : node) for (Object object : entry)
{ {
if (object instanceof String) if (object instanceof String)
continue; continue;
@ -939,12 +946,12 @@ public class XmlConfiguration
{ {
String id = node.getAttribute("id"); String id = node.getAttribute("id");
String name = node.getAttribute("name"); String name = node.getAttribute("name");
String defval = node.getAttribute("default"); String defaultValue = node.getAttribute("default");
Object prop = null; Object prop;
if (_propertyMap != null && _propertyMap.containsKey(name)) if (_propertyMap != null && _propertyMap.containsKey(name))
prop = _propertyMap.get(name); prop = _propertyMap.get(name);
else else
prop = defval; prop = defaultValue;
if (id != null) if (id != null)
_idMap.put(id,prop); _idMap.put(id,prop);
if (prop != null) if (prop != null)
@ -960,7 +967,7 @@ public class XmlConfiguration
*/ */
private Object value(Object obj, XmlParser.Node node) throws Exception private Object value(Object obj, XmlParser.Node node) throws Exception
{ {
Object value = null; Object value;
// Get the type // Get the type
String type = node.getAttribute("type"); String type = node.getAttribute("type");
@ -989,7 +996,7 @@ public class XmlConfiguration
if (type == null || !"String".equals(type)) if (type == null || !"String".equals(type))
{ {
// Skip leading white // Skip leading white
Object item = null; Object item;
while (first <= last) while (first <= last)
{ {
item = node.get(first); item = node.get(first);
@ -1097,8 +1104,7 @@ public class XmlConfiguration
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private static boolean isTypeMatchingClass(String type, Class<?> classToMatch) private static boolean isTypeMatchingClass(String type, Class<?> classToMatch)
{ {
boolean match = classToMatch.getSimpleName().equalsIgnoreCase(type) || classToMatch.getName().equals(type); return classToMatch.getSimpleName().equalsIgnoreCase(type) || classToMatch.getName().equals(type);
return match;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -1167,6 +1173,7 @@ public class XmlConfiguration
* *
* @param args * @param args
* array of property and xml configuration filenames or {@link Resource}s. * array of property and xml configuration filenames or {@link Resource}s.
* @throws Exception if the XML configurations cannot be run
*/ */
public static void main(final String[] args) throws Exception public static void main(final String[] args) throws Exception
{ {

View File

@ -18,6 +18,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.junit.Ignore; import org.junit.Ignore;
@ -42,6 +43,7 @@ public class TestConfiguration extends HashMap<String,Object>
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private Set set; private Set set;
private ConstructorArgTestClass constructorArgTestClass; private ConstructorArgTestClass constructorArgTestClass;
public Map map;
public void setTest(Object value) public void setTest(Object value)
{ {
@ -141,4 +143,9 @@ public class TestConfiguration extends HashMap<String,Object>
{ {
this.constructorArgTestClass = constructorArgTestClass; this.constructorArgTestClass = constructorArgTestClass;
} }
public void setMap(Map map)
{
this.map = map;
}
} }

View File

@ -13,16 +13,20 @@
package org.eclipse.jetty.xml; package org.eclipse.jetty.xml;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import java.net.URL; import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class XmlConfigurationTest public class XmlConfigurationTest
{ {
protected String _configure="org/eclipse/jetty/xml/configure.xml"; protected String _configure="org/eclipse/jetty/xml/configure.xml";
@ -314,4 +318,28 @@ public class XmlConfigurationTest
xmlConfiguration.configure(tc); xmlConfiguration.configure(tc);
assertThat("tc.getSet() has two entries as specified in the xml",tc.getSet().size(),is(2)); assertThat("tc.getSet() has two entries as specified in the xml",tc.getSet().size(),is(2));
} }
@Test
public void testMap() throws Exception
{
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\">" +
" <Set name=\"map\">" +
" <Map>" +
" <Entry>" +
" <Item>key1</Item>" +
" <Item>value1</Item>" +
" </Entry>" +
" <Entry>" +
" <Item>key2</Item>" +
" <Item>value2</Item>" +
" </Entry>" +
" </Map>" +
" </Set>" +
"</Configure>");
TestConfiguration tc = new TestConfiguration();
Assert.assertNull("tc.map is null as it's not configured yet", tc.map);
xmlConfiguration.configure(tc);
Assert.assertEquals("tc.map is has two entries as specified in the XML", 2, tc.map.size());
}
} }