001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.jdbc.support.nativejdbc;
018:
019: import java.lang.reflect.Method;
020: import java.sql.CallableStatement;
021: import java.sql.Connection;
022: import java.sql.PreparedStatement;
023: import java.sql.ResultSet;
024: import java.sql.SQLException;
025: import java.sql.Statement;
026:
027: import org.springframework.util.ReflectionUtils;
028:
029: /**
030: * Implementation of the NativeJdbcExtractor interface for JBoss 3.2.4+.
031: *
032: * <p>Returns the underlying native Connection, Statement, etc to
033: * application code instead of JBoss' wrapper implementations.
034: * The returned JDBC classes can then safely be cast, e.g. to
035: * <code>oracle.jdbc.OracleConnection</code>.
036: *
037: * <p>This NativeJdbcExtractor can be set just to <i>allow</i> working with
038: * a JBoss connection pool: If a given object is not a JBoss wrapper,
039: * it will be returned as-is.
040: *
041: * @author Juergen Hoeller
042: * @since 03.01.2004
043: * @see org.jboss.resource.adapter.jdbc.WrappedConnection#getUnderlyingConnection
044: * @see org.jboss.resource.adapter.jdbc.WrappedStatement#getUnderlyingStatement
045: * @see org.jboss.resource.adapter.jdbc.WrappedResultSet#getUnderlyingResultSet
046: */
047: public class JBossNativeJdbcExtractor extends
048: NativeJdbcExtractorAdapter {
049:
050: private static final String WRAPPED_CONNECTION_NAME = "org.jboss.resource.adapter.jdbc.WrappedConnection";
051:
052: private static final String WRAPPED_STATEMENT_NAME = "org.jboss.resource.adapter.jdbc.WrappedStatement";
053:
054: private static final String WRAPPED_RESULT_SET_NAME = "org.jboss.resource.adapter.jdbc.WrappedResultSet";
055:
056: private Class wrappedConnectionClass;
057:
058: private Class wrappedStatementClass;
059:
060: private Class wrappedResultSetClass;
061:
062: private Method getUnderlyingConnectionMethod;
063:
064: private Method getUnderlyingStatementMethod;
065:
066: private Method getUnderlyingResultSetMethod;
067:
068: /**
069: * This constructor retrieves JBoss JDBC wrapper classes,
070: * so we can get the underlying vendor connection using reflection.
071: */
072: public JBossNativeJdbcExtractor() {
073: try {
074: this .wrappedConnectionClass = getClass().getClassLoader()
075: .loadClass(WRAPPED_CONNECTION_NAME);
076: this .wrappedStatementClass = getClass().getClassLoader()
077: .loadClass(WRAPPED_STATEMENT_NAME);
078: this .wrappedResultSetClass = getClass().getClassLoader()
079: .loadClass(WRAPPED_RESULT_SET_NAME);
080: this .getUnderlyingConnectionMethod = this .wrappedConnectionClass
081: .getMethod("getUnderlyingConnection",
082: (Class[]) null);
083: this .getUnderlyingStatementMethod = this .wrappedStatementClass
084: .getMethod("getUnderlyingStatement", (Class[]) null);
085: this .getUnderlyingResultSetMethod = this .wrappedResultSetClass
086: .getMethod("getUnderlyingResultSet", (Class[]) null);
087: } catch (Exception ex) {
088: throw new IllegalStateException(
089: "Could not initialize JBossNativeJdbcExtractor because JBoss API classes are not available: "
090: + ex);
091: }
092: }
093:
094: /**
095: * Retrieve the Connection via JBoss' <code>getUnderlyingConnection</code> method.
096: */
097: protected Connection doGetNativeConnection(Connection con)
098: throws SQLException {
099: if (this .wrappedConnectionClass
100: .isAssignableFrom(con.getClass())) {
101: return (Connection) ReflectionUtils.invokeMethod(
102: this .getUnderlyingConnectionMethod, con);
103: }
104: return con;
105: }
106:
107: /**
108: * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
109: */
110: public Statement getNativeStatement(Statement stmt)
111: throws SQLException {
112: if (this .wrappedStatementClass
113: .isAssignableFrom(stmt.getClass())) {
114: return (Statement) ReflectionUtils.invokeMethod(
115: this .getUnderlyingStatementMethod, stmt);
116: }
117: return stmt;
118: }
119:
120: /**
121: * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
122: */
123: public PreparedStatement getNativePreparedStatement(
124: PreparedStatement ps) throws SQLException {
125: return (PreparedStatement) getNativeStatement(ps);
126: }
127:
128: /**
129: * Retrieve the Connection via JBoss' <code>getUnderlyingStatement</code> method.
130: */
131: public CallableStatement getNativeCallableStatement(
132: CallableStatement cs) throws SQLException {
133: return (CallableStatement) getNativeStatement(cs);
134: }
135:
136: /**
137: * Retrieve the Connection via JBoss' <code>getUnderlyingResultSet</code> method.
138: */
139: public ResultSet getNativeResultSet(ResultSet rs)
140: throws SQLException {
141: if (this .wrappedResultSetClass.isAssignableFrom(rs.getClass())) {
142: return (ResultSet) ReflectionUtils.invokeMethod(
143: this.getUnderlyingResultSetMethod, rs);
144: }
145: return rs;
146: }
147:
148: }
|