From: David J. <d_j...@us...> - 2002-08-14 18:34:44
|
User: d_jencks Date: 02/08/14 11:34:43 Modified: src/main/org/jboss/resource/adapter/jdbc/xa XAManagedConnection.java XAManagedConnectionFactory.java Log: replaced jdbc xa wrapper. New wrapper is lgpl, jca compliant, and allows easy extension to fix vendor driver xa problems. Refactored local wrapper to ease code sharing Revision Changes Path 1.4 +159 -162 jbosscx/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnection.java Index: XAManagedConnection.java =================================================================== RCS file: /cvsroot/jboss/jbosscx/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnection.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- XAManagedConnection.java 5 Jul 2002 05:59:45 -0000 1.3 +++ XAManagedConnection.java 14 Aug 2002 18:34:43 -0000 1.4 @@ -1,222 +1,219 @@ /* - * Licensed under the X license (see http://www.x.org/terms.htm) + * JBoss, the OpenSource J2EE webOS + * + * Distributable under LGPL license. + * See terms of license at gnu.org. */ + package org.jboss.resource.adapter.jdbc.xa; -import java.sql.Connection; -import java.sql.SQLException; -import javax.resource.ResourceException; -import javax.resource.spi.ConnectionRequestInfo; import javax.resource.spi.LocalTransaction; -import javax.resource.spi.ManagedConnectionMetaData; -import javax.security.auth.Subject; -import javax.sql.ConnectionEventListener; import javax.sql.XAConnection; -import javax.sql.XADataSource; +import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; +import org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection; +import java.sql.SQLException; +import java.util.Properties; +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionEvent; +import javax.resource.spi.ConnectionEventListener; + -import org.jboss.resource.adapter.jdbc.BaseManagedConnection; /** - * ManagedConnection implementation for XADataSource connections. Does nothing - * on cleanup, closes on destroy. This represents one physical connection to the - * DB. It cannot be shared, and uses XAResources only (no LocalTransactions). + * XAManagedConnection.java + * + * + * Created: Mon Aug 12 23:02:44 2002 * - * @author Aaron Mulder <amm...@al...> - * @author <a href="mailto:d_j...@us...">David Jencks</a> - * @version $Revision: 1.3 $ + * @author <a href="mailto:d_j...@us...">David Jencks</a> + * @version */ -public class XAManagedConnection extends BaseManagedConnection + +public class XAManagedConnection + extends BaseWrapperManagedConnection + implements XAResource { - private XAConnection con; - private XADataSource source; - private XAResource res; - private int transactionIsolation; - /* - * For logging, use JBossCategory getLog() from the superclass + protected final XAConnection xaConnection; + + protected final XAResource xaResource; + + public XAManagedConnection(XAManagedConnectionFactory mcf, + XAConnection xaConnection, + Properties props, + int transactionIsolation) throws SQLException + { + super(mcf, xaConnection.getConnection(), props, transactionIsolation); + this.xaConnection = xaConnection; + xaConnection.addConnectionEventListener( new javax.sql.ConnectionEventListener () + { + public void connectionClosed(javax.sql.ConnectionEvent ce) + { + //only we can do this, ignore + } + + public void connectionErrorOccurred(javax.sql.ConnectionEvent ce) + { + SQLException ex = ce.getSQLException(); + broadcastConnectionError(ex); + } + } + ); + this.xaResource = xaConnection.getXAResource(); + } + + /** + * Describe <code>broadcastConnectionError</code> method here. + * this is present so the ConnectionEventListener inner class can access the method. + * @param e a <code>SQLException</code> value */ + protected void broadcastConnectionError(SQLException e) + { + super.broadcastConnectionError(e); + } + + /** + * + * @return <description> + * @exception javax.resource.ResourceException <description> + */ + public LocalTransaction getLocalTransaction() throws ResourceException + { + throw new ResourceException("xa tx only!"); + } /** - * Constructor for the XAManagedConnection object * - * @param source Description of Parameter - * @param con Description of Parameter - * @param user Description of Parameter - * @param transactionIsolation Description of Parameter + * @return <description> + * @exception javax.resource.ResourceException <description> */ - public XAManagedConnection(XADataSource source, XAConnection con, String user, int transactionIsolation) + public XAResource getXAResource() throws ResourceException { - super(user); - this.con = con; - this.source = source; - this.transactionIsolation = transactionIsolation; + return this; } + // implementation of javax.transaction.xa.XAResource interface + /** - * Gets the LocalTransaction attribute of the XAManagedConnection object * - * @return The LocalTransaction value - * @exception javax.resource.ResourceException Description of Exception + * @param param1 <description> + * @param param2 <description> + * @exception javax.transaction.xa.XAException <description> */ - public LocalTransaction getLocalTransaction() - throws javax.resource.ResourceException + public void start(Xid xid, int flags) throws XAException { - throw new ResourceException("getLocalTransaction not supported"); + xaResource.start(xid, flags); } /** - * Gets the XAResource attribute of the XAManagedConnection object * - * @return The XAResource value - * @exception javax.resource.ResourceException Description of Exception + * @param param1 <description> + * @param param2 <description> + * @exception javax.transaction.xa.XAException <description> */ - public synchronized XAResource getXAResource() - // ifedorenko remove synchronized if it does not make sense here - throws javax.resource.ResourceException - { - try - { - // ifedorenko - // Cache XAResource as a workaround for a bug in oracle xa driver - // which returns a different XAResource for each getXAResource call - // (see JDBC 2.0 spec, section 7.2.2 for a reason why it should not). - //david jencks -- I don't see any problem in always caching the - //XAResource. It can't do anything but speed up access. - if (res == null) - { - res = con.getXAResource(); - } - return res; - } - catch (SQLException e) - { - ResourceException re = new ResourceException("Unable to get XAResource: " + e); - re.setLinkedException(e); - throw re; - } + public void end(Xid xid, int flags) throws XAException + { + xaResource.end(xid, flags); } /** - * This implementation does not support re-authentication. It also does not - * support connection sharing. - * - * @param sub Description of Parameter - * @param info Description of Parameter - * @return The Connection value - * @exception javax.resource.ResourceException Description of Exception - */ - public Object getConnection(Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException - { - try - { - final Connection wrapper = con.getConnection(); - con.addConnectionEventListener( - new ConnectionEventListener() - { - /** - * #Description of the Method - * - * @param evt Description of Parameter - */ - public void connectionClosed(javax.sql.ConnectionEvent evt) - { - javax.resource.spi.ConnectionEvent ce = new javax.resource.spi.ConnectionEvent(XAManagedConnection.this, javax.resource.spi.ConnectionEvent.CONNECTION_CLOSED); - ce.setConnectionHandle(wrapper); - fireConnectionEvent(ce); - con.removeConnectionEventListener(this); - } - - /** - * #Description of the Method - * - * @param evt Description of Parameter - */ - public void connectionErrorOccurred(javax.sql.ConnectionEvent evt) - { - javax.resource.spi.ConnectionEvent ce = new javax.resource.spi.ConnectionEvent(XAManagedConnection.this, javax.resource.spi.ConnectionEvent.CONNECTION_ERROR_OCCURRED); - ce.setConnectionHandle(wrapper); - fireConnectionEvent(ce); - con.removeConnectionEventListener(this); - } - }); - if (transactionIsolation != -1) - { - wrapper.setTransactionIsolation(transactionIsolation); - } - try - { - wrapper.setAutoCommit(false); - } - catch (Exception e) - { - } - return wrapper; - } - catch (SQLException e) - { - ResourceException re = new ResourceException("Unable to get XAResource: " + e); - re.setLinkedException(e); - throw re; - } + * + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public int prepare(Xid xid) throws XAException + { + return xaResource.prepare(xid); } /** - * Gets the MetaData attribute of the XAManagedConnection object * - * @return The MetaData value - * @exception javax.resource.ResourceException Description of Exception + * @param param1 <description> + * @param param2 <description> + * @exception javax.transaction.xa.XAException <description> */ - public ManagedConnectionMetaData getMetaData() - throws javax.resource.ResourceException + public void commit(Xid xid, boolean onePhase) throws XAException { + xaResource.commit(xid, onePhase); + } - throw new java.lang.UnsupportedOperationException("Method getMetaData() not yet implemented."); + /** + * + * @param param1 <description> + * @exception javax.transaction.xa.XAException <description> + */ + public void rollback(Xid xid) throws XAException + { + xaResource.rollback(xid); } /** - * #Description of the Method * - * @exception ResourceException Description of Exception + * @param param1 <description> + * @exception javax.transaction.xa.XAException <description> */ - public void destroy() - throws ResourceException + public void forget(Xid xid) throws XAException { - super.destroy(); - try - { - con.close(); - } - catch (SQLException e) - { - ResourceException re = new ResourceException("Unable to close DB connection: " + e); - re.setLinkedException(e); - throw re; - } - con = null; - source = null; + xaResource.forget(xid); } /** - * #Description of the Method * - * @exception ResourceException Description of Exception + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> */ - public void cleanup() - throws ResourceException + public Xid[] recover(int flag) throws XAException { + return xaResource.recover(flag); } - //To work around apparent jvm or compiler bug where inner class cannot call protected - //method on superclass of containing class. - protected void fireConnectionEvent(javax.resource.spi.ConnectionEvent ce) + /** + * + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public boolean isSameRM(XAResource other) throws XAException { - super.fireConnectionEvent(ce); + return xaResource.isSameRM(other); } - XADataSource getDataSource() + /** + * + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public int getTransactionTimeout() throws XAException + { + return xaResource.getTransactionTimeout(); + } + + /** + * + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public boolean setTransactionTimeout(int seconds) throws XAException + { + return xaResource.setTransactionTimeout(seconds); + } + + + /** + * Describe <code>getProps</code> method here. + * for the mcf to access in matchManagedConnection + * @return a <code>Properties</code> value + */ + Properties getProps() { - return source; + return props; } -} + + + +}// XAManagedConnection 1.7 +175 -510 jbosscx/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java Index: XAManagedConnectionFactory.java =================================================================== RCS file: /cvsroot/jboss/jbosscx/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- XAManagedConnectionFactory.java 22 Jul 2002 22:50:06 -0000 1.6 +++ XAManagedConnectionFactory.java 14 Aug 2002 18:34:43 -0000 1.7 @@ -1,602 +1,267 @@ /* - * Licensed under the X license (see http://www.x.org/terms.htm) + * JBoss, the OpenSource J2EE webOS + * + * Distributable under LGPL license. + * See terms of license at gnu.org. */ -package org.jboss.resource.adapter.jdbc.xa; - +package org.jboss.resource.adapter.jdbc.xa; -//for transaction isolation constants +import org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnectionFactory; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.beans.PropertyEditorManager; +import java.beans.PropertyEditor; +import javax.sql.XADataSource; +import javax.sql.XAConnection; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; -import java.lang.reflect.*; +import java.io.Serializable; import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverManager; import java.sql.SQLException; -import java.util.*; -import javax.naming.InitialContext; -import org.jboss.resource.ResourceException; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; +import javax.resource.ResourceException; import javax.resource.spi.ConnectionManager; import javax.resource.spi.ConnectionRequestInfo; import javax.resource.spi.ManagedConnection; import javax.resource.spi.ManagedConnectionFactory; import javax.resource.spi.security.PasswordCredential; import javax.security.auth.Subject; -import javax.sql.DataSource; -import javax.sql.XAConnection; -import javax.sql.XADataSource; import org.jboss.logging.Logger; -import org.jboss.resource.adapter.jdbc.JDBCConnectionRequestInfo; -import org.jboss.resource.adapter.jdbc.JDBCDataSource; +import org.jboss.util.NestedRuntimeException; + /** - * ManagedConnectionFactory implementation for XADataSource connections. You - * give it an XADataSource, user, and password and it generated connections. - * Matches connections based on JDBC user and XADataSource. Currently supports - * managed mode only. <p> + * XAManagedConnectionFactory.java * - * In an environment where you invoke this class directly, the preferred way to - * configure it is to call setUserName, setPassword, and setXADataSource with a - * configured XADataSource. In an environment where this is deployed as a RAR - * into a server and configured via a deployment descriptor, you'll need to use - * setXADataSourceClass and setXADataSourceProperties or setXADataSourceJNDIName - * instead of setXADataSource. The XADataSourceProperties value should be a - * string in the format <tt>name=value;name=value;name=value...</tt> where the - * names and values are properties of your XADataSource implementation. For - * example:</p> <pre> * - * xaDataSourceJNDIName java:jdbc/SomeXADataSource - or - xaDataSourceClass - * com.dbproduct.XADataSourceImpl xaDataSourceProperties url=jdbc:dbproduct:config;port=9999 - * </pre> + * Created: Mon Aug 12 21:53:02 2002 * - * @author Aaron Mulder <amm...@al...> - * @author Larry Sanderson <la...@mr...> - * @version $Revision: 1.6 $ + * @author <a href="mailto:d_j...@us...">David Jencks</a> + * @version */ -public class XAManagedConnectionFactory implements ManagedConnectionFactory -{ - - private Logger log = Logger.getLogger(XAManagedConnectionFactory.class); - private transient XADataSource xads; - private String username; - private String password; +public class XAManagedConnectionFactory extends BaseWrapperManagedConnectionFactory +{ private String xaDataSourceClass; - private String xaDataSourceProperties; - private String xaDataSourceName; - - private int transactionIsolation = -1; - - /** - * Constructor for the XAManagedConnectionFactory object - */ - public XAManagedConnectionFactory() - { - } - - /* - * We ignore this and use log4j - */ - /** - * Sets the LogWriter attribute of the XAManagedConnectionFactory object - * - * @param writer The new LogWriter value - * @exception javax.resource.ResourceException Description of Exception - */ - public void setLogWriter(PrintWriter writer) - throws javax.resource.ResourceException - { - } - - /** - * Sets the UserName attribute of the XAManagedConnectionFactory object - * - * @param username The new UserName value - */ - public void setUserName(String username) - { - this.username = username; - } - - /** - * Sets the Password attribute of the XAManagedConnectionFactory object - * - * @param password The new Password value - */ - public void setPassword(String password) - { - this.password = password; - } - /** - * Sets the XADataSource attribute of the XAManagedConnectionFactory object - * - * @param xads The new XADataSource value - */ - public void setXADataSource(XADataSource xads) - { - this.xads = xads; - } - - /** - * Sets the XADataSourceClass attribute of the XAManagedConnectionFactory - * object - * - * @param className The new XADataSourceClass value - */ - public void setXADataSourceClass(String className) - { - xaDataSourceClass = className; - } - - /** - * Sets the XADataSourceProperties attribute of the XAManagedConnectionFactory - * object - * - * @param props The new XADataSourceProperties value - */ - public void setXADataSourceProperties(String props) - { - xaDataSourceProperties = props; - } + private String xaDataSourceProperties; + private final Properties xaProps = new Properties(); + private XADataSource xads; - /** - * Sets the TransactionIsolation attribute of the XAManagedConnectionFactory - * object - * - * @param transactionIsolation The new TransactionIsolation value - */ - public void setTransactionIsolation(String transactionIsolation) - { - log.trace("TransactionIsolation set:" + transactionIsolation); - if (transactionIsolation.equals("TRANSACTION_NONE")) - { - this.transactionIsolation = Connection.TRANSACTION_NONE; - } - else if (transactionIsolation.equals("TRANSACTION_READ_COMMITTED")) - { - this.transactionIsolation = Connection.TRANSACTION_READ_COMMITTED; - } - else if (transactionIsolation.equals("TRANSACTION_READ_UNCOMMITTED")) - { - this.transactionIsolation = Connection.TRANSACTION_READ_UNCOMMITTED; - } - else if (transactionIsolation.equals("TRANSACTION_REPEATABLE_READ")) - { - this.transactionIsolation = Connection.TRANSACTION_REPEATABLE_READ; - } - else if (transactionIsolation.equals("TRANSACTION_SERIALIZABLE")) - { - this.transactionIsolation = Connection.TRANSACTION_SERIALIZABLE; - } - else - { - try - { - this.transactionIsolation = Integer.parseInt(transactionIsolation); - } - catch (NumberFormatException nfe) - { - throw new IllegalArgumentException("Setting Isolation level to unknown state: " + transactionIsolation); - } - } - } - /** - * Gets the LogWriter attribute of the XAManagedConnectionFactory object - * - * @return The LogWriter value - * @exception javax.resource.ResourceException Description of Exception - */ - public PrintWriter getLogWriter() - throws javax.resource.ResourceException - { - return null; + public XAManagedConnectionFactory() + { } - /** - * Gets the UserName attribute of the XAManagedConnectionFactory object - * - * @return The UserName value - */ - public String getUserName() - { - return username; - } /** - * Gets the Password attribute of the XAManagedConnectionFactory object - * - * @return The Password value + * Get the XaDataSourceClass value. + * @return the XaDataSourceClass value. */ - public String getPassword() + public String getXaDataSourceClass() { - return password; + return xaDataSourceClass; } /** - * Gets the XADataSource attribute of the XAManagedConnectionFactory object - * - * @return The XADataSource value + * Set the XaDataSourceClass value. + * @param newXaDataSourceClass The new XaDataSourceClass value. */ - public XADataSource getXADataSource() + public void setXaDataSourceClass(String xaDataSourceClass) { - return xads; + this.xaDataSourceClass = xaDataSourceClass; } - /** - * Gets the XADataSourceClass attribute of the XAManagedConnectionFactory - * object - * - * @return The XADataSourceClass value - */ - public String getXADataSourceClass() - { - return xaDataSourceClass; - } /** - * Gets the XADataSourceProperties attribute of the XAManagedConnectionFactory - * object - * - * @return The XADataSourceProperties value + * Get the XADataSourceProperties value. + * @return the XADataSourceProperties value. */ public String getXADataSourceProperties() { return xaDataSourceProperties; } - /** - * Gets the TransactionIsolation attribute of the XAManagedConnectionFactory - * object - * - * @return The TransactionIsolation value + * Set the XADataSourceProperties value. + * @param newXADataSourceProperties The new XADataSourceProperties value. */ - public String getTransactionIsolation() + public void setXADataSourceProperties(String xaDataSourceProperties) { - switch (this.transactionIsolation) + this.xaDataSourceProperties = xaDataSourceProperties; + xaProps.clear(); + if (xaDataSourceProperties != null) { - case Connection.TRANSACTION_NONE: - return "TRANSACTION_NONE"; - case Connection.TRANSACTION_READ_COMMITTED: - return "TRANSACTION_READ_COMMITTED"; - case Connection.TRANSACTION_READ_UNCOMMITTED: - return "TRANSACTION_READ_UNCOMMITTED"; - case Connection.TRANSACTION_REPEATABLE_READ: - return "TRANSACTION_REPEATABLE_READ"; - case Connection.TRANSACTION_SERIALIZABLE: - return "TRANSACTION_SERIALIZABLE"; - case -1: - return "DEFAULT"; - default: - return Integer.toString(transactionIsolation); + InputStream is = new ByteArrayInputStream(xaDataSourceProperties.getBytes()); + try + { + xaProps.load(is); + } + catch (IOException ioe) + { + throw new NestedRuntimeException("Could not load connection properties", ioe); + } } } - /** - * #Description of the Method - * - * @param mgr Description of Parameter - * @return Description of the Returned - * Value - * @exception javax.resource.ResourceException Description of Exception - */ - public Object createConnectionFactory(ConnectionManager mgr) - throws javax.resource.ResourceException + + + + public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cri) + throws javax.resource.ResourceException { - DataSource ds = new JDBCDataSource(mgr, this); - return ds; - } - - /** - * #Description of the Method - * - * @return Description of the Returned - * Value - * @exception javax.resource.ResourceException Description of Exception - */ - public Object createConnectionFactory() - throws javax.resource.ResourceException - { - throw new java.lang.UnsupportedOperationException("Must be used in managed mode"); - } - - /** - * #Description of the Method - * - * @param sub Description of Parameter - * @param info Description of Parameter - * @return Description of the Returned - * Value - * @exception javax.resource.ResourceException Description of Exception - */ - public ManagedConnection createManagedConnection(Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException - { - // Set user and password to default - String user = username; - String pw = password; - - // Check passed Subject and ConnectionRequestInfo for user/password overrides - if (sub != null) + Properties props = getConnectionProperties(subject, cri); + try { - Set creds = sub.getPrivateCredentials(javax.resource.spi.security.PasswordCredential.class); - for (Iterator it = creds.iterator(); it.hasNext(); ) - { - PasswordCredential pc = (PasswordCredential)it.next(); - user = pc.getUserName(); - pw = new String(pc.getPassword()); - break; - } - } - else - { - if (info != null) - { - JDBCConnectionRequestInfo jdbcInfo = (JDBCConnectionRequestInfo)info; - user = jdbcInfo.user; - pw = jdbcInfo.password; - } - } + XAConnection xaConnection = getXADataSource().getXAConnection(props.getProperty("user"), props.getProperty("password")); - // Create the connection - try - { - XAConnection con = getXADS().getXAConnection(user, pw); - ManagedConnection mc = new XAManagedConnection(xads, con, user, transactionIsolation); - return mc; + + return new XAManagedConnection(this, xaConnection, props, transactionIsolation); } - catch (SQLException e) + catch (java.sql.SQLException e) { - throw new ResourceException("Unable to create DB XAConnection: " + e); - } + // use our ResourceException to properly display linked exception in stack trace + throw new org.jboss.resource.ResourceException("Could not create connection", e); + } // end of try-catch } /** - * #Description of the Method * - * @param cons Description of Parameter - * @param sub Description of Parameter - * @param info Description of Parameter - * @return Description of the Returned - * Value - * @exception javax.resource.ResourceException Description of Exception + * @param param1 <description> + * @param param2 <description> + * @param param3 <description> + * @return <description> + * @exception javax.resource.ResourceException <description> */ - public ManagedConnection matchManagedConnections(Set cons, Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException + public ManagedConnection matchManagedConnections(Set mcs, Subject subject, ConnectionRequestInfo cri) + throws ResourceException { - // Set user and password to default - String user = username; - String pw = password; - - // Check passed Subject and ConnectionRequestInfo for user/password overrides - if (sub != null) - { - Set creds = sub.getPrivateCredentials(javax.resource.spi.security.PasswordCredential.class); - for (Iterator it = creds.iterator(); it.hasNext(); ) - { - PasswordCredential pc = (PasswordCredential)it.next(); - user = pc.getUserName(); - pw = new String(pc.getPassword()); - break; - } - } - else + Properties newProps = getConnectionProperties(subject, cri); + for (Iterator i = mcs.iterator(); i.hasNext(); ) { - if (info != null) + Object o = i.next(); + if (o instanceof XAManagedConnection) { - if (!(info instanceof JDBCConnectionRequestInfo)) + XAManagedConnection mc = (XAManagedConnection)o; + if (mc.getProps().equals(newProps)) { - throw new ResourceException("Passed ConnectionRequestInfo class '" + info.getClass().getName() + "' to XAManagedConnectionFactory!"); - } - JDBCConnectionRequestInfo jdbcInfo = (JDBCConnectionRequestInfo)info; - user = jdbcInfo.user; - pw = jdbcInfo.password; - } - } - - // Check the connections in the Set - for (Iterator it = cons.iterator(); it.hasNext(); ) - { - Object unknown = it.next(); - if (!(unknown instanceof XAManagedConnection)) - { - continue; - } - XAManagedConnection con = (XAManagedConnection)unknown; - String conUser = con.getUser(); - if (((conUser == null)? (user == null) : conUser.equals(user)) - && con.getDataSource().equals(xads)) - { - return con; - } - } + return mc; + } // end of if () + + } // end of if () + } // end of for () return null; } - private XADataSource getXADS() throws ResourceException - { - if (xads != null) - { - return xads; - } - if (xaDataSourceClass != null) - { - try - { - log.trace("XADatasourceClass: " + xaDataSourceClass); - Class cls = Thread.currentThread().getContextClassLoader().loadClass(xaDataSourceClass); - xads = (XADataSource)cls.newInstance(); - log.trace("got DataSource instance"); - - Properties props = parseProperties(); - populate(xads, props); - return xads; - } - catch (Exception e) - { - xads = null; - throw new ResourceException("Could not create or configure XADataSource", e); - } - } - else if (xaDataSourceName != null) - { - try - { - InitialContext ic = new InitialContext(); - xads = (XADataSource)ic.lookup(xaDataSourceName); - return xads; - } - catch (Exception e) - { - xads = null; - log.warn("Unable to reach XADataSource in JNDI:", e); - } - } - return null; - } - - private Properties parseProperties() throws IOException + /** + * + * @return hashcode computed according to recommendations in Effective Java. + */ + public int hashCode() { - Properties props = new Properties(); - if (xaDataSourceProperties.indexOf(";") == -1) - { - InputStream is = new ByteArrayInputStream(xaDataSourceProperties.getBytes()); - props.load(is); - } - else - { - log.trace("parsing props: " + xaDataSourceProperties); - StringTokenizer tokens = new StringTokenizer(xaDataSourceProperties, ";="); - - while (tokens.hasMoreTokens()) - { - String key = tokens.nextToken(); - String value = tokens.nextToken(); - props.put(key, value); - } - } - return props; + int result = 17; + result = result * 37 + ((xaDataSourceClass == null)? 0: xaDataSourceClass.hashCode()); + result = result * 37 + xaProps.hashCode(); + result = result * 37 + ((userName == null)? 0: userName.hashCode()); + result = result * 37 + ((password == null)? 0: password.hashCode()); + result = result * 37 + transactionIsolation; + return result; } /** - * Populate the obj with the properties in the Map. No exceptions - * are thrown if a property is specified for which there is no setter, - * however a warning is issued. * - * @param props the properties to use. + * @param param1 <description> + * @return <description> */ - private void populate(Object obj, Map props) + public boolean equals(Object other) { - // get all valid set methods - - Method[] methods = obj.getClass().getMethods(); - HashMap setters = new HashMap(); - - for (int i = 0; i < methods.length; i++) + if (this == other) { - Method meth = methods[i]; - String name = meth.getName(); - if (name.startsWith("set")) - { - String attrName = name.substring(3); - if (meth.getParameterTypes().length == 1) - { - Class type = meth.getParameterTypes()[0]; - if (type == String.class || type.isPrimitive()) - { - setters.put(attrName, meth); - } - } - } - } - - for (Iterator i = props.entrySet().iterator(); i.hasNext();) + return true; + } // end of if () + if (getClass() != other.getClass()) { - Map.Entry entry = (Map.Entry)i.next(); - String attributeName = (String)entry.getKey(); - String attributeValue = (String)entry.getValue(); + return false; + } // end of if () + XAManagedConnectionFactory otherMcf = (XAManagedConnectionFactory)other; + return this.xaDataSourceClass.equals(otherMcf.xaDataSourceClass) + && this.xaProps.equals(otherMcf.xaProps) + && ((this.userName == null) ? otherMcf.userName == null: + this.userName.equals(otherMcf.userName)) + && ((this.password == null) ? otherMcf.password == null: + this.password.equals(otherMcf.password)) + && this.transactionIsolation == otherMcf.transactionIsolation; - Method meth = (Method)setters.get(attributeName); - if (meth != null) - { - try - { - Object val = convert(attributeValue, meth.getParameterTypes()[0]); - meth.invoke(obj, new Object[] {val }); - } - catch (Exception e) - { - log.warn("Unable to set XADataSource property " + - attributeName + "=" + - attributeValue + ":"); - } - } - else - { - log.warn("No setter method for attribute " + attributeName + - " (value=" + attributeValue + ")."); - } - } } - /** - * Convert the specified value to the specified class. This should be - * replaced with the org.apache.commons.beanUtils.ConvertUtils class. - * - * @return the value converted to type - * @param value the String value to convert - * @type the class to convert to. Must be a primitive type or String. - */ - private Object convert(String value, Class type) + protected XADataSource getXADataSource() throws ResourceException { - if (type == String.class) - { - return value; - } - if (type == Integer.TYPE) - { - return Integer.valueOf(value); - } - if (type == Double.TYPE) - { - return Double.valueOf(value); - } - if (type == Boolean.TYPE) { - return new Boolean( - value.equalsIgnoreCase("true") || - value.equalsIgnoreCase("on") || - value.equalsIgnoreCase("yes") - ); - } - if (type == Long.TYPE) - { - return Long.valueOf(value); - } - if (type == Float.TYPE) - { - return Float.valueOf(value); - } - if (type == Byte.TYPE) + if (xads == null) { - return Byte.valueOf(value); - } - if (type == Short.TYPE) - { - return Short.valueOf(value); - } - if (type == Character.TYPE) - { - return new Character(value.charAt(0)); - } - if (type == Double.TYPE) - { - return Double.valueOf(value); - } - return null; + if (xaDataSourceClass == null) + { + throw new ResourceException("No XADataSourceClass supplied!"); + } // end of if () + try + { + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(xaDataSourceClass); + xads = (XADataSource)clazz.newInstance(); + Class[] NOCLASSES = new Class[] {}; + for (Iterator i = xaProps.keySet().iterator(); i.hasNext(); ) + { + String name = (String)i.next(); + String value = xaProps.getProperty(name); + Method getter = clazz.getMethod("get" + name, NOCLASSES); + Class type = getter.getReturnType(); + Method setter = clazz.getMethod("set" + name, new Class[] {type}); + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor == null) + { + throw new ResourceException("No property editor found for type: " + type); + } // end of if () + editor.setAsText(value); + setter.invoke(xads, new Object[] {editor.getValue()}); + + } // end of for () + } + catch (ClassNotFoundException cnfe) + { + throw new ResourceException("Class not found for XADataSource " + xaDataSourceClass); + } // end of try-catch + catch (InstantiationException ie) + { + throw new ResourceException("Could not create an XADataSource: " + ie); + } // end of catch + catch (IllegalAccessException iae) + { + throw new ResourceException("Could not set a property: " + iae); + } // end of catch + + catch (IllegalArgumentException iae) + { + throw new ResourceException("Could not set a property: " + iae); + } // end of catch + + catch (InvocationTargetException ite) + { + throw new ResourceException("Could not invoke setter on XADataSource: " + ite); + } // end of catch + catch (NoSuchMethodException nsme) + { + throw new ResourceException("Could not find accessor on XADataSource: " + nsme); + } // end of catch + } // end of if () + return xads; } -} +}// XAManagedConnectionFactory |