io.atlasmap.json.inspect.InstanceInspector Maven / Gradle / Ivy
package io.atlasmap.json.inspect;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.atlasmap.json.core.JsonComplexTypeFactory;
import io.atlasmap.json.v2.AtlasJsonModelFactory;
import io.atlasmap.json.v2.JsonComplexType;
import io.atlasmap.json.v2.JsonDocument;
import io.atlasmap.json.v2.JsonField;
import io.atlasmap.json.v2.JsonFields;
import io.atlasmap.v2.CollectionType;
import io.atlasmap.v2.FieldStatus;
import io.atlasmap.v2.FieldType;
/**
*/
public class InstanceInspector implements JsonInspector {
private static final Logger LOG = LoggerFactory.getLogger(InstanceInspector.class);
private static InstanceInspector myself = new InstanceInspector();
private InstanceInspector() {
}
public static InstanceInspector instance() {
return myself;
}
public JsonDocument inspect(String instance) throws JsonInspectionException {
if (instance == null || instance.isEmpty()) {
throw new IllegalArgumentException("JSON instance cannot be null");
}
try {
JsonDocument jsonDocument = AtlasJsonModelFactory.createJsonDocument();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(instance);
if (rootNode.isArray()) {
// TODO how do we handle a topmost array
JsonComplexType field = JsonComplexTypeFactory.createJsonComlexField();
field.setFieldType(null);
field.setJsonFields(new JsonFields());
field.setStatus(FieldStatus.UNSUPPORTED);
field.setCollectionType(CollectionType.ARRAY);
field.setValue(rootNode.toString());
jsonDocument.getFields().getField().add(field);
} else if (rootNode.isObject()) {
Iterator> nodes = rootNode.fields();
while (nodes.hasNext()) {
Map.Entry entry = nodes.next();
if (entry.getValue().isObject()) {
LOG.trace("NODE IS AN OBJECT --> " + entry.getKey() + " WITH ---> " + entry.getValue().size()
+ " FIELDS");
// this is a complex type
JsonComplexType parent = getJsonComplexTypeFromEntry(entry);
jsonDocument.getFields().getField().add(parent);
handleObjectNode(jsonDocument, entry.getValue(), parent, 0);
} else if (entry.getValue().isArray()) {
// this is a complex type as an ARRAY
LOG.trace("NODE IS AN ARRAY --> " + entry.getKey() + " WITH ---> " + entry.getValue().size()
+ " CHILDREN");
JsonComplexType parent = getJsonComplexTypeFromEntry(entry);
parent.setCollectionType(CollectionType.ARRAY);
jsonDocument.getFields().getField().add(parent);
handleArrayNode(jsonDocument, (ArrayNode) entry.getValue(), parent, entry.getKey(), 0);
} else if (entry.getValue().isValueNode()) {
LOG.trace("NODE IS A VALUE --> " + entry.getKey() + " WITH ---> " + entry.getValue().size()
+ " CHILDREN");
handleValueEntry(jsonDocument, entry, null, 0);
}
}
}
return jsonDocument;
} catch (IOException e) {
throw new JsonInspectionException(e);
}
}
private void handleArrayNode(JsonDocument jsonDocument, ArrayNode aNode, JsonComplexType parent, String aKey, int index) throws IOException {
if (aNode.get(0).isObject()) {
LOG.trace("ARRAY OF OBJECTS WITH PARENT ---> " + parent.getName().concat(String.valueOf(index))
+ " WITH KEY ----> " + aKey + " AND SIZE OF ---> " + aNode.size());
int childIndex = 0;
JsonComplexType childObject = null;
if (!aKey.equals(parent.getName())) {
childObject = getJsonComplexType(parent, aKey, index);
childObject.setCollectionType(CollectionType.LIST);
}
for (JsonNode jsonNode : aNode) {
if (childObject != null) {
// rest for child fields...
handleObjectNode(jsonDocument, jsonNode, childObject, childIndex);
} else {
handleObjectNode(jsonDocument, jsonNode, parent, index);
}
childIndex++;
index++;
}
} else if (aNode.get(0).isArray()) {
LOG.trace("**TODO** > HANDLE ARRAY OF AN ARRAY WITH PARENT ---> " + parent.getName() + " WITH KEY ----> "
+ aKey);
} else if (aNode.get(0).isValueNode()) {
LOG.trace("**TODO** > HANDLE ARRAY OF A VALUES WITH PARENT ---> " + parent.getName() + " WITH KEY ----> "
+ aKey);
}
}
private void handleObjectNode(JsonDocument jsonDocument, JsonNode jsonNode, JsonComplexType parent, int index) throws IOException {
LOG.trace("HANDLING AN OBJECT NODE " + jsonNode.fields().next().getKey() + " WITH PARENT ---> "
+ parent.getName() + " WITH INDEX OF " + index);
Iterator> fields = jsonNode.fields();
while (fields.hasNext()) {
Map.Entry next = fields.next();
String key = next.getKey();
JsonNode node = next.getValue();
if (node.isValueNode()) {
handleValueEntry(jsonDocument, next, parent, index);
} else if (node.isObject()) {
LOG.trace("FOUND AN OBJECT NODE THAT IS A CONTAINER WITH KEY --> " + key + " WITH A PARENT INDEX OF "
+ index);
JsonComplexType container = getJsonComplexType(parent, key, index);
// rest index to zero when dealing with containers (we don't need an index on
// containers)
handleObjectNode(jsonDocument, next.getValue(), container, 0);
} else if (node.isArray() && node.get(0).isObject()) {
ArrayNode arrayNode = (ArrayNode) node;
// index for children
int innerIndex = 0;
JsonComplexType deeperChild = getJsonComplexType(parent, key, index);
if (parent.getCollectionType() == null) {
deeperChild.setCollectionType(CollectionType.LIST);
} else {
deeperChild.setCollectionType(CollectionType.ARRAY);
}
for (JsonNode deeperJsonNode : arrayNode) {
handleObjectNode(jsonDocument, deeperJsonNode, deeperChild, innerIndex);
innerIndex++;
}
}
}
}
private void handleValueEntry(JsonDocument jsonDocument, Map.Entry jsonNodeEntry, JsonComplexType parent, int index) {
JsonNode theNode = jsonNodeEntry.getValue();
String nodeKey = jsonNodeEntry.getKey();
JsonField field = AtlasJsonModelFactory.createJsonField();
if (nodeKey != null) {
field.setName(nodeKey);
if (parent != null) {
LOG.trace("HANDLING AN VALUE NODE WITH PARENT ---> " + parent.getName() + " WITH INDEX OF " + index);
if (index > 0 && (parent.getCollectionType() != null
&& parent.getCollectionType().compareTo(CollectionType.ARRAY) == 0)) {
field.setPath(parent.getPath().concat("/").concat(nodeKey).concat("[").concat(String.valueOf(index))
.concat("]"));
} else if (index > 0 && (parent.getCollectionType() != null
&& parent.getCollectionType().compareTo(CollectionType.LIST) == 0)) {
field.setPath(
parent.getPath().concat("[").concat(String.valueOf(index)).concat("]/").concat(nodeKey));
} else {
field.setPath(parent.getPath().concat("/").concat(nodeKey));
}
} else {
LOG.trace("HANDLING AN VALUE NODE WITH NO PARENT WITH INDEX OF " + index);
field.setPath("/".concat(nodeKey));
}
}
setNodeValueOnField(theNode, field);
if (parent == null) {
jsonDocument.getFields().getField().add(field);
} else {
parent.getJsonFields().getJsonField().add(field);
}
}
private void setNodeValueOnField(JsonNode valueNode, JsonField field) {
LOG.trace("VALUE IS A " + valueNode.getNodeType().name());
if (valueNode.isNumber()) {
if (valueNode.isInt()) {
field.setFieldType(FieldType.INTEGER);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.intValue());
} else if (valueNode.isBigInteger()) {
field.setFieldType(FieldType.INTEGER);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.bigIntegerValue());
} else if (valueNode.isFloat()) {
field.setFieldType(FieldType.FLOAT);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.floatValue());
} else if (valueNode.isDouble()) {
field.setFieldType(FieldType.DOUBLE);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.asDouble());
} else if (valueNode.isBigDecimal()) {
field.setFieldType(FieldType.DECIMAL);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.decimalValue());
} else if (valueNode.isShort()) {
field.setFieldType(FieldType.SHORT);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.shortValue());
} else if (valueNode.isLong()) {
field.setFieldType(FieldType.LONG);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.longValue());
}
} else if (valueNode.isTextual()) {
field.setFieldType(FieldType.STRING);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.textValue());
} else if (valueNode.isBoolean()) {
field.setFieldType(FieldType.BOOLEAN);
field.setStatus(FieldStatus.SUPPORTED);
field.setValue(valueNode.booleanValue());
} else if (valueNode.isBinary() || valueNode.isPojo()) {
field.setFieldType(FieldType.UNSUPPORTED);
field.setStatus(FieldStatus.UNSUPPORTED);
}
}
private JsonComplexType getJsonComplexType(JsonComplexType parent, String aKey, int index) {
JsonComplexType jsonComplexType = JsonComplexTypeFactory.createJsonComlexField();
jsonComplexType.setJsonFields(new JsonFields());
jsonComplexType.setName(aKey);
jsonComplexType.setStatus(FieldStatus.SUPPORTED);
if (index > 0) {
jsonComplexType
.setPath(parent.getPath().concat("[").concat(String.valueOf(index)).concat("]/").concat(aKey));
} else {
jsonComplexType.setPath(parent.getPath().concat("/").concat(aKey));
}
parent.getJsonFields().getJsonField().add(jsonComplexType);
return jsonComplexType;
}
private JsonComplexType getJsonComplexTypeFromEntry(Map.Entry entry) {
JsonComplexType parent = JsonComplexTypeFactory.createJsonComlexField();
parent.setJsonFields(new JsonFields());
parent.setName(entry.getKey());
parent.setStatus(FieldStatus.SUPPORTED);
parent.setPath("/".concat(entry.getKey()));
return parent;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy