package io.cattle.platform.json;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
/**
* Default implementation of JsonMapper that uses Jackson for marshaling and
* supports JAXB annotations.
*/
public class JacksonJsonMapper implements JsonMapper {
ObjectMapper mapper;
List<Module> modules;
public JacksonJsonMapper() {
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(mapper.getTypeFactory());
AnnotationIntrospector pair = AnnotationIntrospectorPair.create(primary, secondary);
mapper.setAnnotationIntrospector(pair);
}
@PostConstruct
public void init() {
if (modules != null) {
for (Module module : modules) {
mapper.registerModule(module);
}
}
}
public JacksonJsonMapper(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public <T> T readValue(InputStream is, Class<T> type) throws IOException {
return mapper.readValue(is, type);
}
@Override
public <T> T readValue(byte[] bytes, Class<T> type) throws IOException {
return mapper.readValue(bytes, type);
}
@Override
public <T> T readValue(String text, Class<T> type) throws IOException {
return mapper.readValue(text, type);
}
@Override
public String writeValueAsString(Object object) throws IOException {
return mapper.writeValueAsString(object);
}
@Override
public byte[] writeValueAsBytes(Object data) throws IOException {
return mapper.writeValueAsBytes(data);
}
@Override
public void writeValue(OutputStream baos, Object object) throws IOException {
mapper.writeValue(baos, object);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> writeValueAsMap(Object data) {
return convertValue(data, Map.class);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public <T> T readCollectionValue(String content, Class<? extends Collection> collectionClass, Class<?> elementsClass) throws IOException {
CollectionType type = mapper.getTypeFactory().constructCollectionType(collectionClass, elementsClass);
return (T) mapper.readValue(content, type);
}
@SuppressWarnings("unchecked")
@Override
public <T> T convertValue(Object fromValue, Class<T> toValueType) {
if (fromValue == null)
return null;
if (toValueType.isAssignableFrom(fromValue.getClass()))
return (T) fromValue;
return mapper.convertValue(fromValue, toValueType);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public <T> T convertCollectionValue(Object fromValue, Class<? extends Collection> collectionClass, Class<?> elementsClass) {
CollectionType type = mapper.getTypeFactory().constructCollectionType(collectionClass, elementsClass);
return (T) mapper.convertValue(fromValue, type);
}
public void setPrettyPrinting() {
mapper.enable(SerializationFeature.INDENT_OUTPUT);
}
public ObjectMapper getObjectMapper() {
return mapper;
}
public void setObjectMapper(ObjectMapper objectMapper) {
this.mapper = objectMapper;
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> readValue(InputStream is) throws IOException {
return readValue(is, Map.class);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> readValue(byte[] bytes) throws IOException {
return readValue(bytes, Map.class);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> readValue(String text) throws IOException {
return readValue(text, Map.class);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public <T> T readCollectionValue(InputStream is, Class<? extends Collection> collectionClass, Class<?> elementsClass) throws IOException {
CollectionType type = mapper.getTypeFactory().constructCollectionType(collectionClass, elementsClass);
return (T) mapper.readValue(is, type);
}
public List<Module> getModules() {
return modules;
}
public void setModules(List<Module> modules) {
this.modules = modules;
}
}