/* * JBoss, Home of Professional Open Source * Copyright 2007, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2005-2006, * @author JBoss Inc. */ /* * Copyright (C) 1998, 1999, 2000, * * Arjuna Solutions Limited, * Newcastle upon Tyne, * Tyne and Wear, * UK. * * $Id: JNDIManager.java,v 1.10 2004/07/26 09:49:59 jcoleman Exp $ */ package org.jboss.jbossts.qa.Utils; import com.arjuna.ats.internal.jdbc.DynamicClass; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.XADataSource; import java.util.Hashtable; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; /** * Uses reflection to configure the datasources to avoid the need for * compile time linking against specific drivers jars */ public class JNDIManager { public static void main(String[] args) { try { String profileName = args[args.length - 1]; String driver = JDBCProfileStore.driver(profileName, 0 /*driver number*/); String binding = JDBCProfileStore.binding(profileName); String databaseName = JDBCProfileStore.databaseName(profileName); String host = JDBCProfileStore.host(profileName); String dynamicClass = JDBCProfileStore.databaseDynamicClass(profileName); String databaseURL = JDBCProfileStore.databaseURL(profileName); String port = JDBCProfileStore.port(profileName); XADataSource xaDataSourceToBind = null; if (driver == null || binding == null) { throw new Exception("Driver or binding was not specified"); } // We use reflection to configure the data source so as to avoid a compile or runtime // dependency on all the drivers. see JBTM-543 if (driver.equals("com.arjuna.ats.jdbc.TransactionalDriver")) { if ((dynamicClass == null) || (databaseURL == null)) { throw new Exception("One of dynamicClass/datbaseURL was not specified for: " + profileName); } Class c = Class.forName(dynamicClass); DynamicClass arjunaJDBC2DynamicClass = (DynamicClass) c.newInstance(); javax.sql.XADataSource xaDataSource = arjunaJDBC2DynamicClass.getDataSource(databaseURL); xaDataSourceToBind = xaDataSource; } else if (driver.equals("oracle.jdbc.driver.OracleDriver")) { if (databaseName == null) { throw new Exception("DatabaseName was not specified for profile: " + profileName); } XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("oracle.jdbc.xa.client.OracleXADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); wrapper.setProperty("portNumber", Integer.valueOf(port)); wrapper.setProperty("driverType", "thin"); xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else if( driver.equals("com.microsoft.sqlserver.jdbc.SQLServerDriver")) { XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("com.microsoft.sqlserver.jdbc.SQLServerXADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); wrapper.setProperty("portNumber", Integer.valueOf(port)); wrapper.setProperty("sendStringParametersAsUnicode", false); xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else if( driver.equals("org.postgresql.Driver")) { XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("org.postgresql.xa.PGXADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else if( driver.equals("com.mysql.jdbc.Driver")) { // Note: MySQL XA only works on InnoDB tables. // set 'default-storage-engine=innodb' in e.g. /etc/my.cnf // so that the 'CREATE TABLE ...' statments behave correctly. // doing this config on a per connection basis instead is // possible but would require lots of code changes :-( XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); wrapper.setProperty("pinGlobalTxToPhysicalConnection", true); // Bad Things happen if you forget this bit. xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else if( driver.equals("com.ibm.db2.jcc.DB2Driver")) { // for DB2 version 8.2 XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("com.ibm.db2.jcc.DB2XADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); wrapper.setProperty("driverType", 4); wrapper.setProperty("portNumber", Integer.valueOf(port)); xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else if( driver.equals("com.sybase.jdbc3.jdbc.SybDriver")) { XADataSourceReflectionWrapper wrapper = new XADataSourceReflectionWrapper("com.sybase.jdbc3.jdbc.SybXADataSource"); wrapper.setProperty("databaseName", databaseName); wrapper.setProperty("serverName", host); wrapper.setProperty("portNumber", Integer.valueOf(port)); xaDataSourceToBind = wrapper.getWrappedXADataSource(); } else { throw new Exception("JDBC2 driver " + driver + " not recognised"); } // // bind to JDNI // try { // expect suitable java.naming.provider.url and java.naming.factory.initial // system properties have been set. InitialContext ctx = new InitialContext(); ctx.rebind(binding, xaDataSourceToBind); System.out.println("bound "+binding); } catch (Exception e) { System.err.println("JNDIManager.main: Problem binding resource into JNDI"); e.printStackTrace(); System.out.println("Failed"); System.exit(1); } System.out.println("Passed"); } catch (Exception e) { e.printStackTrace(System.err); System.out.println("Failed"); } } } class XADataSourceReflectionWrapper { private XADataSource xaDataSource; XADataSourceReflectionWrapper(String classname) { try { xaDataSource = (XADataSource)Class.forName(classname).newInstance(); } catch(Exception e) { throw new ExceptionInInitializerError(e); } } public void setProperty(String name, Object value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { name = "set"+name.substring(0,1).toUpperCase()+name.substring(1); Class type = value.getClass(); if(value instanceof Integer) { type = Integer.TYPE; } if(value instanceof Boolean) { type = Boolean.TYPE; } Method method = xaDataSource.getClass().getMethod(name, type); method.invoke(xaDataSource, value); } public XADataSource getWrappedXADataSource() { return xaDataSource; } }