Skip to content

Commit fbe8735

Browse files
committed
Extract InvocableHandlerMethodSupport
This prepares the way to invoke handler methods other than those adapted to a DataFetcher with DataFetcherEnvironment as input. See gh-130
1 parent f8f6a3e commit fbe8735

File tree

3 files changed

+83
-45
lines changed

3 files changed

+83
-45
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethod.java renamed to spring-graphql/src/main/java/org/springframework/graphql/data/method/DataFetcherHandlerMethod.java

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,26 @@
1515
*/
1616
package org.springframework.graphql.data.method;
1717

18-
import java.lang.reflect.InvocationTargetException;
19-
import java.lang.reflect.Method;
2018
import java.util.Arrays;
2119

2220
import graphql.schema.DataFetchingEnvironment;
2321

24-
import org.springframework.core.CoroutinesUtils;
2522
import org.springframework.core.DefaultParameterNameDiscoverer;
26-
import org.springframework.core.KotlinDetector;
2723
import org.springframework.core.MethodParameter;
2824
import org.springframework.core.ParameterNameDiscoverer;
2925
import org.springframework.lang.Nullable;
3026
import org.springframework.util.Assert;
3127
import org.springframework.util.ObjectUtils;
32-
import org.springframework.util.ReflectionUtils;
3328

3429
/**
35-
* Extension of {@link HandlerMethod} that can resolve method arguments from a
36-
* {@link DataFetchingEnvironment} and invoke the method.
30+
* An extension of {@link HandlerMethod} for annotated handler methods adapted
31+
* to {@link graphql.schema.DataFetcher} with {@link DataFetchingEnvironment}
32+
* as their input.
3733
*
3834
* @author Rossen Stoyanchev
3935
* @since 1.0.0
4036
*/
41-
public class InvocableHandlerMethod extends HandlerMethod {
37+
public class DataFetcherHandlerMethod extends InvocableHandlerMethodSupport {
4238

4339
private static final Object[] EMPTY_ARGS = new Object[0];
4440

@@ -48,7 +44,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
4844
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
4945

5046

51-
public InvocableHandlerMethod(HandlerMethod handlerMethod, HandlerMethodArgumentResolverComposite resolvers) {
47+
public DataFetcherHandlerMethod(HandlerMethod handlerMethod, HandlerMethodArgumentResolverComposite resolvers) {
5248
super(handlerMethod);
5349
Assert.isTrue(!resolvers.getResolvers().isEmpty(), "No argument resolvers");
5450
this.resolvers = resolvers;
@@ -127,40 +123,4 @@ protected Object[] getMethodArgumentValues(
127123
return args;
128124
}
129125

130-
/**
131-
* Invoke the handler method with the given argument values.
132-
*/
133-
@Nullable
134-
protected Object doInvoke(Object... args) throws Exception {
135-
Method method = getBridgedMethod();
136-
ReflectionUtils.makeAccessible(method);
137-
try {
138-
if (KotlinDetector.isSuspendingFunction(method)) {
139-
return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
140-
}
141-
return method.invoke(getBean(), args);
142-
}
143-
catch (IllegalArgumentException ex) {
144-
assertTargetBean(method, getBean(), args);
145-
String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
146-
throw new IllegalStateException(formatInvokeError(text, args), ex);
147-
}
148-
catch (InvocationTargetException ex) {
149-
// Unwrap for DataFetcherExceptionResolvers ...
150-
Throwable targetException = ex.getTargetException();
151-
if (targetException instanceof RuntimeException) {
152-
throw (RuntimeException) targetException;
153-
}
154-
else if (targetException instanceof Error) {
155-
throw (Error) targetException;
156-
}
157-
else if (targetException instanceof Exception) {
158-
throw (Exception) targetException;
159-
}
160-
else {
161-
throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
162-
}
163-
}
164-
}
165-
166126
}

spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethod.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.util.Assert;
3333
import org.springframework.util.ClassUtils;
3434
import org.springframework.util.ObjectUtils;
35+
import org.springframework.util.ReflectionUtils;
3536
import org.springframework.util.StringUtils;
3637

3738
/**
@@ -78,6 +79,7 @@ public HandlerMethod(Object bean, Method method) {
7879
this.beanType = ClassUtils.getUserClass(bean);
7980
this.method = method;
8081
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
82+
ReflectionUtils.makeAccessible(this.bridgedMethod);
8183
this.parameters = initMethodParameters();
8284
}
8385

@@ -100,6 +102,7 @@ public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
100102
this.beanType = ClassUtils.getUserClass(beanType);
101103
this.method = method;
102104
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
105+
ReflectionUtils.makeAccessible(this.bridgedMethod);
103106
this.parameters = initMethodParameters();
104107
}
105108

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2002-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.graphql.data.method;
17+
18+
import java.lang.reflect.InvocationTargetException;
19+
import java.lang.reflect.Method;
20+
21+
import org.springframework.core.CoroutinesUtils;
22+
import org.springframework.core.KotlinDetector;
23+
import org.springframework.lang.Nullable;
24+
25+
/**
26+
* Extension of {@link HandlerMethod} that adds support for invoking the
27+
* annotated handler methods.
28+
*
29+
* @author Rossen Stoyanchev
30+
* @since 1.0.0
31+
*/
32+
public abstract class InvocableHandlerMethodSupport extends HandlerMethod {
33+
34+
35+
protected InvocableHandlerMethodSupport(HandlerMethod handlerMethod) {
36+
super(handlerMethod.createWithResolvedBean());
37+
}
38+
39+
40+
/**
41+
* Invoke the handler method with the given argument values.
42+
*/
43+
@Nullable
44+
protected Object doInvoke(Object... args) throws Exception {
45+
Method method = getBridgedMethod();
46+
try {
47+
if (KotlinDetector.isSuspendingFunction(method)) {
48+
return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
49+
}
50+
return method.invoke(getBean(), args);
51+
}
52+
catch (IllegalArgumentException ex) {
53+
assertTargetBean(method, getBean(), args);
54+
String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
55+
throw new IllegalStateException(formatInvokeError(text, args), ex);
56+
}
57+
catch (InvocationTargetException ex) {
58+
// Unwrap for DataFetcherExceptionResolvers ...
59+
Throwable targetException = ex.getTargetException();
60+
if (targetException instanceof RuntimeException) {
61+
throw (RuntimeException) targetException;
62+
}
63+
else if (targetException instanceof Error) {
64+
throw (Error) targetException;
65+
}
66+
else if (targetException instanceof Exception) {
67+
throw (Exception) targetException;
68+
}
69+
else {
70+
throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
71+
}
72+
}
73+
}
74+
75+
}

0 commit comments

Comments
 (0)