1 package com.fasterxml.jackson.databind.deser; 2 3 4 import com.fasterxml.jackson.core.type.TypeReference; 5 import com.fasterxml.jackson.databind.*; 6 7 public class TestGenerics 8 extends BaseMapTest 9 { 10 static abstract class BaseNumberBean<T extends Number> 11 { setNumber(T value)12 public abstract void setNumber(T value); 13 } 14 15 static class NumberBean 16 extends BaseNumberBean<Long> 17 { 18 long _number; 19 20 @Override setNumber(Long value)21 public void setNumber(Long value) 22 { 23 _number = value.intValue(); 24 } 25 } 26 27 /** 28 * Very simple bean class 29 */ 30 static class SimpleBean 31 { 32 public int x; 33 } 34 35 static class Wrapper<T> 36 { 37 public T value; 38 Wrapper()39 public Wrapper() { } 40 Wrapper(T v)41 public Wrapper(T v) { value = v; } 42 43 @Override equals(Object o)44 public boolean equals(Object o) { 45 return (o instanceof Wrapper<?>) && (((Wrapper<?>) o).value.equals(value)); 46 } 47 } 48 49 /* 50 /*************************************************** 51 /* Test cases 52 /*************************************************** 53 */ 54 testSimpleNumberBean()55 public void testSimpleNumberBean() throws Exception 56 { 57 ObjectMapper mapper = new ObjectMapper(); 58 NumberBean result = mapper.readValue("{\"number\":17}", NumberBean.class); 59 assertEquals(17, result._number); 60 } 61 62 /** 63 * Unit test for verifying fix to [JACKSON-109]. 64 */ testGenericWrapper()65 public void testGenericWrapper() throws Exception 66 { 67 ObjectMapper mapper = new ObjectMapper(); 68 Wrapper<SimpleBean> result = mapper.readValue 69 ("{\"value\": { \"x\" : 13 } }", 70 new TypeReference<Wrapper<SimpleBean>>() { }); 71 assertNotNull(result); 72 assertEquals(Wrapper.class, result.getClass()); 73 Object contents = result.value; 74 assertNotNull(contents); 75 assertEquals(SimpleBean.class, contents.getClass()); 76 SimpleBean bean = (SimpleBean) contents; 77 assertEquals(13, bean.x); 78 } 79 testGenericWrapperWithSingleElementArray()80 public void testGenericWrapperWithSingleElementArray() throws Exception 81 { 82 ObjectMapper mapper = new ObjectMapper(); 83 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); 84 85 Wrapper<SimpleBean> result = mapper.readValue 86 ("[{\"value\": [{ \"x\" : 13 }] }]", 87 new TypeReference<Wrapper<SimpleBean>>() { }); 88 assertNotNull(result); 89 assertEquals(Wrapper.class, result.getClass()); 90 Object contents = result.value; 91 assertNotNull(contents); 92 assertEquals(SimpleBean.class, contents.getClass()); 93 SimpleBean bean = (SimpleBean) contents; 94 assertEquals(13, bean.x); 95 } 96 97 // Test for verifying that we can use different 98 // type bindings for individual generic types. testMultipleWrappers()99 public void testMultipleWrappers() throws Exception 100 { 101 ObjectMapper mapper = new ObjectMapper(); 102 103 // First, numeric wrapper 104 Wrapper<Boolean> result = mapper.readValue 105 ("{\"value\": true}", new TypeReference<Wrapper<Boolean>>() { }); 106 assertEquals(new Wrapper<Boolean>(Boolean.TRUE), result); 107 108 // Then string one 109 Wrapper<String> result2 = mapper.readValue 110 ("{\"value\": \"abc\"}", new TypeReference<Wrapper<String>>() { }); 111 assertEquals(new Wrapper<String>("abc"), result2); 112 113 // And then number 114 Wrapper<Long> result3 = mapper.readValue 115 ("{\"value\": 7}", new TypeReference<Wrapper<Long>>() { }); 116 assertEquals(new Wrapper<Long>(7L), result3); 117 } 118 119 //[databind#381] testMultipleWrappersSingleValueArray()120 public void testMultipleWrappersSingleValueArray() throws Exception 121 { 122 ObjectMapper mapper = new ObjectMapper(); 123 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); 124 125 // First, numeric wrapper 126 Wrapper<Boolean> result = mapper.readValue 127 ("[{\"value\": [true]}]", new TypeReference<Wrapper<Boolean>>() { }); 128 assertEquals(new Wrapper<Boolean>(Boolean.TRUE), result); 129 130 // Then string one 131 Wrapper<String> result2 = mapper.readValue 132 ("[{\"value\": [\"abc\"]}]", new TypeReference<Wrapper<String>>() { }); 133 assertEquals(new Wrapper<String>("abc"), result2); 134 135 // And then number 136 Wrapper<Long> result3 = mapper.readValue 137 ("[{\"value\": [7]}]", new TypeReference<Wrapper<Long>>() { }); 138 assertEquals(new Wrapper<Long>(7L), result3); 139 } 140 141 /** 142 * Unit test for verifying fix to [JACKSON-109]. 143 */ testArrayOfGenericWrappers()144 public void testArrayOfGenericWrappers() throws Exception 145 { 146 ObjectMapper mapper = new ObjectMapper(); 147 Wrapper<SimpleBean>[] result = mapper.readValue 148 ("[ {\"value\": { \"x\" : 9 } } ]", 149 new TypeReference<Wrapper<SimpleBean>[]>() { }); 150 assertNotNull(result); 151 assertEquals(Wrapper[].class, result.getClass()); 152 assertEquals(1, result.length); 153 Wrapper<SimpleBean> elem = result[0]; 154 Object contents = elem.value; 155 assertNotNull(contents); 156 assertEquals(SimpleBean.class, contents.getClass()); 157 SimpleBean bean = (SimpleBean) contents; 158 assertEquals(9, bean.x); 159 } 160 161 // [Issue#381] testArrayOfGenericWrappersSingleValueArray()162 public void testArrayOfGenericWrappersSingleValueArray() throws Exception 163 { 164 ObjectMapper mapper = new ObjectMapper(); 165 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS); 166 167 Wrapper<SimpleBean>[] result = mapper.readValue 168 ("[ {\"value\": [ { \"x\" : [ 9 ] } ] } ]", 169 new TypeReference<Wrapper<SimpleBean>[]>() { }); 170 assertNotNull(result); 171 assertEquals(Wrapper[].class, result.getClass()); 172 assertEquals(1, result.length); 173 Wrapper<SimpleBean> elem = result[0]; 174 Object contents = elem.value; 175 assertNotNull(contents); 176 assertEquals(SimpleBean.class, contents.getClass()); 177 SimpleBean bean = (SimpleBean) contents; 178 assertEquals(9, bean.x); 179 } 180 } 181