1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.hivemind.service.impl; |
16 |
| |
17 |
| import java.lang.reflect.Constructor; |
18 |
| import java.lang.reflect.Modifier; |
19 |
| import java.util.Iterator; |
20 |
| import java.util.List; |
21 |
| |
22 |
| import org.apache.commons.logging.Log; |
23 |
| import org.apache.hivemind.ApplicationRuntimeException; |
24 |
| import org.apache.hivemind.InterceptorStack; |
25 |
| import org.apache.hivemind.ServiceInterceptorFactory; |
26 |
| import org.apache.hivemind.internal.Module; |
27 |
| import org.apache.hivemind.methodmatch.MethodMatcher; |
28 |
| import org.apache.hivemind.service.BodyBuilder; |
29 |
| import org.apache.hivemind.service.ClassFab; |
30 |
| import org.apache.hivemind.service.ClassFabUtils; |
31 |
| import org.apache.hivemind.service.ClassFactory; |
32 |
| import org.apache.hivemind.service.MethodContribution; |
33 |
| import org.apache.hivemind.service.MethodFab; |
34 |
| import org.apache.hivemind.service.MethodIterator; |
35 |
| import org.apache.hivemind.service.MethodSignature; |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| public class LoggingInterceptorFactory implements ServiceInterceptorFactory |
53 |
| { |
54 |
| private ClassFactory _factory; |
55 |
| private String _serviceId; |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
1
| private void addPassThruMethodImplementation(ClassFab classFab, MethodSignature sig)
|
62 |
| { |
63 |
1
| BodyBuilder builder = new BodyBuilder();
|
64 |
1
| builder.begin();
|
65 |
| |
66 |
1
| builder.add("return ($r) _delegate.");
|
67 |
1
| builder.add(sig.getName());
|
68 |
1
| builder.addln("($$);");
|
69 |
| |
70 |
1
| builder.end();
|
71 |
| |
72 |
1
| classFab.addMethod(Modifier.PUBLIC, sig, builder.toString());
|
73 |
| } |
74 |
| |
75 |
18
| protected void addServiceMethodImplementation(ClassFab classFab, MethodSignature sig)
|
76 |
| { |
77 |
18
| Class returnType = sig.getReturnType();
|
78 |
18
| String methodName = sig.getName();
|
79 |
| |
80 |
18
| boolean isVoid = (returnType == void.class);
|
81 |
| |
82 |
18
| BodyBuilder builder = new BodyBuilder();
|
83 |
| |
84 |
18
| builder.begin();
|
85 |
18
| builder.addln("boolean debug = _log.isDebugEnabled();");
|
86 |
| |
87 |
18
| builder.addln("if (debug)");
|
88 |
18
| builder.add(" org.apache.hivemind.service.impl.LoggingUtils.entry(_log, ");
|
89 |
18
| builder.addQuoted(methodName);
|
90 |
18
| builder.addln(", $args);");
|
91 |
| |
92 |
18
| if (!isVoid)
|
93 |
| { |
94 |
7
| builder.add(ClassFabUtils.getJavaClassName(returnType));
|
95 |
7
| builder.add(" result = ");
|
96 |
| } |
97 |
| |
98 |
18
| builder.add("_delegate.");
|
99 |
18
| builder.add(methodName);
|
100 |
18
| builder.addln("($$);");
|
101 |
| |
102 |
18
| if (isVoid)
|
103 |
| { |
104 |
11
| builder.addln("if (debug)");
|
105 |
11
| builder.add(" org.apache.hivemind.service.impl.LoggingUtils.voidExit(_log, ");
|
106 |
11
| builder.addQuoted(methodName);
|
107 |
11
| builder.addln(");");
|
108 |
| } |
109 |
| else |
110 |
| { |
111 |
7
| builder.addln("if (debug)");
|
112 |
7
| builder.add(" org.apache.hivemind.service.impl.LoggingUtils.exit(_log, ");
|
113 |
7
| builder.addQuoted(methodName);
|
114 |
7
| builder.addln(", ($w)result);");
|
115 |
7
| builder.addln("return result;");
|
116 |
| } |
117 |
| |
118 |
18
| builder.end();
|
119 |
| |
120 |
18
| MethodFab methodFab = classFab.addMethod(Modifier.PUBLIC, sig, builder.toString());
|
121 |
| |
122 |
18
| builder.clear();
|
123 |
| |
124 |
18
| builder.begin();
|
125 |
18
| builder.add("org.apache.hivemind.service.impl.LoggingUtils.exception(_log, ");
|
126 |
18
| builder.addQuoted(methodName);
|
127 |
18
| builder.addln(", $e);");
|
128 |
18
| builder.addln("throw $e;");
|
129 |
18
| builder.end();
|
130 |
| |
131 |
18
| String body = builder.toString();
|
132 |
| |
133 |
18
| Class[] exceptions = sig.getExceptionTypes();
|
134 |
| |
135 |
18
| int count = exceptions.length;
|
136 |
| |
137 |
18
| for (int i = 0; i < count; i++)
|
138 |
| { |
139 |
0
| methodFab.addCatch(exceptions[i], body);
|
140 |
| } |
141 |
| |
142 |
| |
143 |
| |
144 |
| |
145 |
18
| methodFab.addCatch(RuntimeException.class, body);
|
146 |
| } |
147 |
| |
148 |
12
| protected void addServiceMethods(InterceptorStack stack, ClassFab fab, List parameters)
|
149 |
| { |
150 |
12
| MethodMatcher matcher = buildMethodMatcher(parameters);
|
151 |
| |
152 |
12
| MethodIterator mi = new MethodIterator(stack.getServiceInterface());
|
153 |
| |
154 |
12
| while (mi.hasNext())
|
155 |
| { |
156 |
19
| MethodSignature sig = mi.next();
|
157 |
| |
158 |
19
| if (includeMethod(matcher, sig))
|
159 |
18
| addServiceMethodImplementation(fab, sig);
|
160 |
| else |
161 |
1
| addPassThruMethodImplementation(fab, sig);
|
162 |
| } |
163 |
| |
164 |
12
| if (!mi.getToString())
|
165 |
11
| addToStringMethod(stack, fab);
|
166 |
| } |
167 |
| |
168 |
| |
169 |
| |
170 |
| |
171 |
| |
172 |
11
| protected void addToStringMethod(InterceptorStack stack, ClassFab fab)
|
173 |
| { |
174 |
11
| ClassFabUtils.addToStringMethod(
|
175 |
| fab, |
176 |
| "<LoggingInterceptor for " |
177 |
| + stack.getServiceExtensionPointId() |
178 |
| + "(" |
179 |
| + stack.getServiceInterface().getName() |
180 |
| + ")>"); |
181 |
| |
182 |
| } |
183 |
| |
184 |
12
| private MethodMatcher buildMethodMatcher(List parameters)
|
185 |
| { |
186 |
12
| MethodMatcher result = null;
|
187 |
| |
188 |
12
| Iterator i = parameters.iterator();
|
189 |
12
| while (i.hasNext())
|
190 |
| { |
191 |
2
| MethodContribution mc = (MethodContribution) i.next();
|
192 |
| |
193 |
2
| if (result == null)
|
194 |
1
| result = new MethodMatcher();
|
195 |
| |
196 |
2
| result.put(mc.getMethodPattern(), mc);
|
197 |
| } |
198 |
| |
199 |
12
| return result;
|
200 |
| } |
201 |
| |
202 |
12
| private Class constructInterceptorClass(InterceptorStack stack, List parameters)
|
203 |
| { |
204 |
12
| Class serviceInterfaceClass = stack.getServiceInterface();
|
205 |
| |
206 |
12
| String name = ClassFabUtils.generateClassName(serviceInterfaceClass);
|
207 |
| |
208 |
12
| ClassFab classFab = _factory.newClass(name, Object.class);
|
209 |
| |
210 |
12
| classFab.addInterface(serviceInterfaceClass);
|
211 |
| |
212 |
12
| createInfrastructure(stack, classFab);
|
213 |
| |
214 |
12
| addServiceMethods(stack, classFab, parameters);
|
215 |
| |
216 |
12
| return classFab.createClass();
|
217 |
| } |
218 |
| |
219 |
12
| private void createInfrastructure(InterceptorStack stack, ClassFab classFab)
|
220 |
| { |
221 |
12
| Class topClass = ClassFabUtils.getInstanceClass(stack.peek(), stack.getServiceInterface());
|
222 |
| |
223 |
12
| classFab.addField("_log", Log.class);
|
224 |
| |
225 |
| |
226 |
| |
227 |
| |
228 |
| |
229 |
| |
230 |
| |
231 |
12
| classFab.addField("_delegate", topClass);
|
232 |
| |
233 |
12
| classFab.addConstructor(
|
234 |
| new Class[] { Log.class, topClass }, |
235 |
| null, |
236 |
| "{ _log = $1; _delegate = $2; }"); |
237 |
| } |
238 |
| |
239 |
| |
240 |
| |
241 |
| |
242 |
| |
243 |
| |
244 |
| |
245 |
| |
246 |
12
| public void createInterceptor(
|
247 |
| InterceptorStack stack, |
248 |
| Module contributingModule, |
249 |
| List parameters) |
250 |
| { |
251 |
12
| Class interceptorClass = constructInterceptorClass(stack, parameters);
|
252 |
| |
253 |
12
| try
|
254 |
| { |
255 |
12
| Object interceptor = instantiateInterceptor(stack, interceptorClass);
|
256 |
| |
257 |
12
| stack.push(interceptor);
|
258 |
| } |
259 |
| catch (Exception ex) |
260 |
| { |
261 |
0
| throw new ApplicationRuntimeException(
|
262 |
| ServiceMessages.errorInstantiatingInterceptor( |
263 |
| _serviceId, |
264 |
| stack, |
265 |
| interceptorClass, |
266 |
| ex), |
267 |
| ex); |
268 |
| } |
269 |
| } |
270 |
| |
271 |
| |
272 |
| |
273 |
19
| private boolean includeMethod(MethodMatcher matcher, MethodSignature sig)
|
274 |
| { |
275 |
19
| if (matcher == null)
|
276 |
16
| return true;
|
277 |
| |
278 |
3
| MethodContribution mc = (MethodContribution) matcher.get(sig);
|
279 |
| |
280 |
3
| return mc == null || mc.getInclude();
|
281 |
| } |
282 |
| |
283 |
12
| private Object instantiateInterceptor(InterceptorStack stack, Class interceptorClass)
|
284 |
| throws Exception |
285 |
| { |
286 |
12
| Object stackTop = stack.peek();
|
287 |
| |
288 |
12
| Constructor c = interceptorClass.getConstructors()[0];
|
289 |
| |
290 |
12
| return c.newInstance(new Object[] { stack.getServiceLog(), stackTop });
|
291 |
| } |
292 |
| |
293 |
12
| public void setFactory(ClassFactory factory)
|
294 |
| { |
295 |
12
| _factory = factory;
|
296 |
| } |
297 |
| |
298 |
11
| public void setServiceId(String string)
|
299 |
| { |
300 |
11
| _serviceId = string;
|
301 |
| } |
302 |
| } |