1 package com.fasterxml.jackson.databind.jsontype; 2 3 import java.util.*; 4 5 import org.junit.Assert; 6 7 8 import com.fasterxml.jackson.annotation.*; 9 import com.fasterxml.jackson.annotation.JsonSubTypes.Type; 10 import com.fasterxml.jackson.annotation.JsonTypeInfo.As; 11 import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; 12 13 import com.fasterxml.jackson.core.type.TypeReference; 14 15 import com.fasterxml.jackson.databind.BaseMapTest; 16 import com.fasterxml.jackson.databind.JavaType; 17 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.annotation.JsonSerialize; 19 20 public class TestTypedContainerSerialization 21 extends BaseMapTest 22 { 23 @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "object-type") 24 @JsonSubTypes( { @Type(value = Dog.class, name = "doggy"), 25 @Type(value = Cat.class, name = "kitty") }) 26 static abstract class Animal { 27 public String name; 28 Animal(String n)29 protected Animal(String n) { 30 name = n; 31 } 32 } 33 34 @JsonTypeName("doggie") 35 static class Dog extends Animal { 36 public int boneCount; 37 Dog()38 public Dog() { 39 super(null); 40 } 41 42 @JsonCreator Dog(@sonProperty"name") String name)43 public Dog(@JsonProperty("name") String name) { 44 super(name); 45 } 46 setBoneCount(int i)47 public void setBoneCount(int i) { 48 boneCount = i; 49 } 50 } 51 52 @JsonTypeName("kitty") 53 static class Cat extends Animal { 54 public String furColor; 55 Cat()56 public Cat() { 57 super(null); 58 } 59 60 @JsonCreator Cat(@sonProperty"furColor") String c)61 public Cat(@JsonProperty("furColor") String c) { 62 super(null); 63 furColor = c; 64 } 65 setName(String n)66 public void setName(String n) { 67 name = n; 68 } 69 } 70 71 static class Container1 { 72 Animal animal; 73 getAnimal()74 public Animal getAnimal() { 75 return animal; 76 } 77 setAnimal(Animal animal)78 public void setAnimal(Animal animal) { 79 this.animal = animal; 80 } 81 } 82 83 static class Container2<T extends Animal> { 84 @JsonSerialize 85 T animal; 86 getAnimal()87 public T getAnimal() { 88 return animal; 89 } 90 setAnimal(T animal)91 public void setAnimal(T animal) { 92 this.animal = animal; 93 } 94 95 } 96 97 @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class") 98 static class Issue508A { } 99 static class Issue508B extends Issue508A { } 100 101 private final static ObjectMapper mapper = new ObjectMapper(); 102 103 /* 104 /********************************************************** 105 /* Test methods 106 /********************************************************** 107 */ 108 testPolymorphicWithContainer()109 public void testPolymorphicWithContainer() throws Exception 110 { 111 Dog dog = new Dog("medor"); 112 dog.setBoneCount(3); 113 Container1 c1 = new Container1(); 114 c1.setAnimal(dog); 115 String s1 = mapper.writeValueAsString(c1); 116 Assert.assertTrue("polymorphic type info is kept (1)", s1 117 .indexOf("\"object-type\":\"doggy\"") >= 0); 118 Container2<Animal> c2 = new Container2<Animal>(); 119 c2.setAnimal(dog); 120 String s2 = mapper.writeValueAsString(c2); 121 Assert.assertTrue("polymorphic type info is kept (2)", s2 122 .indexOf("\"object-type\":\"doggy\"") >= 0); 123 } 124 testIssue329()125 public void testIssue329() throws Exception 126 { 127 ArrayList<Animal> animals = new ArrayList<Animal>(); 128 animals.add(new Dog("Spot")); 129 JavaType rootType = mapper.getTypeFactory().constructParametricType(Iterator.class, Animal.class); 130 String json = mapper.writerFor(rootType).writeValueAsString(animals.iterator()); 131 if (json.indexOf("\"object-type\":\"doggy\"") < 0) { 132 fail("No polymorphic type retained, should be; JSON = '"+json+"'"); 133 } 134 } 135 testIssue508()136 public void testIssue508() throws Exception 137 { 138 List<List<Issue508A>> l = new ArrayList<List<Issue508A>>(); 139 List<Issue508A> l2 = new ArrayList<Issue508A>(); 140 l2.add(new Issue508A()); 141 l.add(l2); 142 TypeReference<List<List<Issue508A>>> typeRef = new TypeReference<List<List<Issue508A>>>() {}; 143 String json = mapper.writerFor(typeRef).writeValueAsString(l); 144 145 List<?> output = mapper.readValue(json, typeRef); 146 assertEquals(1, output.size()); 147 Object ob = output.get(0); 148 assertTrue(ob instanceof List<?>); 149 List<?> list2 = (List<?>) ob; 150 assertEquals(1, list2.size()); 151 ob = list2.get(0); 152 assertSame(Issue508A.class, ob.getClass()); 153 } 154 } 155