blob: d8675129f0aef0e2f7f5f7c9c6039870db93c80e [file] [log] [blame]
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);
}
}