Skip to content

Commit

Permalink
Fixes #8913 - Review Jetty XML syntax to allow calling JDK methods
Browse files Browse the repository at this point in the history
Now <Call>, <Get> and <Set> elements can use the "class" attribute
to specify the exact class to perform method lookup.

Improved support for <Property>, <SystemProperty> and <Env> so that
attribute "name" is now optional (as specified in the DTD), and a
"deprecated" attribute may be present instead.
This is necessary to terminally deprecate properties that have
no replacement.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
  • Loading branch information
sbordet committed Nov 18, 2022
1 parent 8de1bad commit 4c79cb1
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 57 deletions.
88 changes: 48 additions & 40 deletions jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,7 @@ private void set(Object obj, XmlParser.Node node) throws Exception
String propertyValue = null;

Class<?> oClass = nodeClass(node);
if (oClass != null)
obj = null;
else
if (oClass == null)
oClass = obj.getClass();

// Look for a property value
Expand Down Expand Up @@ -553,9 +551,9 @@ private void set(Object obj, XmlParser.Node node) throws Exception
value = propertyValue;
Object[] arg = {value};

Class<?>[] vClass = {Object.class};
Class<?> vClass = Object.class;
if (value != null)
vClass[0] = value.getClass();
vClass = value.getClass();

if (LOG.isDebugEnabled())
LOG.debug("XML {}.{} ({})", (obj != null ? obj.toString() : oClass.getName()), setter, value);
Expand All @@ -582,8 +580,8 @@ private void set(Object obj, XmlParser.Node node) throws Exception
// Try for native match
try
{
Field type = vClass[0].getField("TYPE");
vClass[0] = (Class<?>)type.get(null);
Field type = vClass.getField("TYPE");
vClass = (Class<?>)type.get(null);
Method set = oClass.getMethod(setter, vClass);
invokeMethod(set, obj, arg);
return;
Expand Down Expand Up @@ -715,7 +713,7 @@ private void set(Object obj, XmlParser.Node node) throws Exception
}

// No Joy
String message = oClass + "." + setter + "(" + vClass[0] + ")";
String message = oClass + "." + setter + "(" + vClass + ")";
if (types != null)
message += ". Found setters for " + types;
NoSuchMethodException failure = new NoSuchMethodException(message);
Expand Down Expand Up @@ -828,19 +826,11 @@ private Object get(Object obj, XmlParser.Node node) throws Exception

Class<?> oClass;
if (clazz != null)
{
// static call
oClass = Loader.loadClass(clazz);
obj = null;
}
else if (obj != null)
{
oClass = obj.getClass();
}
else
{
throw new IllegalArgumentException(node.toString());
}

if (LOG.isDebugEnabled())
LOG.debug("XML get {}", name);
Expand Down Expand Up @@ -906,19 +896,11 @@ private Object call(Object obj, XmlParser.Node node) throws Exception

Class<?> oClass;
if (clazz != null)
{
// static call
oClass = Loader.loadClass(clazz);
obj = null;
}
else if (obj != null)
{
oClass = obj.getClass();
}
else
{
throw new IllegalArgumentException(node.toString());
}

if (LOG.isDebugEnabled())
LOG.debug("XML call {}", name);
Expand Down Expand Up @@ -955,10 +937,6 @@ private Object call(Class<?> oClass, String methodName, Object obj, Args args) t
Object[] arguments = args.applyTo(method);
if (arguments == null)
continue;
if (Modifier.isStatic(method.getModifiers()) != (obj == null))
continue;
if ((obj == null) && method.getDeclaringClass() != oClass)
continue;

try
{
Expand Down Expand Up @@ -1177,27 +1155,39 @@ private Object propertyObj(XmlParser.Node node) throws Exception
{
AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default");
String id = aoeNode.getString("Id");
String name = aoeNode.getString("Name", true);
String name = aoeNode.getString("Name", false);
List<Object> deprecated = aoeNode.getList("Deprecated");
String dftValue = aoeNode.getString("Default");

if (name == null && deprecated.isEmpty())
throw new IllegalStateException("Invalid <Property> element");

// Look for a value
Map<String, String> properties = _configuration.getProperties();
String value = properties.get(name);
String value = name == null ? null : properties.get(name);

// Look for a deprecated name value
String alternate = null;
if (!deprecated.isEmpty())
{
for (Object d : deprecated)
{
String v = properties.get(StringUtil.valueOf(d));
if (d == null)
continue;
String v = properties.get(d.toString());
if (v != null)
{
if (value == null)
LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
{
if (name == null)
LOG.warn("Property '{}' is deprecated, do not use it", d);
else
LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
}
else
LOG.warn("Property '{}' is deprecated, value from '{}' used", d, name);
{
LOG.warn("Property '{}' is deprecated, value from '{}' used instead", d, name);
}
}
if (alternate == null)
alternate = v;
Expand Down Expand Up @@ -1228,12 +1218,15 @@ private Object systemPropertyObj(XmlParser.Node node) throws Exception
{
AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default");
String id = aoeNode.getString("Id");
String name = aoeNode.getString("Name", true);
String name = aoeNode.getString("Name", false);
List<Object> deprecated = aoeNode.getList("Deprecated");
String dftValue = aoeNode.getString("Default");

if (name == null && deprecated.isEmpty())
throw new IllegalStateException("Invalid <SystemProperty> element");

// Look for a value
String value = System.getProperty(name);
String value = name == null ? null : System.getProperty(name);

// Look for a deprecated name value
String alternate = null;
Expand All @@ -1247,9 +1240,16 @@ private Object systemPropertyObj(XmlParser.Node node) throws Exception
if (v != null)
{
if (value == null)
LOG.warn("SystemProperty '{}' is deprecated, use '{}' instead", d, name);
{
if (name == null)
LOG.warn("SystemProperty '{}' is deprecated, do not use it", d);
else
LOG.warn("SystemProperty '{}' is deprecated, use '{}' instead", d, name);
}
else
{
LOG.warn("SystemProperty '{}' is deprecated, value from '{}' used", d, name);
}
}
if (alternate == null)
alternate = v;
Expand Down Expand Up @@ -1281,22 +1281,30 @@ private Object envObj(XmlParser.Node node) throws Exception
{
AttrOrElementNode aoeNode = new AttrOrElementNode(node, "Id", "Name", "Deprecated", "Default");
String id = aoeNode.getString("Id");
String name = aoeNode.getString("Name", true);
String name = aoeNode.getString("Name", false);
List<Object> deprecated = aoeNode.getList("Deprecated");
String dftValue = aoeNode.getString("Default");

if (name == null && deprecated.isEmpty())
throw new IllegalStateException("Invalid <Env> element");

// Look for a value
String value = System.getenv(name);
String value = name == null ? null : System.getenv(name);

// Look for a deprecated name value
if (value == null && !deprecated.isEmpty())
{
for (Object d : deprecated)
{
value = System.getenv(StringUtil.valueOf(d));
if (d == null)
continue;
value = System.getenv(d.toString());
if (value != null)
{
LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
if (name == null)
LOG.warn("Property '{}' is deprecated, do not use it", d);
else
LOG.warn("Property '{}' is deprecated, use '{}' instead", d, name);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ 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.
default attribute provides a default value.
<SystemProperty name="Test" default="value" />
Expand All @@ -303,15 +303,14 @@ 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.
default attribute provides a default value.
<Env name="Test" default="value" />
This is equivalent to:
String v=System.getEnv("Test");
if (v==null) v="value";
-->
<!ELEMENT Env (Id?,Name?,Deprecated*,Default?) >
<!ATTLIST Env %ID_ATTR; %NAME_ATTR; %DEPRECATED_ATTR; %DEFAULT_ATTR; >
Expand All @@ -321,7 +320,7 @@ This is equivalent to:
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.
default attribute provides a default value.
-->
<!ELEMENT Property (Id?,Name?,Deprecated*,Default?) >
<!ATTLIST Property %ID_ATTR; %NAME_ATTR; %DEPRECATED_ATTR; %DEFAULT_ATTR; >

0 comments on commit 4c79cb1

Please sign in to comment.