1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.aop.aspectj;
18
19 import java.lang.reflect.Method;
20 import java.lang.reflect.Modifier;
21
22 import org.aspectj.lang.JoinPoint;
23 import org.aspectj.lang.ProceedingJoinPoint;
24 import org.aspectj.lang.Signature;
25 import org.aspectj.lang.reflect.MethodSignature;
26 import org.aspectj.lang.reflect.SourceLocation;
27 import org.aspectj.runtime.internal.AroundClosure;
28
29 import org.springframework.aop.ProxyMethodInvocation;
30 import org.springframework.core.DefaultParameterNameDiscoverer;
31 import org.springframework.core.ParameterNameDiscoverer;
32 import org.springframework.util.Assert;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {
54
55 private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
56
57 private final ProxyMethodInvocation methodInvocation;
58
59 private Object[] defensiveCopyOfArgs;
60
61
62 private Signature signature;
63
64
65 private SourceLocation sourceLocation;
66
67
68
69
70
71
72
73 public MethodInvocationProceedingJoinPoint(ProxyMethodInvocation methodInvocation) {
74 Assert.notNull(methodInvocation, "MethodInvocation must not be null");
75 this.methodInvocation = methodInvocation;
76 }
77
78 @Override
79 public void set$AroundClosure(AroundClosure aroundClosure) {
80 throw new UnsupportedOperationException();
81 }
82
83 @Override
84 public Object proceed() throws Throwable {
85 return this.methodInvocation.invocableClone().proceed();
86 }
87
88 @Override
89 public Object proceed(Object[] arguments) throws Throwable {
90 Assert.notNull(arguments, "Argument array passed to proceed cannot be null");
91 if (arguments.length != this.methodInvocation.getArguments().length) {
92 throw new IllegalArgumentException("Expecting " +
93 this.methodInvocation.getArguments().length + " arguments to proceed, " +
94 "but was passed " + arguments.length + " arguments");
95 }
96 this.methodInvocation.setArguments(arguments);
97 return this.methodInvocation.invocableClone(arguments).proceed();
98 }
99
100
101
102
103 @Override
104 public Object getThis() {
105 return this.methodInvocation.getProxy();
106 }
107
108
109
110
111 @Override
112 public Object getTarget() {
113 return this.methodInvocation.getThis();
114 }
115
116 @Override
117 public Object[] getArgs() {
118 if (this.defensiveCopyOfArgs == null) {
119 Object[] argsSource = this.methodInvocation.getArguments();
120 this.defensiveCopyOfArgs = new Object[argsSource.length];
121 System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
122 }
123 return this.defensiveCopyOfArgs;
124 }
125
126 @Override
127 public Signature getSignature() {
128 if (this.signature == null) {
129 this.signature = new MethodSignatureImpl();
130 }
131 return signature;
132 }
133
134 @Override
135 public SourceLocation getSourceLocation() {
136 if (this.sourceLocation == null) {
137 this.sourceLocation = new SourceLocationImpl();
138 }
139 return this.sourceLocation;
140 }
141
142 @Override
143 public String getKind() {
144 return ProceedingJoinPoint.METHOD_EXECUTION;
145 }
146
147 @Override
148 public int getId() {
149
150 return 0;
151 }
152
153 @Override
154 public JoinPoint.StaticPart getStaticPart() {
155 return this;
156 }
157
158 @Override
159 public String toShortString() {
160 return "execution(" + getSignature().toShortString() + ")";
161 }
162
163 @Override
164 public String toLongString() {
165 return "execution(" + getSignature().toLongString() + ")";
166 }
167
168 @Override
169 public String toString() {
170 return "execution(" + getSignature().toString() + ")";
171 }
172
173
174
175
176
177 private class MethodSignatureImpl implements MethodSignature {
178
179 private volatile String[] parameterNames;
180
181 @Override
182 public String getName() {
183 return methodInvocation.getMethod().getName();
184 }
185
186 @Override
187 public int getModifiers() {
188 return methodInvocation.getMethod().getModifiers();
189 }
190
191 @Override
192 public Class<?> getDeclaringType() {
193 return methodInvocation.getMethod().getDeclaringClass();
194 }
195
196 @Override
197 public String getDeclaringTypeName() {
198 return methodInvocation.getMethod().getDeclaringClass().getName();
199 }
200
201 @Override
202 public Class<?> getReturnType() {
203 return methodInvocation.getMethod().getReturnType();
204 }
205
206 @Override
207 public Method getMethod() {
208 return methodInvocation.getMethod();
209 }
210
211 @Override
212 public Class<?>[] getParameterTypes() {
213 return methodInvocation.getMethod().getParameterTypes();
214 }
215
216 @Override
217 public String[] getParameterNames() {
218 if (this.parameterNames == null) {
219 this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
220 }
221 return this.parameterNames;
222 }
223
224 @Override
225 public Class<?>[] getExceptionTypes() {
226 return methodInvocation.getMethod().getExceptionTypes();
227 }
228
229 @Override
230 public String toShortString() {
231 return toString(false, false, false, false);
232 }
233
234 @Override
235 public String toLongString() {
236 return toString(true, true, true, true);
237 }
238
239 @Override
240 public String toString() {
241 return toString(false, true, false, true);
242 }
243
244 private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs,
245 boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) {
246 StringBuilder sb = new StringBuilder();
247 if (includeModifier) {
248 sb.append(Modifier.toString(getModifiers()));
249 sb.append(" ");
250 }
251 if (includeReturnTypeAndArgs) {
252 appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
253 sb.append(" ");
254 }
255 appendType(sb, getDeclaringType(), useLongTypeName);
256 sb.append(".");
257 sb.append(getMethod().getName());
258 sb.append("(");
259 Class<?>[] parametersTypes = getParameterTypes();
260 appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
261 sb.append(")");
262 return sb.toString();
263 }
264
265 private void appendTypes(StringBuilder sb, Class<?>[] types,
266 boolean includeArgs, boolean useLongReturnAndArgumentTypeName) {
267 if (includeArgs) {
268 for (int size = types.length, i = 0; i < size; i++) {
269 appendType(sb, types[i], useLongReturnAndArgumentTypeName);
270 if (i < size - 1) {
271 sb.append(",");
272 }
273 }
274 }
275 else {
276 if (types.length != 0) {
277 sb.append("..");
278 }
279 }
280 }
281
282 private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
283 if (type.isArray()) {
284 appendType(sb, type.getComponentType(), useLongTypeName);
285 sb.append("[]");
286 }
287 else {
288 sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
289 }
290 }
291 }
292
293
294
295
296
297 private class SourceLocationImpl implements SourceLocation {
298
299 @Override
300 public Class<?> getWithinType() {
301 if (methodInvocation.getThis() == null) {
302 throw new UnsupportedOperationException("No source location joinpoint available: target is null");
303 }
304 return methodInvocation.getThis().getClass();
305 }
306
307 @Override
308 public String getFileName() {
309 throw new UnsupportedOperationException();
310 }
311
312 @Override
313 public int getLine() {
314 throw new UnsupportedOperationException();
315 }
316
317 @Override
318 @Deprecated
319 public int getColumn() {
320 throw new UnsupportedOperationException();
321 }
322 }
323
324 }