| package com.fasterxml.jackson.failing; |
| |
| import java.util.ArrayList; |
| import java.util.EnumMap; |
| import java.util.List; |
| import java.util.concurrent.ArrayBlockingQueue; |
| |
| import com.fasterxml.jackson.databind.BaseMapTest; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.objectid.TestObjectId.Employee; |
| import com.fasterxml.jackson.failing.TestObjectIdDeserialization.EnumMapCompany.FooEnum; |
| |
| /** |
| * Unit test to verify handling of Object Id deserialization. |
| *<p> |
| * NOTE: only tests that still fail, even with initial forward-ref-handling |
| * code (2.4), are included here. Other cases moved to successfully |
| * passing tests. |
| */ |
| public class TestObjectIdDeserialization extends BaseMapTest |
| { |
| static class ArrayCompany { |
| public Employee[] employees; |
| } |
| |
| static class ArrayBlockingQueueCompany { |
| public ArrayBlockingQueue<Employee> employees; |
| } |
| |
| static class EnumMapCompany { |
| public EnumMap<FooEnum,Employee> employees; |
| |
| static enum FooEnum { |
| A, B |
| } |
| } |
| |
| static class DefensiveCompany { |
| public List<DefensiveEmployee> employees; |
| |
| static class DefensiveEmployee extends Employee { |
| |
| public void setReports(List<DefensiveEmployee> reports) |
| { |
| this.reports = new ArrayList<Employee>(reports); |
| } |
| } |
| } |
| |
| private final ObjectMapper mapper = new ObjectMapper(); |
| |
| /* |
| /***************************************************** |
| /* Unit tests, external id deserialization |
| /***************************************************** |
| */ |
| |
| public void testForwardReferenceInArray() throws Exception |
| { |
| String json = "{\"employees\":[" |
| + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," |
| + "2," |
| +"{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" |
| + "]}"; |
| ArrayCompany company = mapper.readValue(json, ArrayCompany.class); |
| assertEquals(3, company.employees.length); |
| Employee firstEmployee = company.employees[0]; |
| Employee secondEmployee = company.employees[1]; |
| assertEmployees(firstEmployee, secondEmployee); |
| } |
| |
| // Do a specific test for ArrayBlockingQueue since it has its own deser. |
| public void testForwardReferenceInQueue() throws Exception |
| { |
| String json = "{\"employees\":[" |
| + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," |
| + "2," |
| +"{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" |
| + "]}"; |
| ArrayBlockingQueueCompany company = mapper.readValue(json, ArrayBlockingQueueCompany.class); |
| assertEquals(3, company.employees.size()); |
| Employee firstEmployee = company.employees.take(); |
| Employee secondEmployee = company.employees.take(); |
| assertEmployees(firstEmployee, secondEmployee); |
| } |
| |
| public void testForwardReferenceInEnumMap() |
| throws Exception |
| { |
| String json = "{\"employees\":{" |
| + "\"A\":{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," |
| + "\"B\": 2," |
| + "\"C\":{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" |
| + "}}"; |
| EnumMapCompany company = mapper.readValue(json, EnumMapCompany.class); |
| assertEquals(3, company.employees.size()); |
| Employee firstEmployee = company.employees.get(FooEnum.A); |
| Employee secondEmployee = company.employees.get(FooEnum.B); |
| assertEmployees(firstEmployee, secondEmployee); |
| } |
| |
| public void testForwardReferenceWithDefensiveCopy() |
| throws Exception |
| { |
| String json = "{\"employees\":[" + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," |
| + "{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" + "]}"; |
| DefensiveCompany company = mapper.readValue(json, DefensiveCompany.class); |
| assertEquals(2, company.employees.size()); |
| Employee firstEmployee = company.employees.get(0); |
| Employee secondEmployee = company.employees.get(1); |
| assertEmployees(firstEmployee, secondEmployee); |
| } |
| |
| private void assertEmployees(Employee firstEmployee, Employee secondEmployee) |
| { |
| assertEquals(1, firstEmployee.id); |
| assertEquals(2, secondEmployee.id); |
| assertEquals(1, firstEmployee.reports.size()); |
| assertSame(secondEmployee, firstEmployee.reports.get(0)); // Ensure that forward reference was properly resolved and in order. |
| assertSame(firstEmployee, secondEmployee.manager); // And that back reference is also properly resolved. |
| } |
| } |