graphql.util.DefaultTraverserContext Maven / Gradle / Ivy
package graphql.util;
import com.google.common.collect.ImmutableList;
import graphql.Internal;
import graphql.collect.ImmutableKit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static graphql.Assert.assertFalse;
import static graphql.Assert.assertNotNull;
import static graphql.Assert.assertNull;
import static graphql.Assert.assertTrue;
@Internal
public class DefaultTraverserContext implements TraverserContext {
private final T curNode;
private T newNode;
private boolean nodeDeleted;
private final TraverserContext parent;
private final Set visited;
private final Map, Object> vars;
private final Object sharedContextData;
private Object newAccValue;
private boolean hasNewAccValue;
private Object curAccValue;
private final NodeLocation location;
private final boolean isRootContext;
private boolean parallel;
private Map>> children;
private Phase phase;
private final List> breadcrumbs;
public DefaultTraverserContext(T curNode,
TraverserContext parent,
Set visited,
Map, Object> vars,
Object sharedContextData,
NodeLocation location,
boolean isRootContext,
boolean parallel) {
this.curNode = curNode;
this.parent = parent;
this.visited = visited;
this.vars = vars;
this.sharedContextData = sharedContextData;
this.location = location;
this.isRootContext = isRootContext;
this.parallel = parallel;
if (parent == null || parent.isRootContext()) {
this.breadcrumbs = ImmutableKit.emptyList();
} else {
this.breadcrumbs = ImmutableList.>builderWithExpectedSize(parent.getBreadcrumbs().size() + 1)
.add(new Breadcrumb<>(this.parent.thisNode(), this.location))
.addAll(parent.getBreadcrumbs())
.build();
}
}
public static DefaultTraverserContext dummy() {
return new DefaultTraverserContext<>(null, null, null, null, null, null, true, false);
}
public static DefaultTraverserContext simple(T node) {
return new DefaultTraverserContext<>(node, null, null, null, null, null, true, false);
}
@Override
public T thisNode() {
assertFalse(this.nodeDeleted, () -> "node is deleted");
if (newNode != null) {
return newNode;
}
return curNode;
}
@Override
public T originalThisNode() {
return curNode;
}
@Override
public void changeNode(T newNode) {
assertNotNull(newNode);
assertFalse(this.nodeDeleted, () -> "node is deleted");
this.newNode = newNode;
}
@Override
public void deleteNode() {
assertNull(this.newNode, () -> "node is already changed");
assertFalse(this.nodeDeleted, () -> "node is already deleted");
this.nodeDeleted = true;
}
@Override
public boolean isDeleted() {
return this.nodeDeleted;
}
@Override
public boolean isChanged() {
return this.newNode != null;
}
@Override
public TraverserContext getParentContext() {
return parent;
}
@Override
public List getParentNodes() {
List result = new ArrayList<>();
TraverserContext curContext = parent;
while (!curContext.isRootContext()) {
result.add(curContext.thisNode());
curContext = curContext.getParentContext();
}
return result;
}
@Override
public List> getBreadcrumbs() {
return breadcrumbs;
}
@Override
public T getParentNode() {
if (parent == null) {
return null;
}
return parent.thisNode();
}
@Override
public Set visitedNodes() {
return visited;
}
@Override
public boolean isVisited() {
return visited.contains(curNode);
}
@Override
public S getVar(Class super S> key) {
return (S) key.cast(vars.get(key));
}
@Override
public TraverserContext setVar(Class super S> key, S value) {
vars.put(key, value);
return this;
}
@Override
public void setAccumulate(Object accumulate) {
hasNewAccValue = true;
newAccValue = accumulate;
}
@Override
public U getNewAccumulate() {
if (hasNewAccValue) {
return (U) newAccValue;
} else {
return (U) curAccValue;
}
}
@Override
public U getCurrentAccumulate() {
return (U) curAccValue;
}
@Override
public Object getSharedContextData() {
return sharedContextData;
}
/*
* PRIVATE: Used by {@link Traverser}
*/
void setCurAccValue(Object curAccValue) {
hasNewAccValue = false;
this.curAccValue = curAccValue;
}
@Override
public NodeLocation getLocation() {
return location;
}
@Override
public boolean isRootContext() {
return isRootContext;
}
@Override
public S getVarFromParents(Class super S> key) {
TraverserContext curContext = parent;
while (curContext != null) {
S var = curContext.getVar(key);
if (var != null) {
return var;
}
curContext = curContext.getParentContext();
}
return null;
}
/*
* PRIVATE: Used by {@link Traverser}
*/
void setChildrenContexts(Map>> children) {
assertTrue(this.children == null, () -> "children already set");
this.children = children;
}
@Override
public Map>> getChildrenContexts() {
assertNotNull(children, () -> "children not available");
return children;
}
/*
* PRIVATE: Used by {@link Traverser}
*/
void setPhase(Phase phase) {
this.phase = phase;
}
@Override
public Phase getPhase() {
return phase;
}
@Override
public boolean isParallel() {
return parallel;
}
}