WrapperDataSourceServicepublic class WrapperDataSourceService extends org.jboss.resource.connectionmanager.ConnectionFactoryBindingService implements WrapperDataSourceServiceMBeanAn mbean service that pvovides the detached invoker ops for the
javax.sql.DataSource and related java.sql.* interfaces.
TODO this does not belong in the resource adapter |
Fields Summary |
---|
private static Logger | log | private ObjectName | jmxInvokerName | private org.jboss.invocation.Invoker | delegateInvoker | private Object | theProxy | private HashMap | marshalledInvocationMapping | private HashMap | connectionMap | private HashMap | statementMap | private HashMap | resultSetMap | private HashMap | lobMap | private HashMap | databaseMetaDataMap | private boolean | trace |
Methods Summary |
---|
protected void | bindConnectionFactory()
InitialContext ctx = new InitialContext();
try
{
log.debug("Binding object '" + cf + "' into JNDI at '" + bindName + "'");
// Associated the local cf with the NonSerializable factory
NonSerializableFactory.rebind(bindName, cf);
/* Create a reference that uses the the DataSourceFactory as the
reference factory class. This class detects whether the lookup
is being done locally or remotely and returns either the just bound
connection factory, or a DataSource proxy that uses the detached
invoker framework to expose remote proxies to the server side
DataSource and related elements.
*/
Referenceable referenceable = (Referenceable) cf;
// Set the DataSource proxy as the ProxyData ref address
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(theProxy);
oos.close();
byte[] proxyBytes = baos.toByteArray();
BinaryRefAddr dsAddr = new BinaryRefAddr("ProxyData", proxyBytes);
String factory = DataSourceFactory.class.getName();
Reference dsRef = new Reference("javax.sql.DataSource", dsAddr, factory, null);
referenceable.setReference(dsRef);
// Set the VMID as the address local/remote indicator
baos.reset();
ObjectOutputStream oos2 = new ObjectOutputStream(baos);
oos2.writeObject(DataSourceFactory.vmID);
oos2.close();
byte[] id = baos.toByteArray();
BinaryRefAddr localAddr = new BinaryRefAddr("VMID", id);
dsRef.add(localAddr);
/* Bind the Referenceable connection factory into JNDI and set the
JndiName value of the reference address for use by the DataSourceFactory
when looking up the local factory from the NonSerializableFactory.
*/
StringRefAddr jndiRef = new StringRefAddr("JndiName", bindName);
dsRef.add(jndiRef);
Util.rebind(ctx, bindName, cf);
log.info("Bound ConnectionManager '" + serviceName + "' to JNDI name '" + bindName + "'");
}
catch (NamingException ne)
{
throw new DeploymentException("Could not bind ConnectionFactory into jndi: " + bindName, ne);
}
finally
{
ctx.close();
}
| protected void | calculateMethodHases()Calculate the method hashes
Method[] methods = DataSource.class.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
marshalledInvocationMapping.put(hash, method);
}
// Get the Long to Method mappings
Map m = MarshalledInvocation.methodToHashesMap(Connection.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
m = MarshalledInvocation.methodToHashesMap(Statement.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
m = MarshalledInvocation.methodToHashesMap(CallableStatement.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
m = MarshalledInvocation.methodToHashesMap(PreparedStatement.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
m = MarshalledInvocation.methodToHashesMap(ResultSet.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
m = MarshalledInvocation.methodToHashesMap(DatabaseMetaData.class);
displayHashes(m);
marshalledInvocationMapping.putAll(m);
| private java.lang.Object | createConnectionProxy(java.lang.Object conn)
Object cacheID = new Integer(conn.hashCode());
ObjectName targetName = getServiceName();
String proxyBindingName = null;
String jndiName = null;
Class[] ifaces = {java.sql.Connection.class};
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
Object connProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
connectionMap.put(cacheID, conn);
log.debug("Created Connection proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", cacheID=" + cacheID);
return connProxy;
| private java.lang.Object | createDatabaseMetaData(java.lang.Object dbMetaData)
Object cacheID = new Integer(dbMetaData.hashCode());
ObjectName targetName = getServiceName();
String proxyBindingName = null;
String jndiName = null;
Class[] ifaces = {java.sql.DatabaseMetaData.class};
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
Object dbMetaDataProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
databaseMetaDataMap.put(cacheID, dbMetaData);
log.debug("Created DatabaseMetadata proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", cacheID=" + cacheID);
return dbMetaDataProxy;
| private java.lang.Object | createLobProxy(java.lang.Object results)
Object cacheID = new Integer(results.hashCode());
ObjectName targetName = getServiceName();
String proxyBindingName = null;
String jndiName = null;
Class[] ifaces = results.getClass().getInterfaces();
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
Object resultsProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
lobMap.put(cacheID, results);
log.debug("Created LOB proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", cacheID=" + cacheID);
return resultsProxy;
| protected void | createProxy()Create the proxy
TODO this should be external configuration
/* Create an JRMPInvokerProxy that will be associated with a naming JMX
invoker given by the jmxInvokerName.
*/
delegateInvoker = (Invoker) Registry.lookup(jmxInvokerName);
log.debug("Using delegate: " + delegateInvoker
+ " for invoker=" + jmxInvokerName);
ObjectName targetName = getServiceName();
Integer nameHash = new Integer(targetName.hashCode());
Registry.bind(nameHash, targetName);
Object cacheID = null;
String proxyBindingName = null;
String jndiName = null;
Class[] ifaces = {javax.sql.DataSource.class};
/* Initialize interceptorClasses with default client interceptor list
if no client interceptor configuration was provided */
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
theProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
log.debug("Created proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", nameHash=" + nameHash);
| private java.lang.Object | createResultSetProxy(java.lang.Object results)
Object cacheID = new Integer(results.hashCode());
ObjectName targetName = getServiceName();
String proxyBindingName = null;
String jndiName = null;
// Filter out all but java* interfaces
Class[] ifaces = getJavaInterfaces(results.getClass());
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
Object resultsProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
resultSetMap.put(cacheID, results);
log.debug("Created ResultSet proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", cacheID=" + cacheID);
return resultsProxy;
| private java.lang.Object | createStatementProxy(java.lang.Object stmt)
Object cacheID = new Integer(stmt.hashCode());
ObjectName targetName = getServiceName();
String proxyBindingName = null;
String jndiName = null;
// Filter out all but java* interfaces
Class[] ifaces = getJavaInterfaces(stmt.getClass());
ArrayList interceptorClasses = new ArrayList();
interceptorClasses.add(StatementInterceptor.class);
interceptorClasses.add(ClientMethodInterceptor.class);
interceptorClasses.add(InvokerInterceptor.class);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
Object stmtProxy = proxyFactory.createProxy(cacheID, targetName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
statementMap.put(cacheID, stmt);
log.debug("Created Statement proxy for invoker=" + jmxInvokerName
+ ", targetName=" + targetName + ", cacheID=" + cacheID);
return stmtProxy;
| protected void | destroyProxy()Destroy the proxy
ObjectName name = getServiceName();
Integer nameHash = new Integer(name.hashCode());
Registry.unbind(nameHash);
| private void | displayHashes(java.util.Map m)
if( trace == false )
return;
Iterator keys = m.keySet().iterator();
while( keys.hasNext() )
{
Long key = (Long) keys.next();
log.trace(key+"="+m.get(key));
}
| private java.lang.Object | doConnectionMethod(java.sql.Connection conn, java.lang.reflect.Method method, java.lang.Object[] args)
if( trace )
{
log.trace("doConnectionMethod, conn="+conn+", method="+method);
}
Object value = method.invoke(conn, args);
if( value instanceof Statement )
{
value = createStatementProxy(value);
}
else if(value instanceof DatabaseMetaData)
{
value = createDatabaseMetaData(value);
}
else if( value != null && (value instanceof Serializable) == false )
{
throw new IllegalAccessException("Method="+method+" does not return Serializable");
}
return value;
| private java.lang.Object | doDataSourceMethod(javax.sql.DataSource ds, java.lang.reflect.Method method, java.lang.Object[] args)
Object value = method.invoke(ds, args);
if( value instanceof Connection )
{
value = createConnectionProxy(value);
}
else if( value != null && (value instanceof Serializable) == false )
{
throw new IllegalAccessException("Method="+method+" does not return Serializable");
}
return value;
| private java.lang.Object | doDatabaseMetaDataMethod(java.sql.DatabaseMetaData dbMetaData, java.lang.reflect.Method method, java.lang.Object[] args)
if( trace )
{
log.trace("doDatabaseMetaDataMethod, dbMetaData="+dbMetaData+", method="+method);
}
Object value = method.invoke(dbMetaData, args);
if( value instanceof ResultSet )
{
value = createResultSetProxy(value);
}
else if( value instanceof Connection )
{
value = createConnectionProxy(value);
}
if( value != null && (value instanceof Serializable) == false )
{
throw new IllegalAccessException("Method="+method+" does not return Serializable");
}
return value;
| private java.lang.Object | doResultSetMethod(java.sql.ResultSet results, java.lang.reflect.Method method, java.lang.Object[] args)
if( trace )
{
log.trace("doStatementMethod, results="+results+", method="+method);
}
if( method.getName().equals("close") )
{
Integer id = new Integer(results.hashCode());
resultSetMap.remove(id);
log.debug("Closed ResultSet="+id);
}
Object value = method.invoke(results, args);
if( value instanceof ResultSetMetaData )
{
ResultSetMetaData rmd = (ResultSetMetaData) value;
value = new SerializableResultSetMetaData(rmd);
}
// Need to create serializable version of ascii stream returned by result set
if(("getBinaryStream".equals(method.getName()) || "getAsciiStream".equals(method.getName())) && value instanceof InputStream)
{
InputStream ins = (InputStream)value;
value = new SerializableInputStream(ins);
}
else if ("getCharacterStream".equals(method.getName()) && value instanceof java.io.Reader)
{
java.io.Reader ins = (java.io.Reader)value;
value = new SerializableReader(ins);
}
else if("getClob".equals(method.getName()) || "getBlob".equals(method.getName()))
{
value = createLobProxy(value);
}
if( value != null && (value instanceof Serializable) == false )
{
throw new IllegalAccessException("Method="+method+" does not return Serializable");
}
return value;
| private java.lang.Object | doStatementMethod(java.sql.Statement stmt, java.lang.reflect.Method method, java.lang.Object[] args)
if( trace )
{
log.trace("doStatementMethod, conn="+stmt+", method="+method);
}
if( method.getName().equals("close") )
{
Integer id = new Integer(stmt.hashCode());
statementMap.remove(id);
log.debug("Closed Statement="+id);
}
Object value = method.invoke(stmt, args);
if( value instanceof ResultSet )
{
value = createResultSetProxy(value);
}
else if( value instanceof ResultSetMetaData )
{
ResultSetMetaData rmd = (ResultSetMetaData) value;
value = new SerializableResultSetMetaData(rmd);
}
else if ( value instanceof ParameterMetaData )
{
ParameterMetaData pmd = (ParameterMetaData) value;
value = new SerializableParameterMetaData(pmd);
}
else if( value != null && (value instanceof Serializable) == false )
{
throw new IllegalAccessException("Method="+method+" does not return Serializable");
}
return value;
| public javax.management.ObjectName | getJMXInvokerName()
return jmxInvokerName;
| private java.lang.Class[] | getJavaInterfaces(java.lang.Class clazz)
ArrayList tmp = new ArrayList();
Classes.getAllInterfaces(tmp, clazz);
Iterator iter = tmp.iterator();
while( iter.hasNext() )
{
Class c = (Class) iter.next();
if( c.getName().startsWith("java") == false )
iter.remove();
}
Class[] ifaces = new Class[tmp.size()];
return (Class[]) tmp.toArray(ifaces);
| public java.lang.Object | invoke(org.jboss.invocation.Invocation invocation)
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the Naming method via reflection
Method method = invocation.getMethod();
Class methodClass = method.getDeclaringClass();
Object[] args = invocation.getArguments();
Object value = null;
try
{
if( methodClass.isAssignableFrom(DataSource.class) )
{
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(bindName);
value = doDataSourceMethod(ds, method, args);
}
else if( methodClass.isAssignableFrom(Connection.class) )
{
Integer id = (Integer) invocation.getId();
Connection conn = (Connection) connectionMap.get(id);
if( conn == null )
{
throw new IllegalAccessException("Failed to find connection: "+id);
}
value = doConnectionMethod(conn, method, args);
}
else if( methodClass.isAssignableFrom(Statement.class) ||
methodClass.isAssignableFrom(PreparedStatement.class) ||
methodClass.isAssignableFrom(CallableStatement.class))
{
Integer id = (Integer) invocation.getId();
Statement stmt = (Statement) statementMap.get(id);
if( stmt == null )
{
throw new SQLException("Failed to find Statement: " + id);
}
value = doStatementMethod(stmt, method, args);
}
else if( methodClass.isAssignableFrom(ResultSet.class) )
{
Integer id = (Integer) invocation.getId();
ResultSet results = (ResultSet) resultSetMap.get(id);
if( results == null )
{
throw new IllegalAccessException("Failed to find ResultSet: "+id);
}
value = doResultSetMethod(results, method, args);
}
else if (methodClass.isAssignableFrom(DatabaseMetaData.class))
{
Integer id = (Integer) invocation.getId();
DatabaseMetaData dbMetaData = (DatabaseMetaData) databaseMetaDataMap.get(id);
if(dbMetaData == null)
{
throw new IllegalAccessException("Failed to find DatabaseMetaData: " + id);
}
value = doDatabaseMetaDataMethod(dbMetaData, method, args);
}
else
{
throw new UnsupportedOperationException("Do not know how to handle method="+method);
}
}
catch (InvocationTargetException e)
{
Throwable t = e.getTargetException();
if (t instanceof Exception)
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
| public void | setJMXInvokerName(javax.management.ObjectName jmxInvokerName)
this.jmxInvokerName = jmxInvokerName;
| protected void | startService()
determineBindName();
createConnectionFactory();
if( jmxInvokerName != null )
{
createProxy();
calculateMethodHases();
bindConnectionFactory();
}
else
{
super.bindConnectionFactory();
}
| protected void | stopService()
unbindConnectionFactory();
if( jmxInvokerName != null )
destroyProxy();
|
|