package com.fasterxml.jackson.databind.jsontype;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Unit tests related to specialized handling of
* otherwise invalid type id embedding cases.
*/
public class TestTypedDeserializationWithDefault extends BaseMapTest
{
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = LegacyInter.class)
@JsonSubTypes(value = {@JsonSubTypes.Type(name = "mine", value = MyInter.class)})
public static interface Inter { }
public static class MyInter implements Inter {
@JsonProperty("blah") public List<String> blah;
}
public static class LegacyInter extends MyInter
{
@JsonCreator
LegacyInter(Object obj)
{
if (obj instanceof List) {
blah = new ArrayList<String>();
for (Object o : (List<?>) obj) {
blah.add(o.toString());
}
}
else if (obj instanceof String) {
blah = Arrays.asList(((String) obj).split(","));
}
else {
throw new IllegalArgumentException("Unknown type: " + obj.getClass());
}
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type",
defaultImpl = Void.class)
public static class DefaultWithNoClass { }
// and then one with no defaultImpl nor listed subtypes
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
abstract static class MysteryPolymorphic { }
// [Databind#511] types
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes(@JsonSubTypes.Type(name="sub1", value = BadSub1.class))
public static class BadItem {}
public static class BadSub1 extends BadItem {
public String a ;
}
public static class Good {
public List<GoodItem> many;
}
public static class Bad {
public List<BadItem> many;
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({@JsonSubTypes.Type(name="sub1", value = GoodSub1.class),
@JsonSubTypes.Type(name="sub2", value = GoodSub2.class) })
public static class GoodItem {}
public static class GoodSub1 extends GoodItem {
public String a ;
}
public static class GoodSub2 extends GoodItem {
public String b ;
}
/*
/**********************************************************
/* Unit tests, deserialization
/**********************************************************
*/
private final ObjectMapper MAPPER = new ObjectMapper();
public void testDeserializationWithObject() throws Exception
{
Inter inter = MAPPER.reader(Inter.class).readValue("{\"type\": \"mine\", \"blah\": [\"a\", \"b\", \"c\"]}");
assertTrue(inter instanceof MyInter);
assertFalse(inter instanceof LegacyInter);
assertEquals(Arrays.asList("a", "b", "c"), ((MyInter) inter).blah);
}
public void testDeserializationWithString() throws Exception
{
Inter inter = MAPPER.reader(Inter.class).readValue("\"a,b,c,d\"");
assertTrue(inter instanceof LegacyInter);
assertEquals(Arrays.asList("a", "b", "c", "d"), ((MyInter) inter).blah);
}
public void testDeserializationWithArray() throws Exception
{
Inter inter = MAPPER.reader(Inter.class).readValue("[\"a\", \"b\", \"c\", \"d\"]");
assertTrue(inter instanceof LegacyInter);
assertEquals(Arrays.asList("a", "b", "c", "d"), ((MyInter) inter).blah);
}
public void testDeserializationWithArrayOfSize2() throws Exception
{
Inter inter = MAPPER.reader(Inter.class).readValue("[\"a\", \"b\"]");
assertTrue(inter instanceof LegacyInter);
assertEquals(Arrays.asList("a", "b"), ((MyInter) inter).blah);
}
// [Databind#148]
public void testDefaultAsNoClass() throws Exception
{
Object ob = MAPPER.reader(DefaultWithNoClass.class).readValue("{ }");
assertNull(ob);
ob = MAPPER.reader(DefaultWithNoClass.class).readValue("{ \"bogus\":3 }");
assertNull(ob);
}
// [Databind#148]
public void testBadTypeAsNull() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
Object ob = mapper.readValue("{}", MysteryPolymorphic.class);
assertNull(ob);
ob = mapper.readValue("{ \"whatever\":13}", MysteryPolymorphic.class);
assertNull(ob);
}
// [Databind#511]
public void testInvalidTypeId511() throws Exception {
ObjectMapper mapper = new ObjectMapper().disable(
DeserializationFeature.FAIL_ON_INVALID_SUBTYPE,
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES
);
String json = "{\"many\":[{\"sub1\":{\"a\":\"foo\"}},{\"sub2\":{\"b\":\"bar\"}}]}" ;
Good goodResult = mapper.readValue(json, Good.class) ;
assertNotNull(goodResult) ;
Bad badResult = mapper.readValue(json, Bad.class);
assertNotNull(badResult);
}
}