diff options
7 files changed, 523 insertions, 271 deletions
diff --git a/jetty-deploy/src/test/resources/jetty.xml b/jetty-deploy/src/test/resources/jetty.xml index da126ab193..4c1734b87f 100644 --- a/jetty-deploy/src/test/resources/jetty.xml +++ b/jetty-deploy/src/test/resources/jetty.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"> +<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <!-- =============================================================== --> <!-- Configure the Jetty Server --> @@ -14,9 +14,8 @@ <!-- =========================================================== --> <!-- Server Thread Pool --> <!-- =========================================================== --> - <Set name="ThreadPool"> - <!-- Default queued blocking threadpool - --> + <Arg name="threadPool"> + <!-- Default queued blocking threadpool --> <New class="org.eclipse.jetty.util.thread.QueuedThreadPool"> <Set name="maxThreads">200</Set> <Set name="minThreads">10</Set> @@ -28,7 +27,7 @@ <Set name="maximumPoolSize">50</Set> </New> --> - </Set> + </Arg> <!-- =========================================================== --> <!-- Set connectors --> @@ -37,10 +36,10 @@ <Call name="addConnector"> <Arg> <New class="org.eclipse.jetty.server.SelectChannelConnector"> + <Arg><Ref id="Server" /></Arg> <Set name="host"></Set> <Set name="port">0</Set> <Set name="idleTimeout">300000</Set> - <Set name="confidentialPort">8443</Set> </New> </Arg> </Call> diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 01567c90d3..8530a5e534 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -15,7 +15,11 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -25,7 +29,6 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; -import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.URIUtil; @@ -44,8 +47,6 @@ import org.eclipse.jetty.util.thread.ThreadPool; * It aggregates Connectors (HTTP request receivers) and request Handlers. * The server is itself a handler and a ThreadPool. Connectors use the ThreadPool methods * to run jobs that will eventually call the handle method. - * - * @org.apache.xbean.XBean description="Creates an embedded Jetty web server" */ public class Server extends HandlerWrapper implements Attributes { @@ -65,7 +66,7 @@ public class Server extends HandlerWrapper implements Attributes private final Container _container=new Container(); private final AttributesMap _attributes = new AttributesMap(); private final ThreadPool _threadPool; - private Connector[] _connectors; + private final List<Connector> _connectors = new CopyOnWriteArrayList<>(); private SessionIdManager _sessionIdManager; private boolean _sendServerVersion = true; //send Server: header private boolean _sendDateHeader = false; //send Date: header @@ -112,7 +113,7 @@ public class Server extends HandlerWrapper implements Attributes public Server(ThreadPool pool) { _threadPool=pool!=null?pool:new QueuedThreadPool(); - addBean(_threadPool,pool==null); + addBean(_threadPool); setServer(this); } @@ -164,23 +165,27 @@ public class Server extends HandlerWrapper implements Attributes */ public Connector[] getConnectors() { - return _connectors; + List<Connector> connectors = new ArrayList<>(_connectors); + return connectors.toArray(new Connector[connectors.size()]); } /* ------------------------------------------------------------ */ public void addConnector(Connector connector) { - setConnectors((Connector[])LazyList.addToArray(getConnectors(), connector, Connector.class)); + if (_connectors.add(connector)) + _container.update(this, null, connector, "connector"); } /* ------------------------------------------------------------ */ /** - * Conveniance method which calls {@link #getConnectors()} and {@link #setConnectors(Connector[])} to + * Convenience method which calls {@link #getConnectors()} and {@link #setConnectors(Connector[])} to * remove a connector. * @param connector The connector to remove. */ - public void removeConnector(Connector connector) { - setConnectors((Connector[])LazyList.removeFromArray (getConnectors(), connector)); + public void removeConnector(Connector connector) + { + if (_connectors.remove(connector)) + _container.update(this, connector, null, "connector"); } /* ------------------------------------------------------------ */ @@ -190,17 +195,21 @@ public class Server extends HandlerWrapper implements Attributes */ public void setConnectors(Connector[] connectors) { - if (connectors!=null) + if (connectors != null) { - for (int i=0;i<connectors.length;i++) + for (Connector connector : connectors) { - if (connectors[i].getServer()!=this) - throw new IllegalArgumentException(); + if (connector.getServer() != this) + throw new IllegalArgumentException("Connector " + connector + + " cannot be shared among server " + connector.getServer() + " and server " + this); } } - _container.update(this, _connectors, connectors, "connector"); - _connectors = connectors; + Connector[] oldConnectors = getConnectors(); + _container.update(this, oldConnectors, connectors, "connector"); + _connectors.removeAll(Arrays.asList(oldConnectors)); + if (connectors != null) + _connectors.addAll(Arrays.asList(connectors)); } /* ------------------------------------------------------------ */ @@ -266,12 +275,15 @@ public class Server extends HandlerWrapper implements Attributes mex.add(e); } - if (_connectors!=null && mex.size()==0) + if (mex.size()==0) { - for (int i=0;i<_connectors.length;i++) + for (Connector _connector : _connectors) { - try{_connectors[i].start();} - catch(Throwable e) + try + { + _connector.start(); + } + catch (Throwable e) { mex.add(e); } @@ -293,38 +305,46 @@ public class Server extends HandlerWrapper implements Attributes MultiException mex=new MultiException(); - if (_graceful>0) + long gracefulTimeout = getGracefulShutdown(); + if (gracefulTimeout>0) { - if (_connectors!=null) + for (Connector connector : _connectors) { - for (int i=_connectors.length;i-->0;) - { - LOG.info("Graceful shutdown {}",_connectors[i]); - if (_connectors[i] instanceof NetworkConnector) - ((NetworkConnector)_connectors[i]).close(); - } + LOG.info("Graceful shutdown {}", connector); + if (connector instanceof NetworkConnector) + ((NetworkConnector)connector).close(); } Handler[] contexts = getChildHandlersByClass(Graceful.class); - for (int c=0;c<contexts.length;c++) + for (Handler context : contexts) { - Graceful context=(Graceful)contexts[c]; - LOG.info("Graceful shutdown {}",context); - context.setShutdown(true); + Graceful graceful = (Graceful)context; + LOG.info("Graceful shutdown {}", graceful); + graceful.setShutdown(true); } - Thread.sleep(_graceful); + Thread.sleep(gracefulTimeout); } - if (_connectors!=null) + for (Connector connector : _connectors) { - for (int i=_connectors.length;i-->0;) + try + { + connector.stop(); + } + catch (Throwable e) { - if (_connectors[i]!=null) - try{_connectors[i].stop();}catch(Throwable e){mex.add(e);} + mex.add(e); } } - try {super.doStop(); } catch(Throwable e) { mex.add(e);} + try + { + super.doStop(); + } + catch (Throwable e) + { + mex.add(e); + } mex.ifExceptionThrow(); @@ -440,9 +460,6 @@ public class Server extends HandlerWrapper implements Attributes } /* ------------------------------------------------------------ */ - /** - * @param sendDateHeader - */ public void setSendDateHeader(boolean sendDateHeader) { _sendDateHeader = sendDateHeader; @@ -456,24 +473,6 @@ public class Server extends HandlerWrapper implements Attributes /* ------------------------------------------------------------ */ /** - */ - @Deprecated - public int getMaxCookieVersion() - { - return 1; - } - - /* ------------------------------------------------------------ */ - /** - */ - @Deprecated - public void setMaxCookieVersion(int maxCookieVersion) - { - } - - - /* ------------------------------------------------------------ */ - /** * Add an associated bean. * The bean will be added to the servers {@link Container} * and if it is a {@link LifeCycle} instance, it will be @@ -535,7 +534,7 @@ public class Server extends HandlerWrapper implements Attributes * @see org.eclipse.util.AttributesMap#getAttributeNames() */ @Override - public Enumeration getAttributeNames() + public Enumeration<String> getAttributeNames() { return AttributesMap.getAttributeNamesCopy(_attributes); } @@ -600,7 +599,7 @@ public class Server extends HandlerWrapper implements Attributes public void dump(Appendable out,String indent) throws IOException { dumpThis(out); - dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors)); + dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),_connectors); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index e87a16fc7e..47e9f9335a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -19,7 +19,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.URL; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -44,7 +43,7 @@ public class TypeUtil public static int LF = '\012'; /* ------------------------------------------------------------ */ - private static final HashMap<String, Class<?>> name2Class=new HashMap<String, Class<?>>(); + private static final HashMap<String, Class<?>> name2Class=new HashMap<>(); static { name2Class.put("boolean",java.lang.Boolean.TYPE); @@ -92,7 +91,7 @@ public class TypeUtil } /* ------------------------------------------------------------ */ - private static final HashMap<Class<?>, String> class2Name=new HashMap<Class<?>, String>(); + private static final HashMap<Class<?>, String> class2Name=new HashMap<>(); static { class2Name.put(java.lang.Boolean.TYPE,"boolean"); @@ -119,7 +118,7 @@ public class TypeUtil } /* ------------------------------------------------------------ */ - private static final HashMap<Class<?>, Method> class2Value=new HashMap<Class<?>, Method>(); + private static final HashMap<Class<?>, Method> class2Value=new HashMap<>(); static { try @@ -168,13 +167,13 @@ public class TypeUtil * Works like {@link Arrays#asList(Object...)}, but handles null arrays. * @return a list backed by the array. */ - public static <T> List<T> asList(T[] a) + public static <T> List<T> asList(T[] a) { if (a==null) return Collections.emptyList(); return Arrays.asList(a); } - + /* ------------------------------------------------------------ */ /** Class from a canonical name for a type. * @param name A class or type name. @@ -214,28 +213,20 @@ public class TypeUtil if (type.equals(java.lang.Character.TYPE) || type.equals(java.lang.Character.class)) - return new Character(value.charAt(0)); + return value.charAt(0); Constructor<?> c = type.getConstructor(java.lang.String.class); return c.newInstance(value); } - catch(NoSuchMethodException e) - { - // LogSupport.ignore(log,e); - } - catch(IllegalAccessException e) + catch (NoSuchMethodException | IllegalAccessException | InstantiationException x) { - // LogSupport.ignore(log,e); + LOG.ignore(x); } - catch(InstantiationException e) + catch (InvocationTargetException x) { - // LogSupport.ignore(log,e); - } - catch(InvocationTargetException e) - { - if (e.getTargetException() instanceof Error) - throw (Error)(e.getTargetException()); - // LogSupport.ignore(log,e); + if (x.getTargetException() instanceof Error) + throw (Error)x.getTargetException(); + LOG.ignore(x); } return null; } @@ -390,7 +381,7 @@ public class TypeUtil { return toHexString(new byte[]{b}, 0, 1); } - + /* ------------------------------------------------------------ */ public static String toHexString(byte[] b) { @@ -499,54 +490,49 @@ public class TypeUtil return buf; } - public static URL jarFor(String className) - { - try - { - className=className.replace('.','/')+".class"; - // hack to discover jstl libraries - URL url = Loader.getResource(null,className,false); - String s=url.toString(); - if (s.startsWith("jar:file:")) - return new URL(s.substring(4,s.indexOf("!/"))); - } - catch(Exception e) - { - LOG.ignore(e); - } - return null; - } - - public static Object call(Class<?> oClass, String method, Object obj, Object[] arg) + public static Object call(Class<?> oClass, String methodName, Object obj, Object[] arg) throws InvocationTargetException, NoSuchMethodException { // Lets just try all methods for now - Method[] methods = oClass.getMethods(); - for (int c = 0; methods != null && c < methods.length; c++) + for (Method method : oClass.getMethods()) { - if (!methods[c].getName().equals(method)) + if (!method.getName().equals(methodName)) continue; - if (methods[c].getParameterTypes().length != arg.length) + if (method.getParameterTypes().length != arg.length) continue; - if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null)) + if (Modifier.isStatic(method.getModifiers()) != (obj == null)) continue; - if ((obj == null) && methods[c].getDeclaringClass() != oClass) + if ((obj == null) && method.getDeclaringClass() != oClass) continue; try { - return methods[c].invoke(obj,arg); + return method.invoke(obj, arg); } - catch (IllegalAccessException e) + catch (IllegalAccessException | IllegalArgumentException e) { LOG.ignore(e); } - catch (IllegalArgumentException e) + } + throw new NoSuchMethodException(methodName); + } + + public static Object construct(Class<?> klass, Object[] arguments) throws InvocationTargetException, NoSuchMethodException + { + for (Constructor<?> constructor : klass.getConstructors()) + { + if (constructor.getParameterTypes().length != arguments.length) + continue; + + try + { + return constructor.newInstance(arguments); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException e) { LOG.ignore(e); } } - - throw new NoSuchMethodException(method); + throw new NoSuchMethodException("<init>"); } } 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 a195d89393..93102918b8 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 @@ -67,13 +67,13 @@ public class XmlConfiguration private static final Logger LOG = Log.getLogger(XmlConfiguration.class); private static final Class<?>[] __primitives = - { Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE }; + {Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE}; - private static final Class<?>[] __primitiveHolders = - { Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class }; + 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,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,}; private static final Iterable<?> __factoryLoader; @@ -81,14 +81,14 @@ public class XmlConfiguration static { - Iterable<?> loader=null; + Iterable<?> loader = null; try { // Use reflection to look up 1.6 service loader // loader=ServiceLoader.load(ConfigurationProcessorFactory.class); Class<?> slc = ClassLoader.getSystemClassLoader().loadClass("java.util.ServiceLoader"); Method load = slc.getMethod("load",Class.class); - loader=(Iterable<?>)load.invoke(null,ConfigurationProcessorFactory.class); + loader = (Iterable<?>)load.invoke(null, ConfigurationProcessorFactory.class); } catch(Exception e) { @@ -96,16 +96,16 @@ public class XmlConfiguration } finally { - __factoryLoader=loader; + __factoryLoader = loader; } } /* ------------------------------------------------------------ */ - private URL _url; - private String _dtd; + private final Map<String, Object> _idMap = new HashMap<>(); + private final Map<String, String> _propertyMap = new HashMap<>(); + private final URL _url; + private final String _dtd; private ConfigurationProcessor _processor; - private final Map<String, Object> _idMap = new HashMap<String, Object>(); - private final Map<String, String> _propertyMap = new HashMap<String, String>(); /* ------------------------------------------------------------ */ private synchronized static XmlParser initParser() @@ -115,20 +115,22 @@ public class XmlConfiguration { URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true); URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true); - parser.redirectEntity("configure.dtd",config76); + URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd",true); + parser.redirectEntity("configure.dtd",config90); parser.redirectEntity("configure_1_0.dtd",config60); parser.redirectEntity("configure_1_1.dtd",config60); parser.redirectEntity("configure_1_2.dtd",config60); parser.redirectEntity("configure_1_3.dtd",config60); parser.redirectEntity("configure_6_0.dtd",config60); parser.redirectEntity("configure_7_6.dtd",config76); + parser.redirectEntity("configure_9_0.dtd",config90); - parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config76); - parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config76); - parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config76); + 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("-//Mort Bay Consulting//DTD Configure//EN",config76); - parser.redirectEntity("-//Jetty//Configure//EN",config76); + parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config90); + parser.redirectEntity("-//Jetty//Configure//EN",config90); } catch (ClassNotFoundException e) { @@ -167,11 +169,12 @@ public class XmlConfiguration */ public XmlConfiguration(String configuration) throws SAXException, IOException { - configuration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Mort Bay Consulting//DTD Configure 1.2//EN\" \"http://jetty.eclipse.org/configure_1_2.dtd\">" + configuration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Jetty//Configure//EN\" \"http://eclipse.org/jetty/configure.dtd\">" + configuration; InputSource source = new InputSource(new StringReader(configuration)); synchronized (__parser) { + _url=null; setConfig( __parser.parse(source)); _dtd=__parser.getDTD(); } @@ -190,6 +193,7 @@ public class XmlConfiguration InputSource source = new InputSource(configuration); synchronized (__parser) { + _url=null; setConfig(__parser.parse(source)); _dtd=__parser.getDTD(); } @@ -335,15 +339,39 @@ public class XmlConfiguration Class<?> oClass = nodeClass(_config); String id = _config.getAttribute("id"); - Object obj = id == null?null:_idMap.get(id); + Object obj = id == null ? null : _idMap.get(id); + int index = 0; if (obj == null && oClass != null) - obj = oClass.newInstance(); + { + List<Object> arguments = new ArrayList<>(); + for (int i = 0; i < _config.size(); i++) + { + Object o = _config.get(i); + if (o instanceof String) + continue; + if (!((XmlParser.Node)o).getTag().equals("Arg")) + { + index = i; + break; + } + else + { + arguments.add(value(obj, (XmlParser.Node)o)); + } + } - if (oClass != null && !oClass.isInstance(obj)) - throw new ClassCastException(oClass.toString()+" in "+_url); + try + { + obj = TypeUtil.construct(oClass, arguments.toArray()); + } + catch (NoSuchMethodException x) + { + throw new IllegalStateException("No suitable constructor on " + oClass, x); + } + } - configure(obj,_config,0); + configure(obj, _config, index); return obj; } @@ -383,24 +411,35 @@ public class XmlConfiguration try { String tag = node.getTag(); - if ("Set".equals(tag)) - set(obj,node); - else if ("Put".equals(tag)) - put(obj,node); - else if ("Call".equals(tag)) - call(obj,node); - else if ("Get".equals(tag)) - get(obj,node); - else if ("New".equals(tag)) - newObj(obj,node); - else if ("Array".equals(tag)) - newArray(obj,node); - else if ("Ref".equals(tag)) - refObj(obj,node); - else if ("Property".equals(tag)) - propertyObj(node); - else - throw new IllegalStateException("Unknown tag: " + tag+" in "+_url); + switch (tag) + { + case "Set": + set(obj, node); + break; + case "Put": + put(obj, node); + break; + case "Call": + call(obj, node); + break; + case "Get": + get(obj, node); + break; + case "New": + newObj(obj, node); + break; + case "Array": + newArray(obj, node); + break; + case "Ref": + refObj(obj, node); + break; + case "Property": + propertyObj(node); + break; + default: + throw new IllegalStateException("Unknown tag: " + tag + " in " + _url); + } } catch (Exception e) { @@ -447,15 +486,7 @@ public class XmlConfiguration set.invoke(obj,arg); return; } - catch (IllegalArgumentException e) - { - LOG.ignore(e); - } - catch (IllegalAccessException e) - { - LOG.ignore(e); - } - catch (NoSuchMethodException e) + catch (IllegalArgumentException | IllegalAccessException | NoSuchMethodException e) { LOG.ignore(e); } @@ -469,19 +500,7 @@ public class XmlConfiguration set.invoke(obj,arg); return; } - catch (NoSuchFieldException e) - { - LOG.ignore(e); - } - catch (IllegalArgumentException e) - { - LOG.ignore(e); - } - catch (IllegalAccessException e) - { - LOG.ignore(e); - } - catch (NoSuchMethodException e) + catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException e) { LOG.ignore(e); } @@ -517,11 +536,7 @@ public class XmlConfiguration sets[s].invoke(obj,arg); return; } - catch (IllegalArgumentException e) - { - LOG.ignore(e); - } - catch (IllegalAccessException e) + catch (IllegalArgumentException | IllegalAccessException e) { LOG.ignore(e); } @@ -554,7 +569,7 @@ public class XmlConfiguration { if (sClass.equals(__primitives[t])) { - sClass = __primitiveHolders[t]; + sClass = __boxedPrimitives[t]; break; } } @@ -564,15 +579,7 @@ public class XmlConfiguration set.invoke(obj,arg); return; } - catch (NoSuchMethodException e) - { - LOG.ignore(e); - } - catch (IllegalAccessException e) - { - LOG.ignore(e); - } - catch (InstantiationException e) + catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) { LOG.ignore(e); } @@ -595,10 +602,10 @@ public class XmlConfiguration if (collectionType.isAssignableFrom(ArrayList.class)) collection = convertArrayToArrayList(array); else if (collectionType.isAssignableFrom(HashSet.class)) - collection = new HashSet<Object>(convertArrayToArrayList(array)); + collection = new HashSet<>(convertArrayToArrayList(array)); else if (collectionType.isAssignableFrom(ArrayQueue.class)) { - ArrayQueue<Object> q= new ArrayQueue<Object>(); + ArrayQueue<Object> q= new ArrayQueue<>(); q.addAll(convertArrayToArrayList(array)); collection=q; } @@ -612,7 +619,7 @@ public class XmlConfiguration private static ArrayList<Object> convertArrayToArrayList(Object array) { int length = Array.getLength(array); - ArrayList<Object> list = new ArrayList<Object>(length); + ArrayList<Object> list = new ArrayList<>(length); for (int i = 0; i < length; i++) list.add(Array.get(array,i)); return list; @@ -755,7 +762,6 @@ public class XmlConfiguration private Object newObj(Object obj, XmlParser.Node node) throws Exception { Class<?> oClass = nodeClass(node); - String id = node.getAttribute("id"); int size = 0; int argi = node.size(); for (int i = 0; i < node.size(); i++) @@ -783,42 +789,16 @@ public class XmlConfiguration if (LOG.isDebugEnabled()) LOG.debug("XML new " + oClass); - // Lets just try all constructors for now - Constructor<?>[] constructors = oClass.getConstructors(); - for (int c = 0; constructors != null && c < constructors.length; c++) + try { - if (constructors[c].getParameterTypes().length != size) - continue; - - Object n = null; - boolean called = false; - try - { - n = constructors[c].newInstance(arg); - called = true; - } - catch (IllegalAccessException e) - { - LOG.ignore(e); - } - catch (InstantiationException e) - { - LOG.ignore(e); - } - catch (IllegalArgumentException e) - { - LOG.ignore(e); - } - if (called) - { - if (id != null) - _idMap.put(id,n); - configure(n,node,argi); - return n; - } + Object n = TypeUtil.construct(oClass, arg); + configure(n,node,argi); + return n; + } + catch (NoSuchMethodException e) + { + throw new IllegalStateException("No suitable constructor: " + node + " on " + obj); } - - throw new IllegalStateException("No Constructor: " + node + " on " + obj); } /* ------------------------------------------------------------ */ @@ -853,14 +833,21 @@ public class XmlConfiguration aClass = TypeUtil.fromName(type); if (aClass == null) { - if ("String".equals(type)) - aClass = java.lang.String.class; - else if ("URL".equals(type)) - aClass = java.net.URL.class; - else if ("InetAddress".equals(type)) - aClass = java.net.InetAddress.class; - else - aClass = Loader.loadClass(XmlConfiguration.class,type,true); + switch (type) + { + case "String": + aClass = String.class; + break; + case "URL": + aClass = URL.class; + break; + case "InetAddress": + aClass = InetAddress.class; + break; + default: + aClass = Loader.loadClass(XmlConfiguration.class, type, true); + break; + } } } @@ -890,7 +877,7 @@ public class XmlConfiguration { String id = node.getAttribute("id"); - Map<Object, Object> map = new HashMap<Object, Object>(); + Map<Object, Object> map = new HashMap<>(); if (id != null) _idMap.put(id,map); @@ -1180,7 +1167,7 @@ public class XmlConfiguration public static void main(final String[] args) throws Exception { - final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); + final AtomicReference<Throwable> exception = new AtomicReference<>(); AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -1198,11 +1185,7 @@ public class XmlConfiguration properties = (Properties)config.getMethod("getProperties").invoke(null); LOG.debug("org.eclipse.jetty.start.Config properties = {}",properties); } - catch (NoClassDefFoundError e) - { - LOG.ignore(e); - } - catch (ClassNotFoundException e) + catch (NoClassDefFoundError | ClassNotFoundException e) { LOG.ignore(e); } @@ -1240,7 +1223,7 @@ public class XmlConfiguration configuration.getIdMap().putAll(last.getIdMap()); if (properties.size() > 0) { - Map<String, String> props = new HashMap<String, String>(); + Map<String, String> props = new HashMap<>(); for (Object key : properties.keySet()) { props.put(key.toString(),String.valueOf(properties.get(key))); diff --git a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_6_0.dtd b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_6_0.dtd index e2139c162e..f79d4b7f00 100644 --- a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_6_0.dtd +++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_6_0.dtd @@ -19,7 +19,7 @@ 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 % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|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 NMTOKEN #IMPLIED" > @@ -245,24 +245,6 @@ This is equivalent to: <!ELEMENT SystemProperty EMPTY> <!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %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 EMPTY> -<!ATTLIST Env %NAMEATTR; %DEFAULTATTR; %IDATTR;> - <!-- Property Element. diff --git a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_7_6.dtd b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_7_6.dtd index f79d4b7f00..04bf422164 100644 --- a/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_7_6.dtd +++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_7_6.dtd @@ -19,7 +19,7 @@ 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|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 NMTOKEN #IMPLIED" > @@ -247,6 +247,25 @@ This is equivalent to: <!-- +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 EMPTY> +<!ATTLIST Env %NAMEATTR; %DEFAULTATTR; %IDATTR;> + + +<!-- Property Element. This element allows arbitrary properties to be retrieved by name. The name attribute specifies the property name and the optional 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 new file mode 100644 index 0000000000..21fd4f7034 --- /dev/null +++ b/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd @@ -0,0 +1,284 @@ +<?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 NMTOKEN #IMPLIED" > +<!ENTITY % CLASSATTR "class NMTOKEN #REQUIRED" > +<!ENTITY % NAMEATTR "name NMTOKEN #REQUIRED" > +<!ENTITY % IMPLIEDNAMEATTR "name NMTOKEN #IMPLIED" > +<!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" > +<!ENTITY % IDATTR "id NMTOKEN #IMPLIED" > +<!ENTITY % REQUIREDIDATTR "id NMTOKEN #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 (Arg*,(%CONFIG;)*) > +<!ATTLIST Call %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; > + + +<!-- +Arg Element. +This element defines a positional argument for the Call element. +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. +A Ref element can contain a sequence of elements such as Set, Put, Call, etc. +which act on the referenced object: + + <Ref id="myobject"> + <Set name="Test">Value2</Set> + </New> +--> +<!ELEMENT Ref (%CONFIG;)* > +<!ATTLIST Ref %REQUIREDIDATTR;> + + +<!-- +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 EMPTY > +<!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %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 EMPTY > +<!ATTLIST Env %NAMEATTR; %DEFAULTATTR; %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. + +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; > |