From: David J. <d_j...@us...> - 2003-02-15 21:01:35
|
User: d_jencks Date: 03/02/15 13:01:33 Modified: src/main/org/jboss/resource/adapter/jdbc/xa Tag: Branch_3_0 XAManagedConnection.java XAManagedConnectionFactory.java Log: backport CachedConnectionManager changes, and test-connection-before-handing-it-out feature. This replaces the old jca-jdbc wrappers with the versions from 3.2/4, enabling oracle xa support in 3.0 Revision Changes Path No revision No revision 1.2.2.2 +169 -157 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.2.2.1 retrieving revision 1.2.2.2 diff -u -r1.2.2.1 -r1.2.2.2 --- XAManagedConnection.java 16 Jun 2002 19:42:51 -0000 1.2.2.1 +++ XAManagedConnection.java 15 Feb 2003 21:01:33 -0000 1.2.2.2 @@ -1,222 +1,234 @@ /* - * 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.JBossResourceException; + -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 + * * - * @author Aaron Mulder <amm...@al...> - * @author <a href="mailto:d_j...@us...">David Jencks</a> - * @version $Revision: 1.2.2.1 $ + * Created: Mon Aug 12 23:02:44 2002 + * + * @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; + + protected Xid currentXid; + + 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); + } /** - * 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 LocalTransaction getLocalTransaction() throws ResourceException { - super(user); - this.con = con; - this.source = source; - this.transactionIsolation = transactionIsolation; + throw new JBossResourceException("xa tx only!"); } /** - * Gets the LocalTransaction attribute of the XAManagedConnection object * - * @return The LocalTransaction value - * @exception javax.resource.ResourceException Description of Exception + * @return <description> + * @exception javax.resource.ResourceException <description> */ - public LocalTransaction getLocalTransaction() - throws javax.resource.ResourceException + public XAResource getXAResource() throws ResourceException { - throw new ResourceException("getLocalTransaction not supported"); + return this; } + // implementation of javax.transaction.xa.XAResource interface + /** - * 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 start(Xid xid, int flags) throws XAException + { + xaResource.start(xid, flags); + currentXid = xid; + inManagedTransaction = true; } /** - * 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 + * @param param1 <description> + * @param param2 <description> + * @exception javax.transaction.xa.XAException <description> */ - public Object getConnection(Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException + public void end(Xid xid, int flags) throws XAException { - 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) + xaResource.end(xid, flags); + //we want to allow ending transactions that are not the current + //one. When one does this, inManagedTransaction is still true. + if (currentXid == xid) { - ResourceException re = new ResourceException("Unable to get XAResource: " + e); - re.setLinkedException(e); - throw re; + inManagedTransaction = false; + currentXid = null; } } /** - * Gets the MetaData attribute of the XAManagedConnection object * - * @return The MetaData value - * @exception javax.resource.ResourceException Description of Exception + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> */ - public ManagedConnectionMetaData getMetaData() - throws javax.resource.ResourceException + public int prepare(Xid xid) throws XAException { + return xaResource.prepare(xid); + } - throw new java.lang.UnsupportedOperationException("Method getMetaData() not yet implemented."); + /** + * + * @param param1 <description> + * @param param2 <description> + * @exception javax.transaction.xa.XAException <description> + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + xaResource.commit(xid, onePhase); } /** - * #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 rollback(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.rollback(xid); + } + + /** + * + * @param param1 <description> + * @exception javax.transaction.xa.XAException <description> + */ + public void forget(Xid xid) throws XAException + { + xaResource.forget(xid); + } + + /** + * + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public Xid[] recover(int flag) throws XAException + { + return xaResource.recover(flag); } /** - * #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 boolean isSameRM(XAResource other) throws XAException { + // compare apples to apples + return (other instanceof XAManagedConnection)? + xaResource.isSameRM(((XAManagedConnection)other).xaResource): + xaResource.isSameRM(other); } - //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) + /** + * + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public int getTransactionTimeout() throws XAException { - super.fireConnectionEvent(ce); + return xaResource.getTransactionTimeout(); } - XADataSource getDataSource() + /** + * + * @param param1 <description> + * @return <description> + * @exception javax.transaction.xa.XAException <description> + */ + public boolean setTransactionTimeout(int seconds) throws XAException { - return source; + 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 props; + } + + + +}// XAManagedConnection 1.5.2.1 +176 -507 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.5 retrieving revision 1.5.2.1 diff -u -r1.5 -r1.5.2.1 --- XAManagedConnectionFactory.java 8 Apr 2002 23:23:47 -0000 1.5 +++ XAManagedConnectionFactory.java 15 Feb 2003 21:01:33 -0000 1.5.2.1 @@ -1,614 +1,283 @@ /* - * 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.io.PrintWriter; -import java.lang.reflect.*; -import java.sql.Connection; +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.sql.SQLException; -import java.util.*; -import javax.naming.InitialContext; +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.resource.JBossResourceException; -import org.jboss.logging.Logger; -import org.jboss.resource.adapter.jdbc.JDBCConnectionRequestInfo; -//for transaction isolation constants -import org.jboss.resource.adapter.jdbc.JDBCDataSource; /** - * 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.5 $ + * @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; + private String xaDataSourceProperties; + private final Properties xaProps = new Properties(); - /** - * Constructor for the XAManagedConnectionFactory object - */ - public XAManagedConnectionFactory() - { - } + private XADataSource xads; - /* - * 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) + public XAManagedConnectionFactory() { - 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 + * Get the XaDataSourceClass value. + * @return the XaDataSourceClass value. */ - public void setXADataSource(XADataSource xads) + public String getXADataSourceClass() { - this.xads = xads; + return xaDataSourceClass; } /** - * Sets the XADataSourceClass attribute of the XAManagedConnectionFactory - * object - * - * @param className The new XADataSourceClass value + * Set the XaDataSourceClass value. + * @param newXaDataSourceClass The new XaDataSourceClass value. */ - public void setXADataSourceClass(String className) + public void setXADataSourceClass(String xaDataSourceClass) { - xaDataSourceClass = className; + this.xaDataSourceClass = xaDataSourceClass; } - /** - * Sets the XADataSourceProperties attribute of the XAManagedConnectionFactory - * object - * - * @param props The new XADataSourceProperties value - */ - public void setXADataSourceProperties(String props) - { - xaDataSourceProperties = props; - } - /* - * As far as I know, there is no way to use this - * since RawXADataSourceLoader is gone - */ /** - * Sets the XADataSourceJNDIName attribute of the XAManagedConnectionFactory - * object - * - * @param name The new XADataSourceJNDIName value + * Get the XADataSourceProperties value. + * @return the XADataSourceProperties value. */ - public void setXADataSourceJNDIName(String name) + public String getXADataSourceProperties() { - xaDataSourceName = name; + return xaDataSourceProperties; } /** - * Sets the TransactionIsolation attribute of the XAManagedConnectionFactory - * object - * - * @param transactionIsolation The new TransactionIsolation value + * Set the XADataSourceProperties value. + * @param newXADataSourceProperties The new XADataSourceProperties value. */ - public void setTransactionIsolation(String transactionIsolation) + public void setXADataSourceProperties(String xaDataSourceProperties) throws ResourceException { - 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 + this.xaDataSourceProperties = xaDataSourceProperties; + xaProps.clear(); + if (xaDataSourceProperties != null) { + InputStream is = new ByteArrayInputStream(xaDataSourceProperties.getBytes()); try { - this.transactionIsolation = Integer.parseInt(transactionIsolation); + xaProps.load(is); } - catch (NumberFormatException nfe) + catch (IOException ioe) { - throw new IllegalArgumentException("Setting Isolation level to unknown state: " + transactionIsolation); + throw new JBossResourceException("Could not load connection properties", ioe); } } } - /** - * 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; - } - - /** - * 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 - */ - public String getPassword() + public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cri) + throws javax.resource.ResourceException { - return password; - } - - /** - * Gets the XADataSource attribute of the XAManagedConnectionFactory object - * - * @return The XADataSource value - */ - public XADataSource getXADataSource() - { - return xads; - } + Properties props = getConnectionProperties(subject, cri); + try + { + final String user = props.getProperty("user"); + final String password = props.getProperty("password"); - /** - * Gets the XADataSourceClass attribute of the XAManagedConnectionFactory - * object - * - * @return The XADataSourceClass value - */ - public String getXADataSourceClass() - { - return xaDataSourceClass; - } + XAConnection xaConnection = (user != null)? + getXADataSource().getXAConnection(user, password): + getXADataSource().getXAConnection(); - /** - * Gets the XADataSourceProperties attribute of the XAManagedConnectionFactory - * object - * - * @return The XADataSourceProperties value - */ - public String getXADataSourceProperties() - { - return xaDataSourceProperties; + return newXAManagedConnection(props, xaConnection); + } + catch (java.sql.SQLException e) + { + throw new JBossResourceException("Could not create connection", e); + } // end of try-catch } /** - * Gets the XADataSourceJNDIName attribute of the XAManagedConnectionFactory - * object - * - * @return The XADataSourceJNDIName value + * This method can be overwritten by sublcasses to provide rm specific + * implementation of XAManagedConnection */ - public String getXADataSourceJNDIName() + protected ManagedConnection newXAManagedConnection( Properties props, + XAConnection xaConnection ) + throws SQLException { - return xaDataSourceName; + return new XAManagedConnection(this, xaConnection, props, transactionIsolation); } /** - * Gets the TransactionIsolation attribute of the XAManagedConnectionFactory - * object * - * @return The TransactionIsolation value + * @param param1 <description> + * @param param2 <description> + * @param param3 <description> + * @return <description> + * @exception javax.resource.ResourceException <description> */ - public String getTransactionIsolation() + public ManagedConnection matchManagedConnections(Set mcs, Subject subject, ConnectionRequestInfo cri) + throws ResourceException { - switch (this.transactionIsolation) + Properties newProps = getConnectionProperties(subject, cri); + for (Iterator i = mcs.iterator(); i.hasNext(); ) { - 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); - } - } + Object o = i.next(); + if (o instanceof XAManagedConnection) + { + XAManagedConnection mc = (XAManagedConnection)o; + if (mc.getProps().equals(newProps)) + { + return mc; + } // end of if () - /** - * #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 - { - DataSource ds = new JDBCDataSource(mgr, this); - return ds; + } // end of if () + } // end of for () + return null; } /** - * #Description of the Method * - * @return Description of the Returned - * Value - * @exception javax.resource.ResourceException Description of Exception + * @return hashcode computed according to recommendations in Effective Java. */ - public Object createConnectionFactory() - throws javax.resource.ResourceException + public int hashCode() { - throw new java.lang.UnsupportedOperationException("Must be used in managed mode"); + 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; } /** - * #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 + * @param param1 <description> + * @return <description> */ - public ManagedConnection createManagedConnection(Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException + public boolean equals(Object other) { - // Set user and password to default - String user = username; - String pw = password; - - // Check passed Subject and ConnectionRequestInfo for user/password overrides - if (sub != null) + if (this == other) { - 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 + return true; + } // end of if () + if (getClass() != other.getClass()) { - if (info != null) - { - JDBCConnectionRequestInfo jdbcInfo = (JDBCConnectionRequestInfo)info; - user = jdbcInfo.user; - pw = jdbcInfo.password; - } - } + 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; - // Create the connection - try - { - XAConnection con = getXADS().getXAConnection(user, pw); - ManagedConnection mc = new XAManagedConnection(xads, con, user, transactionIsolation); - return mc; - } - catch (SQLException e) - { - throw new ResourceException("Unable to create DB XAConnection: " + e); - } } - /** - * #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 - */ - public ManagedConnection matchManagedConnections(Set cons, Subject sub, ConnectionRequestInfo info) - throws javax.resource.ResourceException + protected synchronized XADataSource getXADataSource() 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) + if (xads == null) { - Set creds = sub.getPrivateCredentials(javax.resource.spi.security.PasswordCredential.class); - for (Iterator it = creds.iterator(); it.hasNext(); ) + if (xaDataSourceClass == null) { - PasswordCredential pc = (PasswordCredential)it.next(); - user = pc.getUserName(); - pw = new String(pc.getPassword()); - break; - } - } - else - { - if (info != null) + throw new JBossResourceException("No XADataSourceClass supplied!"); + } // end of if () + try { - if (!(info instanceof JDBCConnectionRequestInfo)) + Class clazz = Thread.currentThread().getContextClassLoader().loadClass(xaDataSourceClass); + xads = (XADataSource)clazz.newInstance(); + Class[] NOCLASSES = new Class[] {}; + for (Iterator i = xaProps.keySet().iterator(); i.hasNext(); ) { - throw new ResourceException("Passed ConnectionRequestInfo class '" + info.getClass().getName() + "' to XAManagedConnectionFactory!"); - } - JDBCConnectionRequestInfo jdbcInfo = (JDBCConnectionRequestInfo)info; - user = jdbcInfo.user; - pw = jdbcInfo.password; - } - } + String name = (String)i.next(); + String value = xaProps.getProperty(name); + //This is a bad solution. On the other hand the only known example + // of a setter with no getter is for Oracle with password. + //Anyway, each xadatasource implementation should get its + //own subclass of this that explicitly sets the + //properties individually. + Class type = null; + try + { + Method getter = clazz.getMethod("get" + name, NOCLASSES); + type = getter.getReturnType(); + } + catch (NoSuchMethodException e) + { + type = String.class; + } // end of try-catch - // 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 null; - } + Method setter = clazz.getMethod("set" + name, new Class[] {type}); + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor == null) + { + throw new JBossResourceException("No property editor found for type: " + type); + } // end of if () + editor.setAsText(value); + setter.invoke(xads, new Object[] {editor.getValue()}); - private XADataSource getXADS() - { - if (xads != null) - { - return xads; - } - if (xaDataSourceClass != null) - { - try - { - log.trace("XADatasourceClass: " + xaDataSourceClass); - Class cls = Class.forName(xaDataSourceClass); - xads = (XADataSource)cls.newInstance(); - log.trace("got DataSource instance"); - - Properties props = parseProperties(); - populate(xads, props); - return xads; + } // end of for () } - catch (Exception e) + catch (ClassNotFoundException cnfe) { - xads = null; - log.warn("Unable to create and initialize XADataSource:", e); - } - } - else if (xaDataSourceName != null) - { - try + throw new JBossResourceException("Class not found for XADataSource " + xaDataSourceClass, cnfe); + } // end of try-catch + catch (InstantiationException ie) { - InitialContext ic = new InitialContext(); - xads = (XADataSource)ic.lookup(xaDataSourceName); - return xads; - } - catch (Exception e) + throw new JBossResourceException("Could not create an XADataSource: ", ie); + } // end of catch + catch (IllegalAccessException iae) { - xads = null; - log.warn("Unable to reach XADataSource in JNDI:", e); - } - } - return null; - } + throw new JBossResourceException("Could not set a property: ", iae); + } // end of catch - private Properties parseProperties() - { - Properties props = new Properties(); - 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; - } - - /** - * 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. - */ - private void populate(Object obj, Map props) - { - // get all valid set methods - - Method[] methods = obj.getClass().getMethods(); - HashMap setters = new HashMap(); - - for (int i = 0; i < methods.length; i++) - { - Method meth = methods[i]; - String name = meth.getName(); - if (name.startsWith("set")) + catch (IllegalArgumentException iae) { - 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); - } - } - } - } + throw new JBossResourceException("Could not set a property: ", iae); + } // end of catch - for (Iterator i = props.entrySet().iterator(); i.hasNext();) - { - Map.Entry entry = (Map.Entry)i.next(); - String attributeName = (String)entry.getKey(); - String attributeValue = (String)entry.getValue(); - - Method meth = (Method)setters.get(attributeName); - if (meth != null) + catch (InvocationTargetException ite) { - 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 + throw new JBossResourceException("Could not invoke setter on XADataSource: ", ite); + } // end of catch + catch (NoSuchMethodException nsme) { - 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) - { - 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) - { - 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; + throw new JBossResourceException("Could not find accessor on XADataSource: ", nsme); + } // end of catch + } // end of if () + return xads; } -} +}// XAManagedConnectionFactory |