JzonObject patch = (JzonObject) patchEl;
Set<Entry<String, JzonElement>> memb = new TreeSet<Entry<String, JzonElement>>(INSTRUCTIONS_COMPARATOR);
memb.addAll(patch.entrySet());
for (Entry<String, JzonElement> entry : memb) {
String key = entry.getKey();
JzonElement value = entry.getValue();
if (key.startsWith(MOD)) {
JzonElement partialInstructions = entry.getValue();
if (!partialInstructions.isJsonArray()) {
throw new IllegalArgumentException();
}
JzonArray array = (JzonArray) partialInstructions;
JzonElement applyTo;
if (key.equals(MOD)) {
applyTo = origEl;
} else if (origEl.isJsonArray()) {
int index = Integer.parseInt(key.substring(1));
applyTo = ((JzonArray) origEl).get(index);
} else {
applyTo = ((JzonObject) origEl).get(key.substring(1));
}
for (int i = 0; i < array.size(); i++) {
JzonElement partial = array.get(i);
if (!partial.isJsonObject()) {
throw new IllegalArgumentException();
}
Entry<String, JzonElement> childentry = ((JzonObject) partial).entrySet().iterator().next();
String childKey = childentry.getKey();
Instruction instruction = create(childKey);
boolean newAppliance = false;
if (instruction.isIndexed() && !applyTo.isJsonArray()) {
applyTo = factory.createJsonArray();
newAppliance = true;
} else if (!instruction.isIndexed() && !applyTo.isJsonObject()) {
applyTo = factory.createJsonObject();
newAppliance = true;
}
if (newAppliance) {
if (origEl.isJsonArray()) {
int index = Integer.parseInt(key);
((JzonArray) origEl).insert(index, applyTo);
} else {
((JzonObject) origEl).add(key.substring(1), applyTo);
}
}
applyPartial(applyTo, instruction, childentry.getValue());
}
} else {
Instruction instruction = create(key);
if (instruction.oper == Oper.INSERT || instruction.oper == Oper.DELETE) {
applyPartial(origEl, instruction, value);
} else if (instruction.isIndexed()) {
if (!origEl.isJsonArray()) {
throw new IllegalArgumentException();
}
if (value.isJsonPrimitive()) {
((JzonArray) origEl).set(instruction.index, value);
} else {
if (((JzonArray) origEl).size() <= instruction.index) {
throw new IllegalArgumentException("Wrong index " + instruction.index + " for " + origEl);
}
JzonElement childEl = ((JzonArray) origEl).get(instruction.index);
apply(childEl, value);
}
} else if (origEl.isJsonObject()) {
if (value.isJsonPrimitive() || value.isJsonNull()) {
((JzonObject) origEl).add(key, value);
} else {
JzonElement childEl = ((JzonObject) origEl).get(key);
apply(childEl, value);
}
} else {
throw new IllegalArgumentException();
}