diff --git a/README.md b/README.md
index 124f1136..5b5255e5 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,33 @@
+
+# GraphQL-Java Annotations
[](https://travis-ci.org/graphql-java/graphql-java-annotations)
[]()
-# GraphQL Annotations for Java
[GraphQL-Java](https://github.com/andimarek/graphql-java) is a great library, but its syntax is a little bit verbose. This library offers an annotations-based
syntax for GraphQL schema definition.
+
+## Table Of Contents
+- [Getting Started](#getting-started)
+- [GraphQLAnnotations class](#graphqlannotations-class)
+- [Annotations Schema Creator](#annotations-schema-creator)
+- [Defining Objects](#defining-objects)
+- [Defining Interfaces](#defining-interfaces)
+- [Defining Unions](#defining-unions)
+- [Fields](#fields)
+ - [Custom DataFetcher](#custom-data-fetcher)
+- [Type Extensions](#type-extensions)
+ - [Defining Extensions in Annotation](#defining-extensions-in-annotations)
+ - [Data Fetching with Extensions](#data-fetching-with-extensions)
+- [Type Inference](#type-inference)
+- [Directives](#directives)
+ - [Creating/Defining a GraphQL Directive](#creatingdefining-a-graphqldirective)
+ - [Wiring with Directives](#wiring-with-directives)
+- [Relay Support](#relay-support)
+ - [Mutations](#mutations)
+ - [Connection](#connection)
+ - [Customizing Relay Schema](#customizing-relay-schema)
+
## Getting Started
@@ -12,7 +35,7 @@ syntax for GraphQL schema definition.
```groovy
dependencies {
- compile "io.github.graphql-java:graphql-java-annotations:6.1"
+ compile "io.github.graphql-java:graphql-java-annotations:7.0"
}
```
@@ -22,10 +45,65 @@ dependencies {
io.github.graphql-javagraphql-java-annotations
- 6.1
+ 7.0
```
+The graphql-java-annotations library is able to create GraphQLType objects out of your Java classes.
+These GraphQLType objects can be later injected into the graphql-java schema.
+
+graphql-java-annotations also allows you to wire your objects with data fetchers and type resolvers while annotating your fields/types. The result of this process will be a ``GraphQLCodeRegistry.Builder`` object that can be later built and injected to the graphql-java schema.
+
+
+## GraphQLAnnotations class
+
+You can create an instance of the `GraphQLAnnotations` class in order to create the GraphQL types.
+```java
+GraphQLAnnotations graphqlAnnotations = new GraphQLAnnotations();
+```
+
+Using this object, you will be able to create the GraphQL types.
+There are few types that can be generated - a `GraphQLObjectType`, a `GraphQLInterfaceType` and a `GraphQLDirective`.
+
+```java
+GraphQLObjectType query = graphqlAnnotations.object(Query.class);
+GraphQLDirective upperDirective = graphqlAnnotations.directive(UpperDirective.class);
+GraphQLInterfaceType myInterface = graphqlAnnotations.generateInterface(MyInterface.class);
+```
+
+Then you can use these types in order to create a graphql-java schema.
+But, in order to create a graphql-java schema, you need also the ``GraphQLCodeRegistry``, which contains all the data fetchers mapped to their fields (and also type resolvers).
+
+You can obtain the code registry this way:
+
+```java
+graphqlAnnotations.getContainer().getCodeRegistryBuilder().build();
+```
+
+## Annotations Schema Creator
+
+Using the `GraphQLAnnotations` processor object can be a little bit confusing if you wish to use it to create a GraphQL schema.
+So we created a util class to help you create your desired GraphQL schema, in a syntax similiar to the graphql-java syntax.
+
+In order to do so you can use the ``AnnotationsSchemaCreator.Builder`` in the following way:
+
+```java
+ GraphQLSchema schema = AnnotationsSchemaCreator.newAnnotationsSchema()
+ .query(Query.class) // to create you query object
+ .mutation(Mutation.class) // to create your mutation object
+ .subscription(Subscription.class) // to create your subscription object
+ .directive(UpperDirective.class) // to create a directive
+ .additionalType(AdditionalType.class) // to create some additional type and add it to the schema
+ .typeFunction(CustomType.class) // to add a typefunction
+ .setAlwaysPrettify(true) // to set the global prettifier of field names (removes get/set/is prefixes from names)
+ .setRelay(customRelay) // to add a custom relay object
+ .build();
+```
+
+Of course you can use this builder with only some of the properties, but the query class must be provided.
+note - The GraphQLSchema is a graphql-java type.
+
+Continue reading in order to understand how your java classes should look in order to be provided to the annotations schema creator.
## Defining Objects
@@ -39,7 +117,8 @@ public class SomeObject {
}
// ...
-GraphQLObjectType object = GraphQLAnnotations.object(SomeObject.class);
+GraphQLAnnotations graphQLAnnotations = new GraphQLAnnotations();
+GraphQLObjectType object = graphQLAnnotations.object(SomeObject.class);
```
## Defining Interfaces
@@ -58,7 +137,8 @@ public class MyTypeResolver implements TypeResolver {
}
// ...
-GraphQLInterfaceType object = GraphQLAnnotations.iface(SomeInterface.class);
+GraphQLAnnotations graphQLAnnotations = new GraphQLAnnotations();
+GraphQLInterfaceType object = graphQLAnnotations.generateInterface(SomeInterface.class);
```
An instance of the type resolver will be created from the specified class. If a `getInstance` method is present on the
@@ -262,13 +342,11 @@ public class HumanExtension {
Classes marked as "extensions" will actually not define a new type, but rather set new fields on the class it extends when it will be created.
All GraphQL annotations can be used on extension classes.
-Extensions are registered in GraphQLAnnotationProcessor by using `registerTypeExtension`. Note that extensions must be registered before the type itself is requested with `getObject()` :
+Extensions are registered in GraphQLAnnotations object by using `registerTypeExtension`. Note that extensions must be registered before the type itself is requested with `getObject()` :
```
-GraphQLAnnotationsProcessor processor = GraphQLAnnotations.getInstance();
-
// Register extensions
-processor.registerTypeExtension(HumanExtension.class);
+graphqlAnnotations.registerTypeExtension(HumanExtension.class);
// Create type
GraphQLObjectType type = processor.getObject(Human.class);
@@ -314,7 +392,7 @@ public class UUIDTypeFunction implements TypeFunction {
And register it with `GraphQLAnnotations`:
```java
-GraphQLAnnotations.register(new UUIDTypeFunction())
+graphqlAnnotations.registerType(new UUIDTypeFunction())
// or if not using a static version of GraphQLAnnotations:
// new GraphQLAnnotations().registerType(new UUIDTypeFunction())
@@ -348,7 +426,7 @@ You can also use ``@GraphQLName`` and ``@GraphQLDescription`` annotations on the
After you created the class, you will be able to create the ``GraphQLDirective`` object using the following code:
```java
-GraphQLAnnotations.directive(UpperDirective.class);
+graphqlAnnotations.directive(UpperDirective.class);
```
### Wiring with directives
@@ -361,16 +439,19 @@ public class UpperWiring implements AnnotationsDirectiveWiring {
public GraphQLFieldDefinition onField(AnnotationsWiringEnvironment environment) {
GraphQLFieldDefinition field = (GraphQLFieldDefinition) environment.getElement();
boolean isActive = (boolean) environment.getDirective().getArgument("isActive").getValue();
- DataFetcher dataFetcher = DataFetcherFactories.wrapDataFetcher(field.getDataFetcher(), (((dataFetchingEnvironment, value) -> {
+ CodeRegistryUtil.wrapDataFetcher(field, environment, (((dataFetchingEnvironment, value) -> {
if (value instanceof String && isActive) {
return ((String) value).toUpperCase();
}
- return value;
- })));
- return field.transform(builder -> builder.dataFetcher(dataFetcher));
+ return value;
+ })));
+ return field;
}
}
```
+
+You can also use the `field.transform` method in order to change some of the field's properties.
+
This class turns your string field to upper case if the directive argument "isActive" is set to true.
Now, you have to wire the field itself:
```java
@@ -410,7 +491,7 @@ NOTE: because `PropertyDataFetcher` and `FieldDataFetcher` can't handle connecti
### Customizing Relay schema
By default, GraphQLAnnotations will use the `graphql.relay.Relay` class to create the Relay specific schema types (Mutations, Connections, Edges, PageInfo, ...).
-It is possible to set a custom implementation of the Relay class with `GraphQLAnnotations.setRelay` method. The class should inherit from `graphql.relay.Relay` and
+It is possible to set a custom implementation of the Relay class with `graphqlAnnotations.setRelay` method. The class should inherit from `graphql.relay.Relay` and
can redefine methods that create Relay types.
It is also possible to specify for every connection which relay do you want to use, by giving a value to the annotation:
diff --git a/build.gradle b/build.gradle
index 9f47c788..0945d8ba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,12 +37,6 @@ task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
}
-idea {
- project {
- languageLevel = '1.8'
- vcs = 'Git'
- }
-}
release {
tagTemplate = 'v${version}'
failOnPublishNeeded = false
@@ -69,7 +63,7 @@ gradle.projectsEvaluated {
dependencies {
compile 'javax.validation:validation-api:1.1.0.Final'
- compile 'com.graphql-java:graphql-java:11.0'
+ compile 'com.graphql-java:graphql-java:12.0'
// OSGi
compileOnly 'org.osgi:org.osgi.core:6.0.0'
@@ -169,8 +163,11 @@ bintray {
version {
name = project.version
released = new Date()
+ gpg {
+ sign = false
+ }
mavenCentralSync {
- sync = true //[Default: true] Determines whether to sync the version to Maven Central.
+ sync = true //[Default: true] Determines whether to sync the version to Maven Central..
user = System.getenv('OSS_USER') ?: project.findProperty('OSS_USER') ?: ''
password = System.getenv('OSS_PASS') ?: project.findProperty('OSS_PASS') ?: ''
close = '1'
diff --git a/gradle.properties b/gradle.properties
index 169db324..6b5f42ac 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,4 +5,4 @@ org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.jvmargs=-Dfile.encoding=UTF-8
-version = 6.2
+version = 7.0
diff --git a/polaris-iconsmalredl.png b/polaris-iconsmalredl.png
new file mode 100644
index 00000000..a17b9f19
Binary files /dev/null and b/polaris-iconsmalredl.png differ
diff --git a/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java b/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java
new file mode 100644
index 00000000..a55c3a45
--- /dev/null
+++ b/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java
@@ -0,0 +1,245 @@
+/**
+ * Copyright 2016 Yurii Rashkovskii
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ */
+package graphql.annotations;
+
+import graphql.annotations.processor.GraphQLAnnotations;
+import graphql.annotations.processor.typeFunctions.TypeFunction;
+import graphql.relay.Relay;
+import graphql.schema.GraphQLDirective;
+import graphql.schema.GraphQLSchema;
+import graphql.schema.GraphQLType;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class AnnotationsSchemaCreator {
+
+ public static Builder newAnnotationsSchema() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private Class> queryObject;
+ private Class> mutationObject;
+ private Class> subscriptionObject;
+ private Set> directivesObjectList = new HashSet<>();
+ private Set> additionalTypesList = new HashSet<>();
+ private Set> typeExtensions = new HashSet<>();
+ private Set typeFunctions = new HashSet<>();
+ private Boolean shouldAlwaysPrettify = null;
+ private GraphQLAnnotations graphQLAnnotations;
+ private GraphQLSchema.Builder graphqlSchemaBuilder;
+
+ /**
+ * You can set your own schema builder, but its optional
+ *
+ * @param schemaBuilder a graphql schema builder
+ * @return the builder after setting the schema builder
+ */
+ public Builder setGraphQLSchemaBuilder(GraphQLSchema.Builder schemaBuilder) {
+ this.graphqlSchemaBuilder = schemaBuilder;
+ return this;
+ }
+
+ /**
+ * You can set your own annotations processor
+ *
+ * @param annotationsProcessor the annotations processor which creates the GraphQLTypes
+ * @return the builder after setting the annotations processor
+ */
+ public Builder setAnnotationsProcessor(GraphQLAnnotations annotationsProcessor) {
+ this.graphQLAnnotations = annotationsProcessor;
+ return this;
+ }
+
+ /**
+ * Set the Query of the graphql schema
+ * This method will generate a GraphQL Query type out of your java class using the annotations processor
+ *
+ * @param queryClass the Query java class
+ * @return the builder after setting the query
+ */
+ public Builder query(Class> queryClass) {
+ this.queryObject = queryClass;
+ return this;
+ }
+
+ /**
+ * Set the Mutation of the graphql schema
+ * This method will generate a GraphQL Mutation type out of your java class using the annotations processor
+ *
+ * @param mutationClass the Mutation java class
+ * @return the builder after setting the mutation
+ */
+ public Builder mutation(Class> mutationClass) {
+ this.mutationObject = mutationClass;
+ return this;
+ }
+
+ /**
+ * Set the Subscription of the graphql schema
+ * This method will generate a GraphQL Subscription type out of your java class using the annotations processor
+ *
+ * @param subscriptionClass the Subscription java class
+ * @return the builder after setting the subscription
+ */
+ public Builder subscription(Class> subscriptionClass) {
+ this.subscriptionObject = subscriptionClass;
+ return this;
+ }
+
+ /**
+ * Set the directives of the graphql schema
+ * This method will generate a GraphQL Directive type out of your java classes using the annotations processor
+ *
+ * @param directiveClasses a set of directive classes
+ * @return the builder after setting the directives
+ */
+ public Builder directives(Set> directiveClasses) {
+ this.directivesObjectList.addAll(directiveClasses);
+ return this;
+ }
+
+ /**
+ * Add a directive to the graphql schema
+ * This method will generate a GraphQL Directive type out of your java class using the annotations processor
+ *
+ * @param directiveClass a Directive java class
+ * @return the builder after adding the directive
+ */
+ public Builder directive(Class> directiveClass) {
+ this.directivesObjectList.add(directiveClass);
+ return this;
+ }
+
+ /**
+ * Add an additional type to the additional type list
+ *
+ * @param additionalTypeClass an additional type class
+ * @return the builder after adding an additional type
+ */
+ public Builder additionalType(Class> additionalTypeClass) {
+ this.additionalTypesList.add(additionalTypeClass);
+ return this;
+ }
+
+ /**
+ * Add a set of additional types to the additional type lise
+ *
+ * @param additionalTypes a set of additional type classes
+ * @return the builder after adding the additional types
+ */
+ public Builder additionalTypes(Set> additionalTypes) {
+ this.additionalTypesList.addAll(additionalTypes);
+ return this;
+ }
+
+ /**
+ * Register a type extensions to the graphql processor
+ *
+ * @param typeExtension a type extension class
+ * @return the builder after registering the type extension in the graphql processor
+ */
+ public Builder typeExtension(Class> typeExtension) {
+ this.typeExtensions.add(typeExtension);
+ return this;
+ }
+
+ /**
+ * Register a type function to the graphql processor
+ *
+ * @param typeFunction a type function
+ * @return the builder after registering the type function in the graphql processor
+ */
+ public Builder typeFunction(TypeFunction typeFunction) {
+ this.typeFunctions.add(typeFunction);
+ return this;
+ }
+
+ /**
+ * Set the always prettify property of the graphql annotations processor (whether or not to prettify the graphql names)
+ *
+ * @param shouldAlwaysPrettify a boolean flag
+ * @return the builder after setting the property
+ */
+ public Builder setAlwaysPrettify(Boolean shouldAlwaysPrettify) {
+ this.shouldAlwaysPrettify = shouldAlwaysPrettify;
+ return this;
+ }
+
+ /**
+ * Set the relay object in the graphql annotations processor
+ *
+ * @param relay a relay object
+ * @return the builder after setting the relay object
+ */
+ public Builder setRelay(Relay relay) {
+ this.graphQLAnnotations.setRelay(relay);
+ return this;
+ }
+
+ /**
+ * @return the graphql annotations processor
+ */
+ public GraphQLAnnotations getGraphQLAnnotations() {
+ return this.graphQLAnnotations;
+ }
+
+ /**
+ * Build a graphql schema according to the properties provided
+ * The method generates the GraphQL objects, directives, additional types, etc using the graphql annotations processor and sets them into the GraphQL Schema
+ *
+ * @return a GraphQLSchema which contains generated GraphQL types out of the properties provided to the builder
+ */
+ public GraphQLSchema build() {
+ assert this.queryObject != null;
+
+ if (this.graphQLAnnotations == null) {
+ this.graphQLAnnotations = new GraphQLAnnotations();
+ }
+
+ if (this.graphqlSchemaBuilder == null) {
+ this.graphqlSchemaBuilder = new GraphQLSchema.Builder();
+ }
+
+ this.typeExtensions.forEach(typeExtension -> this.graphQLAnnotations.registerTypeExtension(typeExtension));
+ this.typeFunctions.forEach(typeFunction -> this.graphQLAnnotations.registerTypeFunction(typeFunction));
+
+ if (this.shouldAlwaysPrettify != null) {
+ this.graphQLAnnotations.getObjectHandler().getTypeRetriever().getGraphQLFieldRetriever().setAlwaysPrettify(this.shouldAlwaysPrettify);
+ }
+
+ Set directives = directivesObjectList.stream().map(dir -> graphQLAnnotations.directive(dir)).collect(Collectors.toSet());
+ Set additionalTypes = additionalTypesList.stream().map(additionalType ->
+ additionalType.isInterface() ?
+ graphQLAnnotations.generateInterface(additionalType) : graphQLAnnotations.object(additionalType)).collect(Collectors.toSet());
+
+ this.graphqlSchemaBuilder.query(graphQLAnnotations.object(queryObject));
+ if (this.mutationObject != null) {
+ this.graphqlSchemaBuilder.mutation(graphQLAnnotations.object(mutationObject));
+ }
+ if (this.subscriptionObject != null) {
+ this.graphqlSchemaBuilder.subscription(graphQLAnnotations.object(subscriptionObject));
+ }
+ if (!this.directivesObjectList.isEmpty()) {
+ graphqlSchemaBuilder.additionalDirectives(directives);
+ }
+ this.graphqlSchemaBuilder.additionalTypes(additionalTypes).additionalType(Relay.pageInfoType)
+ .codeRegistry(graphQLAnnotations.getContainer().getCodeRegistryBuilder().build());
+ return this.graphqlSchemaBuilder.build();
+ }
+ }
+}
diff --git a/src/main/java/graphql/annotations/GraphQLFieldDefinitionWrapper.java b/src/main/java/graphql/annotations/GraphQLFieldDefinitionWrapper.java
deleted file mode 100644
index 11cb72aa..00000000
--- a/src/main/java/graphql/annotations/GraphQLFieldDefinitionWrapper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright 2016 Yurii Rashkovskii
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- */
-package graphql.annotations;
-
-import graphql.schema.DataFetcher;
-import graphql.schema.DataFetcherFactories;
-import graphql.schema.GraphQLFieldDefinition;
-
-public class GraphQLFieldDefinitionWrapper extends GraphQLFieldDefinition {
-
- public GraphQLFieldDefinitionWrapper(GraphQLFieldDefinition fieldDefinition) {
- super(fieldDefinition.getName(), fieldDefinition.getDescription(), fieldDefinition.getType(),
- DataFetcherFactories.useDataFetcher((DataFetcher>) fieldDefinition.getDataFetcher()),
- fieldDefinition.getArguments(), fieldDefinition.getDeprecationReason(),
- fieldDefinition.getDirectives(),
- fieldDefinition.getDefinition());
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof GraphQLFieldDefinition &&
- ((GraphQLFieldDefinition) obj).getName().contentEquals(getName());
- }
-}
diff --git a/src/main/java/graphql/annotations/dataFetchers/ExtensionDataFetcherWrapper.java b/src/main/java/graphql/annotations/dataFetchers/ExtensionDataFetcherWrapper.java
index 48efd673..5b880ff1 100644
--- a/src/main/java/graphql/annotations/dataFetchers/ExtensionDataFetcherWrapper.java
+++ b/src/main/java/graphql/annotations/dataFetchers/ExtensionDataFetcherWrapper.java
@@ -16,11 +16,11 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
-import graphql.schema.DataFetchingEnvironmentImpl;
import java.util.Map;
import static graphql.annotations.processor.util.ReflectionKit.newInstance;
+import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment;
public class ExtensionDataFetcherWrapper implements DataFetcher {
@@ -37,16 +37,8 @@ public ExtensionDataFetcherWrapper(Class declaringClass, DataFetcher dataFetc
public T get(DataFetchingEnvironment environment) throws Exception {
Object source = environment.getSource();
if (source != null && (!declaringClass.isInstance(source)) && !(source instanceof Map)) {
- environment = new DataFetchingEnvironmentImpl(newInstance(declaringClass, source),
- environment.getArguments(), environment.getContext(),
- environment.getRoot(), environment.getFieldDefinition(),
- environment.getFields(), environment.getFieldType(), environment.getParentType(),
- environment.getGraphQLSchema(),
- environment.getFragmentsByName(), environment.getExecutionId(),
- environment.getSelectionSet(), environment.getExecutionStepInfo(),
- environment.getExecutionContext());
+ environment = newDataFetchingEnvironment(environment).source(newInstance(declaringClass, source)).build();
}
-
return dataFetcher.get(environment);
}
diff --git a/src/main/java/graphql/annotations/directives/AnnotationsDirectiveWiring.java b/src/main/java/graphql/annotations/directives/AnnotationsDirectiveWiring.java
index 07b0967f..5ce55611 100644
--- a/src/main/java/graphql/annotations/directives/AnnotationsDirectiveWiring.java
+++ b/src/main/java/graphql/annotations/directives/AnnotationsDirectiveWiring.java
@@ -22,7 +22,6 @@ public interface AnnotationsDirectiveWiring {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLObjectType onObject(AnnotationsWiringEnvironment environment) {
@@ -34,7 +33,6 @@ default GraphQLObjectType onObject(AnnotationsWiringEnvironment environment) {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLFieldDefinition onField(AnnotationsWiringEnvironment environment) {
@@ -46,7 +44,6 @@ default GraphQLFieldDefinition onField(AnnotationsWiringEnvironment environment)
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLArgument onArgument(AnnotationsWiringEnvironment environment) {
@@ -58,7 +55,6 @@ default GraphQLArgument onArgument(AnnotationsWiringEnvironment environment) {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLInterfaceType onInterface(AnnotationsWiringEnvironment environment) {
@@ -70,7 +66,6 @@ default GraphQLInterfaceType onInterface(AnnotationsWiringEnvironment environmen
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLUnionType onUnion(AnnotationsWiringEnvironment environment) {
@@ -82,7 +77,6 @@ default GraphQLUnionType onUnion(AnnotationsWiringEnvironment environment) {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLEnumType onEnum(AnnotationsWiringEnvironment environment) {
@@ -94,7 +88,6 @@ default GraphQLEnumType onEnum(AnnotationsWiringEnvironment environment) {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLEnumValueDefinition onEnumValue(AnnotationsWiringEnvironment environment) {
@@ -106,7 +99,6 @@ default GraphQLEnumValueDefinition onEnumValue(AnnotationsWiringEnvironment envi
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLScalarType onScalar(AnnotationsWiringEnvironment environment) {
@@ -118,7 +110,6 @@ default GraphQLScalarType onScalar(AnnotationsWiringEnvironment environment) {
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLInputObjectType onInputObjectType(AnnotationsWiringEnvironment environment) {
@@ -130,7 +121,6 @@ default GraphQLInputObjectType onInputObjectType(AnnotationsWiringEnvironment en
* of that DSL element
*
* @param environment the wiring element
- *
* @return a non null element based on the original one
*/
default GraphQLInputObjectField onInputObjectField(AnnotationsWiringEnvironment environment) {
diff --git a/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironment.java b/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironment.java
index 154e2ff2..4dcc6350 100644
--- a/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironment.java
+++ b/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironment.java
@@ -14,6 +14,7 @@
*/
package graphql.annotations.directives;
+import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLDirective;
import graphql.schema.GraphQLDirectiveContainer;
@@ -27,4 +28,17 @@ public interface AnnotationsWiringEnvironment {
* @return the directive that is being examined
*/
GraphQLDirective getDirective();
+
+ /**
+ *
+ * @return the parent name of the element
+ */
+ String getParentName();
+
+
+ /**
+ *
+ * @return the code registry builder
+ */
+ GraphQLCodeRegistry.Builder getCodeRegistryBuilder();
}
diff --git a/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironmentImpl.java b/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironmentImpl.java
index b93a024a..b3fbb963 100644
--- a/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironmentImpl.java
+++ b/src/main/java/graphql/annotations/directives/AnnotationsWiringEnvironmentImpl.java
@@ -14,16 +14,22 @@
*/
package graphql.annotations.directives;
+import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLDirective;
import graphql.schema.GraphQLDirectiveContainer;
public class AnnotationsWiringEnvironmentImpl implements AnnotationsWiringEnvironment {
private final GraphQLDirectiveContainer element;
private final GraphQLDirective directive;
+ private final String parentName;
+ private GraphQLCodeRegistry.Builder codeRegistryBuilder;
- public AnnotationsWiringEnvironmentImpl(GraphQLDirectiveContainer element, GraphQLDirective directive) {
+ public AnnotationsWiringEnvironmentImpl(GraphQLDirectiveContainer element, GraphQLDirective directive,
+ String parentName, GraphQLCodeRegistry.Builder codeRegistryBuilder) {
this.element = element;
this.directive = directive;
+ this.parentName = parentName;
+ this.codeRegistryBuilder = codeRegistryBuilder;
}
@Override
@@ -36,6 +42,16 @@ public GraphQLDirective getDirective() {
return directive;
}
+ @Override
+ public String getParentName() {
+ return parentName;
+ }
+
+ @Override
+ public GraphQLCodeRegistry.Builder getCodeRegistryBuilder() {
+ return codeRegistryBuilder;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -44,6 +60,9 @@ public boolean equals(Object o) {
AnnotationsWiringEnvironmentImpl that = (AnnotationsWiringEnvironmentImpl) o;
if (element != null ? !element.equals(that.element) : that.element != null) return false;
+ if (parentName != null ? !parentName.equals(that.parentName) : that.parentName != null) return false;
+ if (codeRegistryBuilder != null ? !codeRegistryBuilder.equals(that.codeRegistryBuilder) : that.codeRegistryBuilder != null)
+ return false;
return directive != null ? directive.equals(that.directive) : that.directive == null;
}
diff --git a/src/main/java/graphql/annotations/directives/DirectiveWirer.java b/src/main/java/graphql/annotations/directives/DirectiveWirer.java
index d0f9d72c..0ae85e15 100644
--- a/src/main/java/graphql/annotations/directives/DirectiveWirer.java
+++ b/src/main/java/graphql/annotations/directives/DirectiveWirer.java
@@ -26,7 +26,9 @@
public class DirectiveWirer {
@FunctionalInterface
interface WiringFunction {
- GraphQLDirectiveContainer apply(GraphQLDirective a, GraphQLDirectiveContainer b, AnnotationsDirectiveWiring wiring) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException;
+ GraphQLDirectiveContainer apply(GraphQLDirective a, GraphQLDirectiveContainer b,
+ AnnotationsDirectiveWiring wiring, GraphQLCodeRegistry.Builder codeRegistryBuilder, String parentName)
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException;
}
private Map functionMap;
@@ -37,11 +39,12 @@ public DirectiveWirer() {
private void putInMap(Map map, Class clazz, String functionName,
Introspection.DirectiveLocation... locations) {
- map.put(clazz, (d, e, wiring) -> {
+ map.put(clazz, (d, e, wiring, codeRegistryBuilder, parentName) -> {
assertLocation(d, e, locations);
AnnotationsWiringEnvironmentImpl environment =
- new AnnotationsWiringEnvironmentImpl(e, e.getDirective(d.getName()));
- return (GraphQLDirectiveContainer) wiring.getClass().getMethod(functionName, AnnotationsWiringEnvironment.class).invoke(wiring, environment);
+ new AnnotationsWiringEnvironmentImpl(e, e.getDirective(d.getName()), parentName, codeRegistryBuilder);
+ return (GraphQLDirectiveContainer) wiring.getClass().getMethod(functionName, AnnotationsWiringEnvironment.class)
+ .invoke(wiring, environment);
});
}
@@ -61,14 +64,15 @@ private Map createFunctionsMap() {
return functionMap;
}
- public GraphQLDirectiveContainer wire(GraphQLDirectiveContainer element, HashMap directiveWiringMap) {
+ public GraphQLDirectiveContainer wire(GraphQLDirectiveContainer element, HashMap directiveWiringMap
+ , GraphQLCodeRegistry.Builder codeRegistryBuilder, String parentName) {
for (Map.Entry entry : directiveWiringMap.entrySet()) {
GraphQLDirective graphQLDirective = entry.getKey();
AnnotationsDirectiveWiring wiring = entry.getValue();
Class extends GraphQLDirectiveContainer> aClass = element.getClass();
try {
- element = functionMap.get(aClass).apply(graphQLDirective, element, wiring);
+ element = functionMap.get(aClass).apply(graphQLDirective, element, wiring, codeRegistryBuilder, parentName);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new GraphQLAnnotationsException(e.getMessage(), e);
}
diff --git a/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java b/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java
index e441039b..3bf0d250 100644
--- a/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java
+++ b/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java
@@ -30,6 +30,7 @@
import graphql.annotations.processor.util.DataFetcherConstructor;
import graphql.relay.Relay;
import graphql.schema.GraphQLDirective;
+import graphql.schema.GraphQLInterfaceType;
import graphql.schema.GraphQLObjectType;
import java.util.Arrays;
@@ -94,12 +95,6 @@ public GraphQLAnnotations(TypeFunction defaultTypeFunction, GraphQLObjectHandler
this.container = new ProcessingElementsContainer(defaultTypeFunction);
}
- public static GraphQLAnnotations instance = new GraphQLAnnotations();
-
- public static GraphQLAnnotations getInstance() {
- return instance;
- }
-
public void setRelay(Relay relay) {
this.container.setRelay(relay);
}
@@ -109,38 +104,46 @@ public String getTypeName(Class> objectClass) {
return toGraphqlName(name == null ? objectClass.getSimpleName() : name.value());
}
- public static GraphQLObjectType object(Class> object) throws GraphQLAnnotationsException {
- GraphQLAnnotations instance = getInstance();
+ public GraphQLInterfaceType generateInterface(Class> object) throws GraphQLAnnotationsException {
try {
- return instance.graphQLObjectHandler.getObject(object, instance.getContainer());
+ return this.graphQLObjectHandler.getGraphQLType(object, this.getContainer());
} catch (GraphQLAnnotationsException e) {
- instance.getContainer().getProcessing().clear();
- instance.getTypeRegistry().clear();
+ this.getContainer().getProcessing().clear();
+ this.getTypeRegistry().clear();
throw e;
}
}
- public static GraphQLObjectType object(Class> object, GraphQLDirective... directives) throws GraphQLAnnotationsException {
- GraphQLAnnotations instance = getInstance();
- Arrays.stream(directives).forEach(x -> instance.getContainer().getDirectiveRegistry().put(x.getName(), x));
-
+ public GraphQLObjectType object(Class> object) throws GraphQLAnnotationsException {
try {
- return instance.graphQLObjectHandler.getObject(object, instance.getContainer());
+ return this.graphQLObjectHandler.getGraphQLType(object, this.getContainer());
} catch (GraphQLAnnotationsException e) {
- instance.getContainer().getProcessing().clear();
- instance.getTypeRegistry().clear();
+ this.getContainer().getProcessing().clear();
+ this.getTypeRegistry().clear();
throw e;
}
}
- public static GraphQLDirective directive(Class> object) throws GraphQLAnnotationsException {
- GraphQLAnnotations instance = getInstance();
+ @Deprecated
+ public GraphQLObjectType object(Class> object, GraphQLDirective... directives) throws GraphQLAnnotationsException {
+ Arrays.stream(directives).forEach(directive -> this.getContainer().getDirectiveRegistry().put(directive.getName(), directive));
+ try {
+ return this.graphQLObjectHandler.getGraphQLType(object, this.getContainer());
+ } catch (GraphQLAnnotationsException e) {
+ this.getContainer().getProcessing().clear();
+ this.getTypeRegistry().clear();
+ throw e;
+ }
+ }
+ public GraphQLDirective directive(Class> object) throws GraphQLAnnotationsException {
try {
- return instance.directiveCreator.getDirective(object);
+ GraphQLDirective directive = this.directiveCreator.getDirective(object);
+ this.getContainer().getDirectiveRegistry().put(directive.getName(), directive);
+ return directive;
} catch (GraphQLAnnotationsException e) {
- instance.getContainer().getProcessing().clear();
- instance.getTypeRegistry().clear();
+ this.getContainer().getProcessing().clear();
+ this.getTypeRegistry().clear();
throw e;
}
}
@@ -149,12 +152,13 @@ public void registerTypeExtension(Class> objectClass) {
graphQLExtensionsHandler.registerTypeExtension(objectClass, container);
}
- public void registerType(TypeFunction typeFunction) {
+ public void registerTypeFunction(TypeFunction typeFunction) {
((DefaultTypeFunction) container.getDefaultTypeFunction()).register(typeFunction);
}
- public static void register(TypeFunction typeFunction) {
- getInstance().registerType(typeFunction);
+ @Deprecated
+ public void register(TypeFunction typeFunction) {
+ this.registerTypeFunction(typeFunction);
}
public Map getTypeRegistry() {
diff --git a/src/main/java/graphql/annotations/processor/ProcessingElementsContainer.java b/src/main/java/graphql/annotations/processor/ProcessingElementsContainer.java
index 48614e53..d0a1bec3 100644
--- a/src/main/java/graphql/annotations/processor/ProcessingElementsContainer.java
+++ b/src/main/java/graphql/annotations/processor/ProcessingElementsContainer.java
@@ -20,6 +20,7 @@
import graphql.annotations.processor.typeFunctions.DefaultTypeFunction;
import graphql.annotations.processor.typeFunctions.TypeFunction;
import graphql.relay.Relay;
+import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLDirective;
import java.util.HashMap;
@@ -27,8 +28,9 @@
import java.util.Set;
import java.util.Stack;
-import static graphql.annotations.processor.util.InputPropertiesUtil.DEFAULT_INPUT_SUFFIX;
import static graphql.annotations.processor.util.InputPropertiesUtil.DEFAULT_INPUT_PREFIX;
+import static graphql.annotations.processor.util.InputPropertiesUtil.DEFAULT_INPUT_SUFFIX;
+import static graphql.schema.GraphQLCodeRegistry.newCodeRegistry;
public class ProcessingElementsContainer {
@@ -37,6 +39,7 @@ public class ProcessingElementsContainer {
private Map typeRegistry;
private Map directiveRegistry;
private Map, Set>> extensionsTypeRegistry;
+ private GraphQLCodeRegistry.Builder codeRegistryBuilder;
private Stack processing;
private String inputPrefix = DEFAULT_INPUT_PREFIX;
private String inputSuffix = DEFAULT_INPUT_SUFFIX;
@@ -49,21 +52,25 @@ public void setDirectiveRegistry(Map directiveRegistry
this.directiveRegistry = directiveRegistry;
}
- public ProcessingElementsContainer(TypeFunction defaultTypeFunction, Relay relay, Map typeRegistry, Map directiveRegistry, Map, Set>> extensionsTypeRegistry, Stack processing) {
+ public ProcessingElementsContainer(TypeFunction defaultTypeFunction, Relay relay, Map typeRegistry, Map directiveRegistry,
+ Map, Set>> extensionsTypeRegistry, Stack processing,
+ GraphQLCodeRegistry.Builder codeRegistryBuilder) {
this.defaultTypeFunction = defaultTypeFunction;
this.relay = relay;
this.typeRegistry = typeRegistry;
this.directiveRegistry = directiveRegistry;
this.extensionsTypeRegistry = extensionsTypeRegistry;
this.processing = processing;
+ this.codeRegistryBuilder = codeRegistryBuilder;
}
public ProcessingElementsContainer(TypeFunction typeFunction) {
- this(typeFunction, new Relay(), new HashMap<>(), new HashMap<>(), new HashMap<>(), new Stack<>());
+ this(typeFunction, new Relay(), new HashMap<>(), new HashMap<>(), new HashMap<>(), new Stack<>(), newCodeRegistry());
}
public ProcessingElementsContainer() {
- this(new DefaultTypeFunction(new GraphQLInputProcessor(), new GraphQLOutputProcessor()), new Relay(), new HashMap<>(), new HashMap<>(), new HashMap<>(), new Stack<>());
+ this(new DefaultTypeFunction(new GraphQLInputProcessor(), new GraphQLOutputProcessor()), new Relay(), new HashMap<>(), new HashMap<>(), new HashMap<>(), new Stack<>(), newCodeRegistry());
}
public Relay getRelay() {
@@ -121,4 +128,12 @@ public String getInputSuffix() {
public void setInputSuffix(String inputSuffix) {
this.inputSuffix = inputSuffix;
}
+
+ public void setCodeRegistryBuilder(GraphQLCodeRegistry.Builder builder) {
+ this.codeRegistryBuilder = builder;
+ }
+
+ public GraphQLCodeRegistry.Builder getCodeRegistryBuilder() {
+ return this.codeRegistryBuilder;
+ }
}
diff --git a/src/main/java/graphql/annotations/processor/graphQLProcessors/GraphQLAnnotationsProcessor.java b/src/main/java/graphql/annotations/processor/graphQLProcessors/GraphQLAnnotationsProcessor.java
index 3e729431..853a6849 100644
--- a/src/main/java/graphql/annotations/processor/graphQLProcessors/GraphQLAnnotationsProcessor.java
+++ b/src/main/java/graphql/annotations/processor/graphQLProcessors/GraphQLAnnotationsProcessor.java
@@ -38,5 +38,5 @@ public interface GraphQLAnnotationsProcessor {
*
* @param typeFunction The extension class to register
*/
- void registerType(TypeFunction typeFunction);
+ void registerTypeFunction(TypeFunction typeFunction);
}
diff --git a/src/main/java/graphql/annotations/processor/retrievers/GraphQLExtensionsHandler.java b/src/main/java/graphql/annotations/processor/retrievers/GraphQLExtensionsHandler.java
index 012a6925..19363971 100644
--- a/src/main/java/graphql/annotations/processor/retrievers/GraphQLExtensionsHandler.java
+++ b/src/main/java/graphql/annotations/processor/retrievers/GraphQLExtensionsHandler.java
@@ -18,8 +18,6 @@
import graphql.annotations.processor.ProcessingElementsContainer;
import graphql.annotations.processor.exceptions.CannotCastMemberException;
import graphql.annotations.processor.exceptions.GraphQLAnnotationsException;
-import graphql.annotations.processor.searchAlgorithms.BreadthFirstSearch;
-import graphql.annotations.processor.searchAlgorithms.ParentalSearch;
import graphql.annotations.processor.searchAlgorithms.SearchAlgorithm;
import graphql.schema.GraphQLFieldDefinition;
import org.osgi.service.component.annotations.Component;
@@ -53,7 +51,7 @@ public List getExtensionFields(Class> object, List getExtensionFields(Class> object, List objectClass, ProcessingElementsContai
}
}
- @Reference(policy= ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY)
+ @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
public void setGraphQLObjectInfoRetriever(GraphQLObjectInfoRetriever graphQLObjectInfoRetriever) {
this.graphQLObjectInfoRetriever = graphQLObjectInfoRetriever;
}
@@ -102,7 +100,7 @@ public void unsetGraphQLObjectInfoRetriever(GraphQLObjectInfoRetriever graphQLOb
}
- @Reference(target = "(type=field)", policy=ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY)
+ @Reference(target = "(type=field)", policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
public void setFieldSearchAlgorithm(SearchAlgorithm fieldSearchAlgorithm) {
this.fieldSearchAlgorithm = fieldSearchAlgorithm;
}
@@ -111,7 +109,7 @@ public void unsetFieldSearchAlgorithm(SearchAlgorithm fieldSearchAlgorithm) {
this.fieldSearchAlgorithm = null;
}
- @Reference(target = "(type=method)", policy=ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY)
+ @Reference(target = "(type=method)", policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
public void setMethodSearchAlgorithm(SearchAlgorithm methodSearchAlgorithm) {
this.methodSearchAlgorithm = methodSearchAlgorithm;
}
@@ -120,7 +118,7 @@ public void unsetMethodSearchAlgorithm(SearchAlgorithm methodSearchAlgorithm) {
this.methodSearchAlgorithm = null;
}
- @Reference(policy=ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY)
+ @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
public void setFieldRetriever(GraphQLFieldRetriever fieldRetriever) {
this.fieldRetriever = fieldRetriever;
}
diff --git a/src/main/java/graphql/annotations/processor/retrievers/GraphQLFieldRetriever.java b/src/main/java/graphql/annotations/processor/retrievers/GraphQLFieldRetriever.java
index 46f61f4b..cc8dc4ac 100644
--- a/src/main/java/graphql/annotations/processor/retrievers/GraphQLFieldRetriever.java
+++ b/src/main/java/graphql/annotations/processor/retrievers/GraphQLFieldRetriever.java
@@ -15,7 +15,6 @@
package graphql.annotations.processor.retrievers;
-import graphql.annotations.GraphQLFieldDefinitionWrapper;
import graphql.annotations.annotationTypes.GraphQLRelayMutation;
import graphql.annotations.connection.GraphQLConnection;
import graphql.annotations.directives.DirectiveWirer;
@@ -32,6 +31,7 @@
import graphql.annotations.processor.retrievers.fieldBuilders.method.MethodNameBuilder;
import graphql.annotations.processor.retrievers.fieldBuilders.method.MethodTypeBuilder;
import graphql.annotations.processor.typeFunctions.TypeFunction;
+import graphql.annotations.processor.util.CodeRegistryUtil;
import graphql.annotations.processor.util.ConnectionUtil;
import graphql.annotations.processor.util.DataFetcherConstructor;
import graphql.relay.Relay;
@@ -50,6 +50,7 @@
import java.util.stream.Collectors;
import static graphql.annotations.processor.util.ReflectionKit.newInstance;
+import static graphql.schema.FieldCoordinates.coordinates;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLInputObjectField.newInputObjectField;
@@ -68,16 +69,17 @@ public GraphQLFieldRetriever() {
this(new DataFetcherConstructor());
}
- public GraphQLFieldDefinition getField(Method method, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
+ public GraphQLFieldDefinition getField(String parentName, Method method, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
GraphQLFieldDefinition.Builder builder = newFieldDefinition();
TypeFunction typeFunction = getTypeFunction(method, container);
- builder.name(new MethodNameBuilder(method).alwaysPrettify(alwaysPrettify).build());
+ String fieldName = new MethodNameBuilder(method).alwaysPrettify(alwaysPrettify).build();
+ builder.name(fieldName);
GraphQLOutputType outputType = (GraphQLOutputType) new MethodTypeBuilder(method, typeFunction, container, false).build();
boolean isConnection = ConnectionUtil.isConnection(method, outputType);
if (isConnection) {
outputType = getGraphQLConnection(method, outputType, ConnectionUtil.getRelay(method, container), container.getTypeRegistry());
- builder.argument(ConnectionUtil.getRelay(method, container).getConnectionFieldArguments());
+ builder.arguments(ConnectionUtil.getRelay(method, container).getConnectionFieldArguments());
}
builder.type(outputType);
DirectivesBuilder directivesBuilder = new DirectivesBuilder(method, container);
@@ -86,55 +88,80 @@ public GraphQLFieldDefinition getField(Method method, ProcessingElementsContaine
GraphQLFieldDefinition relayFieldDefinition = handleRelayArguments(method, container, builder, outputType, args);
builder.description(new DescriptionBuilder(method).build())
.deprecate(new DeprecateBuilder(method).build())
- .dataFetcher(new MethodDataFetcherBuilder(method, outputType, typeFunction, container, relayFieldDefinition, args, dataFetcherConstructor, isConnection).build());
+ .build();
+
+ DataFetcher dataFetcher = new MethodDataFetcherBuilder(method, outputType, typeFunction, container, relayFieldDefinition, args, dataFetcherConstructor, isConnection).build();
+ container.getCodeRegistryBuilder().dataFetcher(coordinates(parentName, fieldName), dataFetcher);
- return new GraphQLFieldDefinitionWrapper((GraphQLFieldDefinition) new DirectiveWirer().wire(builder.build(), new DirectiveWiringMapRetriever().getDirectiveWiringMap(method, container)));
+ return (GraphQLFieldDefinition) new DirectiveWirer().wire(builder.build(),
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(method, container),
+ container.getCodeRegistryBuilder(), parentName);
}
- public GraphQLFieldDefinition getField(Field field, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
+ public GraphQLFieldDefinition getField(String parentName, Field field, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
GraphQLFieldDefinition.Builder builder = newFieldDefinition();
- builder.name(new FieldNameBuilder(field).alwaysPrettify(alwaysPrettify).build());
+ String fieldName = new FieldNameBuilder(field).alwaysPrettify(alwaysPrettify).build();
+ builder.name(fieldName);
TypeFunction typeFunction = getTypeFunction(field, container);
GraphQLType outputType = typeFunction.buildType(field.getType(), field.getAnnotatedType(), container);
boolean isConnection = ConnectionUtil.isConnection(field, outputType);
if (isConnection) {
outputType = getGraphQLConnection(field, outputType, ConnectionUtil.getRelay(field, container), container.getTypeRegistry());
- builder.argument(ConnectionUtil.getRelay(field, container).getConnectionFieldArguments());
+ builder.arguments(ConnectionUtil.getRelay(field, container).getConnectionFieldArguments());
}
+ DataFetcher dataFetcher = new FieldDataFetcherBuilder(field, dataFetcherConstructor, outputType, typeFunction, container, isConnection).build();
builder.type((GraphQLOutputType) outputType).description(new DescriptionBuilder(field).build())
- .deprecate(new DeprecateBuilder(field).build())
- .dataFetcher(new FieldDataFetcherBuilder(field, dataFetcherConstructor, outputType, typeFunction, container, isConnection).build());
+ .deprecate(new DeprecateBuilder(field).build());
+
+ container.getCodeRegistryBuilder().dataFetcher(coordinates(parentName, fieldName), dataFetcher);
GraphQLDirective[] graphQLDirectives = new DirectivesBuilder(field, container).build();
builder.withDirectives(graphQLDirectives);
- return new GraphQLFieldDefinitionWrapper((GraphQLFieldDefinition) new DirectiveWirer().wire(builder.build(), new DirectiveWiringMapRetriever().getDirectiveWiringMap(field, container)));
+ return (GraphQLFieldDefinition) new DirectiveWirer().wire(builder.build(),
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(field, container),
+ container.getCodeRegistryBuilder(), parentName);
}
- public GraphQLInputObjectField getInputField(Method method, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
+ public GraphQLInputObjectField getInputField(Method method, ProcessingElementsContainer container, String parentName) throws GraphQLAnnotationsException {
GraphQLInputObjectField.Builder builder = newInputObjectField();
builder.name(new MethodNameBuilder(method).alwaysPrettify(alwaysPrettify).build());
TypeFunction typeFunction = getTypeFunction(method, container);
GraphQLInputType inputType = (GraphQLInputType) new MethodTypeBuilder(method, typeFunction, container, true).build();
- return builder.type(inputType).description(new DescriptionBuilder(method).build()).build();
+ builder.withDirectives(new DirectivesBuilder(method, container).build());
+ return (GraphQLInputObjectField) new DirectiveWirer().wire(builder.type(inputType)
+ .description(new DescriptionBuilder(method).build()).build(),
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(method, container), container.getCodeRegistryBuilder(), parentName
+ );
}
- public GraphQLInputObjectField getInputField(Field field, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
+ public GraphQLInputObjectField getInputField(Field field, ProcessingElementsContainer container, String parentName) throws GraphQLAnnotationsException {
GraphQLInputObjectField.Builder builder = newInputObjectField();
builder.name(new FieldNameBuilder(field).alwaysPrettify(alwaysPrettify).build());
TypeFunction typeFunction = getTypeFunction(field, container);
GraphQLType graphQLType = typeFunction.buildType(true, field.getType(), field.getAnnotatedType(), container);
- return builder.type((GraphQLInputType) graphQLType).description(new DescriptionBuilder(field).build()).build();
+ builder.withDirectives(new DirectivesBuilder(field, container).build());
+ return (GraphQLInputObjectField) new DirectiveWirer().wire(builder.type((GraphQLInputType) graphQLType)
+ .description(new DescriptionBuilder(field).build()).build(),
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(field, container), container.getCodeRegistryBuilder(), parentName);
}
private GraphQLFieldDefinition handleRelayArguments(Method method, ProcessingElementsContainer container, GraphQLFieldDefinition.Builder builder, GraphQLOutputType outputType, List args) {
GraphQLFieldDefinition relayFieldDefinition = null;
if (method.isAnnotationPresent(GraphQLRelayMutation.class)) {
relayFieldDefinition = buildRelayMutation(method, container, builder, outputType, args);
+
+ // Getting the data fetcher from the old field type and putting it as the new type
+ String newParentType = relayFieldDefinition.getType().getName();
+ relayFieldDefinition.getType().getChildren().forEach(field -> {
+ DataFetcher dataFetcher = CodeRegistryUtil.getDataFetcher(container.getCodeRegistryBuilder(), outputType.getName(), (GraphQLFieldDefinition) field);
+ container.getCodeRegistryBuilder().dataFetcher(coordinates(newParentType, field.getName()), dataFetcher);
+ });
+
} else {
- builder.argument(args);
+ builder.arguments(args);
}
return relayFieldDefinition;
}
@@ -164,7 +191,7 @@ private GraphQLFieldDefinition buildRelayMutation(Method method, ProcessingEleme
args.stream().
map(t -> newInputObjectField().name(t.getName()).type(t.getType()).description(t.getDescription()).build()).
collect(Collectors.toList()), fieldDefinitions, new StaticDataFetcher(null));
- builder.argument(relayFieldDefinition.getArguments()).type(relayFieldDefinition.getType());
+ builder.arguments(relayFieldDefinition.getArguments()).type(relayFieldDefinition.getType());
return relayFieldDefinition;
}
diff --git a/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectHandler.java b/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectHandler.java
index 96acd484..081cda8c 100644
--- a/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectHandler.java
+++ b/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectHandler.java
@@ -17,7 +17,6 @@
import graphql.annotations.processor.ProcessingElementsContainer;
import graphql.annotations.processor.exceptions.CannotCastMemberException;
import graphql.annotations.processor.exceptions.GraphQLAnnotationsException;
-import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLOutputType;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -29,12 +28,14 @@ public class GraphQLObjectHandler {
private GraphQLTypeRetriever typeRetriever;
- public GraphQLObjectType getObject(Class> object, ProcessingElementsContainer container) throws GraphQLAnnotationsException, CannotCastMemberException {
+ public T getGraphQLType(Class> object, ProcessingElementsContainer container) throws GraphQLAnnotationsException, CannotCastMemberException {
GraphQLOutputType type = (GraphQLOutputType) typeRetriever.getGraphQLType(object, container, false);
- if (type instanceof GraphQLObjectType) {
- return (GraphQLObjectType) type;
- } else {
- throw new IllegalArgumentException("Object resolve to a " + type.getClass().getSimpleName());
+ try{
+ return (T)type;
+
+ }
+ catch (Exception e){
+ throw new IllegalArgumentException("Cannot cast type " + type.getClass().getSimpleName());
}
}
@@ -42,7 +43,7 @@ public GraphQLTypeRetriever getTypeRetriever() {
return typeRetriever;
}
- @Reference(policy= ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY)
+ @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
public void setTypeRetriever(GraphQLTypeRetriever typeRetriever) {
this.typeRetriever = typeRetriever;
}
diff --git a/src/main/java/graphql/annotations/processor/retrievers/GraphQLTypeRetriever.java b/src/main/java/graphql/annotations/processor/retrievers/GraphQLTypeRetriever.java
index d4c9069b..94628f85 100644
--- a/src/main/java/graphql/annotations/processor/retrievers/GraphQLTypeRetriever.java
+++ b/src/main/java/graphql/annotations/processor/retrievers/GraphQLTypeRetriever.java
@@ -46,7 +46,7 @@ public class GraphQLTypeRetriever {
*
* @param object the object class to examine*
* @param container a class that hold several members that are required in order to build schema
- * @param isInput true if the type is an input type, false otherwise
+ * @param isInput true if the type is an input type, false otherwise
* @return a {@link GraphQLType} that represents that object class
* @throws graphql.annotations.processor.exceptions.GraphQLAnnotationsException if the object class cannot be examined
* @throws graphql.annotations.processor.exceptions.CannotCastMemberException if the object class cannot be examined
@@ -90,7 +90,9 @@ public GraphQLType getGraphQLType(Class> object, ProcessingElementsContainer c
DirectiveWirer directiveWirer = new DirectiveWirer();
// wire the type with the directives and change the original type
- type = directiveWirer.wire((GraphQLDirectiveContainer) type, new DirectiveWiringMapRetriever().getDirectiveWiringMap(object, container));
+ type = directiveWirer.wire((GraphQLDirectiveContainer) type,
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(object, container),
+ container.getCodeRegistryBuilder(), null);
container.getTypeRegistry().put(type.getName(), type);
container.getProcessing().pop();
diff --git a/src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/ArgumentBuilder.java b/src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/ArgumentBuilder.java
index 5cd97b57..461851e4 100644
--- a/src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/ArgumentBuilder.java
+++ b/src/main/java/graphql/annotations/processor/retrievers/fieldBuilders/ArgumentBuilder.java
@@ -81,7 +81,9 @@ private GraphQLArgument getArgument(Parameter parameter, graphql.schema.GraphQLI
argumentBuilder.name(toGraphqlName(parameter.getName()));
}
argumentBuilder.withDirectives(new DirectivesBuilder(parameter, container).build());
- return (GraphQLArgument) new DirectiveWirer().wire(argumentBuilder.build(), new DirectiveWiringMapRetriever().getDirectiveWiringMap(parameter, container));
+ return (GraphQLArgument) new DirectiveWirer().wire(argumentBuilder.build(),
+ new DirectiveWiringMapRetriever().getDirectiveWiringMap(parameter, container), container.getCodeRegistryBuilder(),
+ inputType.getName());
}
}
diff --git a/src/main/java/graphql/annotations/processor/typeBuilders/InputObjectBuilder.java b/src/main/java/graphql/annotations/processor/typeBuilders/InputObjectBuilder.java
index 3e20eec9..553922d2 100644
--- a/src/main/java/graphql/annotations/processor/typeBuilders/InputObjectBuilder.java
+++ b/src/main/java/graphql/annotations/processor/typeBuilders/InputObjectBuilder.java
@@ -55,7 +55,8 @@ public InputObjectBuilder(GraphQLObjectInfoRetriever graphQLObjectInfoRetriever,
public GraphQLInputObjectType.Builder getInputObjectBuilder(Class> object, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
GraphQLInputObjectType.Builder builder = GraphQLInputObjectType.newInputObject();
- builder.name(container.getInputPrefix() + graphQLObjectInfoRetriever.getTypeName(object) + container.getInputSuffix());
+ String name = container.getInputPrefix() + graphQLObjectInfoRetriever.getTypeName(object) + container.getInputSuffix();
+ builder.name(name);
GraphQLDescription description = object.getAnnotation(GraphQLDescription.class);
if (description != null) {
builder.description(description.value());
@@ -68,7 +69,7 @@ public GraphQLInputObjectType.Builder getInputObjectBuilder(Class> object, Pro
continue;
}
if (methodSearchAlgorithm.isFound(method)) {
- GraphQLInputObjectField gqlField = graphQLFieldRetriever.getInputField(method,container);
+ GraphQLInputObjectField gqlField = graphQLFieldRetriever.getInputField(method, container, name);
definedFields.add(gqlField.getName());
builder.field(gqlField);
}
@@ -79,7 +80,7 @@ public GraphQLInputObjectType.Builder getInputObjectBuilder(Class> object, Pro
continue;
}
if (fieldSearchAlgorithm.isFound(field)) {
- GraphQLInputObjectField gqlField = graphQLFieldRetriever.getInputField(field,container);
+ GraphQLInputObjectField gqlField = graphQLFieldRetriever.getInputField(field, container, name);
definedFields.add(gqlField.getName());
builder.field(gqlField);
}
diff --git a/src/main/java/graphql/annotations/processor/typeBuilders/InterfaceBuilder.java b/src/main/java/graphql/annotations/processor/typeBuilders/InterfaceBuilder.java
index 0fda433d..699e09ea 100644
--- a/src/main/java/graphql/annotations/processor/typeBuilders/InterfaceBuilder.java
+++ b/src/main/java/graphql/annotations/processor/typeBuilders/InterfaceBuilder.java
@@ -18,10 +18,10 @@
import graphql.annotations.annotationTypes.GraphQLField;
import graphql.annotations.annotationTypes.GraphQLTypeResolver;
import graphql.annotations.processor.ProcessingElementsContainer;
+import graphql.annotations.processor.exceptions.CannotCastMemberException;
import graphql.annotations.processor.exceptions.GraphQLAnnotationsException;
import graphql.annotations.processor.retrievers.GraphQLExtensionsHandler;
import graphql.annotations.processor.retrievers.GraphQLFieldRetriever;
-import graphql.annotations.processor.exceptions.CannotCastMemberException;
import graphql.annotations.processor.retrievers.GraphQLObjectInfoRetriever;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLInterfaceType;
@@ -33,6 +33,7 @@
import static graphql.annotations.processor.util.ReflectionKit.newInstance;
import static graphql.schema.GraphQLInterfaceType.newInterface;
+
/**
* Copyright 2016 Yurii Rashkovskii
*
@@ -55,7 +56,7 @@ public class InterfaceBuilder {
public InterfaceBuilder(GraphQLObjectInfoRetriever graphQLObjectInfoRetriever, GraphQLFieldRetriever graphQLFieldRetriever, GraphQLExtensionsHandler extensionsHandler) {
this.graphQLObjectInfoRetriever = graphQLObjectInfoRetriever;
- this.graphQLFieldRetriever=graphQLFieldRetriever;
+ this.graphQLFieldRetriever = graphQLFieldRetriever;
this.extensionsHandler = extensionsHandler;
}
@@ -66,7 +67,8 @@ public GraphQLInterfaceType.Builder getInterfaceBuilder(Class> iface, Processi
}
GraphQLInterfaceType.Builder builder = newInterface();
- builder.name(graphQLObjectInfoRetriever.getTypeName(iface));
+ String typeName = graphQLObjectInfoRetriever.getTypeName(iface);
+ builder.name(typeName);
GraphQLDescription description = iface.getAnnotation(GraphQLDescription.class);
if (description != null) {
builder.description(description.value());
@@ -76,15 +78,15 @@ public GraphQLInterfaceType.Builder getInterfaceBuilder(Class> iface, Processi
boolean valid = !Modifier.isStatic(method.getModifiers()) &&
method.getAnnotation(GraphQLField.class) != null;
if (valid) {
- GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(method,container);
+ GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(typeName, method, container);
definedFields.add(gqlField.getName());
builder.field(gqlField);
}
}
- builder.fields(extensionsHandler.getExtensionFields(iface, definedFields,container));
+ builder.fields(extensionsHandler.getExtensionFields(iface, definedFields, container));
GraphQLTypeResolver typeResolver = iface.getAnnotation(GraphQLTypeResolver.class);
- builder.typeResolver(newInstance(typeResolver.value()));
+ container.getCodeRegistryBuilder().typeResolver(typeName, newInstance(typeResolver.value()));
return builder;
}
}
diff --git a/src/main/java/graphql/annotations/processor/typeBuilders/OutputObjectBuilder.java b/src/main/java/graphql/annotations/processor/typeBuilders/OutputObjectBuilder.java
index a430d7c4..44c04d90 100644
--- a/src/main/java/graphql/annotations/processor/typeBuilders/OutputObjectBuilder.java
+++ b/src/main/java/graphql/annotations/processor/typeBuilders/OutputObjectBuilder.java
@@ -66,7 +66,8 @@ public OutputObjectBuilder(GraphQLObjectInfoRetriever graphQLObjectInfoRetriever
public GraphQLObjectType.Builder getOutputObjectBuilder(Class> object, ProcessingElementsContainer container) throws GraphQLAnnotationsException {
GraphQLObjectType.Builder builder = newObject();
- builder.name(graphQLObjectInfoRetriever.getTypeName(object));
+ String typeName = graphQLObjectInfoRetriever.getTypeName(object);
+ builder.name(typeName);
GraphQLDescription description = object.getAnnotation(GraphQLDescription.class);
if (description != null) {
builder.description(description.value());
@@ -77,7 +78,7 @@ public GraphQLObjectType.Builder getOutputObjectBuilder(Class> object, Process
continue;
}
if (methodSearchAlgorithm.isFound(method)) {
- GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(method, container);
+ GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(typeName, method, container);
definedFields.add(gqlField.getName());
builder.field(gqlField);
}
@@ -88,7 +89,7 @@ public GraphQLObjectType.Builder getOutputObjectBuilder(Class> object, Process
continue;
}
if (fieldSearchAlgorithm.isFound(field)) {
- GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(field, container);
+ GraphQLFieldDefinition gqlField = graphQLFieldRetriever.getField(typeName, field, container);
definedFields.add(gqlField.getName());
builder.field(gqlField);
}
diff --git a/src/main/java/graphql/annotations/processor/typeBuilders/UnionBuilder.java b/src/main/java/graphql/annotations/processor/typeBuilders/UnionBuilder.java
index 22e1c1a9..d918d0ab 100644
--- a/src/main/java/graphql/annotations/processor/typeBuilders/UnionBuilder.java
+++ b/src/main/java/graphql/annotations/processor/typeBuilders/UnionBuilder.java
@@ -58,7 +58,8 @@ public Builder getUnionBuilder(Class> iface, ProcessingElementsContainer conta
Builder builder = newUnionType();
GraphQLUnion unionAnnotation = iface.getAnnotation(GraphQLUnion.class);
- builder.name(graphQLObjectInfoRetriever.getTypeName(iface));
+ String typeName = graphQLObjectInfoRetriever.getTypeName(iface);
+ builder.name(typeName);
GraphQLDescription description = iface.getAnnotation(GraphQLDescription.class);
if (description != null) {
builder.description(description.value());
@@ -78,8 +79,7 @@ public Builder getUnionBuilder(Class> iface, ProcessingElementsContainer conta
.forEach(builder::possibleType);
TypeResolver typeResolver = getTypeResolver(container, unionAnnotation);
-
- builder.typeResolver(typeResolver);
+ container.getCodeRegistryBuilder().typeResolver(typeName, typeResolver);
return builder;
}
@@ -90,10 +90,9 @@ private TypeResolver getTypeResolver(ProcessingElementsContainer container, Grap
return typeResolverConstructorOptional
.map(constructor -> {
- if(constructor.getParameterCount() == 0) {
+ if (constructor.getParameterCount() == 0) {
return (TypeResolver) constructNewInstance(constructor);
- }
- else {
+ } else {
return (TypeResolver) constructNewInstance(constructor, unionAnnotation.possibleTypes(), container);
}
})
diff --git a/src/main/java/graphql/annotations/processor/util/CodeRegistryUtil.java b/src/main/java/graphql/annotations/processor/util/CodeRegistryUtil.java
new file mode 100644
index 00000000..f9e70aca
--- /dev/null
+++ b/src/main/java/graphql/annotations/processor/util/CodeRegistryUtil.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2016 Yurii Rashkovskii
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ */
+package graphql.annotations.processor.util;
+
+import graphql.annotations.directives.AnnotationsWiringEnvironment;
+import graphql.schema.*;
+
+import java.util.function.BiFunction;
+
+import static graphql.schema.GraphQLObjectType.newObject;
+
+public class CodeRegistryUtil {
+ /**
+ * This util method helps you wrap your datafetcher with some lambda code
+ *
+ * @param fieldDefinition The field you want to wrap its datafetcher
+ * @param environment the environment object of the Wiring process
+ * @param mapFunction the lambda expression to wrap with
+ */
+ public static void wrapDataFetcher(GraphQLFieldDefinition fieldDefinition, AnnotationsWiringEnvironment environment,
+ BiFunction mapFunction) {
+ DataFetcher originalDataFetcher = getDataFetcher(environment.getCodeRegistryBuilder(), environment.getParentName(), fieldDefinition);
+ DataFetcher wrappedDataFetcher = DataFetcherFactories.wrapDataFetcher(originalDataFetcher, mapFunction);
+ environment.getCodeRegistryBuilder()
+ .dataFetcher(FieldCoordinates.coordinates(environment.getParentName(), fieldDefinition.getName()), wrappedDataFetcher);
+ }
+
+ /**
+ * this util method helps you retrieve the data fetcher from the code registry if you do not have the whole parent object (only parent name)
+ *
+ * @param codeRegistryBuilder the code registry builder
+ * @param parentName the parent name
+ * @param fieldDefinition the field definition which the data fetcher is linked to
+ * @return the data fetcher
+ */
+ public static DataFetcher getDataFetcher(GraphQLCodeRegistry.Builder codeRegistryBuilder, String parentName, GraphQLFieldDefinition fieldDefinition) {
+ return codeRegistryBuilder.getDataFetcher(newObject().name(parentName).build(), fieldDefinition);
+ }
+}
diff --git a/src/main/java/graphql/annotations/strategies/EnhancedExecutionStrategy.java b/src/main/java/graphql/annotations/strategies/EnhancedExecutionStrategy.java
index b9ad19f3..dc1c63d1 100644
--- a/src/main/java/graphql/annotations/strategies/EnhancedExecutionStrategy.java
+++ b/src/main/java/graphql/annotations/strategies/EnhancedExecutionStrategy.java
@@ -31,8 +31,8 @@ public class EnhancedExecutionStrategy extends AsyncSerialExecutionStrategy {
@Override
protected CompletableFuture resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) {
- GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getType();
- GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, parameters.getField().get(0));
+ GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType();
+ GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, parameters.getField().getSingleField());
if (fieldDef == null) return null;
if (fieldDef.getName().contentEquals(CLIENT_MUTATION_ID)) {
diff --git a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java
new file mode 100644
index 00000000..bc061eb2
--- /dev/null
+++ b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright 2016 Yurii Rashkovskii
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ */
+package graphql.annotations;
+
+import graphql.annotations.AnnotationsSchemaCreator;
+import graphql.annotations.annotationTypes.GraphQLDescription;
+import graphql.annotations.annotationTypes.GraphQLField;
+import graphql.annotations.annotationTypes.GraphQLName;
+import graphql.annotations.directives.creation.DirectiveLocations;
+import graphql.annotations.processor.GraphQLAnnotations;
+import graphql.introspection.Introspection;
+import graphql.schema.GraphQLDirective;
+import graphql.schema.GraphQLObjectType;
+import graphql.schema.GraphQLSchema;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static graphql.annotations.AnnotationsSchemaCreator.newAnnotationsSchema;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class AnnotationsSchemaCreatorTest {
+ private AnnotationsSchemaCreator.Builder builder;
+ private GraphQLAnnotations graphQLAnnotations;
+
+ @BeforeMethod
+ public void setUp() {
+ graphQLAnnotations = new GraphQLAnnotations();
+ builder = newAnnotationsSchema().setAnnotationsProcessor(graphQLAnnotations);
+ }
+
+ @Test(expectedExceptions = AssertionError.class)
+ public void build_QueryIsNotProvided_ExceptionIsThrown() {
+ // act
+ builder.build();
+ }
+
+ @GraphQLDescription("query obj")
+ public static class QueryTest {
+ @GraphQLField
+ public int getNum() {
+ return 5;
+ }
+ }
+
+ @Test
+ public void build_QueryIsProvided_SchemaIsCreatedWithQuery() {
+ // arrange + act
+ GraphQLSchema schema = builder.query(QueryTest.class).build();
+
+ // assert
+ GraphQLObjectType queryType = schema.getQueryType();
+ assertThat(queryType.getDescription(), is("query obj"));
+ assertThat(queryType.getFieldDefinition("getNum"), notNullValue());
+ assertThat(queryType.getFieldDefinitions().size(), is(1));
+ }
+
+ public static class MutationTest {
+ @GraphQLField
+ public int mutate() {
+ return 4;
+ }
+ }
+
+ @Test
+ public void build_Mutation_SchemaIsCreatedWithMutation() {
+ // arrange + act
+ GraphQLSchema schema = builder.query(QueryTest.class).mutation(MutationTest.class).build();
+ GraphQLObjectType mutationType = schema.getMutationType();
+
+ /// assert
+ assertThat(mutationType.getFieldDefinition("mutate"), notNullValue());
+ assertThat(mutationType.getFieldDefinitions().size(), is(1));
+ }
+
+ public static class SubscriptionTest {
+ @GraphQLField
+ public int subscribe() {
+ return 4;
+ }
+ }
+
+ @Test
+ public void build_Subscription_SchemaIsCreatedWithSubscription() {
+ // arrange + act
+ GraphQLSchema schema = builder.query(QueryTest.class).subscription(SubscriptionTest.class).build();
+ GraphQLObjectType subscriptionType = schema.getSubscriptionType();
+
+ // assert
+ assertThat(subscriptionType.getFieldDefinition("subscribe"), notNullValue());
+ assertThat(subscriptionType.getFieldDefinitions().size(), is(1));
+ }
+
+ @GraphQLName("testDirective")
+ @DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION})
+ public static class DirectiveDefinitionTest {
+ private boolean isActive = true;
+ }
+
+ @Test
+ public void build_Directive_SchemaIsCreatedWithDirective() {
+ // arrange + act
+ GraphQLSchema schema = builder.query(QueryTest.class).directive(DirectiveDefinitionTest.class).build();
+
+ // assert
+ GraphQLDirective testDirective = schema.getDirective("testDirective");
+ assertThat(testDirective, notNullValue());
+ assertThat(testDirective.getArguments().size(), is(1));
+ assertThat(testDirective.getArgument("isActive"), notNullValue());
+ }
+
+ @GraphQLName("secondDirective")
+ @DirectiveLocations(Introspection.DirectiveLocation.FIELD)
+ public static class SecondDirective {
+
+ }
+
+ @Test
+ public void build_MultipleDirectives_SchemaIsCreatedWithDirectives() {
+ // arrange + act
+ Set> directives = new HashSet<>();
+ directives.add(DirectiveDefinitionTest.class);
+ directives.add(SecondDirective.class);
+ GraphQLDirective directiveTest = graphQLAnnotations.directive(DirectiveDefinitionTest.class);
+ GraphQLDirective secondDirective = graphQLAnnotations.directive(SecondDirective.class);
+ GraphQLSchema schema = builder.query(QueryTest.class).directives(directives).build();
+
+ // assert
+ assertThat(schema.getDirective("secondDirective"), notNullValue());
+ assertThat(schema.getDirective("testDirective"), notNullValue());
+ }
+
+ @GraphQLName("additional")
+ public static class AdditionalTypeTest {
+ public int getI() {
+ return 4;
+ }
+ }
+
+ @Test
+ public void build_AdditionalType_SchemaIsCreatedWithAdditionalType() {
+ // arrange + act
+ GraphQLSchema schema = builder.query(QueryTest.class).additionalType(AdditionalTypeTest.class).build();
+ GraphQLObjectType additionalType = graphQLAnnotations.object(AdditionalTypeTest.class);
+
+ // assert
+ assertThat(schema.getType("additional"), notNullValue());
+ assertThat(schema.getType("additional").toString(), is(additionalType.toString()));
+ }
+}
diff --git a/src/test/java/graphql/annotations/GraphQLBatchedTest.java b/src/test/java/graphql/annotations/GraphQLBatchedTest.java
index a61c3c1b..213b6f18 100644
--- a/src/test/java/graphql/annotations/GraphQLBatchedTest.java
+++ b/src/test/java/graphql/annotations/GraphQLBatchedTest.java
@@ -31,16 +31,18 @@
import java.util.Map;
import static graphql.Scalars.GraphQLString;
-import static graphql.schema.GraphQLSchema.newSchema;
+import static graphql.annotations.AnnotationsSchemaCreator.newAnnotationsSchema;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@SuppressWarnings("unchecked")
public class GraphQLBatchedTest {
+ private GraphQLAnnotations graphQLAnnotations;
+
@BeforeMethod
public void init() {
- GraphQLAnnotations.getInstance().getTypeRegistry().clear();
+ this.graphQLAnnotations = new GraphQLAnnotations();
}
public static class SimpleBatchedField {
@@ -60,11 +62,10 @@ public List fields() {
@Test
public void batchedDataFetcher() throws Throwable {
- GraphQLObjectType nestedObject = GraphQLAnnotations.object(SimpleBatchedField.class);
+ GraphQLObjectType nestedObject = this.graphQLAnnotations.object(SimpleBatchedField.class);
assertEquals(nestedObject.getFieldDefinition("a").getType(), GraphQLString);
- GraphQLObjectType object = GraphQLAnnotations.object(TestBatchedObject.class);
- GraphQLSchema schema = newSchema().query(object).build();
+ GraphQLSchema schema = newAnnotationsSchema().query(TestBatchedObject.class).build();
GraphQL graphql = GraphQL.newGraphQL(schema).queryExecutionStrategy(new BatchedExecutionStrategy()).build();
ExecutionResult result = graphql.execute("{ fields { a } }", new TestBatchedObject());
List errors = result.getErrors();
@@ -88,7 +89,7 @@ public List a() {
@Test(expectedExceptions = IllegalArgumentException.class)
public void noStaticField() {
- GraphQLObjectType object = GraphQLAnnotations.object(NoStaticBatchedField.class);
+ GraphQLObjectType object = this.graphQLAnnotations.object(NoStaticBatchedField.class);
}
public static class NoListBatchedField {
@@ -101,7 +102,7 @@ public String a() {
@Test(expectedExceptions = IllegalArgumentException.class)
public void noListField() {
- GraphQLObjectType object = GraphQLAnnotations.object(NoStaticBatchedField.class);
+ GraphQLObjectType object = this.graphQLAnnotations.object(NoStaticBatchedField.class);
}
public static class NoParameterizedBatchedField {
@@ -114,6 +115,6 @@ public List a() {
@Test(expectedExceptions = IllegalArgumentException.class)
public void noParameterizedReturnField() {
- GraphQLObjectType object = GraphQLAnnotations.object(NoStaticBatchedField.class);
+ GraphQLObjectType object = this.graphQLAnnotations.object(NoStaticBatchedField.class);
}
}
diff --git a/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java b/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java
index 1cc0626d..233a58df 100644
--- a/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java
+++ b/src/test/java/graphql/annotations/GraphQLDataFetcherTest.java
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,27 +20,31 @@
import graphql.annotations.annotationTypes.GraphQLField;
import graphql.annotations.annotationTypes.GraphQLName;
import graphql.annotations.processor.GraphQLAnnotations;
-import graphql.schema.*;
+import graphql.schema.DataFetcher;
+import graphql.schema.DataFetchingEnvironment;
+import graphql.schema.GraphQLSchema;
+import graphql.schema.PropertyDataFetcher;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.HashMap;
-import static graphql.schema.GraphQLSchema.newSchema;
+import static graphql.annotations.AnnotationsSchemaCreator.newAnnotationsSchema;
import static org.testng.Assert.*;
public class GraphQLDataFetcherTest {
+ private GraphQLAnnotations graphQLAnnotations;
+
@BeforeMethod
public void init() {
- GraphQLAnnotations.getInstance().getTypeRegistry().clear();
+ this.graphQLAnnotations = new GraphQLAnnotations();
}
@Test
public void shouldUsePreferredConstructor() {
// Given
- final GraphQLObjectType object = GraphQLAnnotations.object(GraphQLDataFetcherTest.TestGraphQLQuery.class);
- final GraphQLSchema schema = newSchema().query(object).build();
+ final GraphQLSchema schema = newAnnotationsSchema().query(GraphQLDataFetcherTest.TestGraphQLQuery.class).build();
GraphQL graphql = GraphQL.newGraphQL(schema).build();
// When
@@ -56,8 +60,7 @@ public void shouldUsePreferredConstructor() {
@Test
public void shouldUseProvidedSoloArgumentForDataFetcherDeclaredInMethod() {
// Given
- final GraphQLObjectType object = GraphQLAnnotations.object(TestMethodWithDataFetcherGraphQLQuery.class);
- final GraphQLSchema schema = newSchema().query(object).build();
+ final GraphQLSchema schema = newAnnotationsSchema().query(TestMethodWithDataFetcherGraphQLQuery.class).build();
final GraphQL graphql = GraphQL.newGraphQL(schema).build();
// When
@@ -66,14 +69,13 @@ public void shouldUseProvidedSoloArgumentForDataFetcherDeclaredInMethod() {
// Then
final HashMap data = result.getData();
assertNotNull(data);
- assertFalse((Boolean)data.get("great"));
+ assertFalse((Boolean) data.get("great"));
}
@Test
public void shouldUseTargetAndArgumentsForDataFetcherDeclaredInMethod() {
// Given
- final GraphQLObjectType object = GraphQLAnnotations.object(TestMethodWithDataFetcherGraphQLQuery.class);
- final GraphQLSchema schema = newSchema().query(object).build();
+ final GraphQLSchema schema = newAnnotationsSchema().query(TestMethodWithDataFetcherGraphQLQuery.class).build();
final GraphQL graphql = GraphQL.newGraphQL(schema).build();
// When
@@ -82,7 +84,7 @@ public void shouldUseTargetAndArgumentsForDataFetcherDeclaredInMethod() {
// Then
final HashMap data = result.getData();
assertNotNull(data);
- assertTrue(((HashMap)data.get("sample")).get("isBad"));
+ assertTrue(((HashMap) data.get("sample")).get("isBad"));
}
@GraphQLName("Query")
@@ -90,7 +92,7 @@ public static class TestGraphQLQuery {
@GraphQLField
@GraphQLDataFetcher(SampleDataFetcher.class)
public TestSample sample() { // Note that GraphQL uses TestSample to build the graph
- return null;
+ return null;
}
}
@@ -98,11 +100,15 @@ public TestSample sample() { // Note that GraphQL uses TestSample to build the g
public static class TestMethodWithDataFetcherGraphQLQuery {
@GraphQLField
@GraphQLDataFetcher(value = SampleOneArgDataFetcher.class, args = "true")
- public Boolean great() { return false; }
+ public Boolean great() {
+ return false;
+ }
@GraphQLField
@GraphQLDataFetcher(SampleDataFetcher.class)
- public TestSampleMethod sample() { return null; }
+ public TestSampleMethod sample() {
+ return null;
+ }
}
public static class TestSample {
@@ -120,7 +126,9 @@ public static class TestSampleMethod {
@GraphQLField
@GraphQLDataFetcher(value = SampleMultiArgDataFetcher.class, firstArgIsTargetName = true, args = {"true"})
- public Boolean isBad() { return false; } // Defaults to FieldDataFetcher
+ public Boolean isBad() {
+ return false;
+ } // Defaults to FieldDataFetcher
}
@@ -135,16 +143,12 @@ public static class SampleOneArgDataFetcher implements DataFetcher {
private boolean flip = false;
public SampleOneArgDataFetcher(String flip) {
- this.flip = Boolean.valueOf(flip);
+ this.flip = Boolean.valueOf(flip);
}
@Override
public Object get(DataFetchingEnvironment environment) {
- if ( flip ) {
- return !flip;
- } else {
- return flip;
- }
+ return !flip;
}
}
@@ -160,7 +164,7 @@ public SampleMultiArgDataFetcher(String target, String flip) {
public Object get(DataFetchingEnvironment environment) {
final Object result = super.get(environment);
if (flip) {
- return !(Boolean)result;
+ return !(Boolean) result;
} else {
return result;
}
diff --git a/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java b/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java
index 37b43443..9378d61e 100644
--- a/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java
+++ b/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java
@@ -21,6 +21,7 @@
import graphql.introspection.Introspection;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLDirective;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static graphql.Scalars.GraphQLBoolean;
@@ -30,6 +31,13 @@
public class GraphQLDirectiveCreationTest {
+ private GraphQLAnnotations graphQLAnnotations;
+
+ @BeforeMethod
+ public void setUp() {
+ this.graphQLAnnotations = new GraphQLAnnotations();
+ }
+
@GraphQLName("upper")
@GraphQLDescription("makes string upper case")
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.INTERFACE})
@@ -45,7 +53,7 @@ public static class UpperDirective {
@Test
public void test_directive_creation() {
// Act
- GraphQLDirective directive = GraphQLAnnotations.directive(UpperDirective.class);
+ GraphQLDirective directive = this.graphQLAnnotations.directive(UpperDirective.class);
// Assert
assertEquals(directive.getName(), "upper");
diff --git a/src/test/java/graphql/annotations/GraphQLDirectivesTest.java b/src/test/java/graphql/annotations/GraphQLDirectivesTest.java
index 71c6cbfe..2f29e4cc 100644
--- a/src/test/java/graphql/annotations/GraphQLDirectivesTest.java
+++ b/src/test/java/graphql/annotations/GraphQLDirectivesTest.java
@@ -12,20 +12,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/
-package graphql.annotations; /**
- * Copyright 2016 Yurii Rashkovskii
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *