1 package com.fasterxml.jackson.databind.objectid; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.fasterxml.jackson.annotation.*; 7 8 import com.fasterxml.jackson.databind.*; 9 import com.fasterxml.jackson.databind.json.JsonMapper; 10 11 public class TestObjectId extends BaseMapTest 12 { 13 @JsonPropertyOrder({"a", "b"}) 14 static class Wrapper { 15 public ColumnMetadata a, b; 16 } 17 18 @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 19 static class ColumnMetadata { 20 private final String name; 21 private final String type; 22 private final String comment; 23 24 @JsonCreator ColumnMetadata( @sonProperty"name") String name, @JsonProperty("type") String type, @JsonProperty("comment") String comment )25 public ColumnMetadata( 26 @JsonProperty("name") String name, 27 @JsonProperty("type") String type, 28 @JsonProperty("comment") String comment 29 ) { 30 this.name = name; 31 this.type = type; 32 this.comment = comment; 33 } 34 35 @JsonProperty("name") getName()36 public String getName() { 37 return name; 38 } 39 40 @JsonProperty("type") getType()41 public String getType() { 42 return type; 43 } 44 45 @JsonProperty("comment") getComment()46 public String getComment() { 47 return comment; 48 } 49 } 50 51 /* Problem in which always-as-id reference may prevent initial 52 * serialization of a POJO. 53 */ 54 55 static class Company { 56 public List<Employee> employees; 57 add(Employee e)58 public void add(Employee e) { 59 if (employees == null) { 60 employees = new ArrayList<Employee>(); 61 } 62 employees.add(e); 63 } 64 } 65 66 @JsonIdentityInfo(property="id", 67 generator=ObjectIdGenerators.PropertyGenerator.class) 68 public static class Employee { 69 public int id; 70 71 public String name; 72 73 @JsonIdentityReference(alwaysAsId=true) 74 public Employee manager; 75 76 @JsonIdentityReference(alwaysAsId=true) 77 public List<Employee> reports; 78 Employee()79 public Employee() { } Employee(int id, String name, Employee manager)80 public Employee(int id, String name, Employee manager) { 81 this.id = id; 82 this.name = name; 83 this.manager = manager; 84 reports = new ArrayList<Employee>(); 85 } 86 addReport(Employee e)87 public Employee addReport(Employee e) { 88 reports.add(e); 89 return this; 90 } 91 } 92 93 @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 94 @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class") 95 public static class BaseEntity { } 96 97 public static class Foo extends BaseEntity { 98 public BaseEntity ref; 99 } 100 101 public static class Bar extends BaseEntity 102 { 103 public Foo next; 104 } 105 106 // for [databind#1083] 107 @JsonTypeInfo( 108 use = JsonTypeInfo.Id.NAME, 109 property = "type", 110 defaultImpl = JsonMapSchema.class) 111 @JsonSubTypes({ 112 @JsonSubTypes.Type(value = JsonMapSchema.class, name = "map"), 113 @JsonSubTypes.Type(value = JsonJdbcSchema.class, name = "jdbc") }) 114 public static abstract class JsonSchema { 115 public String name; 116 } 117 118 static class JsonMapSchema extends JsonSchema { } 119 120 static class JsonJdbcSchema extends JsonSchema { } 121 122 /* 123 /********************************************************** 124 /* Test methods 125 /********************************************************** 126 */ 127 128 private final ObjectMapper MAPPER = new ObjectMapper(); 129 testColumnMetadata()130 public void testColumnMetadata() throws Exception 131 { 132 ColumnMetadata col = new ColumnMetadata("Billy", "employee", "comment"); 133 Wrapper w = new Wrapper(); 134 w.a = col; 135 w.b = col; 136 String json = MAPPER.writeValueAsString(w); 137 138 Wrapper deserialized = MAPPER.readValue(json, Wrapper.class); 139 assertNotNull(deserialized); 140 assertNotNull(deserialized.a); 141 assertNotNull(deserialized.b); 142 143 assertEquals("Billy", deserialized.a.getName()); 144 assertEquals("employee", deserialized.a.getType()); 145 assertEquals("comment", deserialized.a.getComment()); 146 147 assertSame(deserialized.a, deserialized.b); 148 } 149 150 // For [databind#188] testMixedRefsIssue188()151 public void testMixedRefsIssue188() throws Exception 152 { 153 Company comp = new Company(); 154 Employee e1 = new Employee(1, "First", null); 155 Employee e2 = new Employee(2, "Second", e1); 156 e1.addReport(e2); 157 comp.add(e1); 158 comp.add(e2); 159 160 JsonMapper mapper = JsonMapper.builder().enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY).build(); 161 String json = mapper.writeValueAsString(comp); 162 163 assertEquals("{\"employees\":[" 164 +"{\"id\":1,\"manager\":null,\"name\":\"First\",\"reports\":[2]}," 165 +"{\"id\":2,\"manager\":1,\"name\":\"Second\",\"reports\":[]}" 166 +"]}", 167 json); 168 } 169 testObjectAndTypeId()170 public void testObjectAndTypeId() throws Exception 171 { 172 final ObjectMapper mapper = new ObjectMapper(); 173 174 Bar inputRoot = new Bar(); 175 Foo inputChild = new Foo(); 176 inputRoot.next = inputChild; 177 inputChild.ref = inputRoot; 178 179 String json = mapper.writerWithDefaultPrettyPrinter() 180 .writeValueAsString(inputRoot); 181 182 BaseEntity resultRoot = mapper.readValue(json, BaseEntity.class); 183 assertNotNull(resultRoot); 184 assertTrue(resultRoot instanceof Bar); 185 Bar first = (Bar) resultRoot; 186 187 assertNotNull(first.next); 188 assertTrue(first.next instanceof Foo); 189 Foo second = (Foo) first.next; 190 assertNotNull(second.ref); 191 assertSame(first, second.ref); 192 } 193 194 public static class JsonRoot { 195 public final List<JsonSchema> schemas = new ArrayList<JsonSchema>(); 196 } 197 testWithFieldsInBaseClass1083()198 public void testWithFieldsInBaseClass1083() throws Exception { 199 final String json = aposToQuotes("{'schemas': [{\n" 200 + " 'name': 'FoodMart'\n" 201 + "}]}\n"); 202 MAPPER.readValue(json, JsonRoot.class); 203 } 204 } 205