1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.monitoring.jdbc;
19
20 import org.apache.commons.monitoring.counters.Counter;
21 import org.apache.commons.monitoring.stopwatches.CounterStopWatch;
22 import org.apache.commons.monitoring.stopwatches.StopWatch;
23 import org.apache.commons.monitoring.util.ClassLoaders;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.lang.reflect.Proxy;
29 import java.sql.CallableStatement;
30 import java.sql.Connection;
31 import java.sql.PreparedStatement;
32 import java.sql.Statement;
33
34
35
36
37 public class MonitoredConnection implements InvocationHandler {
38 private Connection connection;
39 private StopWatch stopWatch;
40
41
42
43
44 public MonitoredConnection(final Connection connection, final StopWatch stopWatch) {
45 this.connection = connection;
46 this.stopWatch = stopWatch;
47 }
48
49 @Override
50 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
51 final String name = method.getName();
52 if ("close".equals(name)) {
53 connection.close();
54 stopWatch.stop();
55 return null;
56 }
57
58 if (name.startsWith("prepare") || name.startsWith("create")) {
59 final Class<?> returnType = method.getReturnType();
60 if (CallableStatement.class.equals(returnType)) {
61 return monitor(CallableStatement.class.cast(doInvoke(method, args)), (String) args[0]);
62 } else if (PreparedStatement.class.equals(returnType)) {
63 return monitor(PreparedStatement.class.cast(doInvoke(method, args)), (String) args[0]);
64 } else if (Statement.class.equals(returnType)) {
65 return monitor(Statement.class.cast(doInvoke(method, args)));
66 }
67 }
68
69 return doInvoke(method, args);
70 }
71
72 private Object doInvoke(final Method method, final Object[] args) throws IllegalAccessException, InvocationTargetException {
73 return method.invoke(connection, args);
74 }
75
76 private Statement monitor(final Statement statement) {
77 return Statement.class.cast(Proxy.newProxyInstance(ClassLoaders.current(), new Class<?>[]{Statement.class}, new MonitoredStatement(statement)));
78 }
79
80
81
82
83
84
85 private PreparedStatement monitor(final PreparedStatement statement, final String sql) {
86 return PreparedStatement.class.cast(Proxy.newProxyInstance(ClassLoaders.current(), new Class<?>[]{PreparedStatement.class}, new MonitoredPreparedStatement(statement, sql)));
87 }
88
89
90
91
92
93
94 private CallableStatement monitor(final CallableStatement statement, final String sql) {
95 return CallableStatement.class.cast(Proxy.newProxyInstance(ClassLoaders.current(), new Class<?>[]{CallableStatement.class}, new MonitoredPreparedStatement(statement, sql)));
96 }
97
98 public static Connection monitor(final Connection connection, final Counter counter) {
99 final StopWatch stopWatch = new CounterStopWatch(counter);
100 return Connection.class.cast(Proxy.newProxyInstance(ClassLoaders.current(), new Class<?>[]{Connection.class}, new MonitoredConnection(connection, stopWatch)));
101 }
102 }