Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.
This commit is contained in:
commit
f5cfa2bf7d
|
@ -23,6 +23,7 @@ import java.io.InputStream;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -39,9 +40,9 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
@ -51,7 +52,6 @@ import java.util.Queue;
|
|||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
|
@ -82,21 +82,37 @@ import org.xml.sax.SAXException;
|
|||
public class XmlConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(XmlConfiguration.class);
|
||||
private static final Class<?>[] __primitives =
|
||||
private static final Class<?>[] PRIMITIVES =
|
||||
{
|
||||
Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
|
||||
};
|
||||
private static final Class<?>[] BOXED_PRIMITIVES =
|
||||
{
|
||||
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
|
||||
Void.class
|
||||
};
|
||||
private static final Class<?>[] SUPPORTED_COLLECTIONS =
|
||||
{
|
||||
ArrayList.class, HashSet.class, Queue.class, List.class, Set.class, Collection.class
|
||||
};
|
||||
private static final Iterable<ConfigurationProcessorFactory> PROCESSOR_FACTORIES = ServiceLoader.load(ConfigurationProcessorFactory.class);
|
||||
private static final XmlParser PARSER = initParser();
|
||||
private static final Comparator<Executable> EXECUTABLE_COMPARATOR = (o1, o2) ->
|
||||
{
|
||||
Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
|
||||
int p1 = o1.getParameterCount();
|
||||
int p2 = o2.getParameterCount();
|
||||
int compare = Integer.compare(p1, p2);
|
||||
if (compare == 0 && p1 > 0)
|
||||
{
|
||||
boolean a1 = o1.getParameterTypes()[p1 - 1].isArray();
|
||||
boolean a2 = o2.getParameterTypes()[p2 - 1].isArray();
|
||||
if (a1 && !a2)
|
||||
compare = 1;
|
||||
else if (!a1 && a2)
|
||||
compare = -1;
|
||||
}
|
||||
return compare;
|
||||
};
|
||||
private static final Class<?>[] __boxedPrimitives =
|
||||
{
|
||||
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
|
||||
Void.class
|
||||
};
|
||||
private static final Class<?>[] __supportedCollections =
|
||||
{
|
||||
ArrayList.class, HashSet.class, Queue.class, List.class, Set.class, Collection.class
|
||||
};
|
||||
private static final Iterable<ConfigurationProcessorFactory> __factoryLoader = ServiceLoader.load(ConfigurationProcessorFactory.class);
|
||||
private static final XmlParser __parser = initParser();
|
||||
|
||||
private static XmlParser initParser()
|
||||
{
|
||||
|
@ -201,14 +217,14 @@ public class XmlConfiguration
|
|||
*/
|
||||
public XmlConfiguration(Resource resource) throws SAXException, IOException
|
||||
{
|
||||
synchronized (__parser)
|
||||
synchronized (PARSER)
|
||||
{
|
||||
_location = resource;
|
||||
try (InputStream inputStream = resource.getInputStream())
|
||||
{
|
||||
setConfig(__parser.parse(inputStream));
|
||||
setConfig(PARSER.parse(inputStream));
|
||||
}
|
||||
_dtd = __parser.getDTD();
|
||||
_dtd = PARSER.getDTD();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,9 +244,9 @@ public class XmlConfiguration
|
|||
{
|
||||
_processor = new JettyXmlConfiguration();
|
||||
}
|
||||
else if (__factoryLoader != null)
|
||||
else if (PROCESSOR_FACTORIES != null)
|
||||
{
|
||||
for (ConfigurationProcessorFactory factory : __factoryLoader)
|
||||
for (ConfigurationProcessorFactory factory : PROCESSOR_FACTORIES)
|
||||
{
|
||||
_processor = factory.getConfigurationProcessor(_dtd, config.getTag());
|
||||
if (_processor != null)
|
||||
|
@ -356,39 +372,13 @@ public class XmlConfiguration
|
|||
int index = 0;
|
||||
if (obj == null && oClass != null)
|
||||
{
|
||||
index = _root.size();
|
||||
Map<String, Object> namedArgMap = new HashMap<>();
|
||||
|
||||
List<Object> arguments = new LinkedList<>();
|
||||
for (int i = 0; i < _root.size(); i++)
|
||||
{
|
||||
Object o = _root.get(i);
|
||||
if (o instanceof String)
|
||||
continue;
|
||||
|
||||
XmlParser.Node node = (XmlParser.Node)o;
|
||||
if (node.getTag().equals("Arg"))
|
||||
{
|
||||
String namedAttribute = node.getAttribute("name");
|
||||
Object value = value(null, (XmlParser.Node)o);
|
||||
if (namedAttribute != null)
|
||||
namedArgMap.put(namedAttribute, value);
|
||||
arguments.add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
obj = construct(oClass, arguments.toArray(), namedArgMap);
|
||||
obj = construct(oClass, new Args(null, oClass, XmlConfiguration.getNodes(_root, "Arg")));
|
||||
}
|
||||
catch (NoSuchMethodException x)
|
||||
{
|
||||
throw new IllegalStateException(String.format("No constructor %s(%s,%s) in %s", oClass, arguments, namedArgMap, _configuration));
|
||||
throw new IllegalStateException(String.format("No matching constructor %s in %s", oClass, _configuration));
|
||||
}
|
||||
}
|
||||
if (id != null)
|
||||
|
@ -399,6 +389,14 @@ public class XmlConfiguration
|
|||
return obj;
|
||||
}
|
||||
|
||||
private static Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException
|
||||
{
|
||||
String className = node.getAttribute("class");
|
||||
if (className == null)
|
||||
return null;
|
||||
return Loader.loadClass(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive configuration routine.
|
||||
* This method applies the nested Set, Put, Call, etc. elements to the given object.
|
||||
|
@ -483,14 +481,6 @@ public class XmlConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
private static Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException
|
||||
{
|
||||
String className = node.getAttribute("class");
|
||||
if (className == null)
|
||||
return null;
|
||||
return Loader.loadClass(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Call a setter method.</p>
|
||||
* <p>This method makes a best effort to find a matching set method.
|
||||
|
@ -637,7 +627,7 @@ public class XmlConfiguration
|
|||
|
||||
try
|
||||
{
|
||||
for (Class<?> c : __supportedCollections)
|
||||
for (Class<?> c : SUPPORTED_COLLECTIONS)
|
||||
{
|
||||
if (paramTypes[0].isAssignableFrom(c))
|
||||
{
|
||||
|
@ -663,11 +653,11 @@ public class XmlConfiguration
|
|||
Class<?> sClass = set.getParameterTypes()[0];
|
||||
if (sClass.isPrimitive())
|
||||
{
|
||||
for (int t = 0; t < __primitives.length; t++)
|
||||
for (int t = 0; t < PRIMITIVES.length; t++)
|
||||
{
|
||||
if (sClass.equals(__primitives[t]))
|
||||
if (sClass.equals(PRIMITIVES[t]))
|
||||
{
|
||||
sClass = __boxedPrimitives[t];
|
||||
sClass = BOXED_PRIMITIVES[t];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -863,7 +853,6 @@ public class XmlConfiguration
|
|||
String id = aoeNode.getString("Id");
|
||||
String name = aoeNode.getString("Name");
|
||||
String clazz = aoeNode.getString("Class");
|
||||
List<Object> args = aoeNode.getList("Arg");
|
||||
|
||||
Class<?> oClass;
|
||||
if (clazz != null)
|
||||
|
@ -884,7 +873,7 @@ public class XmlConfiguration
|
|||
|
||||
try
|
||||
{
|
||||
Object nobj = call(oClass, name, obj, args.toArray(new Object[0]));
|
||||
Object nobj = call(oClass, name, obj, new Args(obj, oClass, aoeNode.getNodes("Arg")));
|
||||
if (id != null)
|
||||
_configuration.getIdMap().put(id, nobj);
|
||||
configure(nobj, node, aoeNode.getNext());
|
||||
|
@ -896,7 +885,7 @@ public class XmlConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
private Object call(Class<?> oClass, String methodName, Object obj, Object[] arg) throws InvocationTargetException, NoSuchMethodException
|
||||
private Object call(Class<?> oClass, String methodName, Object obj, Args args) throws InvocationTargetException, NoSuchMethodException
|
||||
{
|
||||
Objects.requireNonNull(oClass, "Class cannot be null");
|
||||
Objects.requireNonNull(methodName, "Method name cannot be null");
|
||||
|
@ -904,11 +893,15 @@ public class XmlConfiguration
|
|||
throw new IllegalArgumentException("Method name cannot be blank");
|
||||
|
||||
// Lets just try all methods for now
|
||||
for (Method method : oClass.getMethods())
|
||||
|
||||
Method[] methods = oClass.getMethods();
|
||||
Arrays.sort(methods, EXECUTABLE_COMPARATOR);
|
||||
for (Method method : methods)
|
||||
{
|
||||
if (!method.getName().equals(methodName))
|
||||
continue;
|
||||
if (method.getParameterCount() != arg.length)
|
||||
Object[] arguments = args.applyTo(method);
|
||||
if (arguments == null)
|
||||
continue;
|
||||
if (Modifier.isStatic(method.getModifiers()) != (obj == null))
|
||||
continue;
|
||||
|
@ -917,34 +910,7 @@ public class XmlConfiguration
|
|||
|
||||
try
|
||||
{
|
||||
return invokeMethod(method, obj, arg);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Lets look for a method with varargs arguments
|
||||
Object[] argsWithVarargs = null;
|
||||
for (Method method : oClass.getMethods())
|
||||
{
|
||||
if (!method.getName().equals(methodName))
|
||||
continue;
|
||||
if (method.getParameterCount() != arg.length + 1)
|
||||
continue;
|
||||
if (!method.getParameterTypes()[arg.length].isArray())
|
||||
continue;
|
||||
if (Modifier.isStatic(method.getModifiers()) != (obj == null))
|
||||
continue;
|
||||
if ((obj == null) && method.getDeclaringClass() != oClass)
|
||||
continue;
|
||||
|
||||
if (argsWithVarargs == null)
|
||||
argsWithVarargs = ArrayUtil.addToArray(arg, new Object[0], Object.class);
|
||||
try
|
||||
{
|
||||
return invokeMethod(method, obj, argsWithVarargs);
|
||||
return invokeMethod(method, obj, arguments);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException e)
|
||||
{
|
||||
|
@ -964,36 +930,19 @@ public class XmlConfiguration
|
|||
*/
|
||||
private Object newObj(Object obj, XmlParser.Node node) throws Exception
|
||||
{
|
||||
final AttrOrElementNode aoeNode = new AttrOrElementNode(obj, node, "Id", "Class", "Arg");
|
||||
final String id = aoeNode.getString("Id");
|
||||
final String clazz = aoeNode.getString("Class");
|
||||
final List<XmlParser.Node> argNodes = aoeNode.getNodes("Arg");
|
||||
AttrOrElementNode aoeNode = new AttrOrElementNode(obj, node, "Id", "Class", "Arg");
|
||||
String id = aoeNode.getString("Id");
|
||||
String clazz = aoeNode.getString("Class");
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("XML new " + clazz);
|
||||
|
||||
Class<?> oClass = Loader.loadClass(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
|
||||
{
|
||||
nobj = construct(oClass, arguments.toArray(), namedArgMap);
|
||||
nobj = construct(oClass, new Args(obj, oClass, aoeNode.getNodes("Arg")));
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
|
@ -1008,80 +957,20 @@ public class XmlConfiguration
|
|||
return nobj;
|
||||
}
|
||||
|
||||
private Object construct(Class<?> klass, Object[] arguments, Map<String, Object> namedArgMap) throws InvocationTargetException, NoSuchMethodException
|
||||
private Object construct(Class<?> klass, Args args) throws InvocationTargetException, NoSuchMethodException
|
||||
{
|
||||
Objects.requireNonNull(klass, "Class cannot be null");
|
||||
Objects.requireNonNull(namedArgMap, "Named Argument Map cannot be null");
|
||||
Objects.requireNonNull(args, "Named list cannot be null");
|
||||
|
||||
for (Constructor<?> constructor : klass.getConstructors())
|
||||
Constructor<?>[] constructors = klass.getConstructors();
|
||||
Arrays.sort(constructors, EXECUTABLE_COMPARATOR);
|
||||
for (Constructor<?> constructor : constructors)
|
||||
{
|
||||
if (arguments == null)
|
||||
{
|
||||
// null arguments in .newInstance() is allowed
|
||||
if (constructor.getParameterCount() != 0)
|
||||
continue;
|
||||
}
|
||||
else if (constructor.getParameterCount() != arguments.length)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (arguments == null || arguments.length == 0)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Invoking constructor, no arguments");
|
||||
return invokeConstructor(constructor);
|
||||
}
|
||||
|
||||
if (namedArgMap.isEmpty())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Invoking constructor, no XML parameter mapping");
|
||||
Object[] arguments = args.applyTo(constructor);
|
||||
if (arguments != null)
|
||||
return invokeConstructor(constructor, arguments);
|
||||
}
|
||||
|
||||
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
|
||||
if (parameterAnnotations == null || parameterAnnotations.length == 0)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Invoking constructor, no parameter annotations");
|
||||
return invokeConstructor(constructor, arguments);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
Object[] swizzled = new Object[arguments.length];
|
||||
for (Annotation[] annotations : parameterAnnotations)
|
||||
{
|
||||
for (Annotation annotation : annotations)
|
||||
{
|
||||
if (annotation instanceof Name)
|
||||
{
|
||||
Name param = (Name)annotation;
|
||||
if (namedArgMap.containsKey(param.value()))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Mapping named parameter {} in position {}", param.value(), count);
|
||||
swizzled[count] = namedArgMap.get(param.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Mapping argument {} in position {}", arguments[count], count);
|
||||
swizzled[count] = arguments[count];
|
||||
}
|
||||
++count;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Skipping parameter annotated with {}", annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return invokeConstructor(constructor, swizzled);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException e)
|
||||
{
|
||||
|
@ -1228,11 +1117,11 @@ public class XmlConfiguration
|
|||
*/
|
||||
private Object propertyObj(XmlParser.Node node) throws Exception
|
||||
{
|
||||
final AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default");
|
||||
final String id = aoeNode.getString("Id");
|
||||
final String name = aoeNode.getString("Name", true);
|
||||
final List<Object> deprecated = aoeNode.getList("Deprecated");
|
||||
final String dftValue = aoeNode.getString("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");
|
||||
|
||||
// Look for a value
|
||||
Map<String, String> properties = _configuration.getProperties();
|
||||
|
@ -1279,11 +1168,11 @@ public class XmlConfiguration
|
|||
*/
|
||||
private Object systemPropertyObj(XmlParser.Node node) throws Exception
|
||||
{
|
||||
final AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default");
|
||||
final String id = aoeNode.getString("Id");
|
||||
final String name = aoeNode.getString("Name", true);
|
||||
final List<Object> deprecated = aoeNode.getList("Deprecated");
|
||||
final String dftValue = aoeNode.getString("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");
|
||||
|
||||
// Look for a value
|
||||
String value = System.getProperty(name);
|
||||
|
@ -1509,7 +1398,7 @@ public class XmlConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
for (Class<?> collectionClass : __supportedCollections)
|
||||
for (Class<?> collectionClass : SUPPORTED_COLLECTIONS)
|
||||
{
|
||||
if (isTypeMatchingClass(type, collectionClass))
|
||||
return convertArrayToCollection(value, collectionClass);
|
||||
|
@ -1685,40 +1574,151 @@ public class XmlConfiguration
|
|||
|
||||
public List<XmlParser.Node> getNodes(String elementName)
|
||||
{
|
||||
String attrName = StringUtil.asciiToLowerCase(elementName);
|
||||
final List<XmlParser.Node> values = new ArrayList<>();
|
||||
|
||||
String attr = _node.getAttribute(attrName);
|
||||
if (attr != null)
|
||||
{
|
||||
for (String a : StringUtil.csvSplit(null, attr, 0, attr.length()))
|
||||
{
|
||||
// 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;
|
||||
return XmlConfiguration.getNodes(_node, elementName);
|
||||
}
|
||||
}
|
||||
|
||||
private class Args
|
||||
{
|
||||
private final Class<?> _class;
|
||||
private final List<Object> _arguments;
|
||||
private final List<String> _names;
|
||||
|
||||
private Args(Object obj, Class<?> oClass, List<XmlParser.Node> args) throws Exception
|
||||
{
|
||||
_class = oClass;
|
||||
_arguments = new ArrayList<>();
|
||||
_names = new ArrayList<>();
|
||||
for (XmlParser.Node child : args)
|
||||
{
|
||||
_arguments.add(value(obj, child));
|
||||
_names.add(child.getAttribute("name"));
|
||||
}
|
||||
}
|
||||
|
||||
private Args(List<Object> arguments, List<String> names)
|
||||
{
|
||||
_class = null;
|
||||
_arguments = arguments;
|
||||
_names = names;
|
||||
}
|
||||
|
||||
Object[] applyTo(Executable executable)
|
||||
{
|
||||
Object[] args = matchArgsToParameters(executable);
|
||||
if (args == null && _class != null)
|
||||
{
|
||||
// Could this be an empty varargs match?
|
||||
int count = executable.getParameterCount();
|
||||
if (count > 0 && executable.getParameterTypes()[count - 1].isArray())
|
||||
{
|
||||
// There is not a no varArgs alternative so let's try a an empty varArgs match
|
||||
args = asEmptyVarArgs(executable.getParameterTypes()[count - 1]).matchArgsToParameters(executable);
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
Args asEmptyVarArgs(Class<?> varArgType)
|
||||
{
|
||||
List<Object> arguments = new ArrayList<>(_arguments);
|
||||
arguments.add(Array.newInstance(varArgType.getComponentType(), 0));
|
||||
List<String> names = new ArrayList<>(_names);
|
||||
names.add(null);
|
||||
return new Args(arguments, names);
|
||||
}
|
||||
|
||||
Object[] matchArgsToParameters(Executable executable)
|
||||
{
|
||||
int count = executable.getParameterCount();
|
||||
|
||||
// No match of wrong number of parameters
|
||||
if (count != _arguments.size())
|
||||
return null;
|
||||
|
||||
// Handle no parameter case
|
||||
if (count == 0)
|
||||
return new Object[0];
|
||||
|
||||
// If no arg names are specified, keep the arg order
|
||||
if (_names.stream().noneMatch(Objects::nonNull))
|
||||
return _arguments.toArray(new Object[0]);
|
||||
|
||||
// If we don't have any parameters with names, then no match
|
||||
Annotation[][] parameterAnnotations = executable.getParameterAnnotations();
|
||||
if (parameterAnnotations == null || parameterAnnotations.length == 0)
|
||||
return null;
|
||||
|
||||
// Find the position of all named parameters from the executable
|
||||
Map<String, Integer> position = new HashMap<>();
|
||||
int p = 0;
|
||||
for (Annotation[] paramAnnotation : parameterAnnotations)
|
||||
{
|
||||
Integer pos = p++;
|
||||
Arrays.stream(paramAnnotation)
|
||||
.filter(Name.class::isInstance)
|
||||
.map(Name.class::cast)
|
||||
.findFirst().ifPresent(n -> position.put(n.value(), pos));
|
||||
}
|
||||
|
||||
List<Object> arguments = new ArrayList<>(_arguments);
|
||||
List<String> names = new ArrayList<>(_names);
|
||||
// Map the actual arguments to the names
|
||||
for (p = 0; p < count; p++)
|
||||
{
|
||||
String name = names.get(p);
|
||||
if (name != null)
|
||||
{
|
||||
Integer pos = position.get(name);
|
||||
if (pos == null)
|
||||
return null;
|
||||
if (pos != p)
|
||||
{
|
||||
// adjust position of parameter
|
||||
arguments.add(pos, arguments.remove(p));
|
||||
names.add(pos, names.remove(p));
|
||||
p = Math.min(p, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arguments.toArray(new Object[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<XmlParser.Node> getNodes(XmlParser.Node node, String elementName)
|
||||
{
|
||||
String attrName = StringUtil.asciiToLowerCase(elementName);
|
||||
final List<XmlParser.Node> values = new ArrayList<>();
|
||||
|
||||
String attr = node.getAttribute(attrName);
|
||||
if (attr != null)
|
||||
{
|
||||
for (String a : StringUtil.csvSplit(null, attr, 0, attr.length()))
|
||||
{
|
||||
// create a fake node
|
||||
XmlParser.Node n = new XmlParser.Node(null, elementName, null);
|
||||
n.add(a);
|
||||
values.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
for (Object o : node)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1789,7 +1789,7 @@ public class XmlConfiguration
|
|||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("objects={}", Arrays.asList(objects));
|
||||
LOG.debug("objects={}", objects);
|
||||
|
||||
// For all objects created by XmlConfigurations, start them if they are lifecycles.
|
||||
List<LifeCycle> started = new ArrayList<>(objects.size());
|
||||
|
|
|
@ -37,6 +37,18 @@ public class AnnotatedTestConfiguration
|
|||
{
|
||||
}
|
||||
|
||||
public AnnotatedTestConfiguration(Integer test)
|
||||
{
|
||||
// exists to make constructor matching harder
|
||||
throw new UnsupportedOperationException("Should not be called");
|
||||
}
|
||||
|
||||
public AnnotatedTestConfiguration(Integer one, Integer two, Integer three)
|
||||
{
|
||||
// exists to make constructor matching harder
|
||||
throw new UnsupportedOperationException("Should not be called");
|
||||
}
|
||||
|
||||
public AnnotatedTestConfiguration(@Name("first") String first, @Name("second") String second, @Name("third") String third)
|
||||
{
|
||||
this.first = first;
|
||||
|
@ -44,6 +56,38 @@ public class AnnotatedTestConfiguration
|
|||
this.third = third;
|
||||
}
|
||||
|
||||
public AnnotatedTestConfiguration(Long one, Long two, Long three)
|
||||
{
|
||||
// exists to make constructor matching harder
|
||||
throw new UnsupportedOperationException("Should not be called");
|
||||
}
|
||||
|
||||
public void setAll(Integer one, Integer two, Integer three)
|
||||
{
|
||||
// exists to make method matching harder
|
||||
throw new UnsupportedOperationException("Should not be called");
|
||||
}
|
||||
|
||||
public void setAll(@Name("first") String first, @Name("second") String second, @Name("third") String third)
|
||||
{
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
this.third = third;
|
||||
}
|
||||
|
||||
public void setAll(long one, long two, long three)
|
||||
{
|
||||
// exists to make method matching harder
|
||||
throw new UnsupportedOperationException("Should not be called");
|
||||
}
|
||||
|
||||
public void setVarArgs(String first, String... theRest)
|
||||
{
|
||||
this.first = first;
|
||||
this.second = theRest.length > 0 ? theRest[0] : null;
|
||||
this.third = theRest.length > 1 ? theRest[1] : null;
|
||||
}
|
||||
|
||||
public String getFirst()
|
||||
{
|
||||
return first;
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.xml;
|
||||
|
@ -44,6 +44,8 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
@ -66,10 +68,6 @@ public class XmlConfigurationTest
|
|||
{
|
||||
public WorkDir workDir;
|
||||
|
||||
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>";
|
||||
|
||||
|
@ -82,170 +80,175 @@ public class XmlConfigurationTest
|
|||
configuration.configure();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPassedObject() throws Exception
|
||||
public static String[] xmlConfigs()
|
||||
{
|
||||
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(Resource.newResource(url));
|
||||
TestConfiguration tc = new TestConfiguration("tc");
|
||||
configuration.getProperties().putAll(properties);
|
||||
configuration.configure(tc);
|
||||
|
||||
assertEquals("SetValue", tc.testObject, "Set String");
|
||||
assertEquals(2, tc.testInt, "Set Type");
|
||||
|
||||
assertEquals(18080, tc.propValue);
|
||||
|
||||
assertEquals("PutValue", tc.get("Test"), "Put");
|
||||
assertEquals("2", tc.get("TestDft"), "Put dft");
|
||||
assertEquals(2, tc.get("TestInt"), "Put type");
|
||||
|
||||
assertEquals("PutValue", tc.get("Trim"), "Trim");
|
||||
assertNull(tc.get("Null"), "Null");
|
||||
assertNull(tc.get("NullTrim"), "NullTrim");
|
||||
|
||||
assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim");
|
||||
assertEquals("-1String", tc.get("Objects"), "Objects");
|
||||
assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim");
|
||||
assertEquals("\n PutValue\n ", tc.get("String"), "String");
|
||||
assertEquals("", tc.get("NullString"), "NullString");
|
||||
assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace");
|
||||
assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString");
|
||||
assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString");
|
||||
assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString");
|
||||
|
||||
assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty");
|
||||
assertEquals(System.getenv("HOME"), tc.get("Env"), "Env");
|
||||
|
||||
assertEquals("xxx", tc.get("Property"), "Property");
|
||||
|
||||
assertEquals("Yes", tc.get("Called"), "Called");
|
||||
|
||||
assertTrue(TestConfiguration.called);
|
||||
|
||||
assertEquals("Blah", tc.oa[0], "oa[0]");
|
||||
assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]");
|
||||
assertEquals(1.2345, tc.oa[2], "oa[2]");
|
||||
assertNull(tc.oa[3], "oa[3]");
|
||||
|
||||
assertEquals(1, tc.ia[0], "ia[0]");
|
||||
assertEquals(2, tc.ia[1], "ia[1]");
|
||||
assertEquals(3, tc.ia[2], "ia[2]");
|
||||
assertEquals(0, tc.ia[3], "ia[3]");
|
||||
|
||||
TestConfiguration tc2 = tc.nested;
|
||||
assertNotNull(tc2);
|
||||
assertEquals(true, tc2.get("Arg"), "Called(bool)");
|
||||
|
||||
assertNull(tc.get("Arg"), "nested config");
|
||||
assertEquals(true, tc2.get("Arg"), "nested config");
|
||||
|
||||
assertEquals("Call1", tc2.testObject, "nested config");
|
||||
assertEquals(4, tc2.testInt, "nested config");
|
||||
assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call");
|
||||
|
||||
assertEquals(tc.testField1, 77, "static to field");
|
||||
assertEquals(tc.testField2, 2, "field to field");
|
||||
assertEquals(TestConfiguration.VALUE, 42, "literal to static");
|
||||
|
||||
assertEquals(((Map<String, String>)configuration.getIdMap().get("map")).get("key0"), "value0");
|
||||
assertEquals(((Map<String, String>)configuration.getIdMap().get("map")).get("key1"), "value1");
|
||||
}
|
||||
return new String[]{"org/eclipse/jetty/xml/configureWithAttr.xml", "org/eclipse/jetty/xml/configureWithElements.xml"};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewObject() throws Exception
|
||||
@ParameterizedTest
|
||||
@MethodSource("xmlConfigs")
|
||||
public void testPassedObject(String configure) throws Exception
|
||||
{
|
||||
for (String configure : _configure)
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("whatever", "xxx");
|
||||
TestConfiguration.VALUE = 77;
|
||||
URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure);
|
||||
assertNotNull(url);
|
||||
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url));
|
||||
TestConfiguration tc = new TestConfiguration("tc");
|
||||
configuration.getProperties().putAll(properties);
|
||||
configuration.configure(tc);
|
||||
|
||||
assertEquals("SetValue", tc.testObject, "Set String");
|
||||
assertEquals(2, tc.testInt, "Set Type");
|
||||
|
||||
assertEquals(18080, tc.propValue);
|
||||
|
||||
assertEquals("PutValue", tc.get("Test"), "Put");
|
||||
assertEquals("2", tc.get("TestDft"), "Put dft");
|
||||
assertEquals(2, tc.get("TestInt"), "Put type");
|
||||
|
||||
assertEquals("PutValue", tc.get("Trim"), "Trim");
|
||||
assertNull(tc.get("Null"), "Null");
|
||||
assertNull(tc.get("NullTrim"), "NullTrim");
|
||||
|
||||
assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim");
|
||||
assertEquals("-1String", tc.get("Objects"), "Objects");
|
||||
assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim");
|
||||
assertEquals("\n PutValue\n ", tc.get("String"), "String");
|
||||
assertEquals("", tc.get("NullString"), "NullString");
|
||||
assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace");
|
||||
assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString");
|
||||
assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString");
|
||||
assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString");
|
||||
|
||||
assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty");
|
||||
assertEquals(System.getenv("HOME"), tc.get("Env"), "Env");
|
||||
|
||||
assertEquals("xxx", tc.get("Property"), "Property");
|
||||
|
||||
assertEquals("Yes", tc.get("Called"), "Called");
|
||||
|
||||
assertTrue(TestConfiguration.called);
|
||||
|
||||
assertEquals("Blah", tc.oa[0], "oa[0]");
|
||||
assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]");
|
||||
assertEquals(1.2345, tc.oa[2], "oa[2]");
|
||||
assertNull(tc.oa[3], "oa[3]");
|
||||
|
||||
assertEquals(1, tc.ia[0], "ia[0]");
|
||||
assertEquals(2, tc.ia[1], "ia[1]");
|
||||
assertEquals(3, tc.ia[2], "ia[2]");
|
||||
assertEquals(0, tc.ia[3], "ia[3]");
|
||||
|
||||
TestConfiguration tc2 = tc.nested;
|
||||
assertNotNull(tc2);
|
||||
assertEquals(true, tc2.get("Arg"), "Called(bool)");
|
||||
|
||||
assertNull(tc.get("Arg"), "nested config");
|
||||
assertEquals(true, tc2.get("Arg"), "nested config");
|
||||
|
||||
assertEquals("Call1", tc2.testObject, "nested config");
|
||||
assertEquals(4, tc2.testInt, "nested config");
|
||||
assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call");
|
||||
|
||||
assertEquals(tc.testField1, 77, "static to field");
|
||||
assertEquals(tc.testField2, 2, "field to field");
|
||||
assertEquals(TestConfiguration.VALUE, 42, "literal to static");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>)configuration.getIdMap().get("map");
|
||||
assertEquals(map.get("key0"), "value0");
|
||||
assertEquals(map.get("key1"), "value1");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("xmlConfigs")
|
||||
public void testNewObject(String configure) throws Exception
|
||||
{
|
||||
TestConfiguration.VALUE = 71;
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("whatever", "xxx");
|
||||
|
||||
URL url = XmlConfigurationTest.class.getClassLoader().getResource(configure);
|
||||
assertNotNull(url);
|
||||
AtomicInteger count = new AtomicInteger(0);
|
||||
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(url))
|
||||
{
|
||||
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(Resource.newResource(url))
|
||||
@Override
|
||||
public void initializeDefaults(Object object)
|
||||
{
|
||||
@Override
|
||||
public void initializeDefaults(Object object)
|
||||
if (object instanceof TestConfiguration)
|
||||
{
|
||||
if (object instanceof TestConfiguration)
|
||||
{
|
||||
count.incrementAndGet();
|
||||
((TestConfiguration)object).setNested(null);
|
||||
((TestConfiguration)object).setTestString("NEW DEFAULT");
|
||||
}
|
||||
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("SetValue", tc.testObject, "Set String");
|
||||
assertEquals(2, tc.testInt, "Set Type");
|
||||
assertEquals("SetValue", tc.testObject, "Set String");
|
||||
assertEquals(2, tc.testInt, "Set Type");
|
||||
|
||||
assertEquals(18080, tc.propValue);
|
||||
assertEquals(18080, tc.propValue);
|
||||
|
||||
assertEquals("PutValue", tc.get("Test"), "Put");
|
||||
assertEquals("2", tc.get("TestDft"), "Put dft");
|
||||
assertEquals(2, tc.get("TestInt"), "Put type");
|
||||
assertEquals("PutValue", tc.get("Test"), "Put");
|
||||
assertEquals("2", tc.get("TestDft"), "Put dft");
|
||||
assertEquals(2, tc.get("TestInt"), "Put type");
|
||||
|
||||
assertEquals("PutValue", tc.get("Trim"), "Trim");
|
||||
assertNull(tc.get("Null"), "Null");
|
||||
assertNull(tc.get("NullTrim"), "NullTrim");
|
||||
assertEquals("PutValue", tc.get("Trim"), "Trim");
|
||||
assertNull(tc.get("Null"), "Null");
|
||||
assertNull(tc.get("NullTrim"), "NullTrim");
|
||||
|
||||
assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim");
|
||||
assertEquals("-1String", tc.get("Objects"), "Objects");
|
||||
assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim");
|
||||
assertEquals("\n PutValue\n ", tc.get("String"), "String");
|
||||
assertEquals("", tc.get("NullString"), "NullString");
|
||||
assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace");
|
||||
assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString");
|
||||
assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString");
|
||||
assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString");
|
||||
assertEquals(1.2345, tc.get("ObjectTrim"), "ObjectTrim");
|
||||
assertEquals("-1String", tc.get("Objects"), "Objects");
|
||||
assertEquals("-1String", tc.get("ObjectsTrim"), "ObjectsTrim");
|
||||
assertEquals("\n PutValue\n ", tc.get("String"), "String");
|
||||
assertEquals("", tc.get("NullString"), "NullString");
|
||||
assertEquals("\n ", tc.get("WhiteSpace"), "WhiteSpace");
|
||||
assertEquals("\n 1.2345\n ", tc.get("ObjectString"), "ObjectString");
|
||||
assertEquals("-1String", tc.get("ObjectsString"), "ObjectsString");
|
||||
assertEquals("-1\n String", tc.get("ObjectsWhiteString"), "ObjectsWhiteString");
|
||||
|
||||
assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty");
|
||||
assertEquals("xxx", tc.get("Property"), "Property");
|
||||
assertEquals(System.getProperty("user.dir") + "/stuff", tc.get("SystemProperty"), "SystemProperty");
|
||||
assertEquals("xxx", tc.get("Property"), "Property");
|
||||
|
||||
assertEquals("Yes", tc.get("Called"), "Called");
|
||||
assertEquals("Yes", tc.get("Called"), "Called");
|
||||
|
||||
assertTrue(TestConfiguration.called);
|
||||
assertTrue(TestConfiguration.called);
|
||||
|
||||
assertEquals("Blah", tc.oa[0], "oa[0]");
|
||||
assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]");
|
||||
assertEquals(1.2345, tc.oa[2], "oa[2]");
|
||||
assertNull(tc.oa[3], "oa[3]");
|
||||
assertEquals("Blah", tc.oa[0], "oa[0]");
|
||||
assertEquals("1.2.3.4:5678", tc.oa[1], "oa[1]");
|
||||
assertEquals(1.2345, tc.oa[2], "oa[2]");
|
||||
assertNull(tc.oa[3], "oa[3]");
|
||||
|
||||
assertEquals(1, tc.ia[0], "ia[0]");
|
||||
assertEquals(2, tc.ia[1], "ia[1]");
|
||||
assertEquals(3, tc.ia[2], "ia[2]");
|
||||
assertEquals(0, tc.ia[3], "ia[3]");
|
||||
assertEquals(1, tc.ia[0], "ia[0]");
|
||||
assertEquals(2, tc.ia[1], "ia[1]");
|
||||
assertEquals(3, tc.ia[2], "ia[2]");
|
||||
assertEquals(0, tc.ia[3], "ia[3]");
|
||||
|
||||
TestConfiguration tc2 = tc.nested;
|
||||
assertNotNull(tc2);
|
||||
assertEquals(true, tc2.get("Arg"), "Called(bool)");
|
||||
TestConfiguration tc2 = tc.nested;
|
||||
assertNotNull(tc2);
|
||||
assertEquals(true, tc2.get("Arg"), "Called(bool)");
|
||||
|
||||
assertNull(tc.get("Arg"), "nested config");
|
||||
assertEquals(true, tc2.get("Arg"), "nested config");
|
||||
assertNull(tc.get("Arg"), "nested config");
|
||||
assertEquals(true, tc2.get("Arg"), "nested config");
|
||||
|
||||
assertEquals("Call1", tc2.testObject, "nested config");
|
||||
assertEquals(4, tc2.testInt, "nested config");
|
||||
assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call");
|
||||
assertEquals("Call1", tc2.testObject, "nested config");
|
||||
assertEquals(4, tc2.testInt, "nested config");
|
||||
assertEquals("http://www.eclipse.com/", tc2.url.toString(), "nested call");
|
||||
|
||||
assertEquals(71, tc.testField1, "static to field");
|
||||
assertEquals(2, tc.testField2, "field to field");
|
||||
assertEquals(42, TestConfiguration.VALUE, "literal to static");
|
||||
}
|
||||
assertEquals(71, tc.testField1, "static to field");
|
||||
assertEquals(2, tc.testField2, "field to field");
|
||||
assertEquals(42, TestConfiguration.VALUE, "literal to static");
|
||||
}
|
||||
|
||||
public XmlConfiguration asXmlConfiguration(String rawXml) throws IOException, SAXException
|
||||
|
@ -304,7 +307,7 @@ public class XmlConfigurationTest
|
|||
tc.setTestString("default");
|
||||
configuration.configure(tc);
|
||||
assertEquals("default", tc.getTestString());
|
||||
assertEquals(configuration.getIdMap().get("test"), null);
|
||||
assertNull(configuration.getIdMap().get("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -328,7 +331,7 @@ public class XmlConfigurationTest
|
|||
tc.setTestString("default");
|
||||
configuration.configure(tc);
|
||||
assertEquals("default", tc.getTestString());
|
||||
assertEquals(configuration.getIdMap().get("test"), null);
|
||||
assertNull(configuration.getIdMap().get("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -337,10 +340,7 @@ public class XmlConfigurationTest
|
|||
XmlConfiguration configuration = asXmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"PropertyTest\"><Property name=\"null\"/></Set></Configure>");
|
||||
TestConfiguration tc = new TestConfiguration();
|
||||
|
||||
NoSuchMethodException e = assertThrows(NoSuchMethodException.class, () ->
|
||||
{
|
||||
configuration.configure(tc);
|
||||
});
|
||||
NoSuchMethodException e = assertThrows(NoSuchMethodException.class, () -> configuration.configure(tc));
|
||||
|
||||
assertThat(e.getMessage(), containsString("Found setters for int"));
|
||||
}
|
||||
|
@ -380,10 +380,7 @@ public class XmlConfigurationTest
|
|||
"<New class=\"org.eclipse.jetty.xml.ConstructorArgTestClass\"><Arg type=\"List\">Some String</Arg></New></Configure>");
|
||||
TestConfiguration tc = new TestConfiguration();
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
{
|
||||
xmlConfiguration.configure(tc);
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> xmlConfiguration.configure(tc));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -405,10 +402,7 @@ public class XmlConfigurationTest
|
|||
XmlConfiguration xmlConfiguration = asXmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\">" +
|
||||
"<New class=\"org.eclipse.jetty.xml.ConstructorArgTestClass\"><Arg type=\"Set\">Some String</Arg></New></Configure>");
|
||||
TestConfiguration tc = new TestConfiguration();
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
{
|
||||
xmlConfiguration.configure(tc);
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> xmlConfiguration.configure(tc));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -440,10 +434,7 @@ public class XmlConfigurationTest
|
|||
INT_ARRAY_XML + "</Set></Configure>");
|
||||
TestConfiguration tc = new TestConfiguration();
|
||||
assertThat("tc.getSet() returns null as it's not configured yet", tc.getList(), is(nullValue()));
|
||||
assertThrows(NoSuchMethodException.class, () ->
|
||||
{
|
||||
xmlConfiguration.configure(tc);
|
||||
});
|
||||
assertThrows(NoSuchMethodException.class, () -> xmlConfiguration.configure(tc));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -696,6 +687,139 @@ public class XmlConfigurationTest
|
|||
assertEquals("arg3", atc.getNested().getThird(), "nested third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallNamedInjection() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setAll\">" +
|
||||
" <Arg>arg1</Arg> " +
|
||||
" <Arg>arg2</Arg> " +
|
||||
" <Arg>arg3</Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("arg3", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallNamedInjectionOrdered() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setAll\">" +
|
||||
" <Arg name=\"first\">arg1</Arg> " +
|
||||
" <Arg name=\"second\">arg2</Arg> " +
|
||||
" <Arg name=\"third\">arg3</Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("arg3", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallNamedInjectionUnOrdered() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setAll\">" +
|
||||
" <Arg name=\"first\">arg1</Arg> " +
|
||||
" <Arg name=\"third\">arg3</Arg> " +
|
||||
" <Arg name=\"second\">arg2</Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("arg3", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallNamedInjectionOrderedMixed() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setAll\">" +
|
||||
" <Arg name=\"first\">arg1</Arg> " +
|
||||
" <Arg>arg2</Arg> " +
|
||||
" <Arg name=\"third\">arg3</Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("arg3", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallNamedInjectionUnorderedMixed() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setAll\">" +
|
||||
" <Arg name=\"third\">arg3</Arg> " +
|
||||
" <Arg>arg2</Arg> " +
|
||||
" <Arg name=\"first\">arg1</Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("arg1", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("arg2", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("arg3", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallVarArgs() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Call name=\"setVarArgs\">" +
|
||||
" <Arg>one</Arg> " +
|
||||
" <Arg><Array type=\"String\"><Item type=\"String\">two</Item><Item type=\"String\">three</Item></Array></Arg> " +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("one", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertEquals("two", atc.getSecond(), "second parameter not wired correctly");
|
||||
assertEquals("three", atc.getThird(), "third parameter not wired correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallMissingVarArgs() throws Exception
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = asXmlConfiguration(
|
||||
"<Configure class=\"org.eclipse.jetty.xml.AnnotatedTestConfiguration\">" +
|
||||
" <Arg name=\"first\">arg1</Arg> " +
|
||||
" <Arg name=\"second\">arg2</Arg> " +
|
||||
" <Arg name=\"third\">arg3</Arg> " +
|
||||
" <Call name=\"setVarArgs\">" +
|
||||
" <Arg>one</Arg>" +
|
||||
" </Call>" +
|
||||
"</Configure>");
|
||||
|
||||
AnnotatedTestConfiguration atc = (AnnotatedTestConfiguration)xmlConfiguration.configure();
|
||||
|
||||
assertEquals("one", atc.getFirst(), "first parameter not wired correctly");
|
||||
assertNull(atc.getSecond());
|
||||
assertNull(atc.getThird());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgumentsGetIgnoredMissingDTD() throws Exception
|
||||
{
|
||||
|
@ -859,7 +983,7 @@ public class XmlConfigurationTest
|
|||
" <Set name=\"integer\">bad</Set>" +
|
||||
"</Configure>");
|
||||
|
||||
assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure());
|
||||
assertThrows(InvocationTargetException.class, xmlConfiguration::configure);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -870,7 +994,7 @@ public class XmlConfigurationTest
|
|||
" <Set name=\"integer\">100 bas</Set>" +
|
||||
"</Configure>");
|
||||
|
||||
assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure());
|
||||
assertThrows(InvocationTargetException.class, xmlConfiguration::configure);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -937,7 +1061,7 @@ public class XmlConfigurationTest
|
|||
" <Set name=\"integer\">1.5</Set>" +
|
||||
"</Configure>");
|
||||
|
||||
assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure());
|
||||
assertThrows(InvocationTargetException.class, xmlConfiguration::configure);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue