| package com.fasterxml.jackson.databind.jsontype.ext; |
| |
| import com.fasterxml.jackson.annotation.*; |
| import com.fasterxml.jackson.core.type.TypeReference; |
| import com.fasterxml.jackson.databind.*; |
| |
| public class ExternalTypeIdWithCreatorTest extends BaseMapTest |
| { |
| // [databind#1198] |
| |
| public enum Attacks { KICK, PUNCH } |
| |
| static class Character { |
| public String name; |
| public Attacks preferredAttack; |
| |
| @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, defaultImpl=Kick.class, |
| include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="preferredAttack") |
| @JsonSubTypes({ |
| @JsonSubTypes.Type(value=Kick.class, name="KICK"), |
| @JsonSubTypes.Type(value=Punch.class, name="PUNCH") |
| }) |
| public Attack attack; |
| } |
| |
| public static abstract class Attack { |
| public String side; |
| |
| @JsonCreator |
| public Attack(String side) { |
| this.side = side; |
| } |
| } |
| |
| public static class Kick extends Attack { |
| @JsonCreator |
| public Kick(String side) { |
| super(side); |
| } |
| } |
| |
| public static class Punch extends Attack { |
| @JsonCreator |
| public Punch(String side) { |
| super(side); |
| } |
| } |
| |
| // [databind#999] |
| |
| public static interface Payload999 { } |
| |
| @JsonTypeName("foo") |
| public static class FooPayload999 implements Payload999 { } |
| |
| @JsonTypeName("bar") |
| public static class BarPayload999 implements Payload999 { } |
| |
| public static class Message<P extends Payload999> |
| { |
| final String type; |
| |
| @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, |
| visible = true, |
| include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type") |
| @JsonSubTypes({ |
| @JsonSubTypes.Type(FooPayload999.class), |
| @JsonSubTypes.Type(BarPayload999.class) }) |
| private final P payload; |
| |
| @JsonCreator |
| public Message(@JsonProperty("type") String type, |
| @JsonProperty("payload") P payload) |
| { |
| this.type = type; |
| this.payload = payload; |
| } |
| } |
| |
| /* |
| /********************************************************************** |
| /* Test methods |
| /********************************************************************** |
| */ |
| |
| private final ObjectMapper MAPPER = new ObjectMapper(); |
| |
| // [databind#1198] |
| public void testFails() throws Exception { |
| String json = "{ \"name\": \"foo\", \"attack\":\"right\" } }"; |
| |
| Character character = MAPPER.readValue(json, Character.class); |
| |
| assertNotNull(character); |
| assertNotNull(character.attack); |
| assertEquals("foo", character.name); |
| } |
| |
| // [databind#1198] |
| public void testWorks() throws Exception { |
| String json = "{ \"name\": \"foo\", \"preferredAttack\": \"KICK\", \"attack\":\"right\" } }"; |
| |
| Character character = MAPPER.readValue(json, Character.class); |
| |
| assertNotNull(character); |
| assertNotNull(character.attack); |
| assertEquals("foo", character.name); |
| } |
| |
| // [databind#999] |
| public void testExternalTypeId() throws Exception |
| { |
| TypeReference<Message<FooPayload999>> type = new TypeReference<Message<FooPayload999>>() { }; |
| |
| Message<?> msg = MAPPER.readValue(aposToQuotes("{ 'type':'foo', 'payload': {} }"), type); |
| assertNotNull(msg); |
| assertNotNull(msg.payload); |
| assertEquals("foo", msg.type); |
| |
| // and then with different order |
| msg = MAPPER.readValue(aposToQuotes("{'payload': {}, 'type':'foo' }"), type); |
| assertNotNull(msg); |
| assertNotNull(msg.payload); |
| assertEquals("foo", msg.type); |
| } |
| } |