graphql.annotations.dataFetchers.MethodDataFetcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of graphql-java-annotations Show documentation
Show all versions of graphql-java-annotations Show documentation
Annotations-based syntax for GraphQL schema definition
/**
* 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.dataFetchers;
import graphql.annotations.annotationTypes.GraphQLBatched;
import graphql.annotations.annotationTypes.GraphQLInvokeDetached;
import graphql.annotations.annotationTypes.GraphQLName;
import graphql.annotations.processor.ProcessingElementsContainer;
import graphql.annotations.processor.typeFunctions.TypeFunction;
import graphql.schema.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static graphql.annotations.processor.util.NamingKit.toGraphqlName;
import static graphql.annotations.processor.util.PrefixesUtil.addPrefixToPropertyName;
import static graphql.annotations.processor.util.PrefixesUtil.extractPrefixedName;
import static graphql.annotations.processor.util.ReflectionKit.constructNewInstance;
import static graphql.annotations.processor.util.ReflectionKit.newInstance;
/**
* This class is determining how to return value of a method from an api entity
* The order of the mapping:
* 1. If no source is provided to map between - invoking the method implementation
* 2. If annotated with @GraphQLInvokeDetached - invoking the method implementation
* 3. else If source is provided, and method name is matching a method name in the source object - execute source implementation
* i.e method name is: `name` ; existing method in the source object with name: `name`
* 4. else If source is provided, and method name is matching a method name with a `get` prefix in the source object - execute source implementation
* i.e method name is: `name` ; existing method in the source object with name: `getName`
* 5. else If source is provided, and method name is matching a method name with a `is` prefix in the source object - execute source implementation
* i.e method name is: `name` ; existing method in the source object with name: isName
* 6. else If source is provided, and method name is matching a field name in the source object - return field value from the source object
* i.e method name is: `name` ; field name in source object is: `name`
* 7. else If source is provided, and method name is prefixed with `get` or `is` - and it matches to a field name (without the prefix) in the source object - return field value from the source object
* i.e method name is: `getName` ; field name in source object is: `name`
*
* @param type of the returned value
*/
public class MethodDataFetcher implements DataFetcher {
private final Method method;
private final ProcessingElementsContainer container;
private final TypeFunction typeFunction;
public MethodDataFetcher(Method method, TypeFunction typeFunction, ProcessingElementsContainer container) {
this.method = method;
this.typeFunction = typeFunction;
this.container = container;
}
@Override
public T get(DataFetchingEnvironment environment) {
try {
T obj;
if (Modifier.isStatic(method.getModifiers())){
return (T) method.invoke(null, invocationArgs(environment, container));
}
else if (method.isAnnotationPresent(GraphQLBatched.class) || method.isAnnotationPresent(GraphQLInvokeDetached.class)) {
obj = newInstance((Class) method.getDeclaringClass());
} else if (!method.getDeclaringClass().isInstance(environment.getSource())) {
obj = newInstance((Class) method.getDeclaringClass(), environment.getSource());
} else {
obj = environment.getSource();
if (obj == null) {
return null;
}
}
if (obj == null && environment.getSource() != null) {
Object value = getGraphQLFieldValue(environment.getSource(), method.getName());
return (T) value;
}
return (T) method.invoke(obj, invocationArgs(environment, container));
} catch (IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
private Object[] invocationArgs(DataFetchingEnvironment environment, ProcessingElementsContainer container) {
List