464606 - Support property expansion in "default" attribute of Property.

This commit is contained in:
Simone Bordet 2015-04-14 15:56:18 +02:00
parent 55e74c6867
commit 337e0bd8c9
2 changed files with 113 additions and 55 deletions

View File

@ -46,6 +46,8 @@ import java.util.Queue;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jetty.util.ArrayQueue;
import org.eclipse.jetty.util.LazyList;
@ -79,16 +81,13 @@ import org.xml.sax.SAXException;
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};
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 Pattern __propertyPattern = Pattern.compile("\\$\\{([^\\}]+)\\}");
private static final Iterable<ConfigurationProcessorFactory> __factoryLoader = ServiceLoader.load(ConfigurationProcessorFactory.class);
private static final XmlParser __parser = initParser();
private static XmlParser initParser()
@ -629,7 +628,7 @@ public class XmlConfiguration
Map<Object, Object> map = (Map<Object, Object>)obj;
String name = node.getAttribute("name");
Object value = value(obj,node);
Object value = value(obj, node);
map.put(name,value);
if (LOG.isDebugEnabled())
LOG.debug("XML " + obj + ".put(" + name + "," + value + ")");
@ -674,7 +673,7 @@ public class XmlConfiguration
}
}
if (id != null)
_configuration.getIdMap().put(id,obj);
_configuration.getIdMap().put(id, obj);
return obj;
}
@ -891,7 +890,7 @@ public class XmlConfiguration
Map<Object, Object> map = new HashMap<>();
if (id != null)
_configuration.getIdMap().put(id,map);
_configuration.getIdMap().put(id, map);
for (Object o : node)
{
@ -949,32 +948,12 @@ public class XmlConfiguration
String defaultValue = node.getAttribute("default");
Object value = null;
boolean present = false;
Map<String,String> properties = _configuration.getProperties();
if (properties != null && nameAttr != null)
{
String preferredName = null;
String[] names = nameAttr.split(",");
for (String name : names)
{
name = name.trim();
if (name.length() == 0)
continue;
if (preferredName == null)
preferredName = name;
value = resolve(properties, nameAttr);
if (properties.containsKey(name))
{
if (!name.equals(preferredName))
LOG.warn("Property '{}' is deprecated, use '{}' instead", name, preferredName);
present = true;
value = properties.get(name);
break;
}
}
}
if (!present)
value = defaultValue;
if (value == null && defaultValue != null)
value = interpolate(properties, defaultValue);
if (idAttr != null)
_configuration.getIdMap().put(idAttr, value);
@ -985,6 +964,57 @@ public class XmlConfiguration
return value;
}
private String resolve(Map<String, String> properties, String nameAttr)
{
String preferredName = null;
String[] names = nameAttr.split(",");
for (String name : names)
{
name = name.trim();
if (name.length() == 0)
continue;
if (preferredName == null)
preferredName = name;
String value = properties.get(name);
if (value != null)
{
if (!name.equals(preferredName))
LOG.warn("Property '{}' is deprecated, use '{}' instead", name, preferredName);
return value;
}
}
return null;
}
private String interpolate(Map<String, String> properties, String text)
{
StringBuilder result = new StringBuilder();
Matcher matcher = __propertyPattern.matcher(text);
int start = 0;
while (matcher.find(start))
{
int match = matcher.start();
result.append(text.substring(start, match));
String name = matcher.group(1);
String dftValue = null;
int bar = name.indexOf('|');
if (bar > 0)
{
dftValue = name.substring(bar + 1).trim();
name = name.substring(0, bar).trim();
}
String value = resolve(properties, name);
if (value == null)
value = dftValue;
result.append(value);
start = matcher.end();
}
result.append(text.substring(start, text.length()));
String r = result.toString();
return r.isEmpty() ? null : r;
}
/*
* Get the value of an element. 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. @param node

View File

@ -18,13 +18,6 @@
package org.eclipse.jetty.xml;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@ -36,6 +29,13 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class XmlConfigurationTest
{
protected String _configure="org/eclipse/jetty/xml/configure.xml";
@ -219,8 +219,8 @@ public class XmlConfigurationTest
new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"Test\">SetValue</Set><Set name=\"Test\" type=\"int\">2</Set></Configure>");
TestConfiguration tc = new TestConfiguration();
configuration.configure(tc);
assertEquals("Set String 3","SetValue",tc.testObject);
assertEquals("Set Type 3",2,tc.testInt);
assertEquals("Set String 3", "SetValue", tc.testObject);
assertEquals("Set Type 3", 2, tc.testInt);
}
@Test
@ -233,7 +233,7 @@ public class XmlConfigurationTest
assertThat("tc.getList() returns null as it's not configured yet",tc.getList(),is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getList() returns not null",tc.getList(),not(nullValue()));
assertThat("tc.getList() has two entries as specified in the xml",tc.getList().size(),is(2));
assertThat("tc.getList() has two entries as specified in the xml", tc.getList().size(), is(2));
}
@Test
@ -248,7 +248,7 @@ public class XmlConfigurationTest
assertThat("tc.getList() returns null as it's not configured yet",tc.getList(),is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getList() returns not null",tc.getList(),not(nullValue()));
assertThat("tc.getList() has two entries as specified in the xml",tc.getList().size(),is(2));
assertThat("tc.getList() has two entries as specified in the xml", tc.getList().size(), is(2));
}
@Test(expected = IllegalArgumentException.class)
@ -270,7 +270,7 @@ public class XmlConfigurationTest
assertThat("tc.getList() returns null as it's not configured yet",tc.getSet(),is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getList() returns not null",tc.getSet(),not(nullValue()));
assertThat("tc.getList() has two entries as specified in the xml",tc.getSet().size(),is(2));
assertThat("tc.getList() has two entries as specified in the xml", tc.getSet().size(), is(2));
}
@Test(expected = IllegalArgumentException.class)
@ -290,7 +290,7 @@ public class XmlConfigurationTest
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getList() returns null as it's not configured yet",tc.getList(),is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getList() has two entries as specified in the xml",tc.getList().size(),is(2));
assertThat("tc.getList() has two entries as specified in the xml", tc.getList().size(), is(2));
}
@Test
@ -301,7 +301,7 @@ public class XmlConfigurationTest
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getList() returns null as it's not configured yet",tc.getList(),is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getList() has two entries as specified in the xml",tc.getList().size(),is(2));
assertThat("tc.getList() has two entries as specified in the xml", tc.getList().size(), is(2));
}
@Test(expected=NoSuchMethodException.class)
@ -310,7 +310,7 @@ public class XmlConfigurationTest
XmlConfiguration xmlConfiguration = new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"LinkedList\">"
+ INT_ARRAY_XML + "</Set></Configure>");
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getSet() returns null as it's not configured yet",tc.getList(),is(nullValue()));
assertThat("tc.getSet() returns null as it's not configured yet", tc.getList(), is(nullValue()));
xmlConfiguration.configure(tc);
}
@ -320,9 +320,9 @@ public class XmlConfigurationTest
XmlConfiguration xmlConfiguration = new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"ArrayList\">"
+ INT_ARRAY_XML + "</Set></Configure>");
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getSet() returns null as it's not configured yet",tc.getList(),is(nullValue()));
assertThat("tc.getSet() returns null as it's not configured yet", tc.getList(), is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getSet() has two entries as specified in the xml",tc.getList().size(),is(2));
assertThat("tc.getSet() has two entries as specified in the xml", tc.getList().size(), is(2));
}
@Test
@ -331,9 +331,9 @@ public class XmlConfigurationTest
XmlConfiguration xmlConfiguration = new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"Set\">"
+ STRING_ARRAY_XML + "</Set></Configure>");
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getSet() returns null as it's not configured yet",tc.getSet(),is(nullValue()));
assertThat("tc.getSet() returns null as it's not configured yet", tc.getSet(), is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getSet() has two entries as specified in the xml",tc.getSet().size(),is(2));
assertThat("tc.getSet() has two entries as specified in the xml", tc.getSet().size(), is(2));
}
@Test
@ -342,9 +342,9 @@ public class XmlConfigurationTest
XmlConfiguration xmlConfiguration = new XmlConfiguration("<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\"><Set name=\"Set\">"
+ INT_ARRAY_XML + "</Set></Configure>");
TestConfiguration tc = new TestConfiguration();
assertThat("tc.getSet() returns null as it's not configured yet",tc.getSet(),is(nullValue()));
assertThat("tc.getSet() returns null as it's not configured yet", tc.getSet(), is(nullValue()));
xmlConfiguration.configure(tc);
assertThat("tc.getSet() has two entries as specified in the xml",tc.getSet().size(),is(2));
assertThat("tc.getSet() has two entries as specified in the xml", tc.getSet().size(), is(2));
}
@Test
@ -590,7 +590,7 @@ public class XmlConfigurationTest
Assert.assertEquals("third parameter not wired correctly","arg3", atc.getThird());
Assert.assertEquals("nested first parameter not wired correctly","arg1", atc.getNested().getFirst());
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
Assert.assertEquals("nested third parameter not wired correctly", "arg3", atc.getNested().getThird());
}
@Test
@ -618,7 +618,7 @@ public class XmlConfigurationTest
Assert.assertEquals("third parameter not wired correctly","arg3", atc.getThird());
Assert.assertEquals("nested first parameter not wired correctly","arg1", atc.getNested().getFirst());
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
Assert.assertEquals("nested third parameter not wired correctly", "arg3", atc.getNested().getThird());
}
@Test
@ -645,7 +645,7 @@ public class XmlConfigurationTest
Assert.assertEquals("third parameter not wired correctly","arg3", atc.getThird());
Assert.assertEquals("nested first parameter not wired correctly","arg1", atc.getNested().getFirst());
Assert.assertEquals("nested second parameter not wired correctly","arg2", atc.getNested().getSecond());
Assert.assertEquals("nested third parameter not wired correctly","arg3", atc.getNested().getThird());
Assert.assertEquals("nested third parameter not wired correctly", "arg3", atc.getNested().getThird());
}
public static class NativeHolder
@ -820,4 +820,32 @@ public class XmlConfigurationTest
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
assertEquals(value, config.getFirst());
}
@Test
public void testPropertyNotFoundWithPropertyInDefaultValue() throws Exception
{
String name = "bar";
String value = "bar";
String defaultValue = "_${bar}_${bar}_";
String expectedValue = "_" + value + "_" + value + "_";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
" <Set name=\"first\"><Property name=\"not_found\" default=\"" + defaultValue + "\"/></Set> " +
"</Configure>");
xmlConfiguration.getProperties().put(name, value);
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
assertEquals(expectedValue, config.getFirst());
}
@Test
public void testPropertyNotFoundWithPropertyInDefaultValueNotFoundWithDefault() throws Exception
{
String value = "bar";
XmlConfiguration xmlConfiguration = new XmlConfiguration("" +
"<Configure class=\"org.eclipse.jetty.xml.DefaultTestConfiguration\">" +
" <Set name=\"first\"><Property name=\"not_found\" default=\"${not_found|" + value + "}\"/></Set> " +
"</Configure>");
DefaultTestConfiguration config = (DefaultTestConfiguration)xmlConfiguration.configure();
assertEquals(value, config.getFirst());
}
}