| package com.fasterxml.jackson.databind.jsontype.deftyping; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| import com.fasterxml.jackson.databind.*; |
| import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; |
| import com.fasterxml.jackson.databind.node.ObjectNode; |
| import com.fasterxml.jackson.databind.testutil.NoCheckSubTypeValidator; |
| |
| public class TestDefaultForArrays extends BaseMapTest |
| { |
| /* |
| /********************************************************** |
| /* Helper types |
| /********************************************************** |
| */ |
| |
| static class ArrayBean { |
| public Object[] values; |
| |
| public ArrayBean() { this(null); } |
| public ArrayBean(Object[] v) { values = v; } |
| } |
| |
| static class PrimitiveArrayBean { |
| @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) |
| public Object stuff; |
| |
| protected PrimitiveArrayBean() { } |
| public PrimitiveArrayBean(Object value) { stuff = value; } |
| } |
| |
| /* |
| /********************************************************** |
| /* Unit tests |
| /********************************************************** |
| */ |
| |
| /** |
| * Simple unit test for verifying that we get String array |
| * back, even though declared type is Object array |
| */ |
| public void testArrayTypingSimple() throws Exception |
| { |
| ObjectMapper m = jsonMapperBuilder(). |
| activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.NON_CONCRETE_AND_ARRAYS) |
| .build(); |
| ArrayBean bean = new ArrayBean(new String[0]); |
| String json = m.writeValueAsString(bean); |
| ArrayBean result = m.readValue(json, ArrayBean.class); |
| assertNotNull(result.values); |
| assertEquals(String[].class, result.values.getClass()); |
| } |
| |
| // And let's try it with deeper array as well |
| public void testArrayTypingNested() throws Exception |
| { |
| ObjectMapper m = jsonMapperBuilder() |
| .activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.NON_CONCRETE_AND_ARRAYS) |
| .build(); |
| ArrayBean bean = new ArrayBean(new String[0][0]); |
| String json = m.writeValueAsString(bean); |
| ArrayBean result = m.readValue(json, ArrayBean.class); |
| assertNotNull(result.values); |
| assertEquals(String[][].class, result.values.getClass()); |
| } |
| |
| public void testNodeInArray() throws Exception |
| { |
| JsonNode node = new ObjectMapper().readTree("{\"a\":3}"); |
| ObjectMapper m = jsonMapperBuilder() |
| .activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.JAVA_LANG_OBJECT) |
| .build(); |
| Object[] obs = new Object[] { node }; |
| String json = m.writeValueAsString(obs); |
| Object[] result = m.readValue(json, Object[].class); |
| assertEquals(1, result.length); |
| Object ob = result[0]; |
| assertTrue(ob instanceof JsonNode); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testNodeInEmptyArray() throws Exception { |
| Map<String, List<String>> outerMap = new HashMap<String, List<String>>(); |
| outerMap.put("inner", new ArrayList<String>()); |
| ObjectMapper m = new ObjectMapper().disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS); |
| JsonNode tree = m.convertValue(outerMap, JsonNode.class); |
| |
| String json = m.writeValueAsString(tree); |
| assertEquals("{}", json); |
| |
| JsonNode node = new ObjectMapper().readTree("{\"a\":[]}"); |
| |
| m = jsonMapperBuilder() |
| .disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS) |
| .activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.JAVA_LANG_OBJECT) |
| .build(); |
| m.activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.JAVA_LANG_OBJECT); |
| |
| Object[] obs = new Object[] { node }; |
| json = m.writeValueAsString(obs); |
| Object[] result = m.readValue(json, Object[].class); |
| |
| assertEquals(1, result.length); |
| Object elem = result[0]; |
| assertTrue(elem instanceof ObjectNode); |
| assertEquals(0, ((ObjectNode) elem).size()); |
| } |
| |
| public void testArraysOfArrays() throws Exception |
| { |
| ObjectMapper mapper = jsonMapperBuilder() |
| .activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY) |
| .build(); |
| |
| Object value = new Object[][] { new Object[] {} }; |
| String json = mapper.writeValueAsString(value); |
| |
| // try with different (but valid) nominal types: |
| _testArraysAs(mapper, json, Object[][].class); |
| _testArraysAs(mapper, json, Object[].class); |
| _testArraysAs(mapper, json, Object.class); |
| } |
| |
| public void testArrayTypingForPrimitiveArrays() throws Exception |
| { |
| ObjectMapper m = new ObjectMapper(); |
| m.activateDefaultTyping(NoCheckSubTypeValidator.instance, |
| DefaultTyping.NON_CONCRETE_AND_ARRAYS); |
| _testArrayTypingForPrimitiveArrays(m, new int[] { 1, 2, 3 }); |
| _testArrayTypingForPrimitiveArrays(m, new long[] { 1, 2, 3 }); |
| _testArrayTypingForPrimitiveArrays(m, new short[] { 1, 2, 3 }); |
| _testArrayTypingForPrimitiveArrays(m, new double[] { 0.5, 5.5, -1.0 }); |
| _testArrayTypingForPrimitiveArrays(m, new float[] { 0.5f, 5.5f, -1.0f }); |
| _testArrayTypingForPrimitiveArrays(m, new boolean[] { true, false }); |
| _testArrayTypingForPrimitiveArrays(m, new byte[] { 1, 2, 3 }); |
| |
| _testArrayTypingForPrimitiveArrays(m, new char[] { 'a', 'b' }); |
| } |
| |
| private void _testArrayTypingForPrimitiveArrays(ObjectMapper mapper, Object v) throws Exception { |
| PrimitiveArrayBean input = new PrimitiveArrayBean(v); |
| String json = mapper.writeValueAsString(input); |
| PrimitiveArrayBean result = mapper.readValue(json, PrimitiveArrayBean.class); |
| assertNotNull(result.stuff); |
| assertSame(v.getClass(), result.stuff.getClass()); |
| } |
| |
| /* |
| /********************************************************** |
| /* Helper methods |
| /********************************************************** |
| */ |
| |
| protected void _testArraysAs(ObjectMapper mapper, String json, Class<?> type) |
| throws Exception |
| { |
| Object o = mapper.readValue(json, type); |
| assertNotNull(o); |
| assertTrue(o instanceof Object[]); |
| Object[] main = (Object[]) o; |
| assertEquals(1, main.length); |
| Object element = main[0]; |
| assertNotNull(element); |
| assertTrue(element instanceof Object[]); |
| assertEquals(0, ((Object[]) element).length); |
| } |
| } |