1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.dbcp.cpdsadapter;
  17. import java.util.Map;
  18. import java.sql.Connection;
  19. import java.sql.DatabaseMetaData;
  20. import java.sql.PreparedStatement;
  21. import java.sql.CallableStatement;
  22. import java.sql.Statement;
  23. import java.sql.SQLWarning;
  24. import java.sql.SQLException;
  25. /**
  26. * This class is the <code>Connection</code> that will be returned
  27. * from <code>PooledConnectionImpl.getConnection()</code>.
  28. * Most methods are wrappers around the jdbc 1.x <code>Connection</code>.
  29. * A few exceptions include preparedStatement, close and isClosed.
  30. * In accordance with the jdbc specification this Connection cannot
  31. * be used after closed() is called. Any further usage will result in an
  32. * SQLException.
  33. *
  34. * @author John D. McNally
  35. * @version $Revision: 1.9 $ $Date: 2004/02/28 12:18:17 $
  36. */
  37. class ConnectionImpl implements Connection {
  38. private static final String CLOSED
  39. = "Attempted to use Connection after closed() was called.";
  40. /** The JDBC database connection. */
  41. private Connection connection;
  42. /** The object that instantiated this object */
  43. private PooledConnectionImpl pooledConnection;
  44. /** Marks whether is Connection is still usable. */
  45. boolean isClosed;
  46. /**
  47. * Creates a <code>ConnectionImpl</code>.
  48. *
  49. * @param pooledConnection The PooledConnection that is calling the ctor.
  50. * @param connection The JDBC 1.x Connection to wrap.
  51. */
  52. ConnectionImpl(PooledConnectionImpl pooledConnection,
  53. Connection connection) {
  54. this.pooledConnection = pooledConnection;
  55. this.connection = connection;
  56. isClosed = false;
  57. }
  58. /**
  59. * The finalizer helps prevent <code>ConnectionPool</code> leakage.
  60. */
  61. protected void finalize() throws Throwable {
  62. if (!isClosed) {
  63. // If this DBConnection object is finalized while linked
  64. // to a ConnectionPool, it means that it was taken from a pool
  65. // and not returned. We log this fact, close the underlying
  66. // Connection, and return it to the ConnectionPool.
  67. throw new SQLException("A ConnectionImpl was finalized "
  68. + "without being closed which will cause leakage of "
  69. + " PooledConnections from the ConnectionPool.");
  70. }
  71. }
  72. /**
  73. * Throws an SQLException, if isClosed() is true
  74. */
  75. private void assertOpen() throws SQLException {
  76. if (isClosed) {
  77. throw new SQLException(CLOSED);
  78. }
  79. }
  80. // ***********************************************************************
  81. // java.sql.Connection implementation using wrapped Connection
  82. // ***********************************************************************
  83. /**
  84. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  85. *
  86. * @exception SQLException if this connection is closed or an error occurs
  87. * in the wrapped connection.
  88. */
  89. public void clearWarnings() throws SQLException {
  90. assertOpen();
  91. connection.clearWarnings();
  92. }
  93. /**
  94. * Marks the Connection as closed, and notifies the pool that the
  95. * pooled connection is available.
  96. * In accordance with the jdbc specification this Connection cannot
  97. * be used after closed() is called. Any further usage will result in an
  98. * SQLException.
  99. *
  100. * @exception SQLException The database connection couldn't be closed.
  101. */
  102. public void close() throws SQLException {
  103. assertOpen();
  104. isClosed = true;
  105. pooledConnection.notifyListeners();
  106. }
  107. /**
  108. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  109. *
  110. * @exception SQLException if this connection is closed or an error occurs
  111. * in the wrapped connection.
  112. */
  113. public void commit() throws SQLException {
  114. assertOpen();
  115. connection.commit();
  116. }
  117. /**
  118. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  119. *
  120. * @exception SQLException if this connection is closed or an error occurs
  121. * in the wrapped connection.
  122. */
  123. public Statement createStatement() throws SQLException {
  124. assertOpen();
  125. return connection.createStatement();
  126. }
  127. /**
  128. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  129. *
  130. * @exception SQLException if this connection is closed or an error occurs
  131. * in the wrapped connection.
  132. */
  133. public Statement createStatement(int resultSetType,
  134. int resultSetConcurrency)
  135. throws SQLException {
  136. assertOpen();
  137. return connection
  138. .createStatement(resultSetType, resultSetConcurrency);
  139. }
  140. /**
  141. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  142. *
  143. * @exception SQLException if this connection is closed or an error occurs
  144. * in the wrapped connection.
  145. */
  146. public boolean getAutoCommit() throws SQLException {
  147. assertOpen();
  148. return connection.getAutoCommit();
  149. }
  150. /**
  151. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  152. *
  153. * @exception SQLException if this connection is closed or an error occurs
  154. * in the wrapped connection.
  155. */
  156. public String getCatalog() throws SQLException {
  157. assertOpen();
  158. return connection.getCatalog();
  159. }
  160. /**
  161. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  162. *
  163. * @exception SQLException if this connection is closed or an error occurs
  164. * in the wrapped connection.
  165. */
  166. public DatabaseMetaData getMetaData() throws SQLException {
  167. assertOpen();
  168. return connection.getMetaData();
  169. }
  170. /**
  171. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  172. *
  173. * @exception SQLException if this connection is closed or an error occurs
  174. * in the wrapped connection.
  175. */
  176. public int getTransactionIsolation() throws SQLException {
  177. assertOpen();
  178. return connection.getTransactionIsolation();
  179. }
  180. /**
  181. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  182. *
  183. * @exception SQLException if this connection is closed or an error occurs
  184. * in the wrapped connection.
  185. */
  186. public Map getTypeMap() throws SQLException {
  187. assertOpen();
  188. return connection.getTypeMap();
  189. }
  190. /**
  191. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  192. *
  193. * @exception SQLException if this connection is closed or an error occurs
  194. * in the wrapped connection.
  195. */
  196. public SQLWarning getWarnings() throws SQLException {
  197. assertOpen();
  198. return connection.getWarnings();
  199. }
  200. /**
  201. * Returns true after close() is called, and false prior to that.
  202. *
  203. * @return a <code>boolean</code> value
  204. */
  205. public boolean isClosed() {
  206. return isClosed;
  207. }
  208. /**
  209. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  210. *
  211. * @exception SQLException if this connection is closed or an error occurs
  212. * in the wrapped connection.
  213. */
  214. public boolean isReadOnly() throws SQLException {
  215. assertOpen();
  216. return connection.isReadOnly();
  217. }
  218. /**
  219. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  220. *
  221. * @exception SQLException if this connection is closed or an error occurs
  222. * in the wrapped connection.
  223. */
  224. public String nativeSQL(String sql) throws SQLException {
  225. assertOpen();
  226. return connection.nativeSQL(sql);
  227. }
  228. /**
  229. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  230. *
  231. * @exception SQLException if this connection is closed or an error occurs
  232. * in the wrapped connection.
  233. */
  234. public CallableStatement prepareCall(String sql) throws SQLException {
  235. assertOpen();
  236. return connection.prepareCall(sql);
  237. }
  238. /**
  239. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  240. *
  241. * @exception SQLException if this connection is closed or an error occurs
  242. * in the wrapped connection.
  243. */
  244. public CallableStatement prepareCall(String sql, int resultSetType,
  245. int resultSetConcurrency)
  246. throws SQLException {
  247. assertOpen();
  248. return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
  249. }
  250. /**
  251. * If pooling of <code>PreparedStatement</code>s is turned on in the
  252. * {@link DriverAdapterCPDS}, a pooled object may be returned, otherwise
  253. * delegate to the wrapped jdbc 1.x {@link java.sql.Connection}.
  254. *
  255. * @exception SQLException if this connection is closed or an error occurs
  256. * in the wrapped connection.
  257. */
  258. public PreparedStatement prepareStatement(String sql) throws SQLException {
  259. assertOpen();
  260. return pooledConnection.prepareStatement(sql);
  261. }
  262. /**
  263. * If pooling of <code>PreparedStatement</code>s is turned on in the
  264. * {@link DriverAdapterCPDS}, a pooled object may be returned, otherwise
  265. * delegate to the wrapped jdbc 1.x {@link java.sql.Connection}.
  266. *
  267. * @exception SQLException if this connection is closed or an error occurs
  268. * in the wrapped connection.
  269. */
  270. public PreparedStatement prepareStatement(String sql, int resultSetType,
  271. int resultSetConcurrency)
  272. throws SQLException {
  273. assertOpen();
  274. return pooledConnection
  275. .prepareStatement(sql, resultSetType, resultSetConcurrency);
  276. }
  277. /**
  278. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  279. *
  280. * @exception SQLException if this connection is closed or an error occurs
  281. * in the wrapped connection.
  282. */
  283. public void rollback() throws SQLException {
  284. assertOpen();
  285. connection.rollback();
  286. }
  287. /**
  288. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  289. *
  290. * @exception SQLException if this connection is closed or an error occurs
  291. * in the wrapped connection.
  292. */
  293. public void setAutoCommit(boolean b) throws SQLException {
  294. assertOpen();
  295. connection.setAutoCommit(b);
  296. }
  297. /**
  298. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  299. *
  300. * @exception SQLException if this connection is closed or an error occurs
  301. * in the wrapped connection.
  302. */
  303. public void setCatalog(String catalog) throws SQLException {
  304. assertOpen();
  305. connection.setCatalog(catalog);
  306. }
  307. /**
  308. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  309. *
  310. * @exception SQLException if this connection is closed or an error occurs
  311. * in the wrapped connection.
  312. */
  313. public void setReadOnly(boolean readOnly) throws SQLException {
  314. assertOpen();
  315. connection.setReadOnly(readOnly);
  316. }
  317. /**
  318. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  319. *
  320. * @exception SQLException if this connection is closed or an error occurs
  321. * in the wrapped connection.
  322. */
  323. public void setTransactionIsolation(int level) throws SQLException {
  324. assertOpen();
  325. connection.setTransactionIsolation(level);
  326. }
  327. /**
  328. * Pass thru method to the wrapped jdbc 1.x {@link java.sql.Connection}.
  329. *
  330. * @exception SQLException if this connection is closed or an error occurs
  331. * in the wrapped connection.
  332. */
  333. public void setTypeMap(Map map) throws SQLException {
  334. assertOpen();
  335. connection.setTypeMap(map);
  336. }
  337. // ------------------- JDBC 3.0 -----------------------------------------
  338. // Will be commented by the build process on a JDBC 2.0 system
  339. /* JDBC_3_ANT_KEY_BEGIN */
  340. public int getHoldability() throws SQLException {
  341. assertOpen();
  342. return connection.getHoldability();
  343. }
  344. public void setHoldability(int holdability) throws SQLException {
  345. assertOpen();
  346. connection.setHoldability(holdability);
  347. }
  348. public java.sql.Savepoint setSavepoint() throws SQLException {
  349. assertOpen();
  350. return connection.setSavepoint();
  351. }
  352. public java.sql.Savepoint setSavepoint(String name) throws SQLException {
  353. assertOpen();
  354. return connection.setSavepoint(name);
  355. }
  356. public void rollback(java.sql.Savepoint savepoint) throws SQLException {
  357. assertOpen();
  358. connection.rollback(savepoint);
  359. }
  360. public void releaseSavepoint(java.sql.Savepoint savepoint)
  361. throws SQLException {
  362. assertOpen();
  363. connection.releaseSavepoint(savepoint);
  364. }
  365. public Statement createStatement(int resultSetType,
  366. int resultSetConcurrency,
  367. int resultSetHoldability)
  368. throws SQLException {
  369. assertOpen();
  370. return connection.createStatement(resultSetType, resultSetConcurrency,
  371. resultSetHoldability);
  372. }
  373. public PreparedStatement prepareStatement(String sql, int resultSetType,
  374. int resultSetConcurrency,
  375. int resultSetHoldability)
  376. throws SQLException {
  377. assertOpen();
  378. return connection.prepareStatement(sql, resultSetType,
  379. resultSetConcurrency,
  380. resultSetHoldability);
  381. }
  382. public CallableStatement prepareCall(String sql, int resultSetType,
  383. int resultSetConcurrency,
  384. int resultSetHoldability)
  385. throws SQLException {
  386. assertOpen();
  387. return connection.prepareCall(sql, resultSetType,
  388. resultSetConcurrency,
  389. resultSetHoldability);
  390. }
  391. public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
  392. throws SQLException {
  393. assertOpen();
  394. return connection.prepareStatement(sql, autoGeneratedKeys);
  395. }
  396. public PreparedStatement prepareStatement(String sql, int columnIndexes[])
  397. throws SQLException {
  398. assertOpen();
  399. return connection.prepareStatement(sql, columnIndexes);
  400. }
  401. public PreparedStatement prepareStatement(String sql, String columnNames[])
  402. throws SQLException {
  403. assertOpen();
  404. return connection.prepareStatement(sql, columnNames);
  405. }
  406. /* JDBC_3_ANT_KEY_END */
  407. }