Class SingleArgumentAnnotatedMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>
java.lang.Object
dk.cloudcreate.essentials.shared.reflection.invocation.SingleArgumentAnnotatedMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>
- Type Parameters:
ARGUMENT_COMMON_ROOT_TYPE- The method argument common root type (i.e. a common superclass or common interface) for the argument-type that we're performing pattern matching on.
If there isn't a common root type, then you can specifyObjectinsteadExample: Within a single class we have placed a set methods that can handle
OrderEvent's, such asOrderCreated, OrderShipped, OrderAccepted, etc.
In this caseOrderEventwill be ourARGUMENT_ROOT_TYPEas it forms the root of the type hierarchy.
- All Implemented Interfaces:
MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>
public final class SingleArgumentAnnotatedMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>
extends Object
implements MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>
A strategy that matches methods annotated with
Example using parameterized types:
matchOnMethodsAnnotatedWith
and have a single method argument that is the same type or a sub-type of the ARGUMENT_COMMON_ROOT_TYPE
Example using parameterized types:
var patternMatchingInvoker = new PatternMatchingMethodInvoker<>(invokeMethodsOn,
new SingleArgumentAnnotatedMethodPatternMatcher<>(EventHandler.class,
new GenericType<Event<OrderId>>() {}),
InvocationStrategy.InvokeMostSpecificTypeMatched);
Example using non-parameterized types:
var patternMatchingInvoker = new PatternMatchingMethodInvoker<>(invokeMethodsOn,
new SingleArgumentAnnotatedMethodPatternMatcher<>(EventHandler.class,
OrderEvent.class),
InvocationStrategy.InvokeMostSpecificTypeMatched);
Usage:
invoker.invoke(event, unmatchedEvent -> {
// Decide how to handle if a given event doesn't have a corresponding handler
});
-
Constructor Summary
ConstructorsConstructorDescriptionSingleArgumentAnnotatedMethodPatternMatcher(Class<? extends Annotation> matchOnMethodsAnnotatedWith, GenericType<ARGUMENT_COMMON_ROOT_TYPE> argumentCommonRootType) Create a new strategy that matches methods annotated withmatchOnMethodsAnnotatedWithand have a single method argument that is the same type or a sub-type of theARGUMENT_COMMON_ROOT_TYPESingleArgumentAnnotatedMethodPatternMatcher(Class<? extends Annotation> matchOnMethodsAnnotatedWith, Class<ARGUMENT_COMMON_ROOT_TYPE> argumentCommonRootType) Create a new strategy that matches methods annotated withmatchOnMethodsAnnotatedWithand have a single method argument that is the same type or a sub-type of theARGUMENT_COMMON_ROOT_TYPE -
Method Summary
Modifier and TypeMethodDescriptionvoidinvokeMethod(Method methodToInvoke, Object argument, Object invokeMethodOn, Class<?> resolvedInvokeMethodWithArgumentOfType) This method is responsible for calling themethodToInvokeon theinvokeMethodOnObjectobject using the right parameters based on thewithObject.
For simple cases the argument will only be thewithObject, where it for other cases may involve extracting the real object to pass onto themethodToInvokefrom within thewithObject(e.g.booleanisInvokableMethod(Method candidateMethod) Determines if a candidateMethod is a candidate for being invoked byPatternMatchingMethodInvokerClass<?>Returns the (single) type this method can be invoked with.Class<?>Resolves which type should be used for looking up matching invokable methods
In simple cases this will be the same type as theargument's, but for enveloped types (such as Messages that encapsulate a payload) we may want to match methods against the message' payload type instead of the message type
-
Constructor Details
-
SingleArgumentAnnotatedMethodPatternMatcher
public SingleArgumentAnnotatedMethodPatternMatcher(Class<? extends Annotation> matchOnMethodsAnnotatedWith, Class<ARGUMENT_COMMON_ROOT_TYPE> argumentCommonRootType) Create a new strategy that matches methods annotated withmatchOnMethodsAnnotatedWithand have a single method argument that is the same type or a sub-type of theARGUMENT_COMMON_ROOT_TYPE- Parameters:
matchOnMethodsAnnotatedWith- the annotation that invokable methods are annotated withargumentCommonRootType- the base type for the single method argument
-
-
Method Details
-
isInvokableMethod
Description copied from interface:MethodPatternMatcherDetermines if a candidateMethod is a candidate for being invoked byPatternMatchingMethodInvoker- Specified by:
isInvokableMethodin interfaceMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>- Parameters:
candidateMethod- the candidate method to test for invocation- Returns:
- true if the candidateMethod is invokable, otherwise false
-
resolveInvocationArgumentTypeFromMethodDefinition
Description copied from interface:MethodPatternMatcherReturns the (single) type this method can be invoked with. This method MUST return the type supported OR throw aRuntimeExceptionin case the method doesn't allow resolving a type- Specified by:
resolveInvocationArgumentTypeFromMethodDefinitionin interfaceMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>- Parameters:
method- the method to resolve the invokeWithObject type (requirement the method has passed theMethodPatternMatcher.isInvokableMethod(Method)test)- Returns:
- The type supported
-
resolveInvocationArgumentTypeFromObject
Description copied from interface:MethodPatternMatcherResolves which type should be used for looking up matching invokable methods
In simple cases this will be the same type as theargument's, but for enveloped types (such as Messages that encapsulate a payload) we may want to match methods against the message' payload type instead of the message type- Specified by:
resolveInvocationArgumentTypeFromObjectin interfaceMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>- Parameters:
argument- the argument instance- Returns:
- the type that should be used for looking up matching invokable methods
-
invokeMethod
public void invokeMethod(Method methodToInvoke, Object argument, Object invokeMethodOn, Class<?> resolvedInvokeMethodWithArgumentOfType) throws Exception Description copied from interface:MethodPatternMatcherThis method is responsible for calling themethodToInvokeon theinvokeMethodOnObjectobject using the right parameters based on thewithObject.
For simple cases the argument will only be thewithObject, where it for other cases may involve extracting the real object to pass onto themethodToInvokefrom within thewithObject(e.g. in case of a wrapped type, such as a message object that contains the real payload to supply to themethodToInvoke)- Specified by:
invokeMethodin interfaceMethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE>- Parameters:
methodToInvoke- the method that must be reflectively invoked. You can assume that the method is Acessible alreadyargument- The argument instance passed toPatternMatchingMethodInvoker.invoke(Object)/PatternMatchingMethodInvoker.invoke(Object, NoMatchingMethodsHandler)and which was used in the call toMethodPatternMatcher.resolveInvocationArgumentTypeFromObject(Object)
In simple cases this will be the same type as theargument's, but for enveloped types (such as Messages that encapsulate a payload) we may want to match methods against the message' payload type instead of the message type.invokeMethodOn- the object that themethodToInvokemust be invoked on (the target object of theMethod.invoke(Object, Object...))resolvedInvokeMethodWithArgumentOfType- The resolved withObjectType (as resolved byMethodPatternMatcher.resolveInvocationArgumentTypeFromObject(Object))- Throws:
Exception- Feel free to throw any Reflection exceptions, etc.
ThePatternMatchingMethodInvokerwill ensure to either unwrap the real cause or wrap any checked exceptions in a Runtime exception.
-