-
Notifications
You must be signed in to change notification settings - Fork 24
/
InvocationContext.java
210 lines (196 loc) · 9.21 KB
/
InvocationContext.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package jakarta.interceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Exposes contextual information about the intercepted invocation and operations that enable interceptor methods to
* control the behavior of the invocation chain.
*
* <pre>
*
* @AroundInvoke
* public Object logInvocation(InvocationContext ctx) throws Exception {
* String class = ctx.getMethod().getDeclaringClass().getName();
* String method = ctx.getMethod().getName();
* Logger.global.entering(class, method, ctx.getParameters());
* try {
* Object result = ctx.proceed();
* Logger.global.exiting(class, method, result);
* return result;
* }
* catch (Exception e) {
* Logger.global.throwing(class, method, e);
* throw e;
* }
*
* }
*
* </pre>
*
* @since Jakarta Interceptors 1.0
*/
public interface InvocationContext {
/**
* Returns the target instance. For {@link AroundConstruct} lifecycle callback interceptor methods, the
* <code>getTarget</code> method returns <code>null</code> if called before the {@link #proceed} method.
*
* @return the target instance
*/
Object getTarget();
/**
* Returns the timer object associated with a timeout method invocation on the target class, or a null value for
* interceptor method types other than {@link AroundTimeout}. For example, when associated with a Jakarta Enterprise
* Beans component timeout, this method returns {@code jakarta.ejb.Timer}.
*
* @return the timer object or a null value
*
* @since Jakarta Interceptors 1.1
*/
Object getTimer();
/**
* Returns the method of the target class for which the interceptor was invoked. Returns null in a lifecycle callback
* interceptor for which there is no corresponding lifecycle callback method declared in the target class (or inherited
* from a superclass) or in an {@link AroundConstruct} lifecycle callback interceptor method.
*
* @return the method, or a null value
*/
Method getMethod();
/**
* Returns the constructor of the target class for which the {@link AroundConstruct} interceptor method was invoked.
* Returns null for interceptor method types other than {@link AroundConstruct} interceptor methods.
*
* @return the constructor, or a null value
*/
Constructor<?> getConstructor();
/**
* Returns the parameter values that will be passed to the method or constructor of the target class. If
* {@link #setParameters} has been called, <code>getParameters</code> returns the values to which the parameters have
* been set.
*
* @return the parameter values, as an array
*
* @exception java.lang.IllegalStateException if invoked within a lifecycle callback method that is not an
* {@link AroundConstruct} callback.
*/
Object[] getParameters();
/**
* Sets the parameter values that will be passed to the method or constructor of the target class.
*
* @exception java.lang.IllegalStateException if invoked within a lifecycle callback method that is not an
* {@link AroundConstruct} callback.
*
* @exception java.lang.IllegalArgumentException if the types of the given parameter values do not match the types of
* the method or constructor parameters, or if the number of parameters supplied does not equal the number of method or
* constructor parameters (if the last parameter is a vararg parameter of type <code>T</code>, it is considered to be
* equivalent to a parameter of type <code>T[]</code>).
*
* @param params the parameter values, as an array
*/
void setParameters(Object[] params);
/**
* Enables an interceptor to retrieve or update the data associated with the invocation by another interceptor, business
* method, and/or webservices endpoint in the invocation chain.
*
* @return the context data associated with this invocation or lifecycle callback. If there is no context data, an empty
* {@code Map<String,Object>} object will be returned.
*/
Map<String, Object> getContextData();
/**
* Proceed to the next interceptor in the interceptor chain. For around-invoke or around-timeout interceptor methods,
* the invocation of {@code proceed} in the last interceptor method in the chain causes the invocation of the target
* class method. For {@link AroundConstruct} lifecycle callback interceptor methods, the invocation of {@code proceed}
* in the last interceptor method in the chain causes the target instance to be created. For all other lifecycle
* callback interceptor methods, if there is no callback method defined on the target class, the invocation of proceed
* in the last interceptor method in the chain is a no-op.
*
* <p>
* Return the result of the next method invoked, or a null value if the method has return type void.
*
* @return the return value of the next method in the chain
*
* @exception Exception if thrown by target method or interceptor method in call stack
*/
Object proceed() throws Exception;
/**
* Returns the set of interceptor binding annotations for the method or constructor whose
* invocation is being intercepted. In case there is no target method or target constructor,
* interceptor binding annotations applied to the target class are returned.
* <p>
* All interceptor binding annotations are returned, including inherited interceptor binding
* annotations, transitive interceptor binding annotations, interceptor binding annotations
* that associate interceptors of a different interceptor method type, as well as interceptor
* binding annotations that associate no interceptor.
* <p>
* Returns an empty set if no interceptor binding annotation is applied and all interceptors
* were associated using the {@link Interceptors @Interceptors} annotation.
*
* @return immutable set of interceptor binding annotations, never {@code null}
* @since Jakarta Interceptors 2.2
*/
default Set<Annotation> getInterceptorBindings() {
// this method is `default` to maintain binary compatibility,
// but CDI implementations must override it
return Collections.emptySet();
}
/**
* Returns the single annotation of given type present in the {@linkplain #getInterceptorBindings() full set}
* of interceptor binding annotations.
* <p>
* Returns {@code null} if the {@linkplain #getInterceptorBindings() full set} of interceptor
* binding annotations does not contain an annotation of given type.
* <p>
* In case of {@linkplain java.lang.annotation.Repeatable repeatable} interceptor binding
* annotations, {@link #getInterceptorBindings(Class)} should be used instead.
*
* @param annotationType type of the interceptor binding annotation, must not be {@code null}
* @return the interceptor binding annotation of given type, may be {@code null}
* @since Jakarta Interceptors 2.2
*/
default <T extends Annotation> T getInterceptorBinding(Class<T> annotationType) {
for (Annotation interceptorBinding : getInterceptorBindings()) {
if (interceptorBinding.annotationType().equals(annotationType)) {
return (T) interceptorBinding;
}
}
return null;
}
/**
* Returns all annotations of given type present in the {@linkplain #getInterceptorBindings() full set}
* of interceptor binding annotations.
* <p>
* Returns an empty set if the {@linkplain #getInterceptorBindings() full set} of interceptor
* binding annotations does not contain any annotation of given type.
*
* @param annotationType type of the interceptor binding annotations, must not be {@code null}
* @return immutable set of interceptor binding annotations of given type, never {@code null}
* @since Jakarta Interceptors 2.2
*/
default <T extends Annotation> Set<T> getInterceptorBindings(Class<T> annotationType) {
Set<T> result = new HashSet<>();
for (Annotation interceptorBinding : getInterceptorBindings()) {
if (interceptorBinding.annotationType().equals(annotationType)) {
result.add((T) interceptorBinding);
}
}
return Collections.unmodifiableSet(result);
}
}