|
|
|
@ -25,9 +25,7 @@ import java.util.stream.Collectors; |
|
|
|
import java.util.stream.IntStream; |
|
|
|
import java.util.stream.IntStream; |
|
|
|
import java.util.stream.Stream; |
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
|
|
|
import reactor.Flux; |
|
|
|
|
|
|
|
import reactor.Mono; |
|
|
|
import reactor.Mono; |
|
|
|
import reactor.fn.tuple.Tuple; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.DefaultParameterNameDiscoverer; |
|
|
|
import org.springframework.core.DefaultParameterNameDiscoverer; |
|
|
|
import org.springframework.core.GenericTypeResolver; |
|
|
|
import org.springframework.core.GenericTypeResolver; |
|
|
|
@ -46,7 +44,7 @@ import org.springframework.web.reactive.HandlerResult; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class InvocableHandlerMethod extends HandlerMethod { |
|
|
|
public class InvocableHandlerMethod extends HandlerMethod { |
|
|
|
|
|
|
|
|
|
|
|
public static final Mono<Object[]> NO_ARGS = Mono.just(new Object[0]); |
|
|
|
private static final Mono<Object[]> NO_ARGS = Mono.just(new Object[0]); |
|
|
|
|
|
|
|
|
|
|
|
private final static Object NO_VALUE = new Object(); |
|
|
|
private final static Object NO_VALUE = new Object(); |
|
|
|
|
|
|
|
|
|
|
|
@ -85,19 +83,7 @@ public class InvocableHandlerMethod extends HandlerMethod { |
|
|
|
* never throws an exception. |
|
|
|
* never throws an exception. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Mono<HandlerResult> invokeForRequest(ServerHttpRequest request, Object... providedArgs) { |
|
|
|
public Mono<HandlerResult> invokeForRequest(ServerHttpRequest request, Object... providedArgs) { |
|
|
|
|
|
|
|
return resolveArguments(request, providedArgs).then(args -> { |
|
|
|
Mono<Object[]> argsPublisher = NO_ARGS; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
if (!ObjectUtils.isEmpty(getMethodParameters())) { |
|
|
|
|
|
|
|
List<Mono<Object>> publishers = resolveArguments(request, providedArgs); |
|
|
|
|
|
|
|
argsPublisher = Flux.zip(publishers, this::initArgs).next(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Throwable ex) { |
|
|
|
|
|
|
|
return Mono.error(ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Flux.from(argsPublisher).concatMap(args -> { |
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
Object value = doInvoke(args); |
|
|
|
Object value = doInvoke(args); |
|
|
|
ResolvableType type = ResolvableType.forMethodParameter(getReturnType()); |
|
|
|
ResolvableType type = ResolvableType.forMethodParameter(getReturnType()); |
|
|
|
@ -111,35 +97,46 @@ public class InvocableHandlerMethod extends HandlerMethod { |
|
|
|
String s = getInvocationErrorMessage(args); |
|
|
|
String s = getInvocationErrorMessage(args); |
|
|
|
return Mono.error(new IllegalStateException(s)); |
|
|
|
return Mono.error(new IllegalStateException(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
}).next(); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<Mono<Object>> resolveArguments(ServerHttpRequest request, Object... providedArgs) { |
|
|
|
private Mono<Object[]> resolveArguments(ServerHttpRequest request, Object... providedArgs) { |
|
|
|
return Stream.of(getMethodParameters()) |
|
|
|
if (ObjectUtils.isEmpty(getMethodParameters())) { |
|
|
|
.map(parameter -> { |
|
|
|
return NO_ARGS; |
|
|
|
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); |
|
|
|
} |
|
|
|
GenericTypeResolver.resolveParameterType(parameter, getBean().getClass()); |
|
|
|
try { |
|
|
|
if (!ObjectUtils.isEmpty(providedArgs)) { |
|
|
|
List<Mono<Object>> monos = Stream.of(getMethodParameters()) |
|
|
|
for (Object providedArg : providedArgs) { |
|
|
|
.map(param -> { |
|
|
|
if (parameter.getParameterType().isInstance(providedArg)) { |
|
|
|
param.initParameterNameDiscovery(this.parameterNameDiscoverer); |
|
|
|
return Mono.just(providedArg); |
|
|
|
GenericTypeResolver.resolveParameterType(param, getBean().getClass()); |
|
|
|
|
|
|
|
if (!ObjectUtils.isEmpty(providedArgs)) { |
|
|
|
|
|
|
|
for (Object providedArg : providedArgs) { |
|
|
|
|
|
|
|
if (param.getParameterType().isInstance(providedArg)) { |
|
|
|
|
|
|
|
return Mono.just(providedArg); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
HandlerMethodArgumentResolver resolver = this.resolvers.stream() |
|
|
|
HandlerMethodArgumentResolver resolver = this.resolvers.stream() |
|
|
|
.filter(r -> r.supportsParameter(param)) |
|
|
|
.filter(r -> r.supportsParameter(parameter)) |
|
|
|
.findFirst() |
|
|
|
.findFirst() |
|
|
|
.orElseThrow(() -> getArgError("No resolver for ", param, null)); |
|
|
|
.orElseThrow(() -> getArgError("No resolver for ", parameter, null)); |
|
|
|
try { |
|
|
|
try { |
|
|
|
return resolver.resolveArgument(param, request) |
|
|
|
return resolver.resolveArgument(parameter, request) |
|
|
|
.defaultIfEmpty(NO_VALUE) |
|
|
|
.defaultIfEmpty(NO_VALUE) |
|
|
|
.otherwise(ex -> Mono.error(getArgError("Error resolving ", param, ex))); |
|
|
|
.otherwise(ex -> Mono.error(getArgError("Error resolving ", parameter, ex))); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
throw getArgError("Error resolving ", param, ex); |
|
|
|
throw getArgError("Error resolving ", parameter, ex); |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
|
|
|
return Mono.when(monos).map(args -> |
|
|
|
|
|
|
|
Stream.of(args.toArray()).map(o -> o != NO_VALUE ? o : null).toArray()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Throwable ex) { |
|
|
|
|
|
|
|
return Mono.error(ex); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private IllegalStateException getArgError(String message, MethodParameter param, Throwable cause) { |
|
|
|
private IllegalStateException getArgError(String message, MethodParameter param, Throwable cause) { |
|
|
|
@ -173,8 +170,4 @@ public class InvocableHandlerMethod extends HandlerMethod { |
|
|
|
"on method [" + getBridgedMethod().toGenericString() + "]"; |
|
|
|
"on method [" + getBridgedMethod().toGenericString() + "]"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Object[] initArgs(Tuple tuple) { |
|
|
|
|
|
|
|
return Stream.of(tuple.toArray()).map(o -> o != NO_VALUE ? o : null).toArray(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|