1 package org.apache.fulcrum.yaafi.framework.interceptor;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.InvocationHandler;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.concurrent.atomic.AtomicLong;
26
27 import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
28 import org.apache.fulcrum.yaafi.framework.util.Validate;
29
30
31
32
33
34
35
36
37 public class AvalonInterceptorInvocationHandler implements InvocationHandler
38 {
39
40 private String serviceName;
41
42
43 private String serviceShorthand;
44
45
46 private Object serviceDelegate;
47
48
49 private AvalonInterceptorService [] serviceInterceptorList;
50
51
52 private static AtomicLong transactionCounter = new AtomicLong(0);
53
54
55 private Long transactionId;
56
57
58
59
60
61
62
63
64
65 public AvalonInterceptorInvocationHandler(
66 String serviceName,
67 String serviceShorthand,
68 Object serviceDelegate,
69 AvalonInterceptorService [] serviceInterceptorList )
70 {
71 Validate.notEmpty(serviceName,"serviceName");
72 Validate.notEmpty(serviceShorthand,"serviceShorthand");
73 Validate.notNull(serviceDelegate,"serviceDelegate");
74 Validate.notNull(serviceInterceptorList,"serviceInterceptorList");
75
76 this.serviceName = serviceName;
77 this.serviceShorthand = serviceShorthand;
78 this.serviceDelegate = serviceDelegate;
79 this.serviceInterceptorList = serviceInterceptorList;
80 }
81
82
83
84
85 public Object getServiceDelegate()
86 {
87 return this.serviceDelegate;
88 }
89
90
91
92
93 public AvalonInterceptorService [] getServiceInterceptorList()
94 {
95 return serviceInterceptorList;
96 }
97
98
99
100
101 public String getServiceName()
102 {
103 return serviceName;
104 }
105
106
107
108
109 public String getServiceShorthand()
110 {
111 return serviceShorthand;
112 }
113
114
115
116
117 public Long getTransactionId()
118 {
119 return transactionId;
120 }
121
122
123
124
125 public String toString()
126 {
127 ToStringBuilder toStringBuilder = new ToStringBuilder(this);
128
129 toStringBuilder.append("serviceShorthand",this.serviceShorthand);
130 toStringBuilder.append("serviceName",this.serviceName);
131 toStringBuilder.append("serviceDelegate",this.serviceDelegate);
132 toStringBuilder.append("transactionId",this.transactionId);
133
134 return toStringBuilder.toString();
135 }
136
137
138
139
140 public Object invoke(Object proxy, Method method, Object [] args)
141 throws Throwable
142 {
143 Object result;
144
145
146
147 AvalonInterceptorContext context = new AvalonInterceptorContextImpl(
148 this.getServiceName(),
149 this.getServiceShorthand(),
150 this.getServiceDelegate(),
151 method,
152 args
153 );
154
155
156
157 boolean hasCreatedTransaction = this.createTransactionId(context);
158
159 try
160 {
161 context.incrementInvocationDepth();
162 this.onEntry(context);
163 result = method.invoke( this.getServiceDelegate(), args );
164 this.onExit(context,result);
165 return result;
166 }
167 catch (InvocationTargetException e)
168 {
169 this.onError(context,e.getTargetException());
170 throw e.getTargetException();
171 }
172 catch (Throwable t)
173 {
174 this.onError(context,t);
175 throw t;
176 }
177 finally
178 {
179
180
181 context.decrementInvocationDepth();
182
183
184
185 if( hasCreatedTransaction )
186 {
187 context.clearTransactionId();
188 }
189 }
190 }
191
192
193
194
195
196
197 private void onEntry( AvalonInterceptorContext context )
198 {
199 for( int i=0; i<this.getServiceInterceptorList().length; i++ )
200 {
201 AvalonInterceptorService avalonInterceptorService = this.getServiceInterceptorList()[i];
202 avalonInterceptorService.onEntry(context);
203 }
204 }
205
206
207
208
209
210
211
212 private void onExit( AvalonInterceptorContext context, Object result )
213 {
214 for( int i=this.getServiceInterceptorList().length-1; i>=0; i-- )
215 {
216 AvalonInterceptorService avalonInterceptorService = this.getServiceInterceptorList()[i];
217 avalonInterceptorService.onExit(context, result);
218 }
219 }
220
221
222
223
224
225
226
227 private void onError( AvalonInterceptorContext context, Throwable t )
228 {
229 for( int i=this.getServiceInterceptorList().length-1; i>=0; i-- )
230 {
231 AvalonInterceptorService avalonInterceptorService = this.getServiceInterceptorList()[i];
232 avalonInterceptorService.onError(context, t);
233 }
234 }
235
236
237
238
239
240
241 private boolean createTransactionId(AvalonInterceptorContext context)
242 {
243 Long currentTransactionId;
244
245 if( !context.hasTransactionId() )
246 {
247
248
249 currentTransactionId = transactionCounter.incrementAndGet();
250 this.transactionId = currentTransactionId;
251
252
253
254 context.setTransactionId(currentTransactionId);
255
256 return true;
257 }
258
259 return false;
260 }
261 }