package com.fasterxml.jackson.databind.introspect; import java.io.IOException; import java.io.StringWriter; import java.util.*; import javax.xml.namespace.QName; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.*; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.introspect.AnnotatedClass; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; import com.fasterxml.jackson.databind.type.TypeFactory; @SuppressWarnings("serial") public class TestJacksonAnnotationIntrospector extends BaseMapTest { public static enum EnumExample { VALUE1; } public static class JacksonExample { protected String attributeProperty; protected String elementProperty; protected List<String> wrappedElementProperty; protected EnumExample enumProperty; protected 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 { private static final long serialVersionUID = 1L; @Override public String[] findEnumValues(Class<?> enumType, Enum<?>[] enumValues, String[] names) { // kinda sorta wrong, but for testing's sake... for (int i = 0, len = enumValues.length; i < len; ++i) { names[i] = enumValues[i].name().toLowerCase(); } return names; } } /* /********************************************************** /* Unit tests /********************************************************** */ /** * tests getting serializer/deserializer instances. */ public void testSerializeDeserializeWithJaxbAnnotations() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.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 { ObjectMapper mapper = new ObjectMapper(); JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector(); AnnotatedClass ac = AnnotatedClassResolver.resolveWithoutSuperTypes(mapper.getSerializationConfig(), TypeResolverBean.class); JavaType baseType = TypeFactory.defaultInstance().constructType(TypeResolverBean.class); TypeResolverBuilder<?> rb = ai.findTypeResolver(mapper.getDeserializationConfig(), ac, baseType); assertNotNull(rb); assertSame(DummyBuilder.class, rb.getClass()); } 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); } }