graphql.util.TreeTransformerUtil Maven / Gradle / Ivy
package graphql.util;
import graphql.PublicApi;
import java.util.List;
import java.util.Queue;
import static graphql.Assert.assertTrue;
@PublicApi
public class TreeTransformerUtil {
/**
* Can be called multiple times to change the current node of the context. The latest call wins
*
* @param context the context in play
* @param changedNode the changed node
* @param for two
*
* @return traversal control
*/
public static TraversalControl changeNode(TraverserContext context, T changedNode) {
boolean changed = context.isChanged();
if (context.isParallel()) {
List> zippers = context.getVar(List.class);
NodeAdapter adapter = context.getVar(NodeAdapter.class);
if (changed) {
replaceZipperForNode(zippers, context.thisNode(), changedNode);
context.changeNode(changedNode);
} else {
NodeZipper nodeZipper = new NodeZipper<>(changedNode, context.getBreadcrumbs(), adapter);
zippers.add(nodeZipper);
context.changeNode(changedNode);
}
return TraversalControl.CONTINUE;
} else {
NodeZipper zipperWithChangedNode = context.getVar(NodeZipper.class).withNewNode(changedNode);
List> zippers = context.getSharedContextData();
if (changed) {
// this is potentially expensive
replaceZipperForNode(zippers, context.thisNode(), changedNode);
context.changeNode(changedNode);
} else {
zippers.add(zipperWithChangedNode);
context.changeNode(changedNode);
}
return TraversalControl.CONTINUE;
}
}
private static void replaceZipperForNode(List> zippers, T currentNode, T newNode) {
int index = FpKit.findIndex(zippers, zipper -> zipper.getCurNode() == currentNode);
assertTrue(index >= 0, () -> "No current zipper found for provided node");
NodeZipper newZipper = zippers.get(index).withNewNode(newNode);
zippers.set(index, newZipper);
}
public static TraversalControl deleteNode(TraverserContext context) {
if (context.isParallel()) {
NodeAdapter adapter = context.getVar(NodeAdapter.class);
NodeZipper deleteNodeZipper = new NodeZipper<>(context.thisNode(), context.getBreadcrumbs(), adapter).deleteNode();
List> zippers = context.getVar(List.class);
zippers.add(deleteNodeZipper);
context.deleteNode();
return TraversalControl.CONTINUE;
} else {
NodeZipper deleteNodeZipper = context.getVar(NodeZipper.class).deleteNode();
Queue> zippers = context.getSharedContextData();
zippers.add(deleteNodeZipper);
context.deleteNode();
return TraversalControl.CONTINUE;
}
}
public static TraversalControl insertAfter(TraverserContext context, T toInsertAfter) {
if (context.isParallel()) {
NodeAdapter adapter = context.getVar(NodeAdapter.class);
NodeZipper insertNodeZipper = new NodeZipper<>(context.originalThisNode(), context.getBreadcrumbs(), adapter).insertAfter(toInsertAfter);
List> zippers = context.getVar(List.class);
zippers.add(insertNodeZipper);
return TraversalControl.CONTINUE;
} else {
NodeZipper insertNodeZipper = context.getVar(NodeZipper.class).insertAfter(toInsertAfter);
Queue> zippers = context.getSharedContextData();
zippers.add(insertNodeZipper);
return TraversalControl.CONTINUE;
}
}
public static TraversalControl insertBefore(TraverserContext context, T toInsertBefore) {
if (context.isParallel()) {
NodeAdapter adapter = context.getVar(NodeAdapter.class);
NodeZipper insertNodeZipper = new NodeZipper<>(context.originalThisNode(), context.getBreadcrumbs(), adapter).insertBefore(toInsertBefore);
List> zippers = context.getVar(List.class);
zippers.add(insertNodeZipper);
return TraversalControl.CONTINUE;
} else {
NodeZipper insertNodeZipper = context.getVar(NodeZipper.class).insertBefore(toInsertBefore);
Queue> zippers = context.getSharedContextData();
zippers.add(insertNodeZipper);
return TraversalControl.CONTINUE;
}
}
}