Skip to content

Commit f40354e

Browse files
committed
This adds runtime directives to the graphql types. We have started with ObjectType and FieldDefinition and will extend it to other types as we go
1 parent e6b4d5d commit f40354e

9 files changed

Lines changed: 292 additions & 26 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package graphql;
2+
3+
import graphql.schema.GraphQLDirective;
4+
import graphql.util.FpKit;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
@Internal
10+
public class DirectivesUtil {
11+
12+
public static Map<String, GraphQLDirective> directivesByName(List<GraphQLDirective> directiveList) {
13+
return FpKit.getByName(directiveList, GraphQLDirective::getName, FpKit.mergeFirst());
14+
}
15+
}

src/main/java/graphql/language/NodeUtil.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
import graphql.GraphQLException;
44
import graphql.Internal;
5+
import graphql.util.FpKit;
56

67
import java.util.LinkedHashMap;
78
import java.util.List;
89
import java.util.Map;
9-
import java.util.function.BinaryOperator;
10-
import java.util.function.Function;
11-
import java.util.stream.Collectors;
1210

13-
import static java.util.function.Function.identity;
11+
import static graphql.util.FpKit.mergeFirst;
1412

1513
/**
1614
* Helper class for working with {@link Node}s
@@ -31,23 +29,11 @@ public static boolean isEqualTo(String thisStr, String thatStr) {
3129

3230

3331
public static Map<String, Directive> directivesByName(List<Directive> directives) {
34-
return getByName(directives, Directive::getName);
32+
return FpKit.getByName(directives, Directive::getName, mergeFirst());
3533
}
3634

3735
public static Map<String, Argument> argumentsByName(List<Argument> arguments) {
38-
return getByName(arguments, Argument::getName);
39-
}
40-
41-
private static <T> Map<String, T> getByName(List<T> namedObjects, Function<T, String> nameFn) {
42-
return namedObjects.stream().collect(Collectors.toMap(
43-
nameFn,
44-
identity(),
45-
mergeFirst())
46-
);
47-
}
48-
49-
private static <T> BinaryOperator<T> mergeFirst() {
50-
return (o1, o2) -> o1;
36+
return FpKit.getByName(arguments, Argument::getName, mergeFirst());
5137
}
5238

5339

src/main/java/graphql/schema/GraphQLDirective.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import static graphql.introspection.Introspection.DirectiveLocation;
1515

1616
/**
17-
* A directive can be used to modify the behavior of a graphql field.
17+
* A directive can be used to modify the behavior of a graphql field or type.
1818
*
1919
* See http://graphql.org/learn/queries/#directives for more details on the concept.
2020
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package graphql.schema;
2+
3+
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
/**
8+
* Represents a type that can have {@link graphql.schema.GraphQLDirective}s
9+
*/
10+
public interface GraphQLDirectiveContainer extends GraphQLType {
11+
12+
/**
13+
* @return a list of directives associated with the type
14+
*/
15+
List<GraphQLDirective> getDirectives();
16+
17+
/**
18+
* @return a a map of directives by directive name
19+
*/
20+
Map<String, GraphQLDirective> getDirectivesByName();
21+
22+
/**
23+
* Returns a named directive
24+
*
25+
* @param directiveName the name of the directive to retrive
26+
*
27+
* @return the directive or null if there is one one with that name
28+
*/
29+
default GraphQLDirective getDirective(String directiveName) {
30+
return getDirectivesByName().get(directiveName);
31+
}
32+
33+
}

src/main/java/graphql/schema/GraphQLFieldDefinition.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package graphql.schema;
22

33

4+
import graphql.DirectivesUtil;
45
import graphql.Internal;
56
import graphql.PublicApi;
67
import graphql.language.FieldDefinition;
@@ -34,17 +35,19 @@ public class GraphQLFieldDefinition {
3435
private final DataFetcherFactory dataFetcherFactory;
3536
private final String deprecationReason;
3637
private final List<GraphQLArgument> arguments;
38+
private final List<GraphQLDirective> directives;
3739
private final FieldDefinition definition;
3840

3941

4042
@Deprecated
4143
@Internal
4244
public GraphQLFieldDefinition(String name, String description, GraphQLOutputType type, DataFetcher<?> dataFetcher, List<GraphQLArgument> arguments, String deprecationReason) {
43-
this(name, description, type, DataFetcherFactories.useDataFetcher(dataFetcher), arguments, deprecationReason, null);
45+
this(name, description, type, DataFetcherFactories.useDataFetcher(dataFetcher), arguments, deprecationReason, Collections.emptyList(), null);
4446
}
4547

4648
@Internal
47-
public GraphQLFieldDefinition(String name, String description, GraphQLOutputType type, DataFetcherFactory dataFetcherFactory, List<GraphQLArgument> arguments, String deprecationReason, FieldDefinition definition) {
49+
public GraphQLFieldDefinition(String name, String description, GraphQLOutputType type, DataFetcherFactory dataFetcherFactory, List<GraphQLArgument> arguments, String deprecationReason, List<GraphQLDirective> directives, FieldDefinition definition) {
50+
this.directives = directives;
4851
assertValidName(name);
4952
assertNotNull(dataFetcherFactory, "you have to provide a DataFetcher (or DataFetcherFactory)");
5053
assertNotNull(type, "type can't be null");
@@ -85,6 +88,18 @@ public GraphQLArgument getArgument(String name) {
8588
return null;
8689
}
8790

91+
public List<GraphQLDirective> getDirectives() {
92+
return Collections.unmodifiableList(directives);
93+
}
94+
95+
public Map<String, GraphQLDirective> getDirectivesByName() {
96+
return DirectivesUtil.directivesByName(directives);
97+
}
98+
99+
public GraphQLDirective getDirective(String directiveName) {
100+
return getDirectivesByName().get(directiveName);
101+
}
102+
88103
public List<GraphQLArgument> getArguments() {
89104
return arguments;
90105
}
@@ -130,6 +145,7 @@ public static class Builder {
130145
private GraphQLOutputType type;
131146
private DataFetcherFactory<?> dataFetcherFactory;
132147
private final List<GraphQLArgument> arguments = new ArrayList<>();
148+
private final List<GraphQLDirective> directives = new ArrayList<>();
133149
private String deprecationReason;
134150
private boolean isField;
135151
private FieldDefinition definition;
@@ -262,6 +278,11 @@ public Builder deprecate(String deprecationReason) {
262278
return this;
263279
}
264280

281+
public Builder withDirectives(GraphQLDirective... directives) {
282+
Collections.addAll(this.directives, directives);
283+
return this;
284+
}
285+
265286
public GraphQLFieldDefinition build() {
266287
if (dataFetcherFactory == null) {
267288
if (isField) {
@@ -270,7 +291,7 @@ public GraphQLFieldDefinition build() {
270291
dataFetcherFactory = DataFetcherFactories.useDataFetcher(new PropertyDataFetcher<>(name));
271292
}
272293
}
273-
return new GraphQLFieldDefinition(name, description, type, dataFetcherFactory, arguments, deprecationReason, definition);
294+
return new GraphQLFieldDefinition(name, description, type, dataFetcherFactory, arguments, deprecationReason, directives, definition);
274295
}
275296
}
276297
}

src/main/java/graphql/schema/GraphQLObjectType.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package graphql.schema;
22

33
import graphql.AssertException;
4+
import graphql.DirectivesUtil;
45
import graphql.Internal;
56
import graphql.PublicApi;
67
import graphql.language.ObjectTypeDefinition;
78

89
import java.util.ArrayList;
10+
import java.util.Collections;
911
import java.util.LinkedHashMap;
1012
import java.util.List;
1113
import java.util.Map;
@@ -15,6 +17,7 @@
1517
import static graphql.Assert.assertNotNull;
1618
import static graphql.Assert.assertValidName;
1719
import static java.lang.String.format;
20+
import static java.util.Collections.emptyList;
1821

1922
/**
2023
* This is the work horse type and represents an object with one or more field values that can be retrieved
@@ -26,31 +29,33 @@
2629
* See http://graphql.org/learn/schema/#object-types-and-fields for more details on the concept.
2730
*/
2831
@PublicApi
29-
public class GraphQLObjectType implements GraphQLType, GraphQLOutputType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType {
32+
public class GraphQLObjectType implements GraphQLType, GraphQLOutputType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer {
3033

3134

3235
private final String name;
3336
private final String description;
3437
private final Map<String, GraphQLFieldDefinition> fieldDefinitionsByName = new LinkedHashMap<>();
3538
private List<GraphQLOutputType> interfaces = new ArrayList<>();
39+
private final List<GraphQLDirective> directives;
3640
private final ObjectTypeDefinition definition;
3741

3842
@Internal
3943
public GraphQLObjectType(String name, String description, List<GraphQLFieldDefinition> fieldDefinitions,
4044
List<GraphQLOutputType> interfaces) {
41-
this(name, description, fieldDefinitions, interfaces, null);
45+
this(name, description, fieldDefinitions, interfaces, emptyList(), null);
4246
}
4347

4448
@Internal
4549
public GraphQLObjectType(String name, String description, List<GraphQLFieldDefinition> fieldDefinitions,
46-
List<GraphQLOutputType> interfaces, ObjectTypeDefinition definition) {
50+
List<GraphQLOutputType> interfaces, List<GraphQLDirective> directives, ObjectTypeDefinition definition) {
4751
assertValidName(name);
4852
assertNotNull(fieldDefinitions, "fieldDefinitions can't be null");
4953
assertNotNull(interfaces, "interfaces can't be null");
5054
this.name = name;
5155
this.description = description;
5256
this.interfaces = interfaces;
5357
this.definition = definition;
58+
this.directives = assertNotNull(directives);
5459
buildDefinitionMap(fieldDefinitions);
5560
}
5661

@@ -69,6 +74,16 @@ private void buildDefinitionMap(List<GraphQLFieldDefinition> fieldDefinitions) {
6974
}
7075
}
7176

77+
@Override
78+
public List<GraphQLDirective> getDirectives() {
79+
return Collections.unmodifiableList(directives);
80+
}
81+
82+
@Override
83+
public Map<String, GraphQLDirective> getDirectivesByName() {
84+
return DirectivesUtil.directivesByName(directives);
85+
}
86+
7287
public GraphQLFieldDefinition getFieldDefinition(String name) {
7388
return fieldDefinitionsByName.get(name);
7489
}
@@ -121,6 +136,7 @@ public static class Builder {
121136
private String description;
122137
private final List<GraphQLFieldDefinition> fieldDefinitions = new ArrayList<>();
123138
private final List<GraphQLOutputType> interfaces = new ArrayList<>();
139+
private final List<GraphQLDirective> directives = new ArrayList<>();
124140
private ObjectTypeDefinition definition;
125141

126142
public Builder name(String name) {
@@ -209,8 +225,13 @@ public Builder withInterfaces(GraphQLTypeReference... references) {
209225
return this;
210226
}
211227

228+
public Builder withDirectives(GraphQLDirective... directives) {
229+
Collections.addAll(this.directives, directives);
230+
return this;
231+
}
232+
212233
public GraphQLObjectType build() {
213-
return new GraphQLObjectType(name, description, fieldDefinitions, interfaces, definition);
234+
return new GraphQLObjectType(name, description, fieldDefinitions, interfaces, directives, definition);
214235
}
215236

216237
}

0 commit comments

Comments
 (0)