io.sphere.sdk.json.SphereJsonUtils Maven / Gradle / Ivy
package io.sphere.sdk.json;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;
/**
* Internal utility class to work with JSON from SPHERE.IO.
*
* If an error occurs, the {@link JsonException} (a {@link RuntimeException}) will be thrown:
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#exceptionHandling()}
*
*/
final public class SphereJsonUtils {
private static final ObjectMapper objectMapper = newObjectMapper();
private SphereJsonUtils() {
}
/**
* Creates a new {@link ObjectMapper} which is configured for sphere projects.
* @return new object mapper
*/
public static ObjectMapper newObjectMapper() {
return new ObjectMapper()
.registerModule(new LocaleModule())
.registerModule(new ParameterNamesModule())
.registerModule(new JavaTimeModule())
.registerModule(new DateTimeDeserializationModule())
.registerModule(new DateTimeSerializationModule())
.registerModule(new JavaMoneyModule())
.registerModule(new SphereEnumModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
/**
* Converts a SPHERE.IO Java object to JSON as String.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#toJsonString()}
*
* @param value the object to convert
* @return JSON string representation of the value
*/
public static String toJsonString(final Object value) {
return executing(() -> objectMapper.writeValueAsString(value));
}
/**
* Converts a SPHERE.IO Java object to JSON as {@link JsonNode}.
* If {@code value} is of type String and contains JSON data, that will be ignored, {@code value} will be treated as just any String.
* If you want to parse a JSON String to a JsonNode use {@link SphereJsonUtils#parse(java.lang.String)} instead.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#toJsonNode()}
*
* @param value the object to convert
* @return new json
*/
public static JsonNode toJsonNode(final Object value) {
return objectMapper.valueToTree(value);
}
/**
* Parses a String containing JSON data and produces a {@link JsonNode}.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#parse()}
*
* @param jsonAsString json data
* @return new JsonNode
*/
public static JsonNode parse(final String jsonAsString) {
return executing(() -> objectMapper.readTree(jsonAsString));
}
/**
* Parses a byte array containing JSON data and produces a {@link JsonNode}.
*
* @param jsonAsBytes json data
* @return new JsonNode
*/
public static JsonNode parse(final byte[] jsonAsBytes) {
return executing(() -> objectMapper.readTree(jsonAsBytes));
}
/** Pretty prints a given JSON string.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#prettyPrint()}
*
* @param json JSON code as String which should be formatted
* @return json
formatted
*/
public static String prettyPrint(final String json) {
return executing(() -> {
final ObjectMapper jsonParser = new ObjectMapper();
final JsonNode jsonTree = jsonParser.readValue(json, JsonNode.class);
secure(jsonTree);
final ObjectWriter writer = jsonParser.writerWithDefaultPrettyPrinter();
return writer.writeValueAsString(jsonTree);
});
}
/**
*
* Reads a UTF-8 JSON text file from the classpath of the current thread and transforms it into a Java object.
*
* @param resourcePath the path to the resource. Example: If the file is located in "src/test/resources/foo/bar/product.json" then the path should be "foo/bar/product.json"
* @param typeReference the full generic type information about the object to create
* @param the type of the result
* @return the created objected
*/
public static T readObjectFromResource(final String resourcePath, final TypeReference typeReference) {
return executing(() -> {
final InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath);
return objectMapper.readValue(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8.name()), typeReference);
});
}
/**
* Reads a Java object from JSON data (String).
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#readObjectFromJsonString()}
*
* @param jsonAsString the JSON data which represents sth. of type {@code }
* @param typeReference the full generic type information about the object to create
* @param the type of the result
* @return the created objected
*/
public static T readObject(final String jsonAsString, final TypeReference typeReference) {
return executing(() -> objectMapper.readValue(jsonAsString, typeReference));
}
/**
* Reads a Java object from JsonNode data.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#readObjectFromJsonNode()}
*
* @param jsonNode the JSON data which represents sth. of type {@code }
* @param typeReference the full generic type information about the object to create
* @param the type of the result
* @return the created objected
*/
public static T readObject(final JsonNode jsonNode, final TypeReference typeReference) {
return executing(() -> objectMapper.readerFor(typeReference).readValue(jsonNode));
}
/**
* Reads a Java object from JsonNode data.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#readObjectFromJsonNodeWithClass()}
*
* @param jsonNode the JSON data which represents sth. of type {@code }
* @param clazz the class of the type to create
* @param the type of the result
* @return the created objected
*/
public static T readObject(final JsonNode jsonNode, final Class clazz) {
return executing(() -> objectMapper.readerFor(clazz).readValue(jsonNode));
}
/**
* Reads a Java object from JSON string data encoded as UTF-8.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#readObjectFromJsonNodeWithClass()}
*
* @param jsonAsBytes the JSON data which represents sth. of type {@code }
* @param typeReference the full generic type information about the object to create
* @param the type of the result
* @return the created objected
*/
public static T readObject(final byte[] jsonAsBytes, final TypeReference typeReference) {
return executing(() -> objectMapper.readValue(jsonAsBytes, typeReference));
}
/**
* Creates a new {@link ObjectNode} created by the SPHERE.IO object mapper.
*
* {@include.example io.sphere.sdk.json.SphereJsonUtilsTest#readObjectFromJsonNodeWithClass()}
*
* @return new node
*/
public static ObjectNode newObjectNode() {
return objectMapper.createObjectNode();
}
/** Very simple way to "erase" passwords -
* replaces all field values whose names contains {@code 'pass'} by {@code 'xxxxx'}. */
private static JsonNode secure(JsonNode node) {
if (node.isObject()) {
ObjectNode objectNode = (ObjectNode)node;
Iterator> fields = node.fields();
while (fields.hasNext()) {
Map.Entry field = fields.next();
if (field.getValue().isTextual() && field.getKey().toLowerCase().contains("pass")) {
objectNode.put(field.getKey(), "xxxxx");
} else {
secure(field.getValue());
}
}
return objectNode;
} else if (node.isArray()) {
ArrayNode arrayNode = (ArrayNode)node;
Iterator elements = arrayNode.elements();
while (elements.hasNext()) {
secure(elements.next());
}
return arrayNode;
} else {
return node;
}
}
@FunctionalInterface
private interface SupplierThrowingIOException {
T get() throws IOException;
}
private static T executing(final SupplierThrowingIOException supplier) {
try {
return supplier.get();
} catch (final IOException e) {
throw new JsonException(e);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy