001/* 002 * Copyright 2002-2013 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 * https://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 017package org.springframework.jdbc.support.nativejdbc; 018 019import java.lang.reflect.Method; 020import java.sql.Connection; 021import java.sql.SQLException; 022 023import org.springframework.util.ReflectionUtils; 024 025/** 026 * Implementation of the {@link NativeJdbcExtractor} interface for WebSphere, 027 * supporting WebSphere Application Server 6.1 and higher. 028 * 029 * <p>Returns the underlying native Connection to application code instead 030 * of WebSphere's wrapper implementation; unwraps the Connection for 031 * native statements. The returned JDBC classes can then safely be cast, 032 * e.g. to {@code oracle.jdbc.OracleConnection}. 033 * 034 * <p>This NativeJdbcExtractor can be set just to <i>allow</i> working 035 * with a WebSphere DataSource: If a given object is not a WebSphere 036 * Connection wrapper, it will be returned as-is. 037 * 038 * @author Juergen Hoeller 039 * @since 1.1 040 */ 041public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter { 042 043 private static final String JDBC_ADAPTER_CONNECTION_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection"; 044 045 private static final String JDBC_ADAPTER_UTIL_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil"; 046 047 048 private Class<?> webSphereConnectionClass; 049 050 private Method webSphereNativeConnectionMethod; 051 052 053 /** 054 * This constructor retrieves WebSphere JDBC adapter classes, 055 * so we can get the underlying vendor connection using reflection. 056 */ 057 public WebSphereNativeJdbcExtractor() { 058 try { 059 this.webSphereConnectionClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_CONNECTION_NAME); 060 Class<?> jdbcAdapterUtilClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_UTIL_NAME); 061 this.webSphereNativeConnectionMethod = 062 jdbcAdapterUtilClass.getMethod("getNativeConnection", new Class<?>[] {this.webSphereConnectionClass}); 063 } 064 catch (Exception ex) { 065 throw new IllegalStateException( 066 "Could not initialize WebSphereNativeJdbcExtractor because WebSphere API classes are not available: " + ex); 067 } 068 } 069 070 071 /** 072 * Return {@code true}, as WebSphere returns wrapped Statements. 073 */ 074 @Override 075 public boolean isNativeConnectionNecessaryForNativeStatements() { 076 return true; 077 } 078 079 /** 080 * Return {@code true}, as WebSphere returns wrapped PreparedStatements. 081 */ 082 @Override 083 public boolean isNativeConnectionNecessaryForNativePreparedStatements() { 084 return true; 085 } 086 087 /** 088 * Return {@code true}, as WebSphere returns wrapped CallableStatements. 089 */ 090 @Override 091 public boolean isNativeConnectionNecessaryForNativeCallableStatements() { 092 return true; 093 } 094 095 /** 096 * Retrieve the Connection via WebSphere's {@code getNativeConnection} method. 097 */ 098 @Override 099 protected Connection doGetNativeConnection(Connection con) throws SQLException { 100 if (this.webSphereConnectionClass.isAssignableFrom(con.getClass())) { 101 return (Connection) ReflectionUtils.invokeJdbcMethod(this.webSphereNativeConnectionMethod, null, con); 102 } 103 return con; 104 } 105 106}