diff --git a/src/java/ognl/OgnlOps.java b/src/java/ognl/OgnlOps.java index 7bc7e4a1..0f4144fc 100644 --- a/src/java/ognl/OgnlOps.java +++ b/src/java/ognl/OgnlOps.java @@ -35,6 +35,7 @@ import java.lang.reflect.Array; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Collection; import java.util.Enumeration; /** @@ -529,6 +530,9 @@ public static Object toArray(Object value, Class toType, boolean preventNulls) if (toType == Character.TYPE) return stringValue(value).toCharArray(); + if (value instanceof Collection) + return ((Collection)value).toArray((Object[])Array.newInstance(toType, 0)); + Object arr = Array.newInstance(toType, 1); Array.set(arr, 0, convertValue(value, toType, preventNulls)); @@ -571,7 +575,11 @@ public static Object convertValue(Object value, Class toType, boolean preventNul result = stringValue(value).toCharArray(); } else if (toType.getComponentType() == Object.class) { - return new Object[] { value }; + if (value instanceof Collection) { + Collection vc = (Collection) value; + return vc.toArray(new Object[0]); + } else + return new Object[] { value }; } } else { if ((toType == Integer.class) || (toType == Integer.TYPE)) { diff --git a/src/test/java/org/ognl/test/MethodTest.java b/src/test/java/org/ognl/test/MethodTest.java index 38b7e0c3..6db3440b 100644 --- a/src/test/java/org/ognl/test/MethodTest.java +++ b/src/test/java/org/ognl/test/MethodTest.java @@ -65,16 +65,20 @@ public class MethodTest extends OgnlTestCase { "testMethods.getBean('TestBean')", ROOT.getTestMethods().getBean("TestBean") } , // https://issues.apache.org/jira/browse/OGNL-250 - OnglRuntime getMethodValue fails to find method matching propertyName { "testMethods.testProperty", ROOT.getTestMethods().testProperty() } , - // TODO: some further java <> OGNL inconsistencies: - related to https://github.com/jkuhnert/ognl/issues/16 - // Java 'ROOT.getTestMethods().argsTest1(Arrays.asList( ROOT.getOne() )' doesn't compile: - // --> The method argsTest1(Object[]) in the type MethodTestMethods is not applicable for the arguments (List) - { "testMethods.argsTest1({one})", "Array: [[1]]" }, // "Array: [[1]]" means dual-cast is done. - // Java: ROOT.getTestMethods().argsTest(Arrays.asList( ROOT.getOne() )) - // --> The method argsTest2(List) in the type MethodTestMethods is not applicable for the arguments (List) - { "testMethods.argsTest2({one})", "List: [1]" }, + { "testMethods.argsTest1({one})", ROOT.getTestMethods().argsTest1(Arrays.asList( ROOT.getOne() ).toArray()) }, // toArray() is automatically done by OGNL type conversion + // we need to cast out generics (insert "Object") + { "testMethods.argsTest2({one})", ROOT.getTestMethods().argsTest2(Arrays.asList( (Object) ROOT.getOne() )) }, // Java 'ROOT.getTestMethods().argsTest1(Arrays.asList( ROOT.getOne() )' doesn't compile: // --> The method argsTest(Object[]) in the type MethodTestMethods is not applicable for the arguments (List) { "testMethods.argsTest3({one})", "List: [1]" }, + { "testMethods.showList(testMethods.getObjectList())", ROOT.getTestMethods().showList(ROOT.getTestMethods().getObjectList().toArray()) }, + { "testMethods.showList(testMethods.getStringList())", ROOT.getTestMethods().showList(ROOT.getTestMethods().getStringList().toArray()) }, + { "testMethods.showList(testMethods.getStringArray())", ROOT.getTestMethods().showList(ROOT.getTestMethods().getStringArray()) }, + // TODO This one doesn't work - even 'toArray(new String[0]) returns Object[] and so the wrong method is called - currently no idea how to handle this... + // { "testMethods.showList(testMethods.getStringList().toArray(new String[0]))", ROOT.getTestMethods().showList(ROOT.getTestMethods().getStringList().toArray(new String[0])) }, + // but this one works - at least in interpretation mode... + { "testMethods.showStringList(testMethods.getStringList().toArray(new String[0]))", ROOT.getTestMethods().showStringList(ROOT.getTestMethods().getStringList().toArray(new String[0])) }, + // https://github.com/jkuhnert/ognl/issues/23 - Exception selecting overloaded method in 3.1.4 { "testMethods.avg({ 5, 5 })", ROOT.getTestMethods().avg((List)Arrays.asList(5, 5)) }, }; diff --git a/src/test/java/org/ognl/test/objects/MethodTestMethods.java b/src/test/java/org/ognl/test/objects/MethodTestMethods.java index f2b5300f..d814140b 100644 --- a/src/test/java/org/ognl/test/objects/MethodTestMethods.java +++ b/src/test/java/org/ognl/test/objects/MethodTestMethods.java @@ -125,4 +125,28 @@ public double avg(final double[] target) { } return total/target.length; } + + public String[] getStringArray() { + return new String[] { "Hello", "World" }; + } + + public List getStringList() { + return Arrays.asList("Hello", "World"); + } + + public List getObjectList() { + return Arrays.asList((Object)"Object"); + } + + public String showList(String[] args) { + return "Strings: " + Arrays.toString(args); + } + + public String showList(Object[] args) { + return "Objects: " + Arrays.toString(args); + } + + public String showStringList(String[] args) { + return "Strings: " + Arrays.toString(args); + } }