1 package com.fasterxml.jackson.failing; 2 3 import java.util.ArrayList; 4 import java.util.EnumMap; 5 import java.util.List; 6 import java.util.concurrent.ArrayBlockingQueue; 7 8 import com.fasterxml.jackson.databind.BaseMapTest; 9 import com.fasterxml.jackson.databind.ObjectMapper; 10 import com.fasterxml.jackson.databind.objectid.TestObjectId.Employee; 11 import com.fasterxml.jackson.failing.TestObjectIdDeserialization.EnumMapCompany.FooEnum; 12 13 /** 14 * Unit test to verify handling of Object Id deserialization. 15 *<p> 16 * NOTE: only tests that still fail, even with initial forward-ref-handling 17 * code (2.4), are included here. Other cases moved to successfully 18 * passing tests. 19 */ 20 public class TestObjectIdDeserialization extends BaseMapTest 21 { 22 static class ArrayCompany { 23 public Employee[] employees; 24 } 25 26 static class ArrayBlockingQueueCompany { 27 public ArrayBlockingQueue<Employee> employees; 28 } 29 30 static class EnumMapCompany { 31 public EnumMap<FooEnum,Employee> employees; 32 33 static enum FooEnum { 34 A, B 35 } 36 } 37 38 static class DefensiveCompany { 39 public List<DefensiveEmployee> employees; 40 41 static class DefensiveEmployee extends Employee { 42 setReports(List<DefensiveEmployee> reports)43 public void setReports(List<DefensiveEmployee> reports) 44 { 45 this.reports = new ArrayList<Employee>(reports); 46 } 47 } 48 } 49 50 private final ObjectMapper mapper = new ObjectMapper(); 51 52 /* 53 /***************************************************** 54 /* Unit tests, external id deserialization 55 /***************************************************** 56 */ 57 testForwardReferenceInArray()58 public void testForwardReferenceInArray() throws Exception 59 { 60 String json = "{\"employees\":[" 61 + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," 62 + "2," 63 +"{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" 64 + "]}"; 65 ArrayCompany company = mapper.readValue(json, ArrayCompany.class); 66 assertEquals(3, company.employees.length); 67 Employee firstEmployee = company.employees[0]; 68 Employee secondEmployee = company.employees[1]; 69 assertEmployees(firstEmployee, secondEmployee); 70 } 71 72 // Do a specific test for ArrayBlockingQueue since it has its own deser. testForwardReferenceInQueue()73 public void testForwardReferenceInQueue() throws Exception 74 { 75 String json = "{\"employees\":[" 76 + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," 77 + "2," 78 +"{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" 79 + "]}"; 80 ArrayBlockingQueueCompany company = mapper.readValue(json, ArrayBlockingQueueCompany.class); 81 assertEquals(3, company.employees.size()); 82 Employee firstEmployee = company.employees.take(); 83 Employee secondEmployee = company.employees.take(); 84 assertEmployees(firstEmployee, secondEmployee); 85 } 86 testForwardReferenceInEnumMap()87 public void testForwardReferenceInEnumMap() 88 throws Exception 89 { 90 String json = "{\"employees\":{" 91 + "\"A\":{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," 92 + "\"B\": 2," 93 + "\"C\":{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" 94 + "}}"; 95 EnumMapCompany company = mapper.readValue(json, EnumMapCompany.class); 96 assertEquals(3, company.employees.size()); 97 Employee firstEmployee = company.employees.get(FooEnum.A); 98 Employee secondEmployee = company.employees.get(FooEnum.B); 99 assertEmployees(firstEmployee, secondEmployee); 100 } 101 testForwardReferenceWithDefensiveCopy()102 public void testForwardReferenceWithDefensiveCopy() 103 throws Exception 104 { 105 String json = "{\"employees\":[" + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," 106 + "{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" + "]}"; 107 DefensiveCompany company = mapper.readValue(json, DefensiveCompany.class); 108 assertEquals(2, company.employees.size()); 109 Employee firstEmployee = company.employees.get(0); 110 Employee secondEmployee = company.employees.get(1); 111 assertEmployees(firstEmployee, secondEmployee); 112 } 113 assertEmployees(Employee firstEmployee, Employee secondEmployee)114 private void assertEmployees(Employee firstEmployee, Employee secondEmployee) 115 { 116 assertEquals(1, firstEmployee.id); 117 assertEquals(2, secondEmployee.id); 118 assertEquals(1, firstEmployee.reports.size()); 119 assertSame(secondEmployee, firstEmployee.reports.get(0)); // Ensure that forward reference was properly resolved and in order. 120 assertSame(firstEmployee, secondEmployee.manager); // And that back reference is also properly resolved. 121 } 122 } 123