1 package com.fasterxml.jackson.databind;
2 
3 import java.io.*;
4 import java.math.BigDecimal;
5 import java.math.BigInteger;
6 import java.util.*;
7 
8 import static org.junit.Assert.*;
9 
10 import com.fasterxml.jackson.annotation.JsonCreator;
11 
12 import com.fasterxml.jackson.core.*;
13 
14 import com.fasterxml.jackson.databind.ObjectMapper;
15 import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
16 import com.fasterxml.jackson.databind.json.JsonMapper;
17 import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
18 import com.fasterxml.jackson.databind.type.TypeFactory;
19 
20 public abstract class BaseMapTest
21     extends BaseTest
22 {
23     private final static Object SINGLETON_OBJECT = new Object();
24 
25     /*
26     /**********************************************************
27     /* Shared helper classes
28     /**********************************************************
29      */
30 
31     public static class BogusSchema implements FormatSchema {
32         @Override
getSchemaType()33         public String getSchemaType() {
34             return "TestFormat";
35         }
36     }
37 
38     /**
39      * Simple wrapper around boolean types, usually to test value
40      * conversions or wrapping
41      */
42     protected static class BooleanWrapper {
43         public Boolean b;
44 
BooleanWrapper()45         public BooleanWrapper() { }
BooleanWrapper(Boolean value)46         public BooleanWrapper(Boolean value) { b = value; }
47     }
48 
49     protected static class IntWrapper {
50         public int i;
51 
IntWrapper()52         public IntWrapper() { }
IntWrapper(int value)53         public IntWrapper(int value) { i = value; }
54     }
55 
56     protected static class LongWrapper {
57         public long l;
58 
LongWrapper()59         public LongWrapper() { }
LongWrapper(long value)60         public LongWrapper(long value) { l = value; }
61     }
62 
63     protected static class BigIntegerWrapper {
64         public BigInteger i;
65 
BigIntegerWrapper()66         public BigIntegerWrapper() { }
67 
BigIntegerWrapper(final BigInteger value)68         public BigIntegerWrapper(final BigInteger value) { i = value; }
69     }
70 
71     protected static class DoubleWrapper {
72         public double d;
73 
DoubleWrapper()74         public DoubleWrapper() { }
DoubleWrapper(double value)75         public DoubleWrapper(double value) { d = value; }
76     }
77 
78     protected static class BigDecimalWrapper {
79         public BigDecimal d;
80 
BigDecimalWrapper()81         public BigDecimalWrapper() { }
82 
BigDecimalWrapper(final BigDecimal value)83         public BigDecimalWrapper(final BigDecimal value) { d = value; }
84     }
85 
86     /**
87      * Simple wrapper around String type, usually to test value
88      * conversions or wrapping
89      */
90     protected static class StringWrapper {
91         public String str;
92 
StringWrapper()93         public StringWrapper() { }
StringWrapper(String value)94         public StringWrapper(String value) {
95             str = value;
96         }
97     }
98 
99     protected static class ObjectWrapper {
100         final Object object;
ObjectWrapper(final Object object)101         protected ObjectWrapper(final Object object) {
102             this.object = object;
103         }
getObject()104         public Object getObject() { return object; }
105         @JsonCreator
jsonValue(final Object object)106         static ObjectWrapper jsonValue(final Object object) {
107             return new ObjectWrapper(object);
108         }
109     }
110 
111     protected static class ListWrapper<T>
112     {
113         public List<T> list;
114 
ListWrapper(@uppressWarnings"unchecked") T... values)115         public ListWrapper(@SuppressWarnings("unchecked") T... values) {
116             list = new ArrayList<T>();
117             for (T value : values) {
118                 list.add(value);
119             }
120         }
121     }
122 
123     protected static class MapWrapper<K,V>
124     {
125         public Map<K,V> map;
126 
MapWrapper()127         public MapWrapper() { }
MapWrapper(Map<K,V> m)128         public MapWrapper(Map<K,V> m) {
129             map = m;
130         }
MapWrapper(K key, V value)131         public MapWrapper(K key, V value) {
132             map = new LinkedHashMap<>();
133             map.put(key, value);
134         }
135     }
136 
137     protected static class ArrayWrapper<T>
138     {
139         public T[] array;
140 
ArrayWrapper(T[] v)141         public ArrayWrapper(T[] v) {
142             array = v;
143         }
144     }
145 
146     /**
147      * Enumeration type with sub-classes per value.
148      */
149     protected enum EnumWithSubClass {
foobar()150         A { @Override public void foobar() { } }
foobar()151         ,B { @Override public void foobar() { } }
152         ;
153 
foobar()154         public abstract void foobar();
155     }
156 
157     public enum ABC { A, B, C; }
158 
159     // since 2.8
160     public static class Point {
161         public int x, y;
162 
Point()163         protected Point() { } // for deser
Point(int x0, int y0)164         public Point(int x0, int y0) {
165             x = x0;
166             y = y0;
167         }
168 
169         @Override
equals(Object o)170         public boolean equals(Object o) {
171             if (!(o instanceof Point)) {
172                 return false;
173             }
174             Point other = (Point) o;
175             return (other.x == x) && (other.y == y);
176         }
177 
178         @Override
toString()179         public String toString() {
180             return String.format("[x=%d, y=%d]", x, y);
181         }
182     }
183 
184     /*
185     /**********************************************************
186     /* Shared serializers
187     /**********************************************************
188      */
189 
190     @SuppressWarnings("serial")
191     public static class UpperCasingSerializer extends StdScalarSerializer<String>
192     {
UpperCasingSerializer()193         public UpperCasingSerializer() { super(String.class); }
194 
195         @Override
serialize(String value, JsonGenerator gen, SerializerProvider provider)196         public void serialize(String value, JsonGenerator gen,
197                 SerializerProvider provider) throws IOException {
198             gen.writeString(value.toUpperCase());
199         }
200     }
201 
202     @SuppressWarnings("serial")
203     public static class LowerCasingDeserializer extends StdScalarDeserializer<String>
204     {
LowerCasingDeserializer()205         public LowerCasingDeserializer() { super(String.class); }
206 
207         @Override
deserialize(JsonParser p, DeserializationContext ctxt)208         public String deserialize(JsonParser p, DeserializationContext ctxt)
209                 throws IOException, JsonProcessingException {
210             return p.getText().toLowerCase();
211         }
212     }
213 
214     /*
215     /**********************************************************
216     /* Construction
217     /**********************************************************
218      */
219 
BaseMapTest()220     protected BaseMapTest() { super(); }
221 
222     /*
223     /**********************************************************
224     /* Factory methods
225     /**********************************************************
226      */
227 
228     private static ObjectMapper SHARED_MAPPER;
229 
sharedMapper()230     protected ObjectMapper sharedMapper() {
231         if (SHARED_MAPPER == null) {
232             SHARED_MAPPER = newJsonMapper();
233         }
234         return SHARED_MAPPER;
235     }
236 
objectMapper()237     protected ObjectMapper objectMapper() {
238         return sharedMapper();
239     }
240 
objectWriter()241     protected ObjectWriter objectWriter() {
242         return sharedMapper().writer();
243     }
244 
objectReader()245     protected ObjectReader objectReader() {
246         return sharedMapper().reader();
247     }
248 
objectReader(Class<?> cls)249     protected ObjectReader objectReader(Class<?> cls) {
250         return sharedMapper().readerFor(cls);
251     }
252 
253     // @since 2.10
newJsonMapper()254     protected static ObjectMapper newJsonMapper() {
255         return new JsonMapper();
256     }
257 
258     // @since 2.10
jsonMapperBuilder()259     protected static JsonMapper.Builder jsonMapperBuilder() {
260         return JsonMapper.builder();
261     }
262 
263     // @since 2.7
newTypeFactory()264     protected TypeFactory newTypeFactory() {
265         // this is a work-around; no null modifier added
266         return TypeFactory.defaultInstance().withModifier(null);
267     }
268 
269     /*
270     /**********************************************************
271     /* Additional assert methods
272     /**********************************************************
273      */
274 
assertEquals(int[] exp, int[] act)275     protected void assertEquals(int[] exp, int[] act)
276     {
277         assertArrayEquals(exp, act);
278     }
279 
assertEquals(byte[] exp, byte[] act)280     protected void assertEquals(byte[] exp, byte[] act)
281     {
282         assertArrayEquals(exp, act);
283     }
284 
285     /**
286      * Helper method for verifying 3 basic cookie cutter cases;
287      * identity comparison (true), and against null (false),
288      * or object of different type (false)
289      */
assertStandardEquals(Object o)290     protected void assertStandardEquals(Object o)
291     {
292         assertTrue(o.equals(o));
293         assertFalse(o.equals(null));
294         assertFalse(o.equals(SINGLETON_OBJECT));
295         // just for fun, let's also call hash code...
296         o.hashCode();
297     }
298 
299     /*
300     /**********************************************************
301     /* Helper methods, serialization
302     /**********************************************************
303      */
304 
305     @SuppressWarnings("unchecked")
writeAndMap(ObjectMapper m, Object value)306     protected Map<String,Object> writeAndMap(ObjectMapper m, Object value)
307         throws IOException
308     {
309         String str = m.writeValueAsString(value);
310         return (Map<String,Object>) m.readValue(str, Map.class);
311     }
312 
serializeAsString(ObjectMapper m, Object value)313     protected String serializeAsString(ObjectMapper m, Object value)
314         throws IOException
315     {
316         return m.writeValueAsString(value);
317     }
318 
serializeAsString(Object value)319     protected String serializeAsString(Object value)
320         throws IOException
321     {
322         return serializeAsString(sharedMapper(), value);
323     }
324 
asJSONObjectValueString(Object... args)325     protected String asJSONObjectValueString(Object... args)
326         throws IOException
327     {
328         return asJSONObjectValueString(sharedMapper(), args);
329     }
330 
asJSONObjectValueString(ObjectMapper m, Object... args)331     protected String asJSONObjectValueString(ObjectMapper m, Object... args)
332         throws IOException
333     {
334         LinkedHashMap<Object,Object> map = new LinkedHashMap<Object,Object>();
335         for (int i = 0, len = args.length; i < len; i += 2) {
336             map.put(args[i], args[i+1]);
337         }
338         return m.writeValueAsString(map);
339     }
340 
341     /*
342     /**********************************************************
343     /* Helper methods, deserialization
344     /**********************************************************
345      */
346 
readAndMapFromString(String input, Class<T> cls)347     protected <T> T readAndMapFromString(String input, Class<T> cls)
348         throws IOException
349     {
350         return readAndMapFromString(sharedMapper(), input, cls);
351     }
352 
readAndMapFromString(ObjectMapper m, String input, Class<T> cls)353     protected <T> T readAndMapFromString(ObjectMapper m, String input, Class<T> cls) throws IOException
354     {
355         return (T) m.readValue("\""+input+"\"", cls);
356     }
357 
358     /*
359     /**********************************************************
360     /* Helper methods, other
361     /**********************************************************
362      */
363 
getUTCTimeZone()364     protected TimeZone getUTCTimeZone() {
365         return TimeZone.getTimeZone("GMT");
366     }
367 
utf8Bytes(String str)368     protected byte[] utf8Bytes(String str) {
369         try {
370             return str.getBytes("UTF-8");
371         } catch (IOException e) {
372             throw new IllegalArgumentException(e);
373         }
374     }
375 
aposToQuotes(String json)376     protected static String aposToQuotes(String json) {
377         return json.replace("'", "\"");
378     }
379 
a2q(String json)380     protected static String a2q(String json) {
381         return json.replace("'", "\"");
382     }
383 
quotesToApos(String json)384     protected static String quotesToApos(String json) {
385         return json.replace("\"", "'");
386     }
387 }
388