Log Message
Sometimes DependencyInjectionFactory tries to instantiate objects with mismatching constructor arguments.
Modified Paths
- trunk/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java
- trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java
- trunk/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java
- trunk/xstream-distribution/src/content/changes.html
Diff
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java (1969 => 1970)
--- trunk/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java 2012-03-22 23:13:24 UTC (rev 1969)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java 2012-03-30 00:07:23 UTC (rev 1970)
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2009, 2010, 2011 XStream Committers.
+ * Copyright (c) 2007, 2009, 2010, 2011, 2012 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -43,7 +43,7 @@
* @since 1.2.2
*/
public static Object newInstance(final Class type, final Object[] dependencies) {
- return newInstance(type, dependencies, new BitSet());
+ return newInstance(type, dependencies, null);
}
/**
@@ -62,7 +62,9 @@
*/
public static Object newInstance(final Class type, final Object[] dependencies, final BitSet usedDependencies) {
Constructor bestMatchingCtor = null;
- final List matchingDependencies = new ArrayList();
+ final ArrayList matchingDependencies = new ArrayList();
+ List possibleMatchingDependencies = null;
+ BitSet possibleUsedDependencies = null;
if (dependencies != null && dependencies.length > 0) {
// sort available ctors according their arity
@@ -105,7 +107,6 @@
}
if (arity > parameterTypes.length) {
if (possibleCtor != null) {
- bestMatchingCtor = possibleCtor;
continue;
}
arity = parameterTypes.length;
@@ -121,14 +122,14 @@
// of the parameter
// declaration
matchingDependencies.clear();
- for (int j = usedDependencies.length(); j-- > 0;) {
- usedDependencies.clear(j); // JDK 1.3, BitSet.clear() is JDK 1.4
- }
+ clear(usedDependencies);
for (int j = 0, k = 0; j < parameterTypes.length
&& parameterTypes.length + k - j <= typedDependencies.length; k++ ) {
if (parameterTypes[j].isAssignableFrom(typedDependencies[k].type)) {
matchingDependencies.add(typedDependencies[k].value);
- usedDependencies.set(k);
+ if (usedDependencies != null) {
+ usedDependencies.set(k);
+ }
if ( ++j == parameterTypes.length) {
bestMatchingCtor = constructor;
break;
@@ -144,9 +145,7 @@
final TypedValue[] deps = new TypedValue[typedDependencies.length];
System.arraycopy(typedDependencies, 0, deps, 0, deps.length);
matchingDependencies.clear();
- for (int j = usedDependencies.length(); j-- > 0;) {
- usedDependencies.clear(j); // JDK 1.3, BitSet.clear() is JDK 1.4
- }
+ clear(usedDependencies);
for (int j = 0; j < parameterTypes.length; j++ ) {
int assignable = -1;
for (int k = 0; k < deps.length; k++ ) {
@@ -169,26 +168,39 @@
if (assignable >= 0) {
matchingDependencies.add(deps[assignable].value);
- usedDependencies.set(assignable);
+ if (usedDependencies != null) {
+ usedDependencies.set(assignable);
+ }
deps[assignable] = null; // do not match same dep twice
} else {
possibleCtor = null;
break;
}
}
+
+ if (possibleCtor != null) {
+ possibleMatchingDependencies = (List)matchingDependencies.clone();
+ if (usedDependencies != null) {
+ possibleUsedDependencies = (BitSet)usedDependencies.clone();
+ }
+ }
}
}
if (bestMatchingCtor == null) {
if (possibleCtor == null) {
- for (int j = usedDependencies.length(); j-- > 0;) {
- usedDependencies.clear(j); // JDK 1.3, BitSet.clear() is JDK 1.4
- }
+ clear(usedDependencies);
throw new ObjectAccessException("Cannot construct "
+ type.getName()
+ ", none of the dependencies match any constructor's parameters");
} else {
bestMatchingCtor = possibleCtor;
+ matchingDependencies.clear();
+ matchingDependencies.addAll(possibleMatchingDependencies);
+ if (usedDependencies != null) {
+ clear(usedDependencies);
+ usedDependencies.or(possibleUsedDependencies);
+ }
}
}
}
@@ -210,6 +222,14 @@
}
}
+ private static void clear(final BitSet usedDependencies) {
+ if (usedDependencies != null) {
+ for (int j = usedDependencies.length(); j-- > 0;) {
+ usedDependencies.clear(j); // JDK 1.3, BitSet.clear() is JDK 1.4
+ }
+ }
+ }
+
private static class TypedValue {
final Class type;
final Object value;
@@ -222,7 +242,7 @@
public String toString()
{
- return type.getName() + ":" + value;
+ return type.getName() + ":" + value;
}
}
Modified: trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java (1969 => 1970)
--- trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java 2012-03-22 23:13:24 UTC (rev 1969)
+++ trunk/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java 2012-03-30 00:07:23 UTC (rev 1970)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers.
+ * Copyright (C) 2007, 2008, 2009, 2011, 2012 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -492,17 +492,16 @@
args = arguments;
}
- final BitSet usedArgs = new BitSet();
final Converter converter;
try {
if (SingleValueConverter.class.isAssignableFrom(converterType)
&& !Converter.class.isAssignableFrom(converterType)) {
final SingleValueConverter svc = (SingleValueConverter)DependencyInjectionFactory
- .newInstance(converterType, args, usedArgs);
+ .newInstance(converterType, args);
converter = new SingleValueConverterWrapper(svc);
} else {
converter = (Converter)DependencyInjectionFactory.newInstance(
- converterType, args, usedArgs);
+ converterType, args);
}
} catch (final Exception e) {
throw new InitializationException("Cannot instantiate converter "
Modified: trunk/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java (1969 => 1970)
--- trunk/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java 2012-03-22 23:13:24 UTC (rev 1969)
+++ trunk/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java 2012-03-30 00:07:23 UTC (rev 1970)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2009, 2010, 2011 XStream Committers.
+ * Copyright (C) 2007, 2009, 2010, 2011, 2012 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -113,6 +113,18 @@
this(1, 2, null);
}
+ public Thing(Number num) {
+ this(num.intValue(), 8 * num.intValue(), null);
+ }
+
+ public Thing(String str, TestCase testCase) {
+ this(str.length(), 4 * str.length(), testCase);
+ }
+
+ public Thing(Number num, TestCase testCase) {
+ this(num.intValue(), 4 * num.intValue(), testCase);
+ }
+
public Thing(int first, int second, TestCase testCase) {
this.first = first;
this.second = second;
@@ -143,4 +155,24 @@
assertTrue(used.get(1));
assertTrue(used.get(2));
}
+
+ public void testWillSelectMatchingConstructor() {
+ BitSet used = new BitSet();
+ Thing thing = (Thing)DependencyInjectionFactory.newInstance(
+ Thing.class, new Object[]{this, new Integer(1)}, used);
+ assertSame(this, thing.getTestCase());
+ assertEquals(1, thing.getFirst());
+ assertEquals(4, thing.getSecond());
+ assertTrue(used.get(0));
+ assertTrue(used.get(1));
+
+ used = new BitSet();
+ thing = (Thing)DependencyInjectionFactory.newInstance(
+ Thing.class, new Object[]{this, "a"}, used);
+ assertSame(this, thing.getTestCase());
+ assertEquals(1, thing.getFirst());
+ assertEquals(4, thing.getSecond());
+ assertTrue(used.get(0));
+ assertTrue(used.get(1));
+ }
}
Modified: trunk/xstream-distribution/src/content/changes.html (1969 => 1970)
--- trunk/xstream-distribution/src/content/changes.html 2012-03-22 23:13:24 UTC (rev 1969)
+++ trunk/xstream-distribution/src/content/changes.html 2012-03-30 00:07:23 UTC (rev 1970)
@@ -56,6 +56,7 @@
in a derived converter that uses the default constructor to create the original type (as an alternative for
JIRA:XSTR-695).</li>
<li>FieldDictionary may call sort of FieldKeySorter implementation with wrong type as key.</li>
+ <li>Sometimes DependencyInjectionFactory tries to instantiate objects with mismatching constructor arguments.</li>
</ul>
<h1 id="1.4.2">1.4.2</h1>
To unsubscribe from this list please visit:
