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

graphql.execution2.DefaultExecutionStrategy Maven / Gradle / Ivy

package graphql.execution2;

import graphql.Internal;
import graphql.execution.Async;
import graphql.execution.ExecutionContext;
import graphql.execution.ExecutionStepInfo;
import graphql.execution.ExecutionStepInfoFactory;
import graphql.execution2.result.ExecutionResultMultiZipper;
import graphql.execution2.result.ExecutionResultNode;
import graphql.execution2.result.ExecutionResultZipper;
import graphql.execution2.result.NamedResultNode;
import graphql.execution2.result.ObjectExecutionResultNode;
import graphql.execution2.result.ResultNodesUtil;
import graphql.language.Field;

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

import static java.util.stream.Collectors.toList;

@Internal
public class DefaultExecutionStrategy implements ExecutionStrategy {

    ExecutionStepInfoFactory executionInfoFactory;
    ValueFetcher valueFetcher;
    ResultNodesCreator resultNodesCreator = new ResultNodesCreator();

    private final ExecutionContext executionContext;
    private FetchedValueAnalyzer fetchedValueAnalyzer;

    public DefaultExecutionStrategy(ExecutionContext executionContext) {
        this.executionContext = executionContext;
        this.fetchedValueAnalyzer = new FetchedValueAnalyzer(executionContext);
        this.valueFetcher = new ValueFetcher(executionContext);
        this.executionInfoFactory = new ExecutionStepInfoFactory();
    }

    @Override
    public CompletableFuture execute(FieldSubSelection fieldSubSelection) {
        return resolveSubSelection(fieldSubSelection)
                .thenApply(ObjectExecutionResultNode.RootExecutionResultNode::new);
    }

    private CompletableFuture resolveNode(NamedResultNode namedResultNode) {
        ExecutionResultMultiZipper unresolvedMultiZipper = ResultNodesUtil.getUnresolvedNodes(namedResultNode.getNode());
        // must be a unresolved Node
        List> cfList = unresolvedMultiZipper
                .getZippers()
                .stream()
                .map(this::resolveZipper)
                .collect(Collectors.toList());
        return Async
                .each(cfList)
                .thenApply(unresolvedMultiZipper::withZippers)
                .thenApply(ExecutionResultMultiZipper::toRootNode)
                .thenApply(namedResultNode::withNode);
    }

    private CompletableFuture resolveZipper(ExecutionResultZipper unresolvedNodeZipper) {
        FetchedValueAnalysis fetchedValueAnalysis = unresolvedNodeZipper.getCurNode().getFetchedValueAnalysis();
        return resolveSubSelection(fetchedValueAnalysis.getFieldSubSelection())
                .thenApply(resolvedChildMap -> new ObjectExecutionResultNode(fetchedValueAnalysis, resolvedChildMap))
                .thenApply(unresolvedNodeZipper::withNode);
    }

    private CompletableFuture> resolveSubSelection(FieldSubSelection fieldSubSelection) {
        return fetchSubSelection(fieldSubSelection)
                .thenCompose(children -> {
                    List> listOfCF = children
                            .stream()
                            .map(this::resolveNode)
                            .collect(Collectors.toList());
                    return Async.each(listOfCF);
                });
    }


    private CompletableFuture> fetchSubSelection(FieldSubSelection fieldSubSelection) {
        CompletableFuture> fetchedValueAnalysisFlux = fetchAndAnalyze(fieldSubSelection);
        return fetchedValueAnalysisToNodes(fetchedValueAnalysisFlux);
    }

    private CompletableFuture> fetchedValueAnalysisToNodes(CompletableFuture> fetchedValueAnalysisFlux) {
        return Async.map(fetchedValueAnalysisFlux,
                fetchedValueAnalysis -> {
                    ExecutionResultNode resultNode = resultNodesCreator.createResultNode(fetchedValueAnalysis);
                    return new NamedResultNode(fetchedValueAnalysis.getName(), resultNode);
                });
    }

    private CompletableFuture> fetchAndAnalyze(FieldSubSelection fieldSubSelection) {
        List> fetchedValues = fieldSubSelection.getFields().entrySet().stream()
                .map(entry -> {
                    List sameFields = entry.getValue();
                    String name = entry.getKey();
                    ExecutionStepInfo newExecutionStepInfo = executionInfoFactory.newExecutionStepInfoForSubField(executionContext, sameFields, fieldSubSelection.getExecutionStepInfo());
                    return valueFetcher
                            .fetchValue(fieldSubSelection.getSource(), sameFields, newExecutionStepInfo)
                            .thenApply(fetchValue -> analyseValue(fetchValue, name, sameFields, newExecutionStepInfo));
                })
                .collect(toList());
        return Async.each(fetchedValues);
    }

    private FetchedValueAnalysis analyseValue(FetchedValue fetchedValue, String name, List field, ExecutionStepInfo executionInfo) {
        FetchedValueAnalysis fetchedValueAnalysis = fetchedValueAnalyzer.analyzeFetchedValue(fetchedValue.getFetchedValue(), name, field, executionInfo);
        fetchedValueAnalysis.setFetchedValue(fetchedValue);
        return fetchedValueAnalysis;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy