All Downloads are FREE. Search and download functionalities are using the official Maven repository.

graphql.util.DefaultTraverserContext Maven / Gradle / Ivy

There is a newer version: 230521-nf-execution
Show newest version
package graphql.util;

import graphql.Internal;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static graphql.Assert.assertNotNull;
import static graphql.Assert.assertTrue;

@Internal
public class DefaultTraverserContext implements TraverserContext {

    private final T curNode;
    private T newNode;
    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 NodePosition position;
    private final boolean isRootContext;

    public DefaultTraverserContext(T curNode,
                                   TraverserContext parent,
                                   Set visited,
                                   Map, Object> vars,
                                   Object sharedContextData,
                                   NodePosition position,
                                   boolean isRootContext) {
        this.curNode = curNode;
        this.parent = parent;
        this.visited = visited;
        this.vars = vars;
        this.sharedContextData = sharedContextData;
        this.position = position;
        this.isRootContext = isRootContext;
    }

    public static  DefaultTraverserContext dummy() {
        return new DefaultTraverserContext<>(null, null, null, null, null, null, true);
    }

    public static  DefaultTraverserContext simple(T node) {
        return new DefaultTraverserContext<>(node, null, null, null, null, null, true);
    }

    @Override
    public T thisNode() {
        if (newNode != null) {
            return newNode;
        }
        return curNode;
    }


    @Override
    public void changeNode(T newNode) {
        assertNotNull(newNode);
        assertTrue(this.newNode == null, "node can only be changed once");
        this.newNode = newNode;
    }


    @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 Set visitedNodes() {
        return visited;
    }

    @Override
    public boolean isVisited() {
        return visited.contains(curNode);
    }

    @Override
    public  S getVar(Class key) {
        return (S) key.cast(vars.get(key));
    }

    @Override
    public  TraverserContext setVar(Class 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 NodePosition getPosition() {
        return position;
    }

    @Override
    public boolean isRootContext() {
        return isRootContext;
    }

}