Skip to content

Instantly share code, notes, and snippets.

@annagapuz
Created May 17, 2018 21:07
Show Gist options
  • Save annagapuz/ad4eba949cdd493bef01c6f088c2d566 to your computer and use it in GitHub Desktop.
Save annagapuz/ad4eba949cdd493bef01c6f088c2d566 to your computer and use it in GitHub Desktop.
/**
* fieldIdentifier = objectRoot.foo[0].bar, fieldValue = abc
* fieldIdentifier = objectRoot.foo[1].bar, fieldValue = xyz
*/
public final class SimpleJsonGenerator {
private static final Set<String> ARRAY_NODES = getArrayNodes();
private static final String BASE_JSON_PATH = "objectRoot";
public static String generateJson(List<FieldEnumeration> inputFields) {
Node rootNode = new Node(BASE_JSON_PATH);
inputFields.forEach(p -> {
Node previousNode = rootNode;
for (String node : p.getFieldIdentifier().split("\\.")) {
Optional<Node> optionalChild = previousNode.findNode(node);
Node childNode;
if (optionalChild.isPresent()) {
childNode = optionalChild.get();
} else {
childNode = new Node(node);
previousNode.addChild(childNode);
}
previousNode = childNode;
}
previousNode.setValue(p.getFieldValue());
});
ObjectMapper mapper = new ObjectMapper();
ObjectNode jsonRoot = mapper.createObjectNode();
createJsonObject(jsonRoot, 0, rootNode);
return jsonRoot.toString();
}
private static void createJsonObject(JsonNode jsonNode, int jsonNodeIndex, Node node) {
final String strippedNodeName = node.getName().replaceAll("\\[[\\d]\\]", "");
final Integer arrayIndex = node.getName().matches("^.*\\[[\\d]\\]$") ? Integer.parseInt(node.getName().substring(node.getName().indexOf('[')).replaceAll("[\\[\\]]*", "")) : 0;
JsonNode newNode = jsonNode;
if (node.hasChildren()) {
if (jsonNode.has(strippedNodeName) || (jsonNode.has(jsonNodeIndex) && jsonNode.get(jsonNodeIndex).has(strippedNodeName))) {
JsonNode existingNode = jsonNode.getNodeType().equals(JsonNodeType.ARRAY) ? jsonNode.get(jsonNodeIndex).get(strippedNodeName) : jsonNode.get(strippedNodeName);
if (existingNode.getNodeType().equals(JsonNodeType.OBJECT)) {
System.out.println(String.format("Get existing Object node: %s", node.getName()));
newNode = existingNode;
} else if (existingNode.getNodeType().equals(JsonNodeType.ARRAY)) {
if (existingNode.has(arrayIndex)) {
System.out.println(String.format("Get existing Object from existing Array node: %s", node.getName()));
newNode = existingNode.get(arrayIndex);
} else {
System.out.println(String.format("Create Object for existing Array node: %s", node.getName()));
newNode = ((ArrayNode) existingNode).addObject();
}
}
} else {
if (ARRAY_NODES.contains(strippedNodeName)) {
if (jsonNode.getNodeType().equals(JsonNodeType.OBJECT)) {
System.out.println(String.format("Create Array node on Object: %s", node.getName()));
newNode = ((ObjectNode) jsonNode).putArray(strippedNodeName);
} else if (jsonNode.getNodeType().equals(JsonNodeType.ARRAY)) {
if (jsonNode.has(arrayIndex)) {
System.out.println(String.format("Create Array node on existing Array: %s at %s", node.getName(), arrayIndex));
newNode = ((ObjectNode) (jsonNode).get(arrayIndex)).putArray(strippedNodeName);
} else {
System.out.println(String.format("Create Array node on new Array: %s at %s", node.getName(), arrayIndex));
newNode = ((ArrayNode) jsonNode).insertObject(arrayIndex).putArray(strippedNodeName);
}
}
} else {
if (jsonNode.getNodeType().equals(JsonNodeType.OBJECT)) {
System.out.println(String.format("Create Object node on Object: %s", node.getName()));
newNode = ((ObjectNode) jsonNode).putObject(strippedNodeName);
} else if (jsonNode.getNodeType().equals(JsonNodeType.ARRAY)) {
if (jsonNode.has(jsonNodeIndex)) {
System.out.println(String.format("Get existing Object node from Array: %s", node.getName()));
newNode = ((ObjectNode) jsonNode.get(arrayIndex)).putObject(strippedNodeName);
} else {
System.out.println(String.format("Create Object node on Array: %s", node.getName()));
newNode = ((ArrayNode) jsonNode).insertObject(arrayIndex).putObject(strippedNodeName);
}
}
}
}
for (Node c : node.getChildren()) {
if (c.hasChildren()) {
createJsonObject(newNode, arrayIndex, c);
} else {
final String strippedChildName = c.getName().replaceAll("\\[[\\d]\\]", "");
if (newNode.getNodeType().equals(JsonNodeType.OBJECT)) {
System.out.println(String.format(" >>> Leaf node on Object: %s = %s", c.getName(), c.getValue()));
((ObjectNode) newNode).put(strippedChildName, c.getValue());
} else if (newNode.getNodeType().equals(JsonNodeType.ARRAY)) {
System.out.println(String.format(" >>> Leaf node in Array at position %s: %s = %s", arrayIndex, c.getName(), c.getValue()));
if (newNode.has(arrayIndex)) {
((ObjectNode) (newNode).get(arrayIndex)).put(strippedChildName, c.getValue());
} else {
((ArrayNode) newNode).insertObject(arrayIndex).put(strippedChildName, c.getValue());
}
}
}
}
}
}
}
public class Node {
private String name;
private List<Node> children;
private String value;
public Node(String name) {
this.name = name;
children = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void addChild(Node childNode) {
this.children.add(childNode);
}
public Optional<Node> findNode(String nodeName) {
if (nodeName.equals(this.getName())) {
return Optional.of(this);
}
return getChildren().stream().filter(n -> nodeName.equals(n.getName())).findFirst();
}
public boolean hasChildren() {
return !getChildren().isEmpty();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment