Class PatternMatchingMethodInvoker<ARGUMENT_COMMON_ROOT_TYPE>
- java.lang.Object
-
- dk.cloudcreate.essentials.shared.reflection.invocation.PatternMatchingMethodInvoker<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.
public final class PatternMatchingMethodInvoker<ARGUMENT_COMMON_ROOT_TYPE> extends Object
The purpose of thePatternMatchingMethodInvokeris to support pattern matching a set of typed methods against a concreteargumentand have the method(s) that match the type resolved by theMethodPatternMatcher.resolveInvocationArgumentTypeFromObject(Object)will be invoked by theMethodPatternMatcher.invokeMethod(Method, Object, Object, Class)with the argument
Example: Say we have a single class we have placed a set methods that can handle
After deciding on theOrderEvent's, such asOrderCreated, OrderShipped, OrderAccepted, etc.
In this caseOrderEventwill be ourARGUMENT_ROOT_TYPEas it forms the root of the type hierarchy.ARGUMENT_ROOT_TYPEwe need to determine how to match the methods.
This involves several parts: 1. Method Pattern usingMethodPatternMatcher.isInvokableMethod(Method)Example of methods patterns that matches the intention of this class:- Annotation based - where an annotation marks the methods that should be matched:
@EventHandler private void some_name_that_we_do_not_care_about(OrderCreated t, ...) { ... } @EventHandler private void some_name_that_we_do_not_care_about(OrderAccepted t, ...) { ... } - Name based - where a specific name, e.g. "
on" in the example below, the methods that should be matched:private void on(OrderCreated t) { ... } private void on(OrderAccepted t) { ... } - Or some other patterns that you're interested in supporting
MethodPatternMatcher.resolveInvocationArgumentTypeFromMethodDefinition(Method)3. Discover all methods matching the argument instance supplied to theinvoke(Object)/invoke(Object, NoMatchingMethodsHandler)methods After we've filtered out and found the methods that match our pattern, next phase is to figure out what methods match a concrete argument instance.
Example: Let's say theargumentobject is an instance ofOrderAcceptedand we're matching against the following methods@EventHandler private void method1(OrderEvent t) { ... } @EventHandler private void method2(OrderShipped t) { ... } @EventHandler private void method3(OrderAccepted t) { ... }In this case both
4. Choose which method(s) to invoke Next step is to check themethod1andmethod3match on type of the argument instance (OrderAccepted), becauseOrderEvent(ofmethod1) match by hierarchy, andOrderAccepted(ofmethod3) match directly by type.InvocationStrategyto determine which method(s) to invoke based on the concrete argument instance supplied to theinvoke(Object)/invoke(Object, NoMatchingMethodsHandler)methodsInvocationStrategy.InvokeMostSpecificTypeMatched- in which case onlymethod3will be called, sinceOrderAcceptedis a more specific type than the more generic typeOrderEventInvocationStrategy.InvokeAllMatches- in which case BOTHmethod1andmethod3will be called in sequence (notice: the order of the methods called is not deterministic)
MethodPatternMatcherFor some methods, it's not necessarily the first argument that decides what argument-type the method supports and the method may need to be called with multiple arguments and not just one.
E.g. when handling 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
What methods is a candidate for matching, what type a given method supports and how the method is invoked is determined byMethodPatternMatcher.
For more simple cases theSingleArgumentAnnotatedMethodPatternMatcherprovides a good default implementation. Logging Using a setup where thePatternMatchingMethodInvokeris invoking methods on an instance ofdk.cloudcreate.handlers.OrderEventsHandler
and you wantvar patternMatchingInvoker = new PatternMatchingMethodInvoker<>(new dk.cloudcreate.handlers.OrderEventsHandler(), new SingleArgumentAnnotatedMethodPatternMatcher(EventHandler.class, OrderEvent.class), InvocationStrategy.InvokeMostSpecificTypeMatched, Optional.empty());PatternMatchingMethodInvokerlogging then you should set the logging level fordk.cloudcreate.handlers.OrderEventsHandlertoTRACE
-
-
Constructor Summary
Constructors Constructor Description PatternMatchingMethodInvoker(Object invokeMethodsOn, MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE> methodPatternMatcher, InvocationStrategy invocationStrategy)Setup a pattern matching method invoker using the default no-opNoMatchingMethodsHandlerPatternMatchingMethodInvoker(Object invokeMethodsOn, MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE> methodPatternMatcher, InvocationStrategy invocationStrategy, Optional<NoMatchingMethodsHandler> defaultNoMatchingMethodsHandler)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanhasMatchingMethod(Class<?> argumentType)voidinvoke(Object argument)Invoke matching methods based on theargumenton theinvokeMethodsOnbased on theMethodPatternMatcherandInvocationStrategyusing the defaultdefaultNoMatchingMethodsHandlerdefined in thePatternMatchingMethodInvoker(Object, MethodPatternMatcher, InvocationStrategy, Optional)voidinvoke(Object argument, NoMatchingMethodsHandler noMatchingMethodsHandler)Invoke matching methods based on theargumenton theinvokeMethodsOnbased on theMethodPatternMatcherandInvocationStrategy
-
-
-
Constructor Detail
-
PatternMatchingMethodInvoker
public PatternMatchingMethodInvoker(Object invokeMethodsOn, MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE> methodPatternMatcher, InvocationStrategy invocationStrategy)
Setup a pattern matching method invoker using the default no-opNoMatchingMethodsHandler- Parameters:
invokeMethodsOn- The object that contains the methods that we will perform pattern matching and invoke methods onmethodPatternMatcher- The strategy that determines the methods that can be invoked as well as determine which type of argument the given method supports and how the method later is going to be invokedinvocationStrategy- Wheninvoke(Object)orinvoke(Object, NoMatchingMethodsHandler)is called this strategy determines which Methods, among all the methods that match the argument, will be invoked
-
PatternMatchingMethodInvoker
public PatternMatchingMethodInvoker(Object invokeMethodsOn, MethodPatternMatcher<ARGUMENT_COMMON_ROOT_TYPE> methodPatternMatcher, InvocationStrategy invocationStrategy, Optional<NoMatchingMethodsHandler> defaultNoMatchingMethodsHandler)
- Parameters:
invokeMethodsOn- The object that contains the methods that we will perform pattern matching and invoke methods onmethodPatternMatcher- The strategy that determines the methods that can be invoked as well as determine which type of argument the given method supports and how the method later is going to be invokedinvocationStrategy- Wheninvoke(Object)orinvoke(Object, NoMatchingMethodsHandler)is called this strategy determines which Methods, among all the methods that match the argument, will be invokeddefaultNoMatchingMethodsHandler- default consumer that will be called ifinvoke(Object)is called with an argument that doesn't match any methods
-
-
Method Detail
-
invoke
public void invoke(Object argument)
Invoke matching methods based on theargumenton theinvokeMethodsOnbased on theMethodPatternMatcherandInvocationStrategyusing the defaultdefaultNoMatchingMethodsHandlerdefined in thePatternMatchingMethodInvoker(Object, MethodPatternMatcher, InvocationStrategy, Optional)- Parameters:
argument- The argument that will be forwarded to theMethodPatternMatcherfor method invocation
-
invoke
public void invoke(Object argument, NoMatchingMethodsHandler noMatchingMethodsHandler)
Invoke matching methods based on theargumenton theinvokeMethodsOnbased on theMethodPatternMatcherandInvocationStrategy- Parameters:
argument- The argument that will be forwarded to theMethodPatternMatcherfor method invocationnoMatchingMethodsHandler- A Consumer that is called if NO matching methods are found
-
hasMatchingMethod
public boolean hasMatchingMethod(Class<?> argumentType)
-
-