package org.openlca.app.cloud.ui.compare.json;
import java.util.ArrayList;
import java.util.List;
import org.openlca.app.cloud.ui.compare.json.JsonUtil.ElementFinder;
import org.openlca.app.cloud.ui.compare.json.viewer.JsonTreeViewer.Side;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
public class JsonNode {
public String property;
public JsonNode parent;
public JsonElement leftElement;
public JsonElement rightElement;
public boolean readOnly;
public List<JsonNode> children = new ArrayList<>();
JsonElement originalElement;
private ElementFinder elementFinder;
static JsonNode create(JsonNode parent, String property, JsonElement left,
JsonElement right, ElementFinder elementFinder, boolean readOnly) {
JsonElement original = left != null ? JsonUtil.deepCopy(left) : null;
return new JsonNode(parent, property, left, right, original,
elementFinder, readOnly);
}
private JsonNode(JsonNode parent, String property, JsonElement leftElement,
JsonElement rightElement, JsonElement originalElement,
ElementFinder elementFinder, boolean readOnly) {
this.parent = parent;
this.property = property;
this.leftElement = leftElement;
this.rightElement = rightElement;
this.originalElement = originalElement;
this.elementFinder = elementFinder;
this.readOnly = readOnly;
}
public JsonElement getElement() {
if (leftElement != null)
return leftElement;
return rightElement;
}
public JsonElement getElement(Side side) {
if (side == Side.LEFT)
return leftElement;
return rightElement;
}
public boolean hasEqualValues() {
return JsonUtil.equal(property, leftElement, rightElement,
elementFinder);
}
boolean hadDifferences() {
return !JsonUtil.equal(property, leftElement, originalElement,
elementFinder);
}
void setValue(JsonElement toSet, boolean leftToRight) {
if (parent.leftElement == null)
return;
JsonElement current = this.leftElement;
this.leftElement = toSet;
if (parent != null)
updateParent(toSet, current);
updateChildren(leftToRight);
}
private void updateParent(JsonElement toSet, JsonElement current) {
JsonElement parentElement = parent.leftElement;
if (parentElement.isJsonObject())
updateParent(parentElement.getAsJsonObject(), toSet, current);
else if (parentElement.isJsonArray())
updateParent(parentElement.getAsJsonArray(), toSet, current);
}
private void updateParent(JsonObject parentElement, JsonElement toSet,
JsonElement current) {
parentElement.add(property, toSet);
}
private void updateParent(JsonArray parentElement, JsonElement toSet,
JsonElement current) {
JsonObject arrayParent = parent.parent.leftElement.getAsJsonObject();
JsonArray array = parentElement.getAsJsonArray();
if (toSet == null) {
// remove
int index = elementFinder.find(parent.property, current, array);
array = JsonUtil.remove(index, array);
} else {
// add or replace
int index = elementFinder.find(parent.property, toSet, array);
if (index == -1)
array.add(toSet);
else
array = JsonUtil.replace(index, array, toSet);
}
parent.leftElement = array;
arrayParent.add(parent.property, array);
}
private void updateChildren(boolean leftToRight) {
if (children.isEmpty())
return;
for (JsonNode child : children) {
JsonElement element = getElement(child, leftToRight);
child.leftElement = element;
child.updateChildren(leftToRight);
}
}
private JsonElement getElement(JsonNode node, boolean leftToRight) {
if (leftElement == null)
return null;
if (leftElement.isJsonObject())
return leftElement.getAsJsonObject().get(node.property);
if (!leftElement.isJsonArray())
return null;
JsonElement toFind = null;
if (leftToRight)
toFind = node.originalElement;
else
toFind = node.rightElement;
int index = elementFinder.find(property, toFind,
leftElement.getAsJsonArray());
if (index == -1)
return null;
return leftElement.getAsJsonArray().get(index);
}
}