1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.dbutils; 18 19 import java.lang.reflect.InvocationHandler; 20 import java.lang.reflect.Proxy; 21 import java.sql.CallableStatement; 22 import java.sql.Connection; 23 import java.sql.Driver; 24 import java.sql.PreparedStatement; 25 import java.sql.ResultSet; 26 import java.sql.ResultSetMetaData; 27 import java.sql.Statement; 28 29 /** 30 * Creates proxy implementations of JDBC interfaces. This avoids 31 * incompatibilities between the JDBC 2 and JDBC 3 interfaces. This class is 32 * thread safe. 33 * 34 * @see java.lang.reflect.Proxy 35 * @see java.lang.reflect.InvocationHandler 36 */ 37 public class ProxyFactory { 38 39 /** 40 * The Singleton instance of this class. 41 */ 42 private static final ProxyFactory instance = new ProxyFactory(); 43 44 /** 45 * Returns the Singleton instance of this class. 46 * 47 * @return singleton instance 48 */ 49 public static ProxyFactory instance() { 50 return instance; 51 } 52 53 /** 54 * Protected constructor for ProxyFactory subclasses to use. 55 */ 56 protected ProxyFactory() { 57 } 58 59 /** 60 * Creates a new proxy {@code CallableStatement} object. 61 * @param handler The handler that intercepts/overrides method calls. 62 * @return proxied CallableStatement 63 */ 64 public CallableStatement createCallableStatement(final InvocationHandler handler) { 65 return newProxyInstance(CallableStatement.class, handler); 66 } 67 68 /** 69 * Creates a new proxy {@code Connection} object. 70 * @param handler The handler that intercepts/overrides method calls. 71 * @return proxied Connection 72 */ 73 public Connection createConnection(final InvocationHandler handler) { 74 return newProxyInstance(Connection.class, handler); 75 } 76 77 /** 78 * Creates a new proxy {@code Driver} object. 79 * @param handler The handler that intercepts/overrides method calls. 80 * @return proxied Driver 81 */ 82 public Driver createDriver(final InvocationHandler handler) { 83 return newProxyInstance(Driver.class, handler); 84 } 85 86 /** 87 * Creates a new proxy {@code PreparedStatement} object. 88 * @param handler The handler that intercepts/overrides method calls. 89 * @return proxied PreparedStatement 90 */ 91 public PreparedStatement createPreparedStatement(final InvocationHandler handler) { 92 return newProxyInstance(PreparedStatement.class, handler); 93 } 94 95 /** 96 * Creates a new proxy {@code ResultSet} object. 97 * @param handler The handler that intercepts/overrides method calls. 98 * @return proxied ResultSet 99 */ 100 public ResultSet createResultSet(final InvocationHandler handler) { 101 return newProxyInstance(ResultSet.class, handler); 102 } 103 104 /** 105 * Creates a new proxy {@code ResultSetMetaData} object. 106 * @param handler The handler that intercepts/overrides method calls. 107 * @return proxied ResultSetMetaData 108 */ 109 public ResultSetMetaData createResultSetMetaData(final InvocationHandler handler) { 110 return newProxyInstance(ResultSetMetaData.class, handler); 111 } 112 113 /** 114 * Creates a new proxy {@code Statement} object. 115 * @param handler The handler that intercepts/overrides method calls. 116 * @return proxied Statement 117 */ 118 public Statement createStatement(final InvocationHandler handler) { 119 return newProxyInstance(Statement.class, handler); 120 } 121 122 /** 123 * Convenience method to generate a single-interface proxy using the handler's classloader 124 * 125 * @param <T> The type of object to proxy 126 * @param type The type of object to proxy 127 * @param handler The handler that intercepts/overrides method calls. 128 * @return proxied object 129 */ 130 public <T> T newProxyInstance(final Class<T> type, final InvocationHandler handler) { 131 return type.cast(Proxy.newProxyInstance(handler.getClass().getClassLoader(), new Class<?>[] {type}, handler)); 132 } 133 134 }