ExecutionStepInfo newParentExecutionStepInfo = newExecutionStepInfo() .type(curNode.getType()) .fieldDefinition(currentParentExecutionStepInfo.getFieldDefinition()) .field(currentParentExecutionStepInfo.getField()) .path(currentParentExecutionStepInfo.getPath()) .parentInfo(currentParentExecutionStepInfo.getParent()) .build(); ExecutionPath fieldPath = curNode.getExecutionStepInfo().getPath().segment(mkNameForPath(currentField)); GraphQLFieldDefinition fieldDefinition = getFieldDef(executionContext.getGraphQLSchema(), curNode.getType(), currentField.getSingleField()); ExecutionStepInfo executionStepInfo = newExecutionStepInfo() .type(fieldDefinition.getType()) .fieldDefinition(fieldDefinition)
fetchMap.put("path", executionStepInfo.getPath().toList()); fetchMap.put("parentType", executionStepInfo.getParent().getUnwrappedNonNullType().getName()); fetchMap.put("returnType", executionStepInfo.simplePrint()); fetchMap.put("fieldName", executionStepInfo.getFieldDefinition().getName()); fetchMap.put("startOffset", startOffset); fetchMap.put("duration", duration);
public NonNullableFieldWasNullException(NonNullableFieldWasNullException previousException) { super( mkMessage( assertNotNull(previousException.executionStepInfo.getParent()), assertNotNull(previousException.executionStepInfo.getParent().getPath()) ), previousException ); this.executionStepInfo = previousException.executionStepInfo.getParent(); this.path = previousException.executionStepInfo.getParent().getPath(); }
private static String mkMessage(ExecutionStepInfo executionStepInfo, ExecutionPath path) { GraphQLType unwrappedTyped = executionStepInfo.getUnwrappedNonNullType(); if (executionStepInfo.hasParent()) { GraphQLType unwrappedParentType = executionStepInfo.getParent().getUnwrappedNonNullType(); return String.format("Cannot return null for non-nullable type: '%s' within parent '%s' (%s)", unwrappedTyped.getName(), unwrappedParentType.getName(), path); } return String.format("Cannot return null for non-nullable type: '%s' (%s)", unwrappedTyped.getName(), path); }
protected void assertNonNullFieldPrecondition(NonNullableFieldWasNullException e, CompletableFuture<?> completableFuture) throws NonNullableFieldWasNullException { ExecutionStepInfo executionStepInfo = e.getExecutionStepInfo(); if (executionStepInfo.hasParent() && executionStepInfo.getParent().isNonNullType()) { completableFuture.completeExceptionally(new NonNullableFieldWasNullException(e)); } }
public static FragmentDirectiveCollector collect(DataFetchingEnvironment env, ExecutionStepInfo step) { FragmentDirectiveCollector fragmentDirectiveCollector = new FragmentDirectiveCollector(env); // This is safe because top-level fields don't get to here and all deeper fields at least have a parent (source object) and a grand-parent (query root) ExecutionStepInfo rootStep = step.getParent().getParent(); if (rootStep == null) { //Should never be possible, see above return fragmentDirectiveCollector; } GraphQLType rootParentType = GraphQLUtils.unwrapNonNull(rootStep.getType()); while(!(rootParentType instanceof GraphQLObjectType)) { rootStep = rootStep.getParent(); rootParentType = GraphQLUtils.unwrapNonNull(rootStep.getType()); } QueryTraversal traversal = QueryTraversal.newQueryTraversal() .fragmentsByName(env.getExecutionContext().getFragmentsByName()) .schema(env.getGraphQLSchema()) .variables(env.getExecutionContext().getVariables()) .root(env.getExecutionStepInfo().getParent().getField()) .rootParentType((GraphQLObjectType) rootParentType) .build(); traversal.visitPostOrder(fragmentDirectiveCollector); return fragmentDirectiveCollector; }
public FieldSubSelection createFieldSubSelection(ExecutionContext executionContext, FetchedValueAnalysis analysis) { ExecutionStepInfo executionInfo = analysis.getExecutionStepInfo(); MergedField field = analysis.getField(); Object source = analysis.getCompletedValue(); Object localContext = analysis.getFetchedValue().getLocalContext(); GraphQLOutputType sourceType = executionInfo.getUnwrappedNonNullType(); GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, source, executionInfo.getArguments(), sourceType); FieldCollectorParameters collectorParameters = newParameters() .schema(executionContext.getGraphQLSchema()) .objectType(resolvedObjectType) .fragments(executionContext.getFragmentsByName()) .variables(executionContext.getVariables()) .build(); MergedSelectionSet subFields = fieldCollector.collectFields(collectorParameters, executionInfo.getField()); // it is not really a new step but rather a refinement ExecutionStepInfo newExecutionStepInfoWithResolvedType = executionInfo.changeTypeWithPreservedNonNull(resolvedObjectType); return FieldSubSelection.newFieldSubSelection() .source(source) .localContext(localContext) .mergedSelectionSet(subFields) .executionInfo(newExecutionStepInfoWithResolvedType) .build(); }
public ExecutionStepInfo newExecutionStepInfoForListElement(ExecutionStepInfo executionInfo, int index) { GraphQLList fieldType = (GraphQLList) executionInfo.getUnwrappedNonNullType(); GraphQLOutputType typeInList = (GraphQLOutputType) fieldType.getWrappedType(); ExecutionPath indexedPath = executionInfo.getPath().segment(index); return executionInfo.transform(builder -> builder .parentInfo(executionInfo) .type(typeInList) .path(indexedPath)); }
Directives(DataFetchingEnvironment env, ExecutionStepInfo step) { List<Field> fields = env.getFields(); if (step != null) { fields = step.getField() != null ? Collections.singletonList(step.getField()) : Collections.emptyList(); if (step.hasParent() && step.getParent().getField() != null) { FragmentDirectiveCollector fragmentDirectiveCollector = FragmentDirectiveCollector.collect(env, step); directives.put(Introspection.DirectiveLocation.INLINE_FRAGMENT, parseDirectives(fragmentDirectiveCollector.getInlineFragmentDirs(), env));
private String mkMessage(ExecutionPath path, UnresolvedTypeException exception, ExecutionStepInfo info) { return format("Can't resolve '%s'. Abstract type '%s' must resolve to an Object type at runtime for field '%s.%s'. %s", path, exception.getInterfaceOrUnionType().getName(), info.getParent().getUnwrappedNonNullType().getName(), info.getFieldDefinition().getName(), exception.getMessage()); }
private FetchedValueAnalysis analyzeFetchedValueImpl(ExecutionContext executionContext, FetchedValue fetchedValue, Object toAnalyze, ExecutionStepInfo executionInfo) throws NonNullableFieldWasNullException { GraphQLType fieldType = executionInfo.getUnwrappedNonNullType(); MergedField field = executionInfo.getField(); GraphQLObjectType resolvedObjectType = resolveType.resolveType(executionContext, field, toAnalyze, executionInfo.getArguments(), fieldType); return newFetchedValueAnalysis(OBJECT) .fetchedValue(fetchedValue)
private ExecutionStepInfo mkExecutionInfo() { return ExecutionStepInfo.newExecutionStepInfo() .type(Introspection.__Schema) .path(mkPath()) .build(); } }
/** * Called to discover the field definition give the current parameters and the AST {@link Field} * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param field the field to find the definition of * * @return a {@link GraphQLFieldDefinition} */ protected GraphQLFieldDefinition getFieldDef(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Field field) { GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); return getFieldDef(executionContext.getGraphQLSchema(), parentType, field); }
@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; }
GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField()); ExecutionId executionId = executionContext.getExecutionId(); try { log.debug("'{}' fetching field '{}' using data fetcher '{}'...", executionId, executionStepInfo.getPath(), dataFetcher.getClass().getName()); Object fetchedValueRaw = dataFetcher.get(environment); log.debug("'{}' field '{}' fetch returned '{}'", executionId, executionStepInfo.getPath(), fetchedValueRaw == null ? "null" : fetchedValueRaw.getClass().getName()); log.debug(String.format("'%s', field '%s' fetch threw exception", executionId, executionStepInfo.getPath()), e);
private FetchedValueAnalysis analyzeList(ExecutionContext executionContext, FetchedValue fetchedValue, Object toAnalyze, ExecutionStepInfo executionInfo) { if (toAnalyze == null) { return newFetchedValueAnalysis(LIST) .fetchedValue(fetchedValue) .executionStepInfo(executionInfo) .nullValue() .build(); } if (toAnalyze.getClass().isArray() || toAnalyze instanceof Iterable) { Collection<Object> collection = FpKit.toCollection(toAnalyze); return analyzeIterable(executionContext, fetchedValue, collection, executionInfo); } else { TypeMismatchError error = new TypeMismatchError(executionInfo.getPath(), executionInfo.getType()); return newFetchedValueAnalysis(LIST) .fetchedValue(fetchedValue) .executionStepInfo(executionInfo) .nullValue() .error(error) .build(); } }
private EntityType getEntityTypeForQuery(DataFetchingEnvironment graphEnv) { String entityName = graphEnv.getExecutionStepInfo().getType().getName(); if (entityName == null) { entityName = graphEnv.getExecutionStepInfo().getType().getChildren().get(0).getName(); } EntityType et = env.getDefinitionsSet().getFirstEntityTypeByInterfaceName(namespace + ".model." + entityName); requireNonNull(et, "EntityType must exist"); return et; }
@Override protected CompletableFuture<ExecutionResult> resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, parameters.getField().get(0)); if (fieldDef == null) return null; ExecutionStepInfo fieldTypeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldDef.getType()).parentInfo(parameters.getExecutionStepInfo()).build(); ExecutionStrategyParameters newParameters = ExecutionStrategyParameters.newParameters() .arguments(parameters.getArguments())
public MergedField getField() { return executionStepInfo.getField(); }