blob: 11bde67ef7b233b78b9ef6a5325b7ba9774ccfc3 [file] [log] [blame]
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);
}
}