package org.jboss.resource.adapter.jdbc.local;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;
import javax.security.auth.Subject;
import org.jboss.util.NestedRuntimeException;
import org.jboss.resource.JBossResourceException;
import org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnectionFactory;
public class LocalManagedConnectionFactory extends BaseWrapperManagedConnectionFactory
{
private String driverClass;
private transient Driver driver;
private String connectionURL;
protected String connectionProperties;
public LocalManagedConnectionFactory()
{
}
public String getConnectionURL() {
return connectionURL;
}
public void setConnectionURL(final String connectionURL) {
this.connectionURL = connectionURL;
}
public String getDriverClass()
{
return driverClass;
}
public synchronized void setDriverClass(final String driverClass)
{
this.driverClass = driverClass;
driver = null;
}
public String getConnectionProperties() {
return connectionProperties;
}
public void setConnectionProperties(String connectionProperties)
{
this.connectionProperties = connectionProperties;
connectionProps.clear();
if (connectionProperties != null)
{
InputStream is =
new ByteArrayInputStream(connectionProperties.getBytes());
try
{
connectionProps.load(is);
}
catch (IOException ioe)
{
throw new NestedRuntimeException(
"Could not load connection properties",
ioe);
}
}
}
public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cri)
throws javax.resource.ResourceException
{
Properties props = getConnectionProperties(subject, cri);
Properties copy = (Properties) props.clone();
if (log.isDebugEnabled())
{
Properties logCopy = copy;
if( copy.getProperty("password") != null )
{
logCopy = (Properties) props.clone();
logCopy.setProperty("password", "--hidden--");
}
log.debug("Using properties: " + logCopy);
}
try
{
String url = getConnectionURL();
Driver d = getDriver(url);
Connection con = d.connect(url, copy);
if (con == null)
{
throw new JBossResourceException("Wrong driver class for this connection URL");
}
return new LocalManagedConnection(this, con, props, transactionIsolation, preparedStatementCacheSize);
}
catch (Exception e)
{
throw new JBossResourceException("Could not create connection", e);
} }
public ManagedConnection matchManagedConnections(Set mcs, Subject subject, ConnectionRequestInfo cri)
throws ResourceException
{
Properties newProps = getConnectionProperties(subject, cri);
for (Iterator i = mcs.iterator(); i.hasNext(); )
{
Object o = i.next();
if (o instanceof LocalManagedConnection)
{
LocalManagedConnection mc = (LocalManagedConnection)o;
if (mc.getProps().equals(newProps) && mc.checkValid())
{
return mc;
}
} } return null;
}
public int hashCode()
{
int result = 17;
result = result * 37 + ((connectionURL == null)? 0: connectionURL.hashCode());
result = result * 37 + ((driverClass == null)? 0: driverClass.hashCode());
result = result * 37 + ((userName == null)? 0: userName.hashCode());
result = result * 37 + ((password == null)? 0: password.hashCode());
result = result * 37 + transactionIsolation;
return result;
}
public boolean equals(Object other)
{
if (this == other)
{
return true;
} if (getClass() != other.getClass())
{
return false;
} LocalManagedConnectionFactory otherMcf = (LocalManagedConnectionFactory)other;
return this.connectionURL.equals(otherMcf.connectionURL)
&& this.driverClass.equals(otherMcf.driverClass)
&& ((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;
}
protected synchronized Driver getDriver(final String url) throws ResourceException
{
if (driver!=null)
{
return driver;
}
log.debug("Checking driver for URL: " + url);
if (driverClass == null)
{
throw new JBossResourceException("No Driver class specified!");
}
if (isDriverLoadedForURL(url))
{
return driver;
}
try
{
Class clazz = Class.forName(driverClass, true, Thread.currentThread().getContextClassLoader());
if (isDriverLoadedForURL(url))
{
return driver;
} driver = (Driver)clazz.newInstance();
DriverManager.registerDriver(driver);
if (isDriverLoadedForURL(url))
{
return driver;
} }
catch (Exception e)
{
throw new JBossResourceException
("Failed to register driver for: " + driverClass, e);
}
throw new JBossResourceException("Apparently wrong driver class specified for URL: class: " + driverClass + ", url: " + url);
}
private boolean isDriverLoadedForURL(String url)
{
try
{
driver = DriverManager.getDriver(url);
log.debug("Driver already registered for url: " + url);
return true;
}
catch (Exception e)
{
log.debug("Driver not yet registered for url: " + url);
return false;
} }
protected String internalGetConnectionURL()
{
return connectionURL;
}
}