Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 64 additions & 10 deletions src/main/java/graphql/execution/conditional/ConditionalNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
import graphql.GraphQLContext;
import graphql.Internal;
import graphql.execution.CoercedVariables;
import graphql.execution.ValuesResolver;
import graphql.language.Argument;
import graphql.language.BooleanValue;
import graphql.language.Directive;
import graphql.language.DirectivesContainer;
import graphql.language.NodeUtil;
import graphql.language.VariableReference;
import graphql.schema.GraphQLSchema;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import static graphql.Directives.IncludeDirective;
Expand All @@ -20,11 +22,17 @@
@Internal
public class ConditionalNodes {

/**
* return null if skip/include argument contains a variable and therefore could not be resolved
*/
public Boolean shouldIncludeWithoutVariables(DirectivesContainer<?> element) {
return shouldInclude(null, element.getDirectives());
}

public boolean shouldInclude(DirectivesContainer<?> element,
Map<String, Object> variables,
GraphQLSchema graphQLSchema,
GraphQLContext graphQLContext
@Nullable GraphQLContext graphQLContext
) {
//
// call the base @include / @skip first
Expand Down Expand Up @@ -75,28 +83,74 @@ public GraphQLContext getGraphQLContext() {
}


private boolean shouldInclude(Map<String, Object> variables, List<Directive> directives) {
private @Nullable Boolean shouldInclude(Map<String, Object> variables, List<Directive> directives) {
// shortcut on no directives
if (directives.isEmpty()) {
return true;
}
boolean skip = getDirectiveResult(variables, directives, SkipDirective.getName(), false);
Boolean skip = getDirectiveResult(variables, directives, SkipDirective.getName(), false);
if (skip == null) {
return null;
}
if (skip) {
return false;
}

return getDirectiveResult(variables, directives, IncludeDirective.getName(), true);
}

private boolean getDirectiveResult(Map<String, Object> variables, List<Directive> directives, String directiveName, boolean defaultValue) {
public boolean containsSkipOrIncludeDirective(DirectivesContainer<?> directivesContainer) {
return NodeUtil.findNodeByName(directivesContainer.getDirectives(), SkipDirective.getName()) != null ||
NodeUtil.findNodeByName(directivesContainer.getDirectives(), IncludeDirective.getName()) != null;
}


public String getSkipVariableName(DirectivesContainer<?> directivesContainer) {
Directive skipDirective = NodeUtil.findNodeByName(directivesContainer.getDirectives(), SkipDirective.getName());
if (skipDirective == null) {
return null;
}
Argument argument = skipDirective.getArgument("if");
if (argument.getValue() instanceof VariableReference) {
return ((VariableReference) argument.getValue()).getName();
}
return null;
}

public String getIncludeVariableName(DirectivesContainer<?> directivesContainer) {
Directive skipDirective = NodeUtil.findNodeByName(directivesContainer.getDirectives(), IncludeDirective.getName());
if (skipDirective == null) {
return null;
}
Argument argument = skipDirective.getArgument("if");
if (argument.getValue() instanceof VariableReference) {
return ((VariableReference) argument.getValue()).getName();
}
return null;
}


private @Nullable Boolean getDirectiveResult(Map<String, Object> variables, List<Directive> directives, String directiveName, boolean defaultValue) {
Directive foundDirective = NodeUtil.findNodeByName(directives, directiveName);
if (foundDirective != null) {
Map<String, Object> argumentValues = ValuesResolver.getArgumentValues(SkipDirective.getArguments(), foundDirective.getArguments(), CoercedVariables.of(variables), GraphQLContext.getDefault(), Locale.getDefault());
Object flag = argumentValues.get("if");
Assert.assertTrue(flag instanceof Boolean, "The '%s' directive MUST have a value for the 'if' argument", directiveName);
return (Boolean) flag;
return getIfValue(foundDirective.getArguments(), variables);
}
return defaultValue;
}

private @Nullable Boolean getIfValue(List<Argument> arguments, @Nullable Map<String, Object> variables) {
for (Argument argument : arguments) {
if (argument.getName().equals("if")) {
Object value = argument.getValue();
if (value instanceof BooleanValue) {
return ((BooleanValue) value).isValue();
}
if (value instanceof VariableReference && variables != null) {
return (boolean) variables.get(((VariableReference) value).getName());
}
return null;
}
}
return Assert.assertShouldNeverHappen("The 'if' argument must be present");
}
}
47 changes: 47 additions & 0 deletions src/main/java/graphql/normalized/nf/NormalizedDocument.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package graphql.normalized.nf;

import graphql.Assert;
import graphql.ExperimentalApi;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Map;

@ExperimentalApi
public class NormalizedDocument {

private final List<NormalizedOperationWithAssumedSkipIncludeVariables> normalizedOperations;

public NormalizedDocument(List<NormalizedOperationWithAssumedSkipIncludeVariables> normalizedOperations) {
this.normalizedOperations = normalizedOperations;
}

public List<NormalizedOperationWithAssumedSkipIncludeVariables> getNormalizedOperations() {
return normalizedOperations;
}

public NormalizedOperation getSingleNormalizedOperation() {
Assert.assertTrue(normalizedOperations.size() == 1, "Expecting a single normalized operation");
return normalizedOperations.get(0).getNormalizedOperation();
}

public static class NormalizedOperationWithAssumedSkipIncludeVariables {

Map<String, Boolean> assumedSkipIncludeVariables;
NormalizedOperation normalizedOperation;

public NormalizedOperationWithAssumedSkipIncludeVariables(@Nullable Map<String, Boolean> assumedSkipIncludeVariables, NormalizedOperation normalizedOperation) {
this.assumedSkipIncludeVariables = assumedSkipIncludeVariables;
this.normalizedOperation = normalizedOperation;
}

public Map<String, Boolean> getAssumedSkipIncludeVariables() {
return assumedSkipIncludeVariables;
}

public NormalizedOperation getNormalizedOperation() {
return normalizedOperation;
}
}
}

Loading
Loading