diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java index c375ce147..2ef75e88c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java +++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/DefaultObjectTypeDeterminer.java @@ -75,11 +75,11 @@ public class DefaultObjectTypeDeterminer implements ObjectTypeDeterminer { /** * Determines the key class by looking for the value of @Key annotation for the given class. - * If no annotation is found, the key class is determined by using the generic parametrics. - * - * As fallback, it determines the key class by looking for the value of Key_${property} in the properties + * If no annotation is found, it determines the key class by looking for the value of Key_${property} in the properties * file for the given class. * + * As fallback, the key class is determined by using the generic parametrics. + * * @param parentClass the Class which contains as a property the Map or Collection we are finding the key for. * @param property the property of the Map or Collection for the given parent class * @see com.opensymphony.xwork2.conversion.ObjectTypeDeterminer#getKeyClass(Class, String) @@ -89,21 +89,21 @@ public class DefaultObjectTypeDeterminer implements ObjectTypeDeterminer { if (annotation != null) { return annotation.value(); } - Class clazz = getClass(parentClass, property, false); + Class clazz = (Class) xworkConverter.getConverter(parentClass, KEY_PREFIX + property); if (clazz != null) { return clazz; } - return (Class) xworkConverter.getConverter(parentClass, KEY_PREFIX + property); + return getClass(parentClass, property, false); } /** * Determines the element class by looking for the value of @Element annotation for the given * class. - * If no annotation is found, the element class is determined by using the generic parametrics. - * - * As fallback, it determines the key class by looking for the value of Element_${property} in the properties + * If no annotation is found, it determines the key class by looking for the value of Element_${property} in the properties * file for the given class. Also looks for the deprecated Collection_${property} * + * As fallback, the element class is determined by using the generic parametrics. + * * @param parentClass the Class which contains as a property the Map or Collection we are finding the key for. * @param property the property of the Map or Collection for the given parent class * @see com.opensymphony.xwork2.conversion.ObjectTypeDeterminer#getElementClass(Class, String, Object) @@ -113,17 +113,17 @@ public class DefaultObjectTypeDeterminer implements ObjectTypeDeterminer { if (annotation != null) { return annotation.value(); } - Class clazz = getClass(parentClass, property, true); - if (clazz != null) { - return clazz; - } - clazz = (Class) xworkConverter.getConverter(parentClass, ELEMENT_PREFIX + property); + Class clazz = (Class) xworkConverter.getConverter(parentClass, ELEMENT_PREFIX + property); if (clazz == null) { clazz = (Class) xworkConverter.getConverter(parentClass, DEPRECATED_ELEMENT_PREFIX + property); if (clazz != null) { LOG.info("The Collection_xxx pattern for collection type conversion is deprecated. Please use Element_xxx!"); } } + if (clazz != null) { + return clazz; + } + clazz = getClass(parentClass, property, true); return clazz; } diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index dec0cc0ff..87578a7a3 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -582,7 +582,7 @@ public class OgnlUtilTest extends XWorkTestCase { // just do some of the 15 tests Map beans = ognlUtil.getBeanMap(foo); assertNotNull(beans); - assertEquals(21, beans.size()); + assertEquals(22, beans.size()); assertEquals("Hello Santa", beans.get("title")); assertEquals(new Long("123"), beans.get("ALong")); assertEquals(new Integer("44"), beans.get("number")); diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java index 012122085..514b31325 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java @@ -733,6 +733,14 @@ public class OgnlValueStackTest extends XWorkTestCase { assertEquals("Cat One", ((Cat) foo.getCats().get(0)).getName()); assertEquals("Cat Two", ((Cat) foo.getCats().get(1)).getName()); + //test when both Key and Value types of Map are interfaces but concrete classes are defined in .properties file + vs.setValue("animalMap[3].name", "Cat Three by interface"); + vs.setValue("animalMap[6].name", "Cat Six by interface"); + assertNotNull(foo.getAnimalMap()); + assertEquals(2, foo.getAnimalMap().size()); + assertEquals("Cat Three by interface", foo.getAnimalMap().get(new Long(3)).getName()); + assertEquals("Cat Six by interface", foo.getAnimalMap().get(new Long(6)).getName()); + vs.setValue("annotatedCats[0].name", "Cat One By Annotation"); vs.setValue("annotatedCats[1].name", "Cat Two By Annotation"); assertNotNull(foo.getAnnotatedCats()); diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Animal.java b/core/src/test/java/com/opensymphony/xwork2/util/Animal.java new file mode 100644 index 000000000..cc26a4524 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/util/Animal.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.opensymphony.xwork2.util; + +public interface Animal { + String getName(); +} diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Cat.java b/core/src/test/java/com/opensymphony/xwork2/util/Cat.java index 626c78b8e..2ebdd136a 100644 --- a/core/src/test/java/com/opensymphony/xwork2/util/Cat.java +++ b/core/src/test/java/com/opensymphony/xwork2/util/Cat.java @@ -26,7 +26,7 @@ import java.util.List; * @author $Author$ * @version $Revision$ */ -public class Cat { +public class Cat implements Animal { public static final String SCIENTIFIC_NAME = "Feline"; diff --git a/core/src/test/java/com/opensymphony/xwork2/util/Foo.java b/core/src/test/java/com/opensymphony/xwork2/util/Foo.java index b14270a2e..f8b67c71a 100644 --- a/core/src/test/java/com/opensymphony/xwork2/util/Foo.java +++ b/core/src/test/java/com/opensymphony/xwork2/util/Foo.java @@ -53,6 +53,7 @@ public class Foo { long aLong; Calendar calendar; BarJunior barJunior; + Map animalMap; public BarJunior getBarJunior() { return barJunior; @@ -242,5 +243,13 @@ public class Foo { public void setCalendar(Calendar calendar) { this.calendar = calendar; - } + } + + public Map getAnimalMap() { + return animalMap; + } + + public void setAnimalMap(Map animalMap) { + this.animalMap = animalMap; + } } diff --git a/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java b/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java new file mode 100644 index 000000000..218747234 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/util/MyNumber.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.opensymphony.xwork2.util; + +abstract class MyNumber extends Number { +} diff --git a/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.properties b/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.properties index 945f69e2c..b4960c4c1 100644 --- a/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.properties +++ b/core/src/test/resources/com/opensymphony/xwork2/util/Foo-conversion.properties @@ -26,4 +26,5 @@ KeyProperty_barCollection=id Element_barCollection=com.opensymphony.xwork2.util.Bar KeyProperty_barList=id Element_barList=com.opensymphony.xwork2.util.Bar - +Key_animalMap=java.lang.Long +Element_animalMap=com.opensymphony.xwork2.util.Cat