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

graphql.execution.nextgen.DefaultExecutionStrategy Maven / Gradle / Ivy

The newest version!
package graphql.execution.nextgen;

import graphql.ExecutionResult;
import graphql.Internal;
import graphql.execution.ExecutionContext;
import graphql.execution.ExecutionStepInfo;
import graphql.execution.nextgen.result.ExecutionResultNode;
import graphql.execution.nextgen.result.ObjectExecutionResultNode;
import graphql.execution.nextgen.result.ResolvedValue;
import graphql.execution.nextgen.result.ResultNodesUtil;
import graphql.execution.nextgen.result.RootExecutionResultNode;
import graphql.util.NodeMultiZipper;
import graphql.util.NodeZipper;

import java.util.List;
import java.util.concurrent.CompletableFuture;

import static graphql.collect.ImmutableKit.map;
import static graphql.execution.Async.each;
import static graphql.execution.Async.mapCompose;

@Internal
public class DefaultExecutionStrategy implements ExecutionStrategy {

    ExecutionStrategyUtil util = new ExecutionStrategyUtil();
    ExecutionHelper executionHelper = new ExecutionHelper();

    @Override
    public CompletableFuture execute(ExecutionContext context) {
        FieldSubSelection fieldSubSelection = executionHelper.getFieldSubSelection(context);
        return executeImpl(context, fieldSubSelection)
                .thenApply(ResultNodesUtil::toExecutionResult);
    }

    /*
     * the fundamental algorithm is:
     * - fetch sub selection and analyze it
     * - convert the fetched value analysis into result node
     * - get all unresolved result nodes and resolve the sub selection (start again recursively)
     */
    public CompletableFuture executeImpl(ExecutionContext context, FieldSubSelection fieldSubSelection) {
        return resolveSubSelection(context, fieldSubSelection)
                .thenApply(RootExecutionResultNode::new);
    }

    private CompletableFuture> resolveSubSelection(ExecutionContext executionContext, FieldSubSelection fieldSubSelection) {
        List> namedNodesCFList =
                mapCompose(util.fetchSubSelection(executionContext, fieldSubSelection), node -> resolveAllChildNodes(executionContext, node));
        return each(namedNodesCFList);
    }

    private CompletableFuture resolveAllChildNodes(ExecutionContext context, ExecutionResultNode node) {
        NodeMultiZipper unresolvedNodes = ResultNodesUtil.getUnresolvedNodes(node);
        List>> resolvedNodes = map(unresolvedNodes.getZippers(), unresolvedNode -> resolveNode(context, unresolvedNode));
        return resolvedNodesToResultNode(unresolvedNodes, resolvedNodes);
    }

    private CompletableFuture> resolveNode(ExecutionContext executionContext, NodeZipper unresolvedNode) {
        ExecutionStepInfo executionStepInfo = unresolvedNode.getCurNode().getExecutionStepInfo();
        ResolvedValue resolvedValue = unresolvedNode.getCurNode().getResolvedValue();
        FieldSubSelection fieldSubSelection = util.createFieldSubSelection(executionContext, executionStepInfo, resolvedValue);
        return resolveSubSelection(executionContext, fieldSubSelection)
                .thenApply(resolvedChildMap -> unresolvedNode.withNewNode(new ObjectExecutionResultNode(executionStepInfo, resolvedValue, resolvedChildMap)));
    }

    private CompletableFuture resolvedNodesToResultNode(
            NodeMultiZipper unresolvedNodes,
            List>> resolvedNodes) {
        return each(resolvedNodes)
                .thenApply(unresolvedNodes::withReplacedZippers)
                .thenApply(NodeMultiZipper::toRootNode);
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy