@SuppressWarnings("unchecked") private void merge(Map.Entry<Path, Object> simpleEntry, Map<String, Object> compositionMap) { Path path = simpleEntry.getKey(); String head = path.head(); assert head != null; Object nextLevelComposition = compositionMap.get(head); Path tail = path.tail(); Object simpleValue = simpleEntry.getValue(); if (nextLevelComposition == null) { mergeEntryIntoEmptySlot(compositionMap, head, tail, simpleValue); } else if (Types.isSimple(nextLevelComposition)) { mergeEntryWithSimple(compositionMap, nextLevelComposition, head, tail, simpleValue); } else { mergeEntryWithStructure((Map<String, Object>) nextLevelComposition, tail, simpleValue); } }
private void mergeEntryIntoEmptySlot( Map<String, Object> composition, String head, Path tail, Object simpleValue) { if (tail.isEmpty()) { composition.put(head, simpleValue); } else { composition.put(head, composeMap(Collections.singletonMap(tail, simpleValue))); } }
private void mergeEntryWithStructure( Map<String, Object> nextLevelComposition, Path tail, Object simpleValue) { if (tail.isEmpty()) { // INCONSISTENCY!! there is a simple value at the same level as a complex object // Resolve this by putting this value at the special key "@ROOT" inside the complex object. Object previousValue = nextLevelComposition.put(INCONSISTENT_ROOT, simpleValue); // not possible to have a previous value, there can only be one key with this path if (previousValue != null) { // merging two simple values at same level, this cannot happen because map keys are unique throw new IllegalStateException("two simple values at same level?"); } } else { // simply advance to next level since the head matches a key already there merge(new SimpleEntry<Path, Object>(tail, simpleValue), nextLevelComposition); } }
private void mergeEntryWithSimple( Map<String, Object> composition, Object nextLevelComposition, String head, Path tail, Object simpleValue) { if (tail.isEmpty()) { // merging two simple values at same level, this cannot happen because map keys are unique throw new IllegalStateException("two simple values at same level?"); } // merging longer path with simple value Map<String, Object> map = composeMap(Collections.singletonMap(tail, simpleValue)); map.put(INCONSISTENT_ROOT, nextLevelComposition); // replace the simple value with map containing simple value and inconsistent root composition.put(head, map); }