| package com.fasterxml.jackson.databind.objectid; |
| |
| import java.util.*; |
| |
| import com.fasterxml.jackson.annotation.JsonIdentityInfo; |
| import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| import com.fasterxml.jackson.annotation.ObjectIdGenerators; |
| |
| import com.fasterxml.jackson.databind.*; |
| import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; |
| |
| public class TestObjectIdWithPolymorphic extends BaseMapTest |
| { |
| @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) |
| @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id") |
| static abstract class Base |
| { |
| public int value; |
| public Base next; |
| |
| public Base() { this(0); } |
| public Base(int v) { |
| value = v; |
| } |
| } |
| |
| static class Impl extends Base |
| { |
| public int extra; |
| |
| public Impl() { this(0, 0); } |
| public Impl(int v, int e) { |
| super(v); |
| extra = e; |
| } |
| } |
| |
| // [JACKSON-811] types |
| |
| @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") |
| public static class Base811 { |
| public int id; |
| public Base811 owner; |
| |
| protected Base811() {} |
| public Base811(Process owner) { |
| this.owner = owner; |
| if (owner == null) { |
| id = 0; |
| } else { |
| id = ++owner.childIdCounter; |
| owner.children.add(this); |
| } |
| } |
| } |
| |
| public static class Process extends Base811 { |
| protected int childIdCounter = 0; |
| protected List<Base811> children = new ArrayList<Base811>(); |
| |
| public Process() { super(null); } |
| } |
| |
| public static abstract class Activity extends Base811 { |
| protected Activity parent; |
| public Activity(Process owner, Activity parent) { |
| super(owner); |
| this.parent = parent; |
| } |
| protected Activity() { |
| super(); |
| } |
| } |
| |
| public static class Scope extends Activity { |
| public final List<FaultHandler> faultHandlers = new ArrayList<FaultHandler>(); |
| public Scope(Process owner, Activity parent) { |
| super(owner, parent); |
| } |
| protected Scope() { |
| super(); |
| } |
| } |
| |
| public static class FaultHandler extends Base811 { |
| public final List<Catch> catchBlocks = new ArrayList<Catch>(); |
| |
| public FaultHandler(Process owner) { |
| super(owner); |
| } |
| |
| protected FaultHandler() {} |
| } |
| |
| public static class Catch extends Scope { |
| public Catch(Process owner, Activity parent) { |
| super(owner, parent); |
| } |
| protected Catch() {}; |
| } |
| |
| /* |
| /***************************************************** |
| /* Unit tests for polymorphic type handling |
| /***************************************************** |
| */ |
| |
| private final ObjectMapper mapper = new ObjectMapper(); |
| |
| public void testPolymorphicRoundtrip() throws Exception |
| { |
| // create simple 2 node loop: |
| Impl in1 = new Impl(123, 456); |
| in1.next = new Impl(111, 222); |
| in1.next.next = in1; |
| |
| String json = mapper.writeValueAsString(in1); |
| |
| // then bring back... |
| Base result0 = mapper.readValue(json, Base.class); |
| assertNotNull(result0); |
| assertSame(Impl.class, result0.getClass()); |
| Impl result = (Impl) result0; |
| assertEquals(123, result.value); |
| assertEquals(456, result.extra); |
| Impl result2 = (Impl) result.next; |
| assertEquals(111, result2.value); |
| assertEquals(222, result2.extra); |
| assertSame(result, result2.next); |
| } |
| |
| public void testIssue811() throws Exception |
| { |
| ObjectMapper om = new ObjectMapper(); |
| om.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); |
| om.enable(SerializationFeature.INDENT_OUTPUT); |
| om.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, "@class"); |
| |
| Process p = new Process(); |
| Scope s = new Scope(p, null); |
| FaultHandler fh = new FaultHandler(p); |
| Catch c = new Catch(p, s); |
| fh.catchBlocks.add(c); |
| s.faultHandlers.add(fh); |
| |
| String json = om.writeValueAsString(p); |
| Process restored = om.readValue(json, Process.class); |
| assertNotNull(restored); |
| |
| assertEquals(0, p.id); |
| assertEquals(3, p.children.size()); |
| assertSame(p, p.children.get(0).owner); |
| assertSame(p, p.children.get(1).owner); |
| assertSame(p, p.children.get(2).owner); |
| } |
| } |