package org.msh.etbm.commons; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; import org.msh.etbm.commons.objutils.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.Iterator; import java.util.UUID; /** * Class with utilities to help working with JSON files, data and serialization *

* Created by rmemoria on 2/9/15. */ public class JsonUtils { private final static Logger log = LoggerFactory.getLogger(JsonUtils.class); /** * Avoid instantiation of this class */ private JsonUtils() { super(); } /** * Read a json file from the application resources and convert it to a given Java type * * @param resource the full json file name of the resource in the system * @param type the type to parse the file into * @param * @return instance of the type T */ public static T parseResource(String resource, Class type) { ClassPathResource res = new ClassPathResource(resource); try { InputStream in = res.getInputStream(); return parse(in, type); } catch (Exception e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } /** * Read a json file as an array from the application resources * @param resource * @param type * @param * @return */ public static T[] parseArrayResource(String resource, Class type) { ClassPathResource res = new ClassPathResource(resource); try { InputStream in = res.getInputStream(); ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(in, TypeFactory.defaultInstance().constructArrayType(type)); } catch (Exception e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } public static T parse(InputStream in, Class type) { try { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(in, type); } catch (IOException e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } public static T parse(InputStream in, JavaType type) { try { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(in, type); } catch (IOException e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } /** * Convert a json String to a given Java type * * @param jsonString the json string * @param type the type to parse the file into * @param * @return instance of the type T */ public static T parseString(String jsonString, Class type) { try { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(jsonString, type); } catch (Exception e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } /** * Convert an object to JSON string representation * * @param obj object to serialize * @return JSON in string format */ public static String objectToJSONString(Object obj, boolean pretty) { ObjectMapper mapper = new ObjectMapper(); if (pretty) { mapper.configure(SerializationFeature.INDENT_OUTPUT, true); } try { return mapper.writeValueAsString(obj); } catch (JsonProcessingException e) { log.error(e.getMessage(), e); throw new JsonParserException(e); } } /** * Write in a generator a json value of any type. It tests if is a supported primitive and * use the proper serialization. If not a primitive, then serialize to an object value * @param generator the instance of {@link JsonGenerator} from the Jackson library * @param val the value to be serialized * @throws IOException */ public static void writeAny(JsonGenerator generator, Object val) throws IOException { if (val == null) { generator.writeNull(); return; } if (val instanceof String) { generator.writeString((String)val); return; } if (val instanceof Integer) { generator.writeNumber((Integer)val); return; } if (val instanceof Double) { generator.writeNumber((Double)val); return; } if (val instanceof Float) { generator.writeNumber((Float)val); return; } if (val instanceof BigInteger) { generator.writeNumber((BigInteger)val); return; } if (val instanceof Long) { generator.writeNumber((Long)val); return; } if (val instanceof Short) { generator.writeNumber((Short)val); return; } if (val instanceof Boolean) { generator.writeBoolean((Boolean)val); return; } if (val instanceof UUID) { byte[] data = ObjectUtils.uuidAsBytes((UUID)val); generator.writeBinary(data); return; } if (val instanceof byte[]) { generator.writeBinary((byte[])val); return; } generator.writeObject(val); } public static E readValue(JsonParser parser, Class clazz) throws IOException { if (String.class.isAssignableFrom(clazz)) { return (E)parser.nextValue().asString(); } if (Boolean.class.isAssignableFrom(clazz)) { return (E)parser.nextBooleanValue(); } if (Integer.class.isAssignableFrom(clazz)) { return (E)(Integer)parser.nextIntValue(0); } if (Long.class.isAssignableFrom(clazz)) { return (E)(Long)parser.nextLongValue(0L); } if (Float.class.isAssignableFrom(clazz)) { return (E)(Float)parser.getFloatValue(); } if (Double.class.isAssignableFrom(clazz)) { return (E)(Double)parser.getDoubleValue(); } if (UUID.class.isAssignableFrom(clazz)) { byte[] data = parser.getBinaryValue(); return (E)ObjectUtils.bytesToUUID(data); } if (byte[].class.isAssignableFrom(clazz)) { return (E)parser.getBinaryValue(); } if (BigInteger.class.isAssignableFrom(clazz)) { return (E)parser.getBigIntegerValue(); } if (Short.class.isAssignableFrom(clazz)) { return (E)(Short)parser.getShortValue(); } Iterator it = parser.readValuesAs(clazz); E res = it.next(); return res; } }