Skip to content
Closed
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
11 changes: 6 additions & 5 deletions src/main/java/graphql/DirectivesUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
@Internal
public class DirectivesUtil {

public static Map<String, GraphQLDirective> directivesByName(List<GraphQLDirective> directiveList) {
return FpKit.getByName(directiveList, GraphQLDirective::getName, FpKit.mergeFirst());
public static Map<String, List<GraphQLDirective>> directivesByName(List<GraphQLDirective> directiveList) {
return FpKit.groupingBy(directiveList, gd -> gd.getName());
}

public static Optional<GraphQLArgument> directiveWithArg(List<GraphQLDirective> directiveList, String directiveName, String argumentName) {
GraphQLDirective directive = directivesByName(directiveList).get(directiveName);
GraphQLDirective graphQLDirective = FpKit.findOneOrNull(directiveList, d -> d.getName().equals(directiveName));

GraphQLArgument argument = null;
if (directive != null) {
argument = directive.getArgument(argumentName);
if (graphQLDirective != null) {
argument = graphQLDirective.getArgument(argumentName);
}
return Optional.ofNullable(argument);
}
Expand Down
12 changes: 3 additions & 9 deletions src/main/java/graphql/execution/ConditionalNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import graphql.Internal;
import graphql.VisibleForTesting;
import graphql.language.Directive;
import graphql.util.FpKit;

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

import static graphql.Directives.IncludeDirective;
import static graphql.Directives.SkipDirective;
import static graphql.language.NodeUtil.directivesByName;


@Internal
Expand All @@ -25,15 +25,9 @@ public boolean shouldInclude(Map<String, Object> variables, List<Directive> dire
return !skip && include;
}

private Directive getDirectiveByName(List<Directive> directives, String name) {
if (directives.isEmpty()) {
return null;
}
return directivesByName(directives).get(name);
}

private boolean getDirectiveResult(Map<String, Object> variables, List<Directive> directives, String directiveName, boolean defaultValue) {
Directive directive = getDirectiveByName(directives, directiveName);
Directive directive = FpKit.findOneOrNull(directives, d -> d.getName().equals(directiveName));

if (directive != null) {
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(SkipDirective.getArguments(), directive.getArguments(), variables);
return (Boolean) argumentValues.get("if");
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/graphql/execution/defer/DeferSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import graphql.execution.reactive.SingleSubscriberPublisher;
import graphql.language.Directive;
import graphql.language.Field;
import graphql.util.FpKit;
import org.reactivestreams.Publisher;

import java.util.Deque;
Expand All @@ -34,7 +35,12 @@ public class DeferSupport {

public boolean checkForDeferDirective(MergedField currentField, Map<String,Object> variables) {
for (Field field : currentField.getFields()) {
Directive directive = field.getDirective(DeferDirective.getName());
List<Directive> directives = field.getDirectives();
if (directives == null || directives.isEmpty()) {
return false;
}

Directive directive = FpKit.findOneOrNull(directives, d -> d.getName().equals(DeferDirective.getName()));
if (directive != null) {
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(DeferDirective.getArguments(), directive.getArguments(), variables);
return (Boolean) argumentValues.get("if");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/graphql/introspection/Introspection.java
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ public enum DirectiveLocation {
@SuppressWarnings("deprecation") // because graphql spec still has the deprecated fields
public static final GraphQLObjectType __Directive = newObject()
.name("__Directive")
.description("The __Directive type represents a Directive that a server supports.")
.field(newFieldDefinition()
.name("name")
.type(nonNull(GraphQLString)))
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/graphql/language/DirectivesContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ public interface DirectivesContainer<T extends DirectivesContainer> extends Node
List<Directive> getDirectives();

/**
* @return a a map of directives by directive name
* @return a map of directives by directive name
*/
default Map<String, Directive> getDirectivesByName() {
default Map<String, List<Directive>> getDirectivesByName() {
return directivesByName(getDirectives());
}

/**
* Returns a directive with the provided name
* Returns a directive list with the provided name
*
* @param directiveName the name of the directive to retrieve
*
* @return the directive or null if there is one one with that name
* @return the directive list or null if there is one one with that name
*/
default Directive getDirective(String directiveName) {
default List<Directive> getDirective(String directiveName) {
return getDirectivesByName().get(directiveName);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for backwards compatibility I think we should add a getFirstDirective(String name) method. This would get the 0th entry of null if empty

While multiple directives are allowed, I posit that a lot of people will use one mostly.

We also have a choice here - we could make Directive getDirective(String directiveName) be the "get first" and then add a getDirectives(String name) say.

@andimarek - thoughts?

}
4 changes: 2 additions & 2 deletions src/main/java/graphql/language/InlineFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ public List<Directive> getDirectives() {
return new ArrayList<>(directives);
}

public Map<String, Directive> getDirectivesByName() {
public Map<String, List<Directive>> getDirectivesByName() {
return directivesByName(directives);
}

public Directive getDirective(String directiveName) {
public List<Directive> getDirective(String directiveName) {
return getDirectivesByName().get(directiveName);
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/graphql/language/NodeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public static boolean isEqualTo(String thisStr, String thatStr) {
}


public static Map<String, Directive> directivesByName(List<Directive> directives) {
return FpKit.getByName(directives, Directive::getName, mergeFirst());
public static Map<String, List<Directive>> directivesByName(List<Directive> directives) {
return FpKit.groupingBy(directives, Directive::getName);
}

public static Map<String, Argument> argumentsByName(List<Argument> arguments) {
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/graphql/language/SchemaDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import static graphql.language.NodeUtil.directivesByName;

@PublicApi
public class SchemaDefinition extends AbstractNode<SchemaDefinition> implements SDLDefinition<SchemaDefinition> {
public class SchemaDefinition extends AbstractNode<SchemaDefinition> implements DirectivesContainer<SchemaDefinition>, SDLDefinition<SchemaDefinition> {

private final List<Directive> directives;
private final List<OperationTypeDefinition> operationTypeDefinitions;
Expand All @@ -37,15 +37,18 @@ protected SchemaDefinition(List<Directive> directives,
this.operationTypeDefinitions = operationTypeDefinitions;
}

@Override
public List<Directive> getDirectives() {
return new ArrayList<>(directives);
}

public Map<String, Directive> getDirectivesByName() {
@Override
public Map<String, List<Directive>> getDirectivesByName() {
return directivesByName(directives);
}

public Directive getDirective(String directiveName) {
@Override
public List<Directive> getDirective(String directiveName) {
return getDirectivesByName().get(directiveName);
}

Expand Down
21 changes: 19 additions & 2 deletions src/main/java/graphql/schema/GraphQLDirective.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class GraphQLDirective implements GraphQLNamedSchemaElement {

private final String name;
private final String description;
private final boolean isRepeatable;
private final EnumSet<DirectiveLocation> locations;
private final List<GraphQLArgument> arguments = new ArrayList<>();
private final DirectiveDefinition definition;
Expand All @@ -44,20 +45,23 @@ public class GraphQLDirective implements GraphQLNamedSchemaElement {
@Deprecated
public GraphQLDirective(String name,
String description,
boolean isRepeatable,
EnumSet<DirectiveLocation> locations,
List<GraphQLArgument> arguments) {
this(name, description, locations, arguments, null);
this(name, description, isRepeatable, locations, arguments, null);
}

private GraphQLDirective(String name,
String description,
boolean isRepeatable,
EnumSet<DirectiveLocation> locations,
List<GraphQLArgument> arguments,
DirectiveDefinition definition) {
assertValidName(name);
assertNotNull(arguments, () -> "arguments can't be null");
this.name = name;
this.description = description;
this.isRepeatable = isRepeatable;
this.locations = locations;
this.arguments.addAll(arguments);
this.definition = definition;
Expand Down Expand Up @@ -89,6 +93,10 @@ public String getDescription() {
return description;
}

public boolean isRepeatable() {
return isRepeatable;
}

public DirectiveDefinition getDefinition() {
return definition;
}
Expand All @@ -97,6 +105,7 @@ public DirectiveDefinition getDefinition() {
public String toString() {
return "GraphQLDirective{" +
"name='" + name + '\'' +
", isRepeatable=" + isRepeatable +
", arguments=" + arguments +
", locations=" + locations +
'}';
Expand Down Expand Up @@ -150,6 +159,7 @@ public static Builder newDirective(GraphQLDirective existing) {

public static class Builder extends GraphqlTypeBuilder {

private boolean isRepeatable;
private EnumSet<DirectiveLocation> locations = EnumSet.noneOf(DirectiveLocation.class);
private final Map<String, GraphQLArgument> arguments = new LinkedHashMap<>();
private DirectiveDefinition definition;
Expand All @@ -161,6 +171,7 @@ public Builder() {
public Builder(GraphQLDirective existing) {
this.name = existing.getName();
this.description = existing.getDescription();
this.isRepeatable = existing.isRepeatable();
this.locations = existing.validLocations();
this.arguments.putAll(getByName(existing.getArguments(), GraphQLArgument::getName));
}
Expand All @@ -183,6 +194,11 @@ public Builder comparatorRegistry(GraphqlTypeComparatorRegistry comparatorRegist
return this;
}

public Builder isRepeatable(boolean isRepeatable) {
this.isRepeatable = isRepeatable;
return this;
}

public Builder validLocations(DirectiveLocation... validLocations) {
Collections.addAll(locations, validLocations);
return this;
Expand Down Expand Up @@ -264,11 +280,12 @@ public GraphQLDirective build() {
return new GraphQLDirective(
name,
description,
isRepeatable,
locations,
sort(arguments, GraphQLDirective.class, GraphQLArgument.class),
definition);
}


}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Represents a graphql object that can have {@link graphql.schema.GraphQLDirective}s
*/
public interface GraphQLDirectiveContainer extends GraphQLNamedSchemaElement {
public interface GraphQLDirectivesContainer extends GraphQLNamedSchemaElement {

/**
* @return a list of directives associated with the type or field
Expand All @@ -19,7 +19,7 @@ public interface GraphQLDirectiveContainer extends GraphQLNamedSchemaElement {
/**
* @return a a map of directives by directive name
*/
default Map<String, GraphQLDirective> getDirectivesByName() {
default Map<String, List<GraphQLDirective>> getDirectivesByName() {
return directivesByName(getDirectives());
}

Expand All @@ -30,7 +30,7 @@ default Map<String, GraphQLDirective> getDirectivesByName() {
*
* @return the directive or null if there is one one with that name
*/
default GraphQLDirective getDirective(String directiveName) {
default List<GraphQLDirective> getDirective(String directiveName) {
return getDirectivesByName().get(directiveName);
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/graphql/schema/GraphQLEnumType.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* See http://graphql.org/learn/schema/#enumeration-types for more details
*/
@PublicApi
public class GraphQLEnumType implements GraphQLNamedInputType, GraphQLNamedOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer {
public class GraphQLEnumType implements GraphQLNamedInputType, GraphQLNamedOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectivesContainer {

private final String name;
private final String description;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/graphql/schema/GraphQLEnumValueDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* @see graphql.schema.GraphQLEnumType
*/
@PublicApi
public class GraphQLEnumValueDefinition implements GraphQLNamedSchemaElement, GraphQLDirectiveContainer {
public class GraphQLEnumValueDefinition implements GraphQLNamedSchemaElement, GraphQLDirectivesContainer {

private final String name;
private final String description;
Expand Down Expand Up @@ -120,12 +120,12 @@ public List<GraphQLDirective> getDirectives() {
}

@Override
public Map<String, GraphQLDirective> getDirectivesByName() {
public Map<String, List<GraphQLDirective>> getDirectivesByName() {
return DirectivesUtil.directivesByName(directives);
}

@Override
public GraphQLDirective getDirective(String directiveName) {
public List<GraphQLDirective> getDirective(String directiveName) {
return getDirectivesByName().get(directiveName);
}

Expand Down
12 changes: 5 additions & 7 deletions src/main/java/graphql/schema/GraphQLFieldDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* See http://graphql.org/learn/queries/#fields for more details on the concept.
*/
@PublicApi
public class GraphQLFieldDefinition implements GraphQLNamedSchemaElement, GraphQLDirectiveContainer {
public class GraphQLFieldDefinition implements GraphQLNamedSchemaElement, GraphQLDirectivesContainer {

private final String name;
private final String description;
Expand Down Expand Up @@ -225,7 +225,7 @@ public static class Builder extends GraphqlTypeBuilder {
private String deprecationReason;
private FieldDefinition definition;
private final Map<String, GraphQLArgument> arguments = new LinkedHashMap<>();
private final Map<String, GraphQLDirective> directives = new LinkedHashMap<>();
private final List<GraphQLDirective> directives = new ArrayList<>();

public Builder() {
}
Expand All @@ -239,7 +239,7 @@ public Builder(GraphQLFieldDefinition existing) {
this.deprecationReason = existing.getDeprecationReason();
this.definition = existing.getDefinition();
this.arguments.putAll(getByName(existing.getArguments(), GraphQLArgument::getName));
this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName));
this.directives.addAll(existing.getDirectives());
}


Expand Down Expand Up @@ -432,16 +432,14 @@ public Builder withDirectives(GraphQLDirective... directives) {

public Builder withDirective(GraphQLDirective directive) {
assertNotNull(directive, () -> "directive can't be null");
directives.put(directive.getName(), directive);
directives.add(directive);
return this;
}

public Builder replaceDirectives(List<GraphQLDirective> directives) {
assertNotNull(directives, () -> "directive can't be null");
this.directives.clear();
for (GraphQLDirective directive : directives) {
this.directives.put(directive.getName(), directive);
}
this.directives.addAll(directives);
return this;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/graphql/schema/GraphQLInputObjectType.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* See http://graphql.org/learn/schema/#input-types for more details on the concept
*/
@PublicApi
public class GraphQLInputObjectType implements GraphQLNamedInputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLInputFieldsContainer, GraphQLDirectiveContainer {
public class GraphQLInputObjectType implements GraphQLNamedInputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLInputFieldsContainer, GraphQLDirectivesContainer {

private final String name;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @see graphql.schema.GraphQLArgument
*/
@PublicApi
public interface GraphQLInputValueDefinition extends GraphQLDirectiveContainer {
public interface GraphQLInputValueDefinition extends GraphQLDirectivesContainer {

<T extends GraphQLInputType> T getType();
}
2 changes: 1 addition & 1 deletion src/main/java/graphql/schema/GraphQLInterfaceType.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* See http://graphql.org/learn/schema/#interfaces for more details on the concept.
*/
@PublicApi
public class GraphQLInterfaceType implements GraphQLNamedType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer {
public class GraphQLInterfaceType implements GraphQLNamedType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectivesContainer {

private final String name;
private final String description;
Expand Down
Loading