package org.rakam.util;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BinaryNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
import com.google.common.base.Throwables;
import org.rakam.server.http.SwaggerJacksonAnnotationIntrospector;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
public class JsonHelper {
private final static ObjectMapper mapper = new ObjectMapper();
private final static ObjectMapper prettyMapper = new ObjectMapper();
private static final JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(false);
static {
prettyMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.registerModule(new JSR310Module());
mapper.registerModule(new Jdk8Module());
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
SwaggerJacksonAnnotationIntrospector ai = new SwaggerJacksonAnnotationIntrospector();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"));
mapper.registerModule(
new SimpleModule("swagger", Version.unknownVersion()) {
@Override
public void setupModule(SetupContext context) {
context.insertAnnotationIntrospector(ai);
}
});
}
private JsonHelper() {
}
public static String encode(Object obj, boolean prettyPrint) {
try {
return (prettyPrint ? prettyMapper : mapper).writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException("Object is not json serializable", e);
}
}
public static String encode(Object obj) {
return encode(obj, false);
}
public static byte[] encodeAsBytes(Object obj) {
try {
return mapper.writeValueAsBytes(obj);
} catch (JsonProcessingException e) {
throw Throwables.propagate(e);
}
}
public static ObjectNode generate(Map<String, List<String>> map) {
ObjectNode obj = jsonObject();
for (Map.Entry<String, List<String>> item : map.entrySet()) {
String key = item.getKey();
obj.put(key, item.getValue().get(0));
}
return obj;
}
public static ObjectNode jsonObject() {
return jsonNodeFactory.objectNode();
}
public static ArrayNode jsonArray() {
return jsonNodeFactory.arrayNode();
}
public static TextNode textNode(String value) {
return jsonNodeFactory.textNode(value);
}
public static BinaryNode binaryNode(byte[] value) {
return jsonNodeFactory.binaryNode(value);
}
public static BooleanNode booleanNode(boolean value) {
return jsonNodeFactory.booleanNode(value);
}
public static NumericNode numberNode(Number value) {
return jsonNodeFactory.numberNode((value instanceof Double || value instanceof Float) ?
value.doubleValue() : value.longValue());
}
public static <T extends JsonNode> T readSafe(String json) throws IOException {
return (T) mapper.readTree(json);
}
public static <T extends JsonNode> T readSafe(byte[] json) throws IOException {
return (T) mapper.readTree(json);
}
public static <T extends JsonNode> T read(String json){
try {
return (T) mapper.readTree(json);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static <T> T read(byte[] json, TypeReference<T> typeReference){
try {
return (T) mapper.readValue(json, typeReference);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static <T> T read(String json, TypeReference<T> typeReference){
try {
return (T) mapper.readValue(json, typeReference);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static <T extends JsonNode> T read(byte[] json){
try {
return (T) mapper.readTree(json);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static <T> T readSafe(String json, Class<T> clazz) throws IOException {
return mapper.readValue(json, clazz);
}
public static <T> T readSafe(byte[] json, Class<T> clazz) throws IOException {
return mapper.readValue(json, clazz);
}
public static <T> T readSafe(InputStream json, Class<T> clazz) throws IOException {
return mapper.readValue(json, clazz);
}
public static <T> T read(InputStream json, Class<T> clazz) throws IOException {
return mapper.readValue(json, clazz);
}
public static <T> T read(String json, Class<T> clazz) {
try {
return mapper.readValue(json, clazz);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static <T> T convert(Object json, Class<T> clazz) {
try {
return mapper.convertValue(json, clazz);
} catch (IllegalArgumentException e) {
throw Throwables.propagate(e);
}
}
public static <T> T convert(Object json, TypeReference<T> ref) {
try {
return mapper.convertValue(json, ref);
} catch (IllegalArgumentException e) {
throw Throwables.propagate(e);
}
}
public static <T> T read(byte[] json, Class<T> clazz) {
try {
return mapper.readValue(json, clazz);
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
public static ObjectMapper getMapper() {
return mapper;
}
}