1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.apiclient.webflux;
18
19 import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
20
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.AnnotatedElement;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Parameter;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Optional;
29 import java.util.function.Function;
30 import java.util.function.Predicate;
31 import java.util.stream.Stream;
32 import lombok.AllArgsConstructor;
33 import lombok.EqualsAndHashCode;
34 import lombok.Getter;
35 import lombok.NonNull;
36 import org.springframework.util.Assert;
37
38
39
40
41
42
43 @SuppressWarnings("SameNameButDifferent")
44 @Getter
45 @EqualsAndHashCode
46 @AllArgsConstructor
47 public class Invocation {
48
49 @NonNull
50 private final Class<?> targetClass;
51
52 @NonNull
53 private final Method method;
54
55 private final Object[] args;
56
57
58
59
60
61
62 public Stream<InvocationParameter> toMethodParameterStream() {
63 List<InvocationParameter> invocationParameters = new ArrayList<>();
64 Parameter[] parameters = method.getParameters();
65 for (int i = 0; i < parameters.length; i++) {
66 invocationParameters.add(new InvocationParameter(this, parameters[i], args[i], i));
67 }
68 return invocationParameters.stream();
69 }
70
71 @Override
72 public String toString() {
73 return "Invocation{"
74 + "targetClass=" + targetClass.getName()
75 + ", method=" + method.getName()
76 + ", args=" + Arrays.toString(args)
77 + '}';
78 }
79
80
81
82
83
84
85
86
87
88
89
90 public <T, A extends Annotation> Optional<T> findAnnotationValueOnTargetClass(
91 Class<A> annotationType,
92 Predicate<A> condition,
93 Function<A, T> mapper) {
94 return findAnnotationValue(targetClass, annotationType, condition, mapper);
95 }
96
97
98
99
100
101
102
103
104
105
106
107 public <T, A extends Annotation> Optional<T> findAnnotationValueOnMethod(
108 Class<A> annotationType,
109 Predicate<A> condition,
110 Function<A, T> mapper) {
111 return findAnnotationValue(method, annotationType, condition, mapper);
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125 public <T, A extends Annotation> Optional<T> findAnnotationValueOnParameter(
126 int parameterIndex,
127 Class<A> annotationType,
128 Predicate<A> condition,
129 Function<A, T> mapper) {
130 Parameter[] parameters = method.getParameters();
131 if (parameterIndex >= 0 && parameterIndex < parameters.length) {
132 return findAnnotationValue(parameters[parameterIndex], annotationType, condition, mapper);
133 }
134 return Optional.empty();
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148 private static <T, A extends Annotation> Optional<T> findAnnotationValue(
149 AnnotatedElement annotatedElement,
150 Class<A> annotationType,
151 Predicate<A> condition,
152 Function<A, T> mapper) {
153
154 Assert.notNull(annotatedElement, "Annotated element must be present.");
155 Assert.notNull(annotationType, "Annotation type must be present.");
156 Assert.notNull(condition, "Condition must be present.");
157 Assert.notNull(mapper, "Mapper must be present.");
158
159 return Optional.of(annotatedElement)
160 .map(m -> findAnnotation(m, annotationType))
161 .filter(condition)
162 .map(mapper);
163 }
164
165 }