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 }