use of graphql.util.NodeLocation in project graphql-java by graphql-java.
the class SchemaTransformer method moveUp.
private NodeZipper<GraphQLSchemaElement> moveUp(GraphQLSchemaElement parent, Map<NodeZipper<GraphQLSchemaElement>, Breadcrumb<GraphQLSchemaElement>> sameParentsZipper) {
Set<NodeZipper<GraphQLSchemaElement>> sameParent = sameParentsZipper.keySet();
assertNotEmpty(sameParent, () -> "expected at least one zipper");
Map<String, List<GraphQLSchemaElement>> childrenMap = new HashMap<>(SCHEMA_ELEMENT_ADAPTER.getNamedChildren(parent));
Map<String, Integer> indexCorrection = new HashMap<>();
List<ZipperWithOneParent> zipperWithOneParents = new ArrayList<>();
for (NodeZipper<GraphQLSchemaElement> zipper : sameParent) {
Breadcrumb<GraphQLSchemaElement> breadcrumb = sameParentsZipper.get(zipper);
zipperWithOneParents.add(new ZipperWithOneParent(zipper, breadcrumb));
}
zipperWithOneParents.sort((zipperWithOneParent1, zipperWithOneParent2) -> {
NodeZipper<GraphQLSchemaElement> zipper1 = zipperWithOneParent1.zipper;
NodeZipper<GraphQLSchemaElement> zipper2 = zipperWithOneParent2.zipper;
Breadcrumb<GraphQLSchemaElement> breadcrumb1 = zipperWithOneParent1.parent;
Breadcrumb<GraphQLSchemaElement> breadcrumb2 = zipperWithOneParent2.parent;
int index1 = breadcrumb1.getLocation().getIndex();
int index2 = breadcrumb2.getLocation().getIndex();
if (index1 != index2) {
return Integer.compare(index1, index2);
}
NodeZipper.ModificationType modificationType1 = zipper1.getModificationType();
NodeZipper.ModificationType modificationType2 = zipper2.getModificationType();
if (modificationType1 == modificationType2) {
return 0;
}
// always first replacing the node
if (modificationType1 == REPLACE) {
return -1;
}
// and then INSERT_BEFORE before INSERT_AFTER
return modificationType1 == NodeZipper.ModificationType.INSERT_BEFORE ? -1 : 1;
});
for (ZipperWithOneParent zipperWithOneParent : zipperWithOneParents) {
NodeZipper<GraphQLSchemaElement> zipper = zipperWithOneParent.zipper;
Breadcrumb<GraphQLSchemaElement> breadcrumb = zipperWithOneParent.parent;
NodeLocation location = breadcrumb.getLocation();
Integer ixDiff = indexCorrection.getOrDefault(location.getName(), 0);
int ix = location.getIndex() + ixDiff;
String name = location.getName();
List<GraphQLSchemaElement> childList = new ArrayList<>(childrenMap.get(name));
switch(zipper.getModificationType()) {
case REPLACE:
childList.set(ix, zipper.getCurNode());
break;
case DELETE:
childList.remove(ix);
indexCorrection.put(name, ixDiff - 1);
break;
case INSERT_BEFORE:
childList.add(ix, zipper.getCurNode());
indexCorrection.put(name, ixDiff + 1);
break;
case INSERT_AFTER:
childList.add(ix + 1, zipper.getCurNode());
indexCorrection.put(name, ixDiff + 1);
break;
}
childrenMap.put(name, childList);
}
GraphQLSchemaElement newNode = SCHEMA_ELEMENT_ADAPTER.withNewChildren(parent, childrenMap);
final List<Breadcrumb<GraphQLSchemaElement>> oldBreadcrumbs = sameParent.iterator().next().getBreadcrumbs();
List<Breadcrumb<GraphQLSchemaElement>> newBreadcrumbs;
if (oldBreadcrumbs.size() > 1) {
newBreadcrumbs = oldBreadcrumbs.subList(1, oldBreadcrumbs.size());
} else {
newBreadcrumbs = Collections.emptyList();
}
return new NodeZipper<>(newNode, newBreadcrumbs, SCHEMA_ELEMENT_ADAPTER);
}
Aggregations