All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
graphql.execution.FieldCollector Maven / Gradle / Ivy
package graphql.execution;
import graphql.Internal;
import graphql.language.Field;
import graphql.language.FragmentDefinition;
import graphql.language.FragmentSpread;
import graphql.language.InlineFragment;
import graphql.language.Selection;
import graphql.language.SelectionSet;
import graphql.schema.GraphQLInterfaceType;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLType;
import graphql.schema.GraphQLUnionType;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static graphql.execution.MergedSelectionSet.newMergedSelectionSet;
import static graphql.execution.TypeFromAST.getTypeFromAST;
/**
* A field collector can iterate over field selection sets and build out the sub fields that have been selected,
* expanding named and inline fragments as it goes.s
*/
@Internal
public class FieldCollector {
private final ConditionalNodes conditionalNodes = new ConditionalNodes();
public MergedSelectionSet collectFields(FieldCollectorParameters parameters, MergedField mergedField) {
Map subFields = new LinkedHashMap<>();
Set visitedFragments = new LinkedHashSet<>();
for (Field field : mergedField.getFields()) {
if (field.getSelectionSet() == null) {
continue;
}
this.collectFields(parameters, field.getSelectionSet(), visitedFragments, subFields);
}
return newMergedSelectionSet().subFields(subFields).build();
}
/**
* Given a selection set this will collect the sub-field selections and return it as a map
*
* @param parameters the parameters to this method
* @param selectionSet the selection set to collect on
*
* @return a map of the sub field selections
*/
public MergedSelectionSet collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet) {
Map subFields = new LinkedHashMap<>();
Set visitedFragments = new LinkedHashSet<>();
this.collectFields(parameters, selectionSet, visitedFragments, subFields);
return newMergedSelectionSet().subFields(subFields).build();
}
private void collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet, Set visitedFragments, Map fields) {
for (Selection selection : selectionSet.getSelections()) {
if (selection instanceof Field) {
collectField(parameters, fields, (Field) selection);
} else if (selection instanceof InlineFragment) {
collectInlineFragment(parameters, visitedFragments, fields, (InlineFragment) selection);
} else if (selection instanceof FragmentSpread) {
collectFragmentSpread(parameters, visitedFragments, fields, (FragmentSpread) selection);
}
}
}
private void collectFragmentSpread(FieldCollectorParameters parameters, Set visitedFragments, Map fields, FragmentSpread fragmentSpread) {
if (visitedFragments.contains(fragmentSpread.getName())) {
return;
}
if (!conditionalNodes.shouldInclude(parameters.getVariables(), fragmentSpread.getDirectives())) {
return;
}
visitedFragments.add(fragmentSpread.getName());
FragmentDefinition fragmentDefinition = parameters.getFragmentsByName().get(fragmentSpread.getName());
if (!conditionalNodes.shouldInclude(parameters.getVariables(), fragmentDefinition.getDirectives())) {
return;
}
if (!doesFragmentConditionMatch(parameters, fragmentDefinition)) {
return;
}
collectFields(parameters, fragmentDefinition.getSelectionSet(), visitedFragments, fields);
}
private void collectInlineFragment(FieldCollectorParameters parameters, Set visitedFragments, Map fields, InlineFragment inlineFragment) {
if (!conditionalNodes.shouldInclude(parameters.getVariables(), inlineFragment.getDirectives()) ||
!doesFragmentConditionMatch(parameters, inlineFragment)) {
return;
}
collectFields(parameters, inlineFragment.getSelectionSet(), visitedFragments, fields);
}
private void collectField(FieldCollectorParameters parameters, Map fields, Field field) {
if (!conditionalNodes.shouldInclude(parameters.getVariables(), field.getDirectives())) {
return;
}
String name = field.getResultKey();
if (fields.containsKey(name)) {
MergedField curFields = fields.get(name);
fields.put(name, curFields.transform(builder -> builder.addField(field)));
} else {
fields.put(name, MergedField.newMergedField(field).build());
}
}
private boolean doesFragmentConditionMatch(FieldCollectorParameters parameters, InlineFragment inlineFragment) {
if (inlineFragment.getTypeCondition() == null) {
return true;
}
GraphQLType conditionType;
conditionType = getTypeFromAST(parameters.getGraphQLSchema(), inlineFragment.getTypeCondition());
return checkTypeCondition(parameters, conditionType);
}
private boolean doesFragmentConditionMatch(FieldCollectorParameters parameters, FragmentDefinition fragmentDefinition) {
GraphQLType conditionType;
conditionType = getTypeFromAST(parameters.getGraphQLSchema(), fragmentDefinition.getTypeCondition());
return checkTypeCondition(parameters, conditionType);
}
private boolean checkTypeCondition(FieldCollectorParameters parameters, GraphQLType conditionType) {
GraphQLObjectType type = parameters.getObjectType();
if (conditionType.equals(type)) {
return true;
}
if (conditionType instanceof GraphQLInterfaceType) {
List implementations = parameters.getGraphQLSchema().getImplementations((GraphQLInterfaceType) conditionType);
return implementations.contains(type);
} else if (conditionType instanceof GraphQLUnionType) {
return ((GraphQLUnionType) conditionType).getTypes().contains(type);
}
return false;
}
}