io.apicurio.datamodels.compat.JsonCompat Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of data-models-test Show documentation
Show all versions of data-models-test Show documentation
Open Source API Design Studio
/*
* Copyright 2019 Red Hat
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.apicurio.datamodels.compat;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.NullNode;
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.databind.node.ValueNode;
import com.fasterxml.jackson.databind.util.TokenBuffer;
/**
* Compatibility class used to perform actions on JSON data. That data is handled natively in
* the TS/JS version of this class. But when in Java we use Jackson. There is a JsonCompat.ts file
* that replaces this one *after* Java->TS transpilation.
* @author [email protected]
*/
public class JsonCompat {
private static final JsonNodeFactory factory = JsonNodeFactory.instance;
private static final ObjectMapper mapper = new ObjectMapper();
private static class PrettyPrinter extends MinimalPrettyPrinter {
private static final long serialVersionUID = -4446121026177697380L;
private int indentLevel = 0;
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeStartObject(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void writeStartObject(JsonGenerator g) throws IOException {
super.writeStartObject(g);
indentLevel++;
g.writeRaw("\n");
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeEndObject(com.fasterxml.jackson.core.JsonGenerator, int)
*/
@Override
public void writeEndObject(JsonGenerator g, int nrOfEntries) throws IOException {
indentLevel--;
g.writeRaw("\n");
writeIndent(g);
super.writeEndObject(g, nrOfEntries);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeStartArray(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void writeStartArray(JsonGenerator g) throws IOException {
super.writeStartArray(g);
indentLevel++;
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeEndArray(com.fasterxml.jackson.core.JsonGenerator, int)
*/
@Override
public void writeEndArray(JsonGenerator g, int nrOfValues) throws IOException {
g.writeRaw("\n");
indentLevel--;
writeIndent(g);
super.writeEndArray(g, nrOfValues);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#beforeObjectEntries(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void beforeObjectEntries(JsonGenerator g) throws IOException {
writeIndent(g);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#beforeArrayValues(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void beforeArrayValues(JsonGenerator g) throws IOException {
g.writeRaw("\n");
writeIndent(g);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeArrayValueSeparator(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void writeArrayValueSeparator(JsonGenerator g) throws IOException {
super.writeArrayValueSeparator(g);
g.writeRaw("\n");
writeIndent(g);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeObjectEntrySeparator(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void writeObjectEntrySeparator(JsonGenerator g) throws IOException {
super.writeObjectEntrySeparator(g);
g.writeRaw("\n");
writeIndent(g);
}
/**
* @see com.fasterxml.jackson.core.util.MinimalPrettyPrinter#writeObjectFieldValueSeparator(com.fasterxml.jackson.core.JsonGenerator)
*/
@Override
public void writeObjectFieldValueSeparator(JsonGenerator g) throws IOException {
super.writeObjectFieldValueSeparator(g);
g.writeRaw(" ");
}
private void writeIndent(JsonGenerator g) throws IOException {
for (int idx = 0; idx < this.indentLevel; idx++) {
g.writeRaw(" ");
}
}
}
/*
* Util methods
*/
public static String stringify(Object json) {
try {
PrettyPrinter pp = new PrettyPrinter();
return mapper.writer(pp).writeValueAsString(json);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Object parseJSON(String jsonString) {
try {
return mapper.readTree(jsonString);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static JsonNode clone(Object json) {
try {
JsonNode obj = (JsonNode) json;
TokenBuffer tb = new TokenBuffer(mapper, false);
mapper.writeTree(tb, obj);
return mapper.readTree(tb.asParser());
} catch (IOException e) {
throw new RuntimeException("Error cloning JSON node.", e);
}
}
public static ObjectNode objectNode() {
return factory.objectNode();
}
public static ArrayNode arrayNode() {
return factory.arrayNode();
}
public static NullNode nullNode() {
return factory.nullNode();
}
public static boolean isPropertyDefined(Object json, String propertyName) {
ObjectNode node = (ObjectNode) json;
return node.has(propertyName) && !node.get(propertyName).isNull();
}
public static Object removeNullProperties(Object json) {
JsonNode node = (JsonNode) json;
if (node.isArray()) {
ArrayNode array = (ArrayNode) node;
array.forEach(item -> {
JsonCompat.removeNullProperties(item);
});
} else if (node.isObject()) {
ObjectNode object = (ObjectNode) node;
JsonCompat.keys(object).forEach(propertyName -> {
if (!JsonCompat.isPropertyDefined(json, propertyName)) {
JsonCompat.consumeProperty(json, propertyName);
} else {
JsonCompat.removeNullProperties(JsonCompat.getProperty(json, propertyName));
}
});
}
return json;
}
public static boolean isBoolean(Object json) {
if (json == null) {
return false;
}
JsonNode node = (JsonNode) json;
return node.isBoolean();
}
public static boolean isNumber(Object json) {
if (json == null) {
return false;
}
JsonNode node = (JsonNode) json;
return node.isNumber();
}
public static boolean isObject(Object json) {
if (json == null) {
return false;
}
JsonNode node = (JsonNode) json;
return node.isObject();
}
public static boolean isNull(Object json) {
if (json == null) {
return true;
}
JsonNode node = (JsonNode) json;
return node.isNull();
}
public static boolean isString(Object json) {
if (json == null) {
return false;
}
if (json instanceof String) {
return true;
}
JsonNode node = (JsonNode) json;
if (node.isTextual()) {
return true;
}
return false;
}
public static String toString(Object json) {
if (json instanceof String) {
return (String) json;
}
JsonNode node = (JsonNode) json;
if (node.isTextual()) {
return node.asText();
}
return null;
}
public static Boolean toBoolean(Object json) {
if (json == null) {
return null;
}
JsonNode node = (JsonNode) json;
if (node.isBoolean()) {
return ((BooleanNode) json).asBoolean();
}
return null;
}
public static Number toNumber(Object json) {
if (json == null) {
return null;
}
JsonNode node = (JsonNode) json;
if (node.isNumber()) {
return ((NumericNode) json).numberValue();
}
return null;
}
public static boolean isArray(Object json) {
if (json == null) {
return false;
}
JsonNode node = (JsonNode) json;
return node.isArray();
}
public static List