01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */
04: package com.tc.common.proxy;
05:
06: import java.lang.reflect.InvocationHandler;
07: import java.lang.reflect.InvocationTargetException;
08: import java.lang.reflect.Method;
09: import java.lang.reflect.Proxy;
10:
11: /**
12: * A helper class to create proxies that will generate events for any interface method invocations
13: */
14: public class MethodMonitorProxy {
15: public static Object createProxy(final Object objectToMonitor,
16: MethodInvocationEventListener listener) {
17: return createProxy(objectToMonitor,
18: new MethodInvocationEventListener[] { listener });
19: }
20:
21: public static Object createProxy(final Object objectToMonitor,
22: MethodInvocationEventListener listeners[]) {
23: if (null == objectToMonitor) {
24: throw new NullPointerException(
25: "Cannot proxy a null instance");
26: }
27: if (null == listeners) {
28: throw new NullPointerException(
29: "Listener list cannot be null");
30: }
31:
32: for (int i = 0; i < listeners.length; i++) {
33: if (null == listeners[i]) {
34: throw new NullPointerException(
35: "Null listener in list at position " + i);
36: }
37: }
38:
39: final Class clazz = objectToMonitor.getClass();
40: final Class[] interfaces = clazz.getInterfaces();
41:
42: if (0 == interfaces.length) {
43: throw new IllegalArgumentException("Class ("
44: + clazz.getName()
45: + ") does not implement any interfaces");
46: }
47:
48: return Proxy.newProxyInstance(clazz.getClassLoader(),
49: interfaces, new MonitorHandler(objectToMonitor,
50: listeners));
51: }
52:
53: private static class MonitorHandler implements InvocationHandler {
54: private final MethodInvocationEventListener[] listeners;
55: private final Object delegate;
56:
57: MonitorHandler(Object delegate,
58: MethodInvocationEventListener[] listeners) {
59: this .listeners = (MethodInvocationEventListener[]) listeners
60: .clone();
61: this .delegate = delegate;
62: }
63:
64: public Object invoke(Object proxy, Method method, Object[] args)
65: throws Throwable {
66: Throwable exception = null;
67:
68: Object returnValue = null;
69:
70: final long end;
71: final long start = System.currentTimeMillis();
72: try {
73: returnValue = method.invoke(delegate, args);
74: } catch (InvocationTargetException ite) {
75: exception = ite.getCause();
76: } finally {
77: end = System.currentTimeMillis();
78: }
79:
80: final MethodInvocationEvent event = new MethodInvocationEventImpl(
81: start, end, delegate, method, args, exception,
82: returnValue);
83: for (int i = 0; i < listeners.length; i++) {
84: listeners[i].methodInvoked(event);
85: }
86:
87: if (null != exception) {
88: throw exception;
89: } else {
90: return returnValue;
91: }
92: }
93: }
94: }
|