| package org.codehaus.jackson.map.introspect; |
| |
| import java.io.IOException; |
| import java.io.StringWriter; |
| import java.util.*; |
| import javax.xml.namespace.QName; |
| |
| import org.codehaus.jackson.JsonGenerator; |
| import org.codehaus.jackson.JsonParser; |
| import org.codehaus.jackson.JsonProcessingException; |
| import org.codehaus.jackson.annotate.*; |
| import org.codehaus.jackson.annotate.JsonTypeInfo; |
| import org.codehaus.jackson.map.*; |
| import org.codehaus.jackson.map.annotate.JsonDeserialize; |
| import org.codehaus.jackson.map.annotate.JsonSerialize; |
| import org.codehaus.jackson.map.annotate.JsonTypeResolver; |
| import org.codehaus.jackson.map.deser.std.StdDeserializer; |
| import org.codehaus.jackson.map.jsontype.TypeResolverBuilder; |
| import org.codehaus.jackson.map.jsontype.impl.StdTypeResolverBuilder; |
| import org.codehaus.jackson.map.type.TypeFactory; |
| import org.codehaus.jackson.type.JavaType; |
| |
| /** |
| * @author Ryan Heaton |
| */ |
| public class TestJacksonAnnotationIntrospector |
| extends BaseMapTest |
| { |
| public static enum EnumExample { |
| VALUE1; |
| } |
| |
| public static class JacksonExample |
| { |
| private String attributeProperty; |
| private String elementProperty; |
| private List<String> wrappedElementProperty; |
| private EnumExample enumProperty; |
| private QName qname; |
| |
| @JsonSerialize(using=QNameSerializer.class) |
| public QName getQname() |
| { |
| return qname; |
| } |
| |
| @JsonDeserialize(using=QNameDeserializer.class) |
| public void setQname(QName qname) |
| { |
| this.qname = qname; |
| } |
| |
| @JsonProperty("myattribute") |
| public String getAttributeProperty() |
| { |
| return attributeProperty; |
| } |
| |
| @JsonProperty("myattribute") |
| public void setAttributeProperty(String attributeProperty) |
| { |
| this.attributeProperty = attributeProperty; |
| } |
| |
| @JsonProperty("myelement") |
| public String getElementProperty() |
| { |
| return elementProperty; |
| } |
| |
| @JsonProperty("myelement") |
| public void setElementProperty(String elementProperty) |
| { |
| this.elementProperty = elementProperty; |
| } |
| |
| @JsonProperty("mywrapped") |
| public List<String> getWrappedElementProperty() |
| { |
| return wrappedElementProperty; |
| } |
| |
| @JsonProperty("mywrapped") |
| public void setWrappedElementProperty(List<String> wrappedElementProperty) |
| { |
| this.wrappedElementProperty = wrappedElementProperty; |
| } |
| |
| public EnumExample getEnumProperty() |
| { |
| return enumProperty; |
| } |
| |
| public void setEnumProperty(EnumExample enumProperty) |
| { |
| this.enumProperty = enumProperty; |
| } |
| } |
| |
| public static class QNameSerializer extends JsonSerializer<QName> { |
| |
| @Override |
| public void serialize(QName value, JsonGenerator jgen, SerializerProvider provider) |
| throws IOException, JsonProcessingException |
| { |
| jgen.writeString(value.toString()); |
| } |
| } |
| |
| |
| public static class QNameDeserializer extends StdDeserializer<QName> |
| { |
| public QNameDeserializer() { super(QName.class); } |
| @Override |
| public QName deserialize(JsonParser jp, DeserializationContext ctxt) |
| throws IOException, JsonProcessingException |
| { |
| return QName.valueOf(jp.readValueAs(String.class)); |
| } |
| } |
| |
| public static class DummyBuilder extends StdTypeResolverBuilder |
| //<DummyBuilder> |
| { |
| } |
| |
| @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS) |
| @JsonTypeResolver(DummyBuilder.class) |
| static class TypeResolverBean { } |
| |
| // @since 1.7 |
| @JsonIgnoreType |
| static class IgnoredType { } |
| |
| static class IgnoredSubType extends IgnoredType { } |
| |
| // Test to ensure we can override enum settings |
| static class LcEnumIntrospector extends JacksonAnnotationIntrospector |
| { |
| @Override |
| public String findEnumValue(Enum<?> value) |
| { |
| return value.name().toLowerCase(); |
| } |
| } |
| |
| /* |
| /********************************************************** |
| /* Unit tests |
| /********************************************************** |
| */ |
| |
| /** |
| * tests getting serializer/deserializer instances. |
| */ |
| public void testSerializeDeserializeWithJaxbAnnotations() throws Exception |
| { |
| ObjectMapper mapper = new ObjectMapper(); |
| mapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); |
| JacksonExample ex = new JacksonExample(); |
| QName qname = new QName("urn:hi", "hello"); |
| ex.setQname(qname); |
| ex.setAttributeProperty("attributeValue"); |
| ex.setElementProperty("elementValue"); |
| ex.setWrappedElementProperty(Arrays.asList("wrappedElementValue")); |
| ex.setEnumProperty(EnumExample.VALUE1); |
| StringWriter writer = new StringWriter(); |
| mapper.writeValue(writer, ex); |
| writer.flush(); |
| writer.close(); |
| |
| String json = writer.toString(); |
| JacksonExample readEx = mapper.readValue(json, JacksonExample.class); |
| |
| assertEquals(ex.qname, readEx.qname); |
| assertEquals(ex.attributeProperty, readEx.attributeProperty); |
| assertEquals(ex.elementProperty, readEx.elementProperty); |
| assertEquals(ex.wrappedElementProperty, readEx.wrappedElementProperty); |
| assertEquals(ex.enumProperty, readEx.enumProperty); |
| } |
| |
| public void testJsonTypeResolver() throws Exception |
| { |
| JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector(); |
| AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(TypeResolverBean.class, ai, null); |
| JavaType baseType = TypeFactory.defaultInstance().constructType(TypeResolverBean.class); |
| ObjectMapper mapper = new ObjectMapper(); |
| TypeResolverBuilder<?> rb = ai.findTypeResolver(mapper.getDeserializationConfig(), ac, baseType); |
| assertNotNull(rb); |
| assertSame(DummyBuilder.class, rb.getClass()); |
| } |
| |
| /** |
| * Tests to ensure that {@link JsonIgnoreType} is detected as expected |
| * by the standard introspector. |
| * |
| * @since 1.7 |
| */ |
| public void testIgnoredType() throws Exception |
| { |
| JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector(); |
| AnnotatedClass ac = AnnotatedClass.construct(IgnoredType.class, ai, null); |
| assertEquals(Boolean.TRUE, ai.isIgnorableType(ac)); |
| |
| // also, should inherit as expected |
| ac = AnnotatedClass.construct(IgnoredSubType.class, ai, null); |
| assertEquals(Boolean.TRUE, ai.isIgnorableType(ac)); |
| } |
| |
| public void testEnumHandling() throws Exception |
| { |
| ObjectMapper mapper = new ObjectMapper(); |
| mapper.setAnnotationIntrospector(new LcEnumIntrospector()); |
| assertEquals("\"value1\"", mapper.writeValueAsString(EnumExample.VALUE1)); |
| EnumExample result = mapper.readValue(quote("value1"), EnumExample.class); |
| assertEquals(EnumExample.VALUE1, result); |
| } |
| } |