Java tutorial
/* * Copyright 2002-2010 the original author or authors. * * Licensed 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 net.sf.juffrou.reflect.spring; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.juffrou.reflect.JuffrouSpringBeanWrapper; import org.junit.Test; import org.springframework.beans.BeanWrapper; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import test.beans.GenericBean; import test.beans.GenericIntegerBean; import test.beans.GenericSetOfIntegerBean; import test.beans.TestBean; /** * @author Juergen Hoeller * @author Chris Beams * @since 18.01.2006 */ public class BeanWrapperGenericsTests { @Test public void testGenericSet() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); Set<String> input = new HashSet<String>(); input.add("4"); input.add("5"); bw.setPropertyValue("integerSet", input); assertTrue(gb.getIntegerSet().contains(new Integer(4))); assertTrue(gb.getIntegerSet().contains(new Integer(5))); } @Test public void testGenericLowerBoundedSet() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, true)); Set<String> input = new HashSet<String>(); input.add("4"); input.add("5"); bw.setPropertyValue("numberSet", input); assertTrue(gb.getNumberSet().contains(new Integer(4))); assertTrue(gb.getNumberSet().contains(new Integer(5))); } @Test public void testGenericSetWithConversionFailure() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); Set<TestBean> input = new HashSet<TestBean>(); input.add(new TestBean()); try { bw.setPropertyValue("integerSet", input); fail("Should have thrown TypeMismatchException"); } catch (TypeMismatchException ex) { assertTrue(ex.getMessage().indexOf("java.lang.Integer") != -1); } } @Test public void testGenericList() throws MalformedURLException { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); List<String> input = new ArrayList<String>(); input.add("http://localhost:8080"); input.add("http://localhost:9090"); bw.setPropertyValue("resourceList", input); assertEquals(new UrlResource("http://localhost:8080"), gb.getResourceList().get(0)); assertEquals(new UrlResource("http://localhost:9090"), gb.getResourceList().get(1)); } @Test public void testGenericListElement() throws MalformedURLException { GenericBean<?> gb = new GenericBean<Object>(); gb.setResourceList(new ArrayList<Resource>()); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("resourceList[0]", "http://localhost:8080"); assertEquals(new UrlResource("http://localhost:8080"), gb.getResourceList().get(0)); } @Test public void testGenericMap() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); Map<String, String> input = new HashMap<String, String>(); input.put("4", "5"); input.put("6", "7"); bw.setPropertyValue("shortMap", input); assertEquals(new Integer(5), gb.getShortMap().get(new Short("4"))); assertEquals(new Integer(7), gb.getShortMap().get(new Short("6"))); } @Test public void testGenericMapElement() { GenericBean<?> gb = new GenericBean<Object>(); gb.setShortMap(new HashMap<Short, Integer>()); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("shortMap[4]", "5"); assertEquals(new Integer(5), bw.getPropertyValue("shortMap[4]")); assertEquals(new Integer(5), gb.getShortMap().get(new Short("4"))); } @Test public void testGenericMapWithKeyType() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); Map<String, String> input = new HashMap<String, String>(); input.put("4", "5"); input.put("6", "7"); bw.setPropertyValue("longMap", input); assertEquals("5", gb.getLongMap().get(new Long("4"))); assertEquals("7", gb.getLongMap().get(new Long("6"))); } @Test public void testGenericMapElementWithKeyType() { GenericBean<?> gb = new GenericBean<Object>(); gb.setLongMap(new HashMap<Long, Integer>()); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("longMap[4]", "5"); assertEquals("5", gb.getLongMap().get(new Long("4"))); assertEquals("5", bw.getPropertyValue("longMap[4]")); } @Test public void testGenericMapWithCollectionValue() { GenericBean<?> gb = new GenericBean<Object>(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)); @SuppressWarnings("unchecked") Map<String, Collection> input = new HashMap<String, Collection>(); HashSet<Integer> value1 = new HashSet<Integer>(); value1.add(new Integer(1)); input.put("1", value1); ArrayList<Boolean> value2 = new ArrayList<Boolean>(); value2.add(Boolean.TRUE); input.put("2", value2); bw.setPropertyValue("collectionMap", input); assertTrue(gb.getCollectionMap().get(new Integer(1)) instanceof HashSet); assertTrue(gb.getCollectionMap().get(new Integer(2)) instanceof ArrayList); } @Test public void testGenericMapElementWithCollectionValue() { GenericBean<?> gb = new GenericBean<Object>(); gb.setCollectionMap(new HashMap<Number, Collection<? extends Object>>()); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false)); HashSet<Integer> value1 = new HashSet<Integer>(); value1.add(new Integer(1)); bw.setPropertyValue("collectionMap[1]", value1); assertTrue(gb.getCollectionMap().get(new Integer(1)) instanceof HashSet); } @Test public void testGenericListOfLists() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); List<List<Integer>> list = new LinkedList<List<Integer>>(); list.add(new LinkedList<Integer>()); gb.setListOfLists(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfLists[0][0]", new Integer(5)); assertEquals(new Integer(5), bw.getPropertyValue("listOfLists[0][0]")); assertEquals(new Integer(5), gb.getListOfLists().get(0).get(0)); } @Test public void testGenericListOfListsWithElementConversion() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); List<List<Integer>> list = new LinkedList<List<Integer>>(); list.add(new LinkedList<Integer>()); gb.setListOfLists(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfLists[0][0]", "5"); assertEquals(new Integer(5), bw.getPropertyValue("listOfLists[0][0]")); assertEquals(new Integer(5), gb.getListOfLists().get(0).get(0)); } @Test public void testGenericListOfArrays() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); ArrayList<String[]> list = new ArrayList<String[]>(); list.add(new String[] { "str1", "str2" }); gb.setListOfArrays(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfArrays[0][1]", "str3 "); assertEquals("str3 ", bw.getPropertyValue("listOfArrays[0][1]")); assertEquals("str3 ", gb.getListOfArrays().get(0)[1]); } @Test public void testGenericListOfArraysWithElementConversion() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); ArrayList<String[]> list = new ArrayList<String[]>(); list.add(new String[] { "str1", "str2" }); gb.setListOfArrays(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.registerCustomEditor(String.class, new StringTrimmerEditor(false)); bw.setPropertyValue("listOfArrays[0][1]", "str3 "); assertEquals("str3", bw.getPropertyValue("listOfArrays[0][1]")); assertEquals("str3", gb.getListOfArrays().get(0)[1]); } @Test public void testGenericListOfMaps() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); List<Map<Integer, Long>> list = new LinkedList<Map<Integer, Long>>(); list.add(new HashMap<Integer, Long>()); gb.setListOfMaps(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfMaps[0][10]", new Long(5)); assertEquals(new Long(5), bw.getPropertyValue("listOfMaps[0][10]")); assertEquals(new Long(5), gb.getListOfMaps().get(0).get(10)); } @Test public void testGenericListOfMapsWithElementConversion() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); List<Map<Integer, Long>> list = new LinkedList<Map<Integer, Long>>(); list.add(new HashMap<Integer, Long>()); gb.setListOfMaps(list); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfMaps[0][10]", "5"); assertEquals(new Long(5), bw.getPropertyValue("listOfMaps[0][10]")); assertEquals(new Long(5), gb.getListOfMaps().get(0).get(10)); } @Test public void testGenericMapOfMaps() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); Map<String, Map<Integer, Long>> map = new HashMap<String, Map<Integer, Long>>(); map.put("mykey", new HashMap<Integer, Long>()); gb.setMapOfMaps(map); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfMaps[mykey][10]", new Long(5)); assertEquals(new Long(5), bw.getPropertyValue("mapOfMaps[mykey][10]")); assertEquals(new Long(5), gb.getMapOfMaps().get("mykey").get(10)); } @Test public void testGenericMapOfMapsWithElementConversion() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); Map<String, Map<Integer, Long>> map = new HashMap<String, Map<Integer, Long>>(); map.put("mykey", new HashMap<Integer, Long>()); gb.setMapOfMaps(map); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfMaps[mykey][10]", "5"); assertEquals(new Long(5), bw.getPropertyValue("mapOfMaps[mykey][10]")); assertEquals(new Long(5), gb.getMapOfMaps().get("mykey").get(10)); } @Test public void testGenericMapOfLists() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>(); map.put(new Integer(1), new LinkedList<Integer>()); gb.setMapOfLists(map); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfLists[1][0]", new Integer(5)); assertEquals(new Integer(5), bw.getPropertyValue("mapOfLists[1][0]")); assertEquals(new Integer(5), gb.getMapOfLists().get(new Integer(1)).get(0)); } @Test public void testGenericMapOfListsWithElementConversion() throws MalformedURLException { GenericBean<String> gb = new GenericBean<String>(); Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>(); map.put(new Integer(1), new LinkedList<Integer>()); gb.setMapOfLists(map); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfLists[1][0]", "5"); assertEquals(new Integer(5), bw.getPropertyValue("mapOfLists[1][0]")); assertEquals(new Integer(5), gb.getMapOfLists().get(new Integer(1)).get(0)); } @Test public void testGenericTypeNestingMapOfInteger() throws Exception { Map<String, String> map = new HashMap<String, String>(); map.put("testKey", "100"); NestedGenericCollectionBean gb = new NestedGenericCollectionBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfInteger", map); Object obj = gb.getMapOfInteger().get("testKey"); assertTrue(obj instanceof Integer); } @Test public void testGenericTypeNestingMapOfListOfInteger() throws Exception { Map<String, List<String>> map = new HashMap<String, List<String>>(); List<String> list = Arrays.asList(new String[] { "1", "2", "3" }); map.put("testKey", list); NestedGenericCollectionBean gb = new NestedGenericCollectionBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfListOfInteger", map); Object obj = gb.getMapOfListOfInteger().get("testKey").get(0); assertTrue(obj instanceof Integer); assertEquals(1, ((Integer) obj).intValue()); } @Test public void testGenericTypeNestingListOfMapOfInteger() throws Exception { List<Map<String, String>> list = new LinkedList<Map<String, String>>(); Map<String, String> map = new HashMap<String, String>(); map.put("testKey", "5"); list.add(map); NestedGenericCollectionBean gb = new NestedGenericCollectionBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("listOfMapOfInteger", list); Object obj = gb.getListOfMapOfInteger().get(0).get("testKey"); assertTrue(obj instanceof Integer); assertEquals(5, ((Integer) obj).intValue()); } @Test public void testGenericTypeNestingMapOfListOfListOfInteger() throws Exception { Map<String, List<List<String>>> map = new HashMap<String, List<List<String>>>(); List<String> list = Arrays.asList(new String[] { "1", "2", "3" }); map.put("testKey", Collections.singletonList(list)); NestedGenericCollectionBean gb = new NestedGenericCollectionBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("mapOfListOfListOfInteger", map); Object obj = gb.getMapOfListOfListOfInteger().get("testKey").get(0).get(0); assertTrue(obj instanceof Integer); assertEquals(1, ((Integer) obj).intValue()); } @Test public void testComplexGenericMap() { Map<List<String>, List<String>> inputMap = new HashMap<List<String>, List<String>>(); List<String> inputKey = new LinkedList<String>(); inputKey.add("1"); List<String> inputValue = new LinkedList<String>(); inputValue.add("10"); inputMap.put(inputKey, inputValue); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("genericMap", inputMap); assertEquals(new Integer(1), holder.getGenericMap().keySet().iterator().next().get(0)); assertEquals(new Long(10), holder.getGenericMap().values().iterator().next().get(0)); } @Test public void testComplexGenericMapWithCollectionConversion() { Map<Set<String>, Set<String>> inputMap = new HashMap<Set<String>, Set<String>>(); Set<String> inputKey = new HashSet<String>(); inputKey.add("1"); Set<String> inputValue = new HashSet<String>(); inputValue.add("10"); inputMap.put(inputKey, inputValue); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("genericMap", inputMap); assertEquals(new Integer(1), holder.getGenericMap().keySet().iterator().next().get(0)); assertEquals(new Long(10), holder.getGenericMap().values().iterator().next().get(0)); } @Test public void testComplexGenericIndexedMapEntry() { List<String> inputValue = new LinkedList<String>(); inputValue.add("10"); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("genericIndexedMap[1]", inputValue); assertEquals(new Integer(1), holder.getGenericIndexedMap().keySet().iterator().next()); assertEquals(new Long(10), holder.getGenericIndexedMap().values().iterator().next().get(0)); } @Test public void testComplexGenericIndexedMapEntryWithCollectionConversion() { Set<String> inputValue = new HashSet<String>(); inputValue.add("10"); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("genericIndexedMap[1]", inputValue); assertEquals(new Integer(1), holder.getGenericIndexedMap().keySet().iterator().next()); assertEquals(new Long(10), holder.getGenericIndexedMap().values().iterator().next().get(0)); } @Test public void testComplexDerivedIndexedMapEntry() { List<String> inputValue = new LinkedList<String>(); inputValue.add("10"); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("derivedIndexedMap[1]", inputValue); assertEquals(new Integer(1), holder.getDerivedIndexedMap().keySet().iterator().next()); assertEquals(new Long(10), holder.getDerivedIndexedMap().values().iterator().next().get(0)); } @Test public void testComplexDerivedIndexedMapEntryWithCollectionConversion() { Set<String> inputValue = new HashSet<String>(); inputValue.add("10"); ComplexMapHolder holder = new ComplexMapHolder(); BeanWrapper bw = new JuffrouSpringBeanWrapper(holder); bw.setPropertyValue("derivedIndexedMap[1]", inputValue); assertEquals(new Integer(1), holder.getDerivedIndexedMap().keySet().iterator().next()); assertEquals(new Long(10), holder.getDerivedIndexedMap().values().iterator().next().get(0)); } @Test public void testGenericallyTypedIntegerBean() throws Exception { GenericIntegerBean gb = new GenericIntegerBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("genericProperty", "10"); bw.setPropertyValue("genericListProperty", new String[] { "20", "30" }); assertEquals(new Integer(10), gb.getGenericProperty()); assertEquals(new Integer(20), gb.getGenericListProperty().get(0)); assertEquals(new Integer(30), gb.getGenericListProperty().get(1)); } @Test public void testGenericallyTypedSetOfIntegerBean() throws Exception { GenericSetOfIntegerBean gb = new GenericSetOfIntegerBean(); BeanWrapper bw = new JuffrouSpringBeanWrapper(gb); bw.setPropertyValue("genericProperty", "10"); bw.setPropertyValue("genericListProperty", new String[] { "20", "30" }); assertEquals(new Integer(10), gb.getGenericProperty().iterator().next()); assertEquals(new Integer(20), gb.getGenericListProperty().get(0).iterator().next()); assertEquals(new Integer(30), gb.getGenericListProperty().get(1).iterator().next()); } @Test public void testSettingGenericPropertyWithReadOnlyInterface() { Bar bar = new Bar(); BeanWrapper bw = new JuffrouSpringBeanWrapper(bar); bw.setPropertyValue("version", "10"); assertEquals(new Double(10.0), bar.getVersion()); } @Test public void testSettingLongPropertyWithGenericInterface() { Promotion bean = new Promotion(); BeanWrapper bw = new JuffrouSpringBeanWrapper(bean); bw.setPropertyValue("id", "10"); assertEquals(new Long(10), bean.getId()); } private static abstract class BaseGenericCollectionBean { public abstract Object getMapOfInteger(); public abstract Map<String, List<Integer>> getMapOfListOfInteger(); public abstract void setMapOfListOfInteger(Map<String, List<Integer>> mapOfListOfInteger); } private static class NestedGenericCollectionBean extends BaseGenericCollectionBean { private Map<String, Integer> mapOfInteger; private Map<String, List<Integer>> mapOfListOfInteger; private List<Map<String, Integer>> listOfMapOfInteger; private Map<String, List<List<Integer>>> mapOfListOfListOfInteger; @Override public Map<String, Integer> getMapOfInteger() { return mapOfInteger; } public void setMapOfInteger(Map<String, Integer> mapOfInteger) { this.mapOfInteger = mapOfInteger; } @Override public Map<String, List<Integer>> getMapOfListOfInteger() { return mapOfListOfInteger; } @Override public void setMapOfListOfInteger(Map<String, List<Integer>> mapOfListOfInteger) { this.mapOfListOfInteger = mapOfListOfInteger; } public List<Map<String, Integer>> getListOfMapOfInteger() { return listOfMapOfInteger; } public void setListOfMapOfInteger(List<Map<String, Integer>> listOfMapOfInteger) { this.listOfMapOfInteger = listOfMapOfInteger; } public Map<String, List<List<Integer>>> getMapOfListOfListOfInteger() { return mapOfListOfListOfInteger; } public void setMapOfListOfListOfInteger(Map<String, List<List<Integer>>> mapOfListOfListOfInteger) { this.mapOfListOfListOfInteger = mapOfListOfListOfInteger; } } private static class ComplexMapHolder { private Map<List<Integer>, List<Long>> genericMap; private Map<Integer, List<Long>> genericIndexedMap = new HashMap<Integer, List<Long>>(); private DerivedMap derivedIndexedMap = new DerivedMap(); public void setGenericMap(Map<List<Integer>, List<Long>> genericMap) { this.genericMap = genericMap; } public Map<List<Integer>, List<Long>> getGenericMap() { return genericMap; } public void setGenericIndexedMap(Map<Integer, List<Long>> genericIndexedMap) { this.genericIndexedMap = genericIndexedMap; } public Map<Integer, List<Long>> getGenericIndexedMap() { return genericIndexedMap; } public void setDerivedIndexedMap(DerivedMap derivedIndexedMap) { this.derivedIndexedMap = derivedIndexedMap; } public DerivedMap getDerivedIndexedMap() { return derivedIndexedMap; } } @SuppressWarnings("serial") private static class DerivedMap extends HashMap<Integer, List<Long>> { } public interface Foo { Number getVersion(); } public class Bar implements Foo { private double version; @Override public Double getVersion() { return this.version; } public void setVersion(Double theDouble) { this.version = theDouble; } } public interface ObjectWithId<T extends Comparable<T>> { T getId(); void setId(T aId); } public class Promotion implements ObjectWithId<Long> { private Long id; @Override public Long getId() { return id; } @Override public void setId(Long aId) { this.id = aId; } } }