All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.xc.XmlAdapterJsonSerializer Maven / Gradle / Ivy

package org.codehaus.jackson.xc;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import javax.xml.bind.annotation.adapters.XmlAdapter;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.schema.SchemaAware;
import org.codehaus.jackson.schema.JsonSchema;
import org.codehaus.jackson.map.BeanProperty;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.ser.SerializerBase;

/**
 * @author Ryan Heaton
 */
public class XmlAdapterJsonSerializer extends SerializerBase
    implements SchemaAware
{
    private final XmlAdapter xmlAdapter;

    private final BeanProperty _property;
    
    public XmlAdapterJsonSerializer(XmlAdapter xmlAdapter, BeanProperty property)
    {
        super(Object.class);
        this.xmlAdapter = xmlAdapter;
        _property = property;
    }

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException
    {
        Object adapted;
        try {
            adapted = this.xmlAdapter.marshal(value);
        } catch (Exception e) {
            throw new JsonMappingException("Unable to marshal: "+e.getMessage(), e);
        }
        if (adapted == null) {
            provider.getNullValueSerializer().serialize(null, jgen, provider);
        } else {
            Class c = adapted.getClass();
            // true -> do cache for future lookups
            provider.findTypedValueSerializer(c, true, _property).serialize(adapted, jgen, provider);
        }
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint)
            throws JsonMappingException
    {
        // no type resolver needed for schema
        JsonSerializer ser = provider.findValueSerializer(findValueClass(), _property);
        JsonNode schemaNode = (ser instanceof SchemaAware) ?
                ((SchemaAware) ser).getSchema(provider, null) :
                JsonSchema.getDefaultSchemaNode();
        return schemaNode;
    }

    private Class findValueClass()
    {
        Type superClass = this.xmlAdapter.getClass().getGenericSuperclass();
        while (superClass instanceof ParameterizedType && XmlAdapter.class != ((ParameterizedType)superClass).getRawType()) {
            superClass = ((Class) ((ParameterizedType) superClass).getRawType()).getGenericSuperclass();
        }
        return (Class) ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

}