001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.dbutils; 018 019 import java.lang.reflect.InvocationHandler; 020 import java.lang.reflect.Proxy; 021 import java.sql.CallableStatement; 022 import java.sql.Connection; 023 import java.sql.Driver; 024 import java.sql.PreparedStatement; 025 import java.sql.ResultSet; 026 import java.sql.ResultSetMetaData; 027 import java.sql.Statement; 028 029 /** 030 * Creates proxy implementations of JDBC interfaces. This avoids 031 * incompatibilities between the JDBC 2 and JDBC 3 interfaces. This class is 032 * thread safe. 033 * 034 * @see java.lang.reflect.Proxy 035 * @see java.lang.reflect.InvocationHandler 036 */ 037 public class ProxyFactory { 038 039 /** 040 * Class[] for CallableStatement interface. 041 */ 042 private static final Class[] callableStatementClass = 043 new Class[] { CallableStatement.class }; 044 045 /** 046 * Class[] for Connection interface. 047 */ 048 private static final Class[] connectionClass = 049 new Class[] { Connection.class }; 050 051 /** 052 * Class[] for Driver interface. 053 */ 054 private static final Class[] driverClass = new Class[] { Driver.class }; 055 056 /** 057 * The Singleton instance of this class. 058 */ 059 private static final ProxyFactory instance = new ProxyFactory(); 060 061 /** 062 * Class[] for ResultSetMetaData interface. 063 */ 064 private static final Class[] metaClass = 065 new Class[] { ResultSetMetaData.class }; 066 067 /** 068 * Class[] for PreparedStatement interface. 069 */ 070 private static final Class[] preparedStatementClass = 071 new Class[] { PreparedStatement.class }; 072 073 /** 074 * Class[] for ResultSet interface. 075 */ 076 private static final Class[] resultSetClass = 077 new Class[] { ResultSet.class }; 078 079 /** 080 * Class[] for Statement interface. 081 */ 082 private static final Class[] statementClass = 083 new Class[] { Statement.class }; 084 085 /** 086 * Returns the Singleton instance of this class. 087 * 088 * @return singleton instance 089 */ 090 public static ProxyFactory instance() { 091 return instance; 092 } 093 094 /** 095 * Protected constructor for ProxyFactory subclasses to use. 096 */ 097 protected ProxyFactory() { 098 super(); 099 } 100 101 /** 102 * Creates a new proxy <code>CallableStatement</code> object. 103 * @param handler The handler that intercepts/overrides method calls. 104 * @return proxied CallableStatement 105 */ 106 public CallableStatement createCallableStatement(InvocationHandler handler) { 107 return (CallableStatement) Proxy.newProxyInstance( 108 handler.getClass().getClassLoader(), 109 callableStatementClass, 110 handler); 111 } 112 113 /** 114 * Creates a new proxy <code>Connection</code> object. 115 * @param handler The handler that intercepts/overrides method calls. 116 * @return proxied Connection 117 */ 118 public Connection createConnection(InvocationHandler handler) { 119 return (Connection) Proxy.newProxyInstance( 120 handler.getClass().getClassLoader(), 121 connectionClass, 122 handler); 123 } 124 125 /** 126 * Creates a new proxy <code>Driver</code> object. 127 * @param handler The handler that intercepts/overrides method calls. 128 * @return proxied Driver 129 */ 130 public Driver createDriver(InvocationHandler handler) { 131 return (Driver) Proxy.newProxyInstance( 132 handler.getClass().getClassLoader(), 133 driverClass, 134 handler); 135 } 136 137 /** 138 * Creates a new proxy <code>PreparedStatement</code> object. 139 * @param handler The handler that intercepts/overrides method calls. 140 * @return proxied PreparedStatement 141 */ 142 public PreparedStatement createPreparedStatement(InvocationHandler handler) { 143 return (PreparedStatement) Proxy.newProxyInstance( 144 handler.getClass().getClassLoader(), 145 preparedStatementClass, 146 handler); 147 } 148 149 /** 150 * Creates a new proxy <code>ResultSet</code> object. 151 * @param handler The handler that intercepts/overrides method calls. 152 * @return proxied ResultSet 153 */ 154 public ResultSet createResultSet(InvocationHandler handler) { 155 return (ResultSet) Proxy.newProxyInstance( 156 handler.getClass().getClassLoader(), 157 resultSetClass, 158 handler); 159 } 160 161 /** 162 * Creates a new proxy <code>ResultSetMetaData</code> object. 163 * @param handler The handler that intercepts/overrides method calls. 164 * @return proxied ResultSetMetaData 165 */ 166 public ResultSetMetaData createResultSetMetaData(InvocationHandler handler) { 167 return (ResultSetMetaData) Proxy.newProxyInstance( 168 handler.getClass().getClassLoader(), 169 metaClass, 170 handler); 171 } 172 173 /** 174 * Creates a new proxy <code>Statement</code> object. 175 * @param handler The handler that intercepts/overrides method calls. 176 * @return proxied Statement 177 */ 178 public Statement createStatement(InvocationHandler handler) { 179 return (Statement) Proxy.newProxyInstance( 180 handler.getClass().getClassLoader(), 181 statementClass, 182 handler); 183 } 184 185 }