io.setl.json.jackson.Convert Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of canonical-json Show documentation
Show all versions of canonical-json Show documentation
An implementation of the Canonical JSON format with support for javax.json and Jackson
The newest version!
package io.setl.json.jackson;
import java.io.IOException;
import java.util.Base64;
import java.util.Iterator;
import java.util.Map.Entry;
import jakarta.json.JsonArray;
import jakarta.json.JsonException;
import jakarta.json.JsonNumber;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonStructure;
import jakarta.json.JsonValue;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ContainerNode;
import com.fasterxml.jackson.databind.node.JsonNodeCreator;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ValueNode;
import io.setl.json.CJArray;
import io.setl.json.CJObject;
import io.setl.json.primitive.CJFalse;
import io.setl.json.primitive.CJNull;
import io.setl.json.primitive.CJString;
import io.setl.json.primitive.CJTrue;
import io.setl.json.primitive.numbers.CJNumber;
/**
* A utility class to convert between Jackson's JsonNode and javax's JsonValue.
*
* @author Simon Greatrix on 26/02/2020.
*/
public class Convert {
private static ArrayNode createArrayNode(JsonNodeCreator nodeCreator, JsonArray jsonArray) {
ArrayNode arrayNode = nodeCreator.arrayNode(jsonArray.size());
for (JsonValue value : jsonArray) {
arrayNode.add(toJackson(nodeCreator, value));
}
return arrayNode;
}
private static JsonValue createJsonArray(ArrayNode node) {
int s = node.size();
CJArray array = new CJArray(s);
for (int i = 0; i < s; i++) {
array.add(toJson(node.get(i)));
}
return array;
}
private static JsonValue createJsonObject(ObjectNode node) {
CJObject object = new CJObject();
Iterator> iterator = node.fields();
while (iterator.hasNext()) {
Entry entry = iterator.next();
object.put(entry.getKey(), toJson(entry.getValue()));
}
return object;
}
private static ValueNode createNumberNode(JsonNodeCreator nodeCreator, JsonNumber value) {
if (value instanceof CJNumber) {
CJNumber number = (CJNumber) value;
switch (number.getNumberType()) {
case CJNumber.TYPE_INT:
return nodeCreator.numberNode(number.intValue());
case CJNumber.TYPE_LONG:
return nodeCreator.numberNode(number.longValue());
case CJNumber.TYPE_BIG_INT:
return nodeCreator.numberNode(number.bigIntegerValue());
case CJNumber.TYPE_DECIMAL:
return nodeCreator.numberNode(number.bigDecimalValue());
default:
break;
}
}
return value.isIntegral() ? nodeCreator.numberNode(value.bigIntegerValue()) : nodeCreator.numberNode(value.bigDecimalValue());
}
private static ObjectNode createObjectNode(JsonNodeCreator nodeCreator, JsonObject jsonObject) {
ObjectNode objectNode = nodeCreator.objectNode();
for (Entry entry : jsonObject.entrySet()) {
objectNode.set(entry.getKey(), toJackson(nodeCreator, entry.getValue()));
}
return objectNode;
}
/**
* Convert a javax JsonValue to a Jackson JsonNode.
*
* @param nodeCreator factory for Jackson nodes
* @param value the value to convert
*
* @return the Jackson equivalent
*/
public static JsonNode toJackson(JsonNodeCreator nodeCreator, JsonValue value) {
if (value == null) {
return null;
}
switch (value.getValueType()) {
case OBJECT:
return createObjectNode(nodeCreator, (JsonObject) value);
case ARRAY:
return createArrayNode(nodeCreator, (JsonArray) value);
case STRING:
return nodeCreator.textNode(((JsonString) value).getString());
case NUMBER:
return createNumberNode(nodeCreator, (JsonNumber) value);
case NULL:
return nodeCreator.nullNode();
case TRUE:
return nodeCreator.booleanNode(true);
case FALSE:
return nodeCreator.booleanNode(false);
default:
// should be unreachable
throw new JsonException("Unknown value type: " + value.getValueType());
}
}
/**
* Convert a javax JsonValue to a Jackson JsonNode.
*
* @param value the value to convert
*
* @return the Jackson equivalent
*/
public static JsonNode toJackson(JsonValue value) {
return toJackson(JsonNodeFactory.withExactBigDecimals(false), value);
}
/**
* Convert a javax JsonArray to a Jackson ArrayNode.
*
* @param value the value to convert
*
* @return the Jackson equivalent
*/
public static ArrayNode toJackson(JsonArray value) {
return (ArrayNode) toJackson(JsonNodeFactory.withExactBigDecimals(false), value);
}
/**
* Convert a javax JsonObject to a Jackson ObjectNode.
*
* @param value the value to convert
*
* @return the Jackson equivalent
*/
public static ObjectNode toJackson(JsonObject value) {
return (ObjectNode) toJackson(JsonNodeFactory.withExactBigDecimals(false), value);
}
/**
* Convert a javax JsonStructure to a Jackson ContainerNode.
*
* @param value the value to convert
* @param the Jackson structural node type
*
* @return the Jackson equivalent
*/
@SuppressWarnings("unchecked")
public static > ContainerNode toJackson(JsonStructure value) {
return (ContainerNode) toJackson(JsonNodeFactory.withExactBigDecimals(false), value);
}
/**
* Convert a Jackson container to a javax JsonStructure.
*
* @param node the node to convert
*
* @return the equivalent JsonStructure
*/
public static JsonStructure toJson(ContainerNode> node) {
return (JsonStructure) toJson((JsonNode) node);
}
/**
* Convert a Jackson ObjectNode to a javax JsonObject.
*
* @param node the node to convert
*
* @return the equivalent JsonStructure
*/
public static JsonObject toJson(ObjectNode node) {
return (JsonObject) toJson((JsonNode) node);
}
/**
* Convert a Jackson ArrayNode to a javax JsonArray.
*
* @param node the node to convert
*
* @return the equivalent JsonStructure
*/
public static JsonArray toJson(ArrayNode node) {
return (JsonArray) toJson((JsonNode) node);
}
/**
* Convert a Jackson JsonNode to a javax JsonValue.
*
* @param node the node to convert
*
* @return the equivalent JsonValue
*/
public static JsonValue toJson(JsonNode node) {
switch (node.getNodeType()) {
case OBJECT:
return createJsonObject((ObjectNode) node);
case ARRAY:
return createJsonArray((ArrayNode) node);
case STRING:
return CJString.create(node.textValue());
case BOOLEAN:
return node.booleanValue() ? CJTrue.TRUE : CJFalse.FALSE;
case NULL:
return CJNull.NULL;
case NUMBER:
return CJNumber.cast(node.numberValue());
case BINARY:
try {
return CJString.create(Base64.getEncoder().encodeToString(node.binaryValue()));
} catch (IOException ioe) {
throw new JsonException("Jackson failure", ioe);
}
case POJO:
throw new JsonException("Jackson POJO nodes are not supported");
case MISSING:
throw new JsonException("Jackson MISSING nodes are not supported");
default:
// should be unreachable
throw new JsonException("Unknown Jackson node type: " + node.getNodeType());
}
}
private Convert() {
// do nothing
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy