[jboss-cvs] JBossAS SVN: r62221 - trunk/connector/src/main/org/jboss/resource/adapter/jdbc/xa.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Apr 10 12:17:51 EDT 2007
Author: vicky.kak at jboss.com
Date: 2007-04-10 12:17:51 -0400 (Tue, 10 Apr 2007)
New Revision: 62221
Modified:
trunk/connector/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java
Log:
[JBAS-3707] Changes
Modified: trunk/connector/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java
===================================================================
--- trunk/connector/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java 2007-04-10 16:14:29 UTC (rev 62220)
+++ trunk/connector/src/main/org/jboss/resource/adapter/jdbc/xa/XAManagedConnectionFactory.java 2007-04-10 16:17:51 UTC (rev 62221)
@@ -22,6 +22,7 @@
package org.jboss.resource.adapter.jdbc.xa;
import org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnectionFactory;
+import org.jboss.resource.adapter.jdbc.URLSelectorStrategy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.beans.PropertyEditorManager;
@@ -32,7 +33,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.resource.ResourceException;
@@ -61,7 +64,257 @@
private Boolean isSameRMOverrideValue;
private XADataSource xads;
+
+ private String urlProperty;
+ private URLSelectorStrategy xadsSelector;
+
+ public String getURLProperty()
+ {
+ return urlProperty;
+ }
+
+ public void setURLProperty(String urlProperty) throws ResourceException
+ {
+ this.urlProperty = urlProperty;
+ initSelector();
+ }
+
+ public void setURLDelimiter(String urlDelimiter) throws ResourceException
+ {
+ this.urlDelimiter = urlDelimiter;
+ initSelector();
+ }
+
+ private void initSelector() throws JBossResourceException
+ {
+ if(urlProperty != null && urlProperty.length() > 0)
+ {
+ String urlsStr = xaProps.getProperty(urlProperty);
+ if(urlsStr != null && urlsStr.trim().length() > 0 && urlDelimiter != null && urlDelimiter.trim().length() > 0)
+ {
+ List xaDataList = new ArrayList();
+
+ // copy xaProps
+ // ctor doesn't work because iteration won't include defaults
+ // Properties xaPropsCopy = new Properties(xaProps);
+ Properties xaPropsCopy = new Properties();
+ for(Iterator i = xaProps.keySet().iterator(); i.hasNext();)
+ {
+ Object key = i.next();
+ xaPropsCopy.put(key, xaProps.get(key));
+ }
+
+ int urlStart = 0;
+ int urlEnd = urlsStr.indexOf(urlDelimiter);
+ while(urlEnd > 0)
+ {
+ String url = urlsStr.substring(urlStart, urlEnd);
+ xaPropsCopy.setProperty(urlProperty, url);
+ XADataSource xads = createXaDataSource(xaPropsCopy);
+ xaDataList.add(new XAData(xads, url));
+ urlStart = ++urlEnd;
+ urlEnd = urlsStr.indexOf(urlDelimiter, urlEnd);
+ log.debug("added XA HA connection url: " + url);
+ }
+
+ if(urlStart != urlsStr.length())
+ {
+ String url = urlsStr.substring(urlStart, urlsStr.length());
+ xaPropsCopy.setProperty(urlProperty, url);
+ XADataSource xads = createXaDataSource(xaPropsCopy);
+ xaDataList.add(new XAData(xads, url));
+ log.debug("added XA HA connection url: " + url);
+ }
+ if(getUrlSelectorStrategyClassName()==null)
+ {
+ xadsSelector = new XADataSelector(xaDataList);
+ log.debug("Default URLSelectorStrategy is being used : "+xadsSelector);
+ }
+ else
+ {
+ xadsSelector = (URLSelectorStrategy)loadClass(getUrlSelectorStrategyClassName(),xaDataList);
+ log.debug("Customized URLSelectorStrategy is being used : "+xadsSelector);
+ }
+ }
+ }
+ }
+
+ private XADataSource createXaDataSource(Properties xaProps)
+ throws JBossResourceException
+ {
+ if(getXADataSourceClass() == null)
+ {
+ throw new JBossResourceException("No XADataSourceClass supplied!");
+ }
+
+ XADataSource xads;
+ try
+ {
+ Class clazz = Thread.currentThread().getContextClassLoader().loadClass(getXADataSourceClass());
+ 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);
+ //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
+
+ 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()});
+
+ } // end of for ()
+ }
+ catch(ClassNotFoundException cnfe)
+ {
+ throw new JBossResourceException("Class not found for XADataSource " + getXADataSourceClass(), cnfe);
+ } // end of try-catch
+ catch(InstantiationException ie)
+ {
+ throw new JBossResourceException("Could not create an XADataSource: ", ie);
+ } // end of catch
+ catch(IllegalAccessException iae)
+ {
+ throw new JBossResourceException("Could not set a property: ", iae);
+ } // end of catch
+
+ catch(IllegalArgumentException iae)
+ {
+ throw new JBossResourceException("Could not set a property: ", iae);
+ } // end of catch
+
+ catch(InvocationTargetException ite)
+ {
+ throw new JBossResourceException("Could not invoke setter on XADataSource: ", ite);
+ } // end of catch
+ catch(NoSuchMethodException nsme)
+ {
+ throw new JBossResourceException("Could not find accessor on XADataSource: ", nsme);
+ } // end of catch
+
+ return xads;
+ }
+
+ // Default Implementaion of the URLSelectorStrategy
+ public static class XADataSelector implements URLSelectorStrategy
+ {
+ private final List xaDataList;
+ private int xaDataIndex;
+ private XAData xaData;
+
+ public XADataSelector(List xaDataList)
+ {
+ if(xaDataList == null || xaDataList.size() == 0)
+ {
+ throw new IllegalStateException("Expected non-empty list of XADataSource/URL pairs but got: " + xaDataList);
+ }
+
+ this.xaDataList = xaDataList;
+ }
+
+ public synchronized XAData getXAData()
+ {
+ if(xaData == null)
+ {
+ if(xaDataIndex == xaDataList.size())
+ {
+ xaDataIndex = 0;
+ }
+ xaData = (XAData)xaDataList.get(xaDataIndex++);
+ }
+ return xaData;
+ }
+
+ public synchronized void failedXAData(XAData xads)
+ {
+ if(xads.equals(this.xaData))
+ {
+ this.xaData = null;
+ }
+ }
+
+ /* URLSelectorStrategy Implementation goes here*/
+ public List getCustomSortedUrls()
+ {
+ return xaDataList;
+ }
+ public void failedUrlObject(Object urlObject)
+ {
+ failedXAData((XAData)urlObject);
+ }
+ public List getAllUrlObjects()
+ {
+ return xaDataList;
+ }
+ public Object getUrlObject()
+ {
+ return getXAData();
+ }
+ }
+
+ private static class XAData
+ {
+ public final XADataSource xads;
+ public final String url;
+
+ public XAData(XADataSource xads, String url)
+ {
+ this.xads = xads;
+ this.url = url;
+ }
+
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof XAData))
+ {
+ return false;
+ }
+
+ final XAData xaData = (XAData)o;
+
+ if(!url.equals(xaData.url))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return url.hashCode();
+ }
+
+ public String toString()
+ {
+ return "[XA URL=" + url + "]";
+ }
+ }
+
public XAManagedConnectionFactory()
{
}
@@ -120,6 +373,7 @@
throw new JBossResourceException("Could not load connection properties", ioe);
}
}
+ initSelector();
}
/**
@@ -143,25 +397,60 @@
}
public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cri)
- throws javax.resource.ResourceException
+ throws javax.resource.ResourceException
{
- Properties props = getConnectionProperties(subject, cri);
- try
- {
- final String user = props.getProperty("user");
- final String password = props.getProperty("password");
-
- XAConnection xaConnection = (user != null)
- ? getXADataSource().getXAConnection(user, password)
- : getXADataSource().getXAConnection();
-
- return newXAManagedConnection(props, xaConnection);
- }
- catch (Exception e)
- {
- throw new JBossResourceException("Could not create connection", e);
- }
+ if(xadsSelector == null)
+ {
+ return getXAManagedConnection(subject,cri);
+ }
+
+ // try to get a connection as many times as many urls we have in the list
+ for(int i = 0; i < xadsSelector.getCustomSortedUrls().size(); ++i)
+ {
+ XAData xaData = (XAData)xadsSelector.getUrlObject();
+
+ if(log.isTraceEnabled())
+ {
+ log.trace("Trying to create an XA connection to " + xaData.url);
+ }
+
+ try
+ {
+ return getXAManagedConnection(subject,cri);
+ }
+ catch(ResourceException e)
+ {
+ log.warn("Failed to create an XA connection to " + xaData.url + ": " + e.getMessage());
+ xadsSelector.failedUrlObject(xaData);
+ }
+ }
+
+ // we have supposedly tried all the urls
+ throw new JBossResourceException(
+ "Could not create connection using any of the URLs: " + xadsSelector.getAllUrlObjects()
+ );
}
+
+ public ManagedConnection getXAManagedConnection(Subject subject, ConnectionRequestInfo cri)
+ throws javax.resource.ResourceException
+ {
+ Properties props = getConnectionProperties(subject, cri);
+ try
+ {
+ final String user = props.getProperty("user");
+ final String password = props.getProperty("password");
+
+ XAConnection xaConnection = (user != null)
+ ? getXADataSource().getXAConnection(user, password)
+ : getXADataSource().getXAConnection();
+
+ return newXAManagedConnection(props, xaConnection);
+ }
+ catch (Exception e)
+ {
+ throw new JBossResourceException("Could not create connection", e);
+ }
+ }
/**
* This method can be overwritten by sublcasses to provide rm specific
@@ -226,7 +515,12 @@
}
protected synchronized XADataSource getXADataSource() throws ResourceException
- {
+ {
+ if(xadsSelector != null)
+ {
+ XAData xada = (XAData)xadsSelector.getUrlObject();
+ return xada.xads;
+ }
if (xads == null)
{
if (xaDataSourceClass == null)
More information about the jboss-cvs-commits
mailing list