Re: [picocontainer-dev] ConfigParameterTestCase / ConfigParameter
Paul Hammant <[email protected]>
| Newsgroups | gmane.comp.java.picocontainer.devel |
|---|---|
| Message-ID | <[email protected]> |
I've a patch that's a step in the right direction....
It ...
1) abolishes the type conversion stuff that Konstantin did not like
from my ArgumentativePicoContainer
2) has the start of the same type of conversion that ConfigParam did
(without XStream)
3) meets my latest requirements - see that test I added and commented
out in the last email
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
improved.txt
(text/plain, 14.6 KB)
Index: src/test/org/picocontainer/containers/ArgumentativePicoContainerTestCase.java
===================================================================
--- src/test/org/picocontainer/containers/ArgumentativePicoContainerTestCase.java (revision 4004)
+++ src/test/org/picocontainer/containers/ArgumentativePicoContainerTestCase.java (working copy)
@@ -28,9 +28,9 @@
"foo=bar", "foo2=12", "foo3=true", "foo4="
});
assertEquals("bar",apc.getComponent("foo"));
- assertEquals(12,apc.getComponent("foo2"));
- assertEquals(true,apc.getComponent("foo3"));
- assertEquals(true,apc.getComponent("foo4"));
+ assertEquals("12",apc.getComponent("foo2"));
+ assertEquals("true",apc.getComponent("foo3"));
+ assertEquals("true",apc.getComponent("foo4"));
}
public void testAsParentContainer() {
@@ -38,7 +38,7 @@
"a=aaa", "b=bbb", "d=22"});
assertEquals("aaa",apc.getComponent("a"));
assertEquals("bbb",apc.getComponent("b"));
- assertEquals(22,apc.getComponent("d"));
+ assertEquals("22",apc.getComponent("d"));
DefaultPicoContainer dpc = new DefaultPicoContainer(apc);
dpc.addComponent(NeedsString.class);
@@ -57,41 +57,41 @@
"foo:bar", "foo2:12", "foo3:true"
});
assertEquals("bar",apc.getComponent("foo"));
- assertEquals(12,apc.getComponent("foo2"));
- assertEquals(true,apc.getComponent("foo3"));
+ assertEquals("12",apc.getComponent("foo2"));
+ assertEquals("true",apc.getComponent("foo3"));
}
public void testParsingWithWrongSeparator() {
ArgumentativePicoContainer apc = new ArgumentativePicoContainer(":", new String[] {
"foo=bar", "foo2=12", "foo3=true"
});
- assertEquals(true,apc.getComponent("foo=bar"));
- assertEquals(true,apc.getComponent("foo2=12"));
- assertEquals(true,apc.getComponent("foo3=true"));
+ assertEquals("true",apc.getComponent("foo=bar"));
+ assertEquals("true",apc.getComponent("foo2=12"));
+ assertEquals("true",apc.getComponent("foo3=true"));
}
public void testParsingOfPropertiesFile() throws IOException {
ArgumentativePicoContainer apc = new ArgumentativePicoContainer(":",
new StringReader("foo:bar\nfoo2:12\nfoo3:true\n"));
assertEquals("bar",apc.getComponent("foo"));
- assertEquals(12,apc.getComponent("foo2"));
- assertEquals(true,apc.getComponent("foo3"));
+ assertEquals("12",apc.getComponent("foo2"));
+ assertEquals("true",apc.getComponent("foo3"));
}
public void testParsingOfPropertiesFileAndArgs() throws IOException {
ArgumentativePicoContainer apc = new ArgumentativePicoContainer(":",
new StringReader("foo:bar\nfoo2:12\n"), new String[] {"foo3:true"});
assertEquals("bar",apc.getComponent("foo"));
- assertEquals(12,apc.getComponent("foo2"));
- assertEquals(true,apc.getComponent("foo3"));
+ assertEquals("12",apc.getComponent("foo2"));
+ assertEquals("true",apc.getComponent("foo3"));
}
public void testParsingOfPropertiesFileAndArgsWithClash() throws IOException {
ArgumentativePicoContainer apc = new ArgumentativePicoContainer(":",
new StringReader("foo:bar\nfoo2:99\n"), new String[] {"foo2:12","foo3:true"});
assertEquals("bar",apc.getComponent("foo"));
- assertEquals(12,apc.getComponent("foo2"));
- assertEquals(true,apc.getComponent("foo3"));
+ assertEquals("12",apc.getComponent("foo2"));
+ assertEquals("true",apc.getComponent("foo3"));
}
public void testbyTypeFailsEvenIfOneOfSameType() {
Index: src/java/org/picocontainer/parameters/BasicComponentParameter.java
===================================================================
--- src/java/org/picocontainer/parameters/BasicComponentParameter.java (revision 4004)
+++ src/java/org/picocontainer/parameters/BasicComponentParameter.java (working copy)
@@ -16,10 +16,12 @@
import org.picocontainer.PicoVisitor;
import org.picocontainer.injectors.AbstractInjector;
+import java.io.File;
import java.io.Serializable;
-import java.lang.reflect.Field;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -35,15 +37,62 @@
* @author Jörg Schaible
* @author Thomas Heller
*/
-public class BasicComponentParameter
- implements Parameter, Serializable
-{
+public class BasicComponentParameter implements Parameter, Serializable {
+ private static interface Converter {
+ Object convert(String paramValue);
+ }
+
/** <code>BASIC_DEFAULT</code> is an instance of BasicComponentParameter using the default constructor. */
public static final BasicComponentParameter BASIC_DEFAULT = new BasicComponentParameter();
private Object componentKey;
+ private static final Map<Class, Converter> stringConverters = new HashMap<Class, Converter>();
+ static {
+ stringConverters.put(Integer.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Integer.valueOf(paramValue);
+ }
+ });
+ stringConverters.put(File.class, new Converter() {
+ public Object convert(String paramValue) {
+ return new File(paramValue);
+ }
+ });
+ stringConverters.put(Double.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Double.valueOf(paramValue);
+ }
+ });
+ stringConverters.put(Boolean.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Boolean.valueOf(paramValue);
+ }
+ });
+ stringConverters.put(Long.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Long.valueOf(paramValue);
+ }
+ });
+ stringConverters.put(Float.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Float.valueOf(paramValue);
+ }
+ });
+ stringConverters.put(Character.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Character.valueOf(paramValue.charAt(0));
+ }
+ });
+ stringConverters.put(Double.class, new Converter() {
+ public Object convert(String paramValue) {
+ return Double.valueOf(paramValue);
+ }
+ });
+
+ }
+
/**
* Expect a parameter matching a component of a specific key.
*
@@ -80,7 +129,12 @@
final ComponentAdapter componentAdapter =
resolveAdapter(container, adapter, (Class<?>)expectedType, expectedParameterName, useNames);
if (componentAdapter != null) {
- return (T) container.getComponent(componentAdapter.getComponentKey());
+ Object o = container.getComponent(componentAdapter.getComponentKey());
+ if (o instanceof String && expectedType != String.class) {
+ Converter converter = stringConverters.get(expectedType);
+ return (T) converter.convert((String) o);
+ }
+ return (T) o;
}
return null;
}
@@ -112,32 +166,37 @@
ComponentAdapter adapter,
Class<T> expectedType,
ParameterName expectedParameterName, boolean useNames) {
+ Class type = expectedType;
+ if (type.isPrimitive()) {
+ String expectedTypeName = expectedType.getName();
+ if (expectedTypeName == "int") {
+ type = Integer.class;
+ } else if (expectedTypeName == "long") {
+ type = Long.class;
+ } else if (expectedTypeName == "float") {
+ type = Float.class;
+ } else if (expectedTypeName == "double") {
+ type = Double.class;
+ } else if (expectedTypeName == "boolean") {
+ type = Boolean.class;
+ } else if (expectedTypeName == "char") {
+ type = Character.class;
+ } else if (expectedTypeName == "short") {
+ type = Short.class;
+ } else if (expectedTypeName == "byte") {
+ type = Byte.class;
+ }
+ }
- final ComponentAdapter<T> result = getTargetAdapter(container, expectedType, expectedParameterName, adapter, useNames);
+ final ComponentAdapter<T> result = getTargetAdapter(container, type, expectedParameterName, adapter, useNames);
if (result == null) {
return null;
}
- if (!expectedType.isAssignableFrom(result.getComponentImplementation())) {
- // check for primitive value
- if (expectedType.isPrimitive()) {
- try {
- final Field field = result.getComponentImplementation().getField("TYPE");
- final Class type = (Class)field.get(result.getComponentInstance(null));
- if (expectedType.isAssignableFrom(type)) {
- return result;
- }
- } catch (NoSuchFieldException e) {
- //ignore
- } catch (IllegalArgumentException e) {
- //ignore
- } catch (IllegalAccessException e) {
- //ignore
- } catch (ClassCastException e) {
- //ignore
- }
+ if (!type.isAssignableFrom(result.getComponentImplementation())) {
+ if (!(result.getComponentImplementation() == String.class && stringConverters.containsKey(type))) {
+ return null;
}
- return null;
}
return result;
}
@@ -166,7 +225,7 @@
if (useNames) {
ComponentAdapter found = container.getComponentAdapter(expectedParameterName.getName());
if ((found != null)
- && expectedType.isAssignableFrom(found.getComponentImplementation())
+ && areCompatible(expectedType, found)
&& found != excludeAdapter) {
return (ComponentAdapter<T>) found;
}
@@ -196,4 +255,10 @@
}
}
}
+
+ private <T> boolean areCompatible(Class<T> expectedType, ComponentAdapter found) {
+ Class foundImpl = found.getComponentImplementation();
+ return expectedType.isAssignableFrom(foundImpl) ||
+ (foundImpl == String.class && stringConverters.containsKey(expectedType)) ;
+ }
}
Index: src/java/org/picocontainer/injectors/SingleMemberInjector.java
===================================================================
--- src/java/org/picocontainer/injectors/SingleMemberInjector.java (revision 4004)
+++ src/java/org/picocontainer/injectors/SingleMemberInjector.java (working copy)
@@ -46,10 +46,23 @@
*/
protected Class box(Class parameterType) {
if (parameterType.isPrimitive()) {
- if (parameterType == Integer.TYPE) {
+ String parameterTypeName = parameterType.getName();
+ if (parameterTypeName == "int") {
return Integer.class;
- } else if (parameterType == Boolean.TYPE) {
+ } else if (parameterTypeName == "boolean") {
return Boolean.class;
+ } else if (parameterTypeName == "long") {
+ return Long.class;
+ } else if (parameterTypeName == "float") {
+ return Float.class;
+ } else if (parameterTypeName == "double") {
+ return Double.class;
+ } else if (parameterTypeName == "char") {
+ return Character.class;
+ } else if (parameterTypeName == "byte") {
+ return Byte.class;
+ } else if (parameterTypeName == "short") {
+ return Short.class;
}
}
return parameterType;
Index: src/java/org/picocontainer/injectors/ConstructorInjector.java
===================================================================
--- src/java/org/picocontainer/injectors/ConstructorInjector.java (revision 4004)
+++ src/java/org/picocontainer/injectors/ConstructorInjector.java (working copy)
@@ -78,9 +78,11 @@
// remember: all constructors with less arguments than the given parameters are filtered out already
for (int j = 0; j < currentParameters.length; j++) {
- // check wether this constructor is statisfiable
- if (currentParameters[j].isResolvable(container, this, box(parameterTypes[j]),
- new SingleMemberInjectorParameterName(sortedMatchingConstructor,j), useNames())) {
+ // check whether this constructor is statisfiable
+ Class boxed = box(parameterTypes[j]);
+ boolean un = useNames();
+ if (currentParameters[j].isResolvable(container, this, boxed,
+ new SingleMemberInjectorParameterName(sortedMatchingConstructor, j), un)) {
continue;
}
unsatisfiableDependencyTypes.add(Arrays.asList(parameterTypes));
Index: src/java/org/picocontainer/containers/ArgumentativePicoContainer.java
===================================================================
--- src/java/org/picocontainer/containers/ArgumentativePicoContainer.java (revision 4004)
+++ src/java/org/picocontainer/containers/ArgumentativePicoContainer.java (working copy)
@@ -88,25 +88,12 @@
return new EmptyPicoContainer();
}
- private Object getValue(String s) {
- if (s.equals("true")) {
- return true;
- } else if (s.equals("false")) {
- return false;
- }
- try {
- return Integer.parseInt(s);
- } catch (NumberFormatException e) {
- }
- return s;
- }
-
private void processArgument(String argument, String separator) {
String[] kvs = argument.split(separator);
if (kvs.length == 2) {
- addConfig(kvs[0], getValue(kvs[1]));
+ addConfig(kvs[0], kvs[1]);
} else if (kvs.length == 1) {
- addConfig(kvs[0], true);
+ addConfig(kvs[0], "true");
} else if (kvs.length > 2) {
throw new PicoCompositionException(
"Argument name'"+separator+"'value pair '" + argument + "' has too many '"+separator+"' characters");