public Map<String, MergedField> getSubFields() { return mergedSelectionSet.getSubFields(); }
private List<CompletableFuture<List<FetchedValueAnalysis>>> batchFetchForEachSubField(ExecutionContext executionContext, List<FieldSubSelection> fieldSubSelections, MergedSelectionSet mergedSelectionSet) { List<Object> sources = map(fieldSubSelections, FieldSubSelection::getSource); return mapEntries(mergedSelectionSet.getSubFields(), (name, mergedField) -> { List<ExecutionStepInfo> newExecutionStepInfos = newExecutionInfos(executionContext, fieldSubSelections, mergedField); return valueFetcher .fetchBatchedValues(executionContext, sources, mergedField, newExecutionStepInfos) .thenApply(fetchValue -> analyseValues(executionContext, fetchValue, newExecutionStepInfos)); }); }
@SuppressWarnings("UnnecessaryLocalVariable") private List<ExecutionNode> handleObject(ExecutionContext executionContext, Map<String, Object> argumentValues, FetchedValues fetchedValues, String fieldName, MergedField fields, ExecutionStepInfo executionStepInfo) { // collect list of values by actual type (needed because of interfaces and unions) Map<GraphQLObjectType, List<MapOrList>> resultsByType = new LinkedHashMap<>(); Map<GraphQLObjectType, List<Object>> sourceByType = new LinkedHashMap<>(); for (FetchedValue value : fetchedValues.getValues()) { MapOrList mapOrList = value.getParentResult(); if (value.getValue() == null) { mapOrList.putOrAdd(fieldName, null); continue; } MapOrList childResult = mapOrList.createAndPutMap(fieldName); GraphQLObjectType resolvedType = getGraphQLObjectType(executionContext, fields, executionStepInfo.getUnwrappedNonNullType(), value.getValue(), argumentValues); resultsByType.putIfAbsent(resolvedType, new ArrayList<>()); resultsByType.get(resolvedType).add(childResult); sourceByType.putIfAbsent(resolvedType, new ArrayList<>()); sourceByType.get(resolvedType).add(value.getValue()); } List<ExecutionNode> childNodes = new ArrayList<>(); for (GraphQLObjectType resolvedType : resultsByType.keySet()) { List<MapOrList> results = resultsByType.get(resolvedType); List<Object> sources = sourceByType.get(resolvedType); MergedSelectionSet childFields = getChildFields(executionContext, resolvedType, fields); ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedType); childNodes.add(new ExecutionNode(resolvedType, newExecutionStepInfo, childFields.getSubFields(), results, sources)); } return childNodes; }
@Override @SuppressWarnings("FutureReturnValueIgnored") public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { InstrumentationContext<ExecutionResult> executionStrategyCtx = executionContext.getInstrumentation() .beginExecutionStrategy(new InstrumentationExecutionStrategyParameters(executionContext, parameters)); GraphQLObjectType type = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); ExecutionNode root = new ExecutionNode(type, parameters.getExecutionStepInfo(), parameters.getFields().getSubFields(), singletonList(MapOrList.createMap(new LinkedHashMap<>())), Collections.singletonList(parameters.getSource()) ); Queue<ExecutionNode> nodes = new ArrayDeque<>(); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); executeImpl(executionContext, parameters, root, root, nodes, root.getFields().keySet().iterator(), result); executionStrategyCtx.onDispatched(result); result.whenComplete(executionStrategyCtx::onCompleted); return result; }
private void traverseFields(MergedField fieldList, GraphQLFieldsContainer parentFieldType, String fieldPrefix) { FieldCollectorParameters parameters = FieldCollectorParameters.newParameters() .schema(graphQLSchema) .objectType(asObjectTypeOrNull(parentFieldType)) .fragments(fragmentsByName) .variables(variables) .build(); MergedSelectionSet collectedFields = fieldCollector.collectFields(parameters, fieldList); for (Map.Entry<String, MergedField> entry : collectedFields.getSubFields().entrySet()) { String fieldName = mkFieldName(fieldPrefix, entry.getKey()); MergedField collectedFieldList = entry.getValue(); selectionSetFields.put(fieldName, collectedFieldList); Field field = collectedFieldList.getSingleField(); GraphQLFieldDefinition fieldDef = Introspection.getFieldDef(graphQLSchema, parentFieldType, field.getName()); GraphQLType unwrappedType = GraphQLTypeUtil.unwrapAll(fieldDef.getType()); Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldDef.getArguments(), field.getArguments(), variables); selectionSetFieldArgs.put(fieldName, argumentValues); selectionSetFieldDefinitions.put(fieldName, fieldDef); flattenedFields.add(fieldName); if (unwrappedType instanceof GraphQLFieldsContainer) { traverseFields(collectedFieldList, (GraphQLFieldsContainer) unwrappedType, fieldName); } } }
public Map<String, MergedField> getSubFields() { return mergedSelectionSet.getSubFields(); }
private List<CompletableFuture<List<FetchedValueAnalysis>>> batchFetchForEachSubField(ExecutionContext executionContext, List<FieldSubSelection> fieldSubSelections, MergedSelectionSet mergedSelectionSet) { List<Object> sources = map(fieldSubSelections, FieldSubSelection::getSource); return mapEntries(mergedSelectionSet.getSubFields(), (name, mergedField) -> { List<ExecutionStepInfo> newExecutionStepInfos = newExecutionInfos(executionContext, fieldSubSelections, mergedField); return valueFetcher .fetchBatchedValues(executionContext, sources, mergedField, newExecutionStepInfos) .thenApply(fetchValue -> analyseValues(executionContext, fetchValue, newExecutionStepInfos)); }); }
@SuppressWarnings("UnnecessaryLocalVariable") private List<ExecutionNode> handleObject(ExecutionContext executionContext, Map<String, Object> argumentValues, FetchedValues fetchedValues, String fieldName, MergedField fields, ExecutionStepInfo executionStepInfo) { // collect list of values by actual type (needed because of interfaces and unions) Map<GraphQLObjectType, List<MapOrList>> resultsByType = new LinkedHashMap<>(); Map<GraphQLObjectType, List<Object>> sourceByType = new LinkedHashMap<>(); for (FetchedValue value : fetchedValues.getValues()) { MapOrList mapOrList = value.getParentResult(); if (value.getValue() == null) { mapOrList.putOrAdd(fieldName, null); continue; } MapOrList childResult = mapOrList.createAndPutMap(fieldName); GraphQLObjectType resolvedType = getGraphQLObjectType(executionContext, fields, executionStepInfo.getUnwrappedNonNullType(), value.getValue(), argumentValues); resultsByType.putIfAbsent(resolvedType, new ArrayList<>()); resultsByType.get(resolvedType).add(childResult); sourceByType.putIfAbsent(resolvedType, new ArrayList<>()); sourceByType.get(resolvedType).add(value.getValue()); } List<ExecutionNode> childNodes = new ArrayList<>(); for (GraphQLObjectType resolvedType : resultsByType.keySet()) { List<MapOrList> results = resultsByType.get(resolvedType); List<Object> sources = sourceByType.get(resolvedType); MergedSelectionSet childFields = getChildFields(executionContext, resolvedType, fields); ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedType); childNodes.add(new ExecutionNode(resolvedType, newExecutionStepInfo, childFields.getSubFields(), results, sources)); } return childNodes; }
@Override @SuppressWarnings("FutureReturnValueIgnored") public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { InstrumentationContext<ExecutionResult> executionStrategyCtx = executionContext.getInstrumentation() .beginExecutionStrategy(new InstrumentationExecutionStrategyParameters(executionContext, parameters)); GraphQLObjectType type = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); ExecutionNode root = new ExecutionNode(type, parameters.getExecutionStepInfo(), parameters.getFields().getSubFields(), singletonList(MapOrList.createMap(new LinkedHashMap<>())), Collections.singletonList(parameters.getSource()) ); Queue<ExecutionNode> nodes = new ArrayDeque<>(); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); executeImpl(executionContext, parameters, root, root, nodes, root.getFields().keySet().iterator(), result); executionStrategyCtx.onDispatched(result); result.whenComplete(executionStrategyCtx::onCompleted); return result; }
private void traverseFields(MergedField fieldList, GraphQLFieldsContainer parentFieldType, String fieldPrefix) { FieldCollectorParameters parameters = FieldCollectorParameters.newParameters() .schema(graphQLSchema) .objectType(asObjectTypeOrNull(parentFieldType)) .fragments(fragmentsByName) .variables(variables) .build(); MergedSelectionSet collectedFields = fieldCollector.collectFields(parameters, fieldList); for (Map.Entry<String, MergedField> entry : collectedFields.getSubFields().entrySet()) { String fieldName = mkFieldName(fieldPrefix, entry.getKey()); MergedField collectedFieldList = entry.getValue(); selectionSetFields.put(fieldName, collectedFieldList); Field field = collectedFieldList.getSingleField(); GraphQLFieldDefinition fieldDef = Introspection.getFieldDef(graphQLSchema, parentFieldType, field.getName()); GraphQLType unwrappedType = GraphQLTypeUtil.unwrapAll(fieldDef.getType()); Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldDef.getArguments(), field.getArguments(), variables); selectionSetFieldArgs.put(fieldName, argumentValues); selectionSetFieldDefinitions.put(fieldName, fieldDef); flattenedFields.add(fieldName); if (unwrappedType instanceof GraphQLFieldsContainer) { traverseFields(collectedFieldList, (GraphQLFieldsContainer) unwrappedType, fieldName); } } }