com.fitbur.jackson.databind.ser.std.SerializableSerializer Maven / Gradle / Ivy
package com.fitbur.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.AtomicReference;
import com.fitbur.jackson.core.*;
import com.fitbur.jackson.databind.JavaType;
import com.fitbur.jackson.databind.JsonMappingException;
import com.fitbur.jackson.databind.JsonNode;
import com.fitbur.jackson.databind.JsonSerializable;
import com.fitbur.jackson.databind.ObjectMapper;
import com.fitbur.jackson.databind.SerializerProvider;
import com.fitbur.jackson.databind.annotation.JacksonStdImpl;
import com.fitbur.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fitbur.jackson.databind.jsonschema.JsonSerializableSchema;
import com.fitbur.jackson.databind.jsontype.TypeSerializer;
import com.fitbur.jackson.databind.node.ObjectNode;
import com.fitbur.jackson.databind.type.TypeFactory;
/**
* Generic handler for types that implement {@link JsonSerializable}.
*
* Note: given that this is used for anything that implements
* interface, can not be checked for direct class equivalence.
*/
@JacksonStdImpl
@SuppressWarnings("serial")
public class SerializableSerializer
extends StdSerializer
{
public final static SerializableSerializer instance = new SerializableSerializer();
// Ugh. Should NOT need this...
private final static AtomicReference _mapperReference = new AtomicReference();
protected SerializableSerializer() { super(JsonSerializable.class); }
@Override
public boolean isEmpty(SerializerProvider serializers, JsonSerializable value) {
if (value instanceof JsonSerializable.Base) {
return ((JsonSerializable.Base) value).isEmpty(serializers);
}
return false;
}
@Override
public void serialize(JsonSerializable value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
value.serialize(gen, serializers);
}
@Override
public final void serializeWithType(JsonSerializable value, JsonGenerator gen, SerializerProvider serializers,
TypeSerializer typeSer) throws IOException {
value.serializeWithType(gen, serializers, typeSer);
}
@Override
@SuppressWarnings("deprecation")
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode objectNode = createObjectNode();
String schemaType = "any";
String objectProperties = null;
String itemDefinition = null;
if (typeHint != null) {
Class> rawClass = TypeFactory.rawClass(typeHint);
if (rawClass.isAnnotationPresent(JsonSerializableSchema.class)) {
JsonSerializableSchema schemaInfo = rawClass.getAnnotation(JsonSerializableSchema.class);
schemaType = schemaInfo.schemaType();
if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaObjectPropertiesDefinition())) {
objectProperties = schemaInfo.schemaObjectPropertiesDefinition();
}
if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaItemDefinition())) {
itemDefinition = schemaInfo.schemaItemDefinition();
}
}
}
/* 19-Mar-2012, tatu: geez, this is butt-ugly abonimation of code...
* really, really should not require back ref to an ObjectMapper.
*/
objectNode.put("type", schemaType);
if (objectProperties != null) {
try {
objectNode.set("properties", _getObjectMapper().readTree(objectProperties));
} catch (IOException e) {
throw JsonMappingException.from(provider,
"Failed to parse @JsonSerializableSchema.schemaObjectPropertiesDefinition value");
}
}
if (itemDefinition != null) {
try {
objectNode.set("items", _getObjectMapper().readTree(itemDefinition));
} catch (IOException e) {
throw JsonMappingException.from(provider,
"Failed to parse @JsonSerializableSchema.schemaItemDefinition value");
}
}
// always optional, no need to specify:
//objectNode.put("required", false);
return objectNode;
}
private final static synchronized ObjectMapper _getObjectMapper()
{
ObjectMapper mapper = _mapperReference.get();
if (mapper == null) {
mapper = new ObjectMapper();
_mapperReference.set(mapper);
}
return mapper;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
visitor.expectAnyFormat(typeHint);
}
}