package io.github.ibuildthecloud.gdapi.json;
import io.github.ibuildthecloud.gdapi.model.Field;
import io.github.ibuildthecloud.gdapi.model.Resource;
import io.github.ibuildthecloud.gdapi.model.Schema;
import io.github.ibuildthecloud.gdapi.model.SchemaCollection;
import io.github.ibuildthecloud.gdapi.model.impl.FieldImpl;
import io.github.ibuildthecloud.gdapi.model.impl.SchemaImpl;
import io.github.ibuildthecloud.gdapi.util.DateUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.annotation.PostConstruct;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
public class JacksonMapper implements JsonMapper {
ObjectMapper mapper;
boolean escapeForwardSlashes = true;
@PostConstruct
public void init() {
SimpleModule module = getModule();
SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
mapper = new ObjectMapper();
mapper.setDateFormat(df);
mapper.registerModule(new JaxbAnnotationModule());
mapper.registerModule(module);
mapper.getFactory().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
if (escapeForwardSlashes) {
mapper.getFactory().setCharacterEscapes(new EscapeForwardSlash());
}
}
protected SimpleModule getModule() {
SimpleModule module = new SimpleModule();
module.setMixInAnnotation(Resource.class, ResourceMix.class);
module.setMixInAnnotation(SchemaCollection.class, SchemaCollectionMixin.class);
module.setMixInAnnotation(SchemaImpl.class, SchemaImplMixin.class);
return module;
}
@Override
public <T> T readValue(byte[] content, Class<T> type) throws IOException {
return mapper.readValue(content, type);
}
@Override
public Object readValue(byte[] content) throws IOException {
return mapper.readValue(content, Object.class);
}
@Override
public void writeValue(OutputStream os, Object object) throws IOException {
mapper.writeValue(os, object);
}
@Override
public <T> T convertValue(Object fromValue, Class<T> toValueType) {
return mapper.convertValue(fromValue, toValueType);
}
public static interface ResourceMix {
@JsonAnyGetter
Map<String, Object> getFields();
@JsonInclude(Include.NON_NULL)
String getBaseType();
}
public static interface SchemaCollectionMixin {
@JsonDeserialize(as = List.class, contentAs = SchemaImpl.class)
List<Schema> getData();
}
public static interface SchemaImplMixin {
@JsonDeserialize(as = Map.class, contentAs = FieldImpl.class)
Map<String, Field> getResourceFields();
}
public static interface ResourceMixin {
@JsonAnyGetter
Map<String, Object> getFields();
}
public boolean isEscapeForwardSlashes() {
return escapeForwardSlashes;
}
public void setEscapeForwardSlashes(boolean escapeForwardSlashes) {
this.escapeForwardSlashes = escapeForwardSlashes;
}
}