[jboss-cvs] JBossAS SVN: r106768 - in projects/jboss-jca/trunk/core/src: main/java/org/jboss/jca/core/connectionmanager/ccm and 7 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 15 17:04:09 EDT 2010


Author: jesper.pedersen
Date: 2010-07-15 17:04:07 -0400 (Thu, 15 Jul 2010)
New Revision: 106768

Added:
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManager.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/package.html
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/package.html
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/package.html
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAException.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAExceptionFormatter.java
Removed:
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/CachedConnectionManager.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ConnectionValidator.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleConnectionRemovalSupport.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleRemover.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/KeyConnectionAssociation.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/exception/
Modified:
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/InternalManagedConnectionPool.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/LocalXAResource.java
   projects/jboss-jca/trunk/core/src/test/java/org/jboss/jca/core/connectionmanager/unit/AbstractConnectionManagerTestCase.java
   projects/jboss-jca/trunk/core/src/test/resources/connectionmanager-jboss-beans.xml
Log:
[JBJCA-384] Refactor connection manager (Part 1)

Modified: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -23,6 +23,7 @@
 package org.jboss.jca.core.connectionmanager;
 
 import org.jboss.jca.common.JBossResourceException;
+import org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManager;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionState;
 import org.jboss.jca.core.connectionmanager.pool.api.ManagedConnectionPool;

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/CachedConnectionManager.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/CachedConnectionManager.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/CachedConnectionManager.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -1,642 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jca.core.connectionmanager;
-
-import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
-import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
-import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer;
-import org.jboss.jca.spi.ComponentStack;
-
-import java.lang.reflect.Method;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-
-import javax.resource.ResourceException;
-import javax.resource.spi.ConnectionRequestInfo;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.jboss.logging.Logger;
-
-import org.jboss.tm.TxUtils;
-import org.jboss.tm.usertx.UserTransactionListener;
-import org.jboss.tm.usertx.client.ServerVMClientUserTransaction.UserTransactionStartedListener;
-import org.jboss.util.Strings;
-
-/**
- * CacheConnectionManager.
- * @version $Rev$
- *
- */
-public class CachedConnectionManager implements
-   UserTransactionStartedListener,
-   UserTransactionListener,
-   ComponentStack
-{
-   /**Log instance*/
-   private static Logger log = Logger.getLogger(CachedConnectionManager.class);
-   
-   /**Log trace*/
-   private boolean trace;
-   
-   /**Debug flag*/
-   private boolean debug;
-   
-   /**Error flag*/
-   private boolean error;
-   
-   /**Transaction Manager instance*/
-   private TransactionManager transactionManager;
-   
-   /**
-    * ThreadLocal that holds current calling meta-programming aware
-    * object, used in case someone is idiotic enough to cache a
-    * connection between invocations.and want the spec required
-    * behavior of it getting hooked up to an appropriate
-    * ManagedConnection on each method invocation.
-    */
-   private final ThreadLocal<LinkedList<Object>> currentObjects = new ThreadLocal<LinkedList<Object>>();
-
-   /**
-    * The variable <code>objectToConnectionManagerMap</code> holds the
-    * map of meta-aware object to set of connections it holds, used by
-    * the idiot spec compliant behavior.
-    */
-   private final Map<KeyConnectionAssociation, Map<ConnectionCacheListener, Collection<ConnectionRecord>>> 
-   objectToConnectionManagerMap = new HashMap<KeyConnectionAssociation, 
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>>>();
-
-   /**
-    * Connection stacktraces
-    */
-   private Map<Object, Throwable> connectionStackTraces = new WeakHashMap<Object, Throwable>();
-
-   /**
-    * Creates a new instance.
-    */
-   public CachedConnectionManager()
-   {
-      this.trace = log.isTraceEnabled();
-   }
-   
-   /**
-    * Gets transaction manager.
-    * @return transaction manager
-    */
-   public TransactionManager getTransactionManager()
-   {
-      return transactionManager;
-   }
-
-   /**
-    * Sets transaction manager.
-    * @param transactionManager transaction manager
-    */
-   public void setTransactionManager(TransactionManager transactionManager)
-   {
-      this.transactionManager = transactionManager;
-   }
-   
-   
-   /**
-    * {@inheritDoc}
-    */
-   public void userTransactionStarted() throws SystemException
-   {
-      KeyConnectionAssociation key = peekMetaAwareObject();
-      if (trace)
-      {
-         log.trace("user tx started, key: " + key);  
-      }
-      if (key == null)
-      {
-         return; //not participating properly in this management scheme.  
-      }
-
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
-      Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
-         cmToConnectionsMap.entrySet().iterator();
-      
-      while (cmToConnectionsMapIterator.hasNext())
-      {
-         Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
-         ConnectionCacheListener cm = entry.getKey();
-         Collection<ConnectionRecord> conns = entry.getValue();
-         
-         cm.transactionStarted(conns);
-      }
-   }
-   
-   /**
-    * 
-    * @return stack last meta-aware object
-    */
-   KeyConnectionAssociation peekMetaAwareObject()
-   {
-      LinkedList<Object> stack = currentObjects.get();
-      if (stack == null)
-      {
-         return null;  
-      }
-      
-      if (!stack.isEmpty())
-      {
-         return (KeyConnectionAssociation) stack.getLast();  
-      }
-      
-      else
-      {
-         return null;  
-      }
-   }
-   
-   
-   /**
-    * {@inheritDoc}
-    */
-   @SuppressWarnings("unchecked")
-   public void popMetaAwareObject(Set unsharableResources) throws ResourceException
-   {
-      LinkedList<Object> stack = currentObjects.get();
-      KeyConnectionAssociation oldKey = (KeyConnectionAssociation) stack.removeLast();
-      if (trace)
-      {
-         log.trace("popped object: " + Strings.defaultToString(oldKey));  
-      }
-
-      if (!stack.contains(oldKey))
-      {
-         disconnect(oldKey, unsharableResources);
-      } // end of if ()
-       
-      if (debug)
-      {
-         if (closeAll(oldKey.getCMToConnectionsMap()) && error)
-         {
-            throw new ResourceException("Some connections were not closed, " +
-                  "see the log for the allocation stacktraces");  
-         }
-      }
-      
-   }
-
-   /**
-    * Register connection.
-    * @param cm connection manager
-    * @param cl connection listener
-    * @param connection connection handle
-    * @param cri connection request info.
-    */
-   public void registerConnection(ConnectionCacheListener cm, ConnectionListener cl, 
-         Object connection, ConnectionRequestInfo cri)
-   {
-      if (debug)
-      {
-         synchronized (connectionStackTraces)
-         {
-            connectionStackTraces.put(connection, new Throwable("STACKTRACE"));
-         }
-      }
-
-      KeyConnectionAssociation key = peekMetaAwareObject();
-      
-      if (trace)
-      {
-         log.trace("registering connection from connection manager " + cm +
-               ", connection : " + connection + ", key: " + key);  
-      }
-      
-      if (key == null)
-      {
-         return; //not participating properly in this management scheme.  
-      }
-
-      ConnectionRecord cr = new ConnectionRecord(cl, connection, cri);
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
-      Collection<ConnectionRecord> conns = cmToConnectionsMap.get(cm);
-      if (conns == null)
-      {
-         conns = new ArrayList<ConnectionRecord>();
-         cmToConnectionsMap.put(cm, conns);
-      }
-      
-      conns.add(cr);
-   }
-
-   /**
-    * Unregister connection.
-    * @param cm connection manager
-    * @param connection connection handle
-    */
-   public void unregisterConnection(ConnectionCacheListener cm, Object connection)
-   {
-      if (debug)
-      {
-         CloseConnectionSynchronization cas = getCloseConnectionSynchronization(false);
-         if (cas != null)
-         {
-            cas.remove(connection);  
-         }
-         
-         synchronized (connectionStackTraces)
-         {
-            connectionStackTraces.remove(connection);
-         }
-      }
-
-      KeyConnectionAssociation key = peekMetaAwareObject();
-      
-      if (trace)
-      {
-         log.trace("unregistering connection from connection manager " + cm +
-               ", object: " + connection + ", key: " + key);  
-      }
-      
-      if (key == null)
-      {
-         return; //not participating properly in this management scheme.  
-      }
-
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
-      Collection<ConnectionRecord> conns = cmToConnectionsMap.get(cm);
-      if (conns == null)
-      {
-         return; // Can happen if connections are "passed" between contexts  
-      }
-      
-      for (Iterator<ConnectionRecord> i = conns.iterator(); i.hasNext();)
-      {
-         if ((i.next()).getConnection() == connection)
-         {
-            i.remove();
-            return;
-         }
-      }
-      
-      throw new IllegalStateException("Trying to return an unknown connection2! " + connection);
-   }
-   
-   /**
-    * {@inheritDoc}
-    */
-   @SuppressWarnings("unchecked")
-   public void pushMetaAwareObject(final Object rawKey, Set unsharableResources) throws ResourceException
-   {
-      LinkedList<Object> stack = currentObjects.get();
-      if (stack == null)
-      {
-         if (trace)
-         {
-            log.trace("new stack for key: " + Strings.defaultToString(rawKey));  
-         }
-         
-         stack = new LinkedList<Object>();         
-         currentObjects.set(stack);         
-      }
-      else
-      {
-         if (trace)
-         {
-            log.trace("old stack for key: " + Strings.defaultToString(rawKey));  
-         }
-      }
-      
-      KeyConnectionAssociation key = new KeyConnectionAssociation(rawKey);
-      if (!stack.contains(key))
-      {
-         reconnect(key, unsharableResources);
-      }
-      
-      stack.addLast(key);      
-   }
-   
-   /**
-    * The <code>reconnect</code> method gets the cmToConnectionsMap
-    * from objectToConnectionManagerMap, copies it to the key, and
-    * reconnects all the connections in it.
-    *
-    * @param key a <code>KeyConnectionAssociation</code> value
-    * @param unsharableResources a <code>Set</code> value
-    * @exception ResourceException if an error occurs
-    */
-   @SuppressWarnings("unchecked")
-   private void reconnect(KeyConnectionAssociation key, Set unsharableResources) throws ResourceException
-   {
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = null;
-      synchronized (objectToConnectionManagerMap)
-      {
-         cmToConnectionsMap = objectToConnectionManagerMap.get(key);
-         if (cmToConnectionsMap == null)
-         {
-            return;  
-         }
-      }
-      key.setCMToConnectionsMap(cmToConnectionsMap);
-      Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
-         cmToConnectionsMap.entrySet().iterator();
-      
-      while (cmToConnectionsMapIterator.hasNext())
-      {
-         Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
-         ConnectionCacheListener cm = entry.getKey();
-         Collection<ConnectionRecord> conns =  entry.getValue();
-         
-         cm.reconnect(conns, unsharableResources);
-      }
-   }
-   
-   /**
-    * Disconnect connections.
-    * @param key key
-    * @param unsharableResources resource
-    * @throws ResourceException exception
-    */
-   @SuppressWarnings("unchecked")
-   private void disconnect(KeyConnectionAssociation key, Set unsharableResources) throws ResourceException
-   {
-      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = null;
-      cmToConnectionsMap = key.getCMToConnectionsMap();
-      if (!cmToConnectionsMap.isEmpty())
-      {
-         synchronized (objectToConnectionManagerMap)
-         {
-            objectToConnectionManagerMap.put(key, cmToConnectionsMap);
-         }
-         Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
-            cmToConnectionsMap.entrySet().iterator();
-         
-         while (cmToConnectionsMapIterator.hasNext())
-         {
-            Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
-            ConnectionCacheListener cm = entry.getKey();
-            Collection<ConnectionRecord> conns =  entry.getValue();
-            
-            cm.disconnect(conns, unsharableResources);
-         }
-      }
-   }
-   
-   /**
-    * Describe <code>unregisterConnectionCacheListener</code> method here.
-    * This is a shutdown method called by a connection manager.  It will remove all reference
-    * to that connection manager from the cache, so cached connections from that manager
-    * will never be recoverable.
-    * Possibly this method should not exist.
-    * 
-    * @param cm a <code>ConnectionCacheListener</code> value
-    */   
-   public void unregisterConnectionCacheListener(ConnectionCacheListener cm)
-   {
-      if (trace)
-      {
-         log.trace("unregisterConnectionCacheListener: " + cm);  
-      }
-      
-      synchronized (objectToConnectionManagerMap)
-      {
-         Iterator<Map<ConnectionCacheListener, Collection<ConnectionRecord>>> it = 
-               objectToConnectionManagerMap.values().iterator();
-         
-         while (it.hasNext())
-         {
-            Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = it.next();
-            if (cmToConnectionsMap != null)
-            {
-               cmToConnectionsMap.remove(cm);  
-            }
-         }
-      }
-   }
-   
-   
-   /**
-    * Close all connections.
-    * @param cmToConnectionsMap connection manager to connections
-    * @return true if close
-    */
-   private boolean closeAll(Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap)
-   {
-      if (!debug)
-      {
-         return false;  
-      }
-
-      boolean unclosed = false;
-
-      Collection<Collection<ConnectionRecord>> connections = cmToConnectionsMap.values();
-      if (connections.size() != 0)
-      {
-         for (Iterator<Collection<ConnectionRecord>> i = connections.iterator(); i.hasNext();)
-         {
-            Collection<ConnectionRecord> conns = i.next();
-            for (Iterator<ConnectionRecord> j = conns.iterator(); j.hasNext();)
-            {
-               Object c = (j.next()).getConnection();
-               CloseConnectionSynchronization cas = getCloseConnectionSynchronization(true);
-               if (cas == null)
-               {
-                  unclosed = true;
-                  closeConnection(c);
-               }
-               else
-               {
-                  cas.add(c);  
-               }
-            }
-         }
-      }
-      
-      return unclosed;
-   }
-   
-   /**
-    * Gets close sync. instance.
-    * @param createIfNotFound create if not found
-    * @return sync. instance
-    */
-   private CloseConnectionSynchronization getCloseConnectionSynchronization(boolean createIfNotFound)
-   {
-      try
-      {
-         Transaction tx = null;
-         if (transactionManager != null)
-         {
-            tx = transactionManager.getTransaction();  
-         }
-        
-         if (tx != null)
-         {
-            TransactionSynchronizer.lock(tx);
-            try
-            {
-               CloseConnectionSynchronization cas = (CloseConnectionSynchronization) 
-                                                   TransactionSynchronizer.getCCMSynchronization(tx);
-               
-               if (cas == null && createIfNotFound && TxUtils.isActive(tx))
-               {
-                  cas = new CloseConnectionSynchronization();
-                  TransactionSynchronizer.registerCCMSynchronization(tx, cas);
-               }
-               
-               return cas;
-            }
-            finally
-            {
-               TransactionSynchronizer.unlock(tx);
-            }
-         }
-      }
-      catch (Throwable t)
-      {
-         log.debug("Unable to synchronize with transaction", t);
-      }
-      
-      return null;
-   }
-   
-   
-   /**
-    * Close connection handle.
-    * @param connectionHandle connection handle
-    */
-   private void closeConnection(Object connectionHandle)
-   {
-      try
-      {
-         Throwable exception;
-         
-         synchronized (connectionStackTraces)
-         {
-            exception = connectionStackTraces.remove(connectionHandle);
-         }
-         
-         Method m = connectionHandle.getClass().getMethod("close", new Class[]{});
-         
-         try
-         {
-            if (exception != null)
-            {
-               log.info("Closing a connection for you.  Please close them yourself: " + connectionHandle, exception);  
-            }
-            else
-            {
-               log.info("Closing a connection for you.  Please close them yourself: " + connectionHandle);  
-            }
-            
-            m.invoke(connectionHandle, new Object[]{});
-         }
-         catch (Throwable t)
-         {
-            log.info("Throwable trying to close a connection for you, please close it yourself", t);
-         }
-      }
-      catch (NoSuchMethodException nsme)
-      {
-         log.info("Could not find a close method on alleged connection objects.  Please close your own connections.");
-      }
-   }
-   
-   
-   /**
-    * Close synch. class. 
-    */
-   private class CloseConnectionSynchronization implements Synchronization
-   {
-      /**Connection handles*/
-      CopyOnWriteArraySet<Object> connections = new CopyOnWriteArraySet<Object>();
-      
-      /**Closing flag*/
-      AtomicBoolean closing = new AtomicBoolean(false);
-
-      /**
-       * Creates a new instance.
-       */
-      public CloseConnectionSynchronization()
-      {
-         
-      }
-
-      /**
-       * Add new connection handle.
-       * @param c connection handle
-       */
-      public  void add(Object c)
-      {
-         if (closing.get())
-         {
-            return;  
-         }
-         connections.add(c);
-      }
-
-      /**
-       * Removes connection handle.
-       * @param c connection handle
-       */
-      public  void remove(Object c)
-      {
-         if (closing.get())
-         {
-            return;  
-         }
-         
-         connections.remove(c);
-      }
-
-      /**
-       * {@inheritDoc}
-       */
-      public void beforeCompletion()
-      {
-         //No-action
-      }
-
-      /**
-       * {@inheritDoc}
-       */
-      public void afterCompletion(int status)
-      {
-         closing.set(true);
-         
-         for (Iterator<Object> i = connections.iterator(); i.hasNext();)
-         {
-            closeConnection(i.next());  
-         }
-        
-         connections.clear();
-      }
-   }
-   
-}

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ConnectionValidator.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ConnectionValidator.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ConnectionValidator.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -1,299 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.jca.core.connectionmanager;
-
-import org.jboss.jca.core.connectionmanager.pool.InternalManagedConnectionPool;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-
-/**
- * Connection validator class.
- * 
- * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
- * @version $Rev: $
- */
-public class ConnectionValidator
-{
-   /**Logger instance*/
-   private static Logger logger = Logger.getLogger(ConnectionValidator.class);
-   
-   /**Validator thread name*/
-   private static final String VALIDATOR_THREAD_NAME = "JBossConnectionValidator";
-   
-   /**Registered internal pool instances*/
-   private CopyOnWriteArrayList<InternalManagedConnectionPool> registeredPools = 
-      new CopyOnWriteArrayList<InternalManagedConnectionPool>();
-   
-   /**Validator executor service*/
-   private ExecutorService executorService = null;
-   
-   /**Singleton instance*/
-   private static ConnectionValidator instance = new ConnectionValidator();
-   
-   /** The interval */
-   private long interval = Long.MAX_VALUE;
-
-   /** The next */
- //important initialization!
-   private long next = Long.MAX_VALUE;
-   
-   /**Lock for condition*/
-   private Lock lock = new ReentrantLock();
-   
-   /**Condition*/
-   private Condition condition = lock.newCondition();
-   
-   
-   /**
-    * Private constructor.
-    */
-   private ConnectionValidator()
-   {
-      this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory());
-      this.executorService.execute(new JBossConnectionValidator());
-   }
-   
-   /**
-    * Register pool for connection validation.
-    * @param mcp managed connection pool
-    * @param interval validation interval
-    */
-   public static void registerPool(InternalManagedConnectionPool mcp, long interval)
-   {
-      instance.internalRegisterPool(mcp, interval);
-   }
-   
-   /**
-    * Unregister pool instance for connection validation.
-    * @param mcp pool instance
-    */
-   public static void unregisterPool(InternalManagedConnectionPool mcp)
-   {
-      instance.internalUnregisterPool(mcp);
-   }
-   
-   private void internalRegisterPool(InternalManagedConnectionPool mcp, long interval)
-   {
-      try
-      {
-         this.lock.lock();
-         
-         this.registeredPools.addIfAbsent(mcp);
-         
-         if (interval > 1 && interval / 2 < this.interval) 
-         {
-            this.interval = interval / 2;
-            long maybeNext = System.currentTimeMillis() + this.interval;
-            if (next > maybeNext && maybeNext > 0) 
-            {
-               next = maybeNext;
-               if (logger.isDebugEnabled())
-               {
-                  logger.debug("internalRegisterPool: about to notify thread: old next: " +
-                        next + ", new next: " + maybeNext);  
-               }               
-               
-               this.condition.signal();
-               
-            }
-         }
-         
-      } 
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-   
-   private void internalUnregisterPool(InternalManagedConnectionPool mcp)
-   {
-      this.registeredPools.remove(mcp);
-      
-      if (this.registeredPools.size() == 0) 
-      {
-         if (logger.isDebugEnabled())
-         {
-            logger.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE");  
-         }
-         
-         interval = Long.MAX_VALUE;
-      }
-   }
-   
-   /**
-    * Setup context class loader.
-    */
-   private void setupContextClassLoader()
-   {
-      // Could be null if loaded from system classloader
-      final ClassLoader cl = ConnectionValidator.class.getClassLoader();
-      if (cl == null)
-      {
-         return;  
-      }
-      
-      SecurityManager sm = System.getSecurityManager();
-      
-      if (sm == null)
-      {
-         Thread.currentThread().setContextClassLoader(cl);
-         
-         return;
-      }
-      
-      AccessController.doPrivileged(new ClassLoaderAction(cl));
- 
-   }
-   
-   /**
-    * Priviledge action. 
-    */
-   private static class ClassLoaderAction implements PrivilegedAction<Object>
-   {
-      private ClassLoader classLoader;
-      
-      public ClassLoaderAction(ClassLoader cl)
-      {
-         this.classLoader = cl;
-      }
-      
-      public Object run()
-      {
-         Thread.currentThread().setContextClassLoader(classLoader);
-         
-         return null;
-      }
-      
-   }
-   
-   /**
-    * Wait for background thread.
-    */
-   public static void waitForBackgroundThread()
-   {
-      try
-      {
-         instance.lock.lock();
-         
-      }
-      finally
-      {
-         instance.lock.unlock();  
-      }
-   }
-   
-   
-   /**
-    * Thread factory.
-    */
-   private static class ValidatorThreadFactory implements ThreadFactory
-   {
-      /**
-       * {@inheritDoc}
-       */
-      public Thread newThread(Runnable r)
-      {
-         Thread thread = new Thread(r, ConnectionValidator.VALIDATOR_THREAD_NAME);
-         thread.setDaemon(true);
-         
-         return thread;
-      }      
-   }
-   
-   /**
-    * JBossConnectionValidator.
-    *
-    */
-   private class JBossConnectionValidator implements Runnable
-   {
-      
-      /**
-       * {@inheritDoc}
-       */
-      public void run()
-      {
-         setupContextClassLoader();
-         
-         try
-         {
-            lock.lock();
-            
-            while (true)
-            {
-               boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS);
-               
-               if (logger.isTraceEnabled())
-               {
-                  logger.trace("Result of await ConnectionValidator: " + result);
-               }
-               
-               if (logger.isDebugEnabled())
-               {
-                  logger.debug("run: ConnectionValidator notifying pools, interval: " + interval);  
-               }
-     
-               for (InternalManagedConnectionPool mcp : registeredPools)
-               {
-                  mcp.validateConnections();
-               }
-
-               next = System.currentTimeMillis() + interval;
-               
-               if (next < 0)
-               {
-                  next = Long.MAX_VALUE;  
-               }              
-            }            
-         }
-         catch (InterruptedException e)
-         {
-            logger.info("run: ConnectionValidator has been interrupted, returning");
-            
-            return;  
-         }
-         catch (RuntimeException e)
-         {
-            logger.warn("run: ConnectionValidator ignored unexpected runtime exception", e);
-         }
-         catch (Exception e)
-         {
-            logger.warn("run: ConnectionValidator ignored unexpected error", e);
-         }         
-         finally
-         {
-            lock.unlock();  
-         }         
-      }      
-   }
-}

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleConnectionRemovalSupport.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleConnectionRemovalSupport.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleConnectionRemovalSupport.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -1,39 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jca.core.connectionmanager;
-
-/**
- * A IdleConnectionRemovalSupport specified contract for a pool that is able
- * to remove an idle connection.
- * 
- * @author gurkanerdogdu
- * @author <a href="weston.price at jboss.com">Weston Price</a>
- * @version $Revision$
- */
-public interface IdleConnectionRemovalSupport
-{
-   /**
-    * Pool removes idle connections.
-    */
-   public void removeIdleConnections();
-   
-}

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleRemover.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleRemover.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/IdleRemover.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -1,298 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.jca.core.connectionmanager;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-
-/**
- * Connection validator class.
- * 
- * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
- * @version $Rev: $
- */
-public class IdleRemover
-{
-   /**Logger instance*/
-   private static Logger logger = Logger.getLogger(IdleRemover.class);
-   
-   /**Validator thread name*/
-   private static final String VALIDATOR_THREAD_NAME = "JBossConnectionValidator";
-   
-   /**Registered internal pool instances*/
-   private CopyOnWriteArrayList<IdleConnectionRemovalSupport> registeredPools = 
-      new CopyOnWriteArrayList<IdleConnectionRemovalSupport>();
-   
-   /**Validator executor service*/
-   private ExecutorService executorService = null;
-   
-   /**Singleton instance*/
-   private static IdleRemover instance = new IdleRemover();
-   
-   /** The interval */
-   private long interval = Long.MAX_VALUE;
-
-   /** The next */
- //important initialization!
-   private long next = Long.MAX_VALUE;
-   
-   /**Lock for condition*/
-   private Lock lock = new ReentrantLock();
-   
-   /**Condition*/
-   private Condition condition = lock.newCondition();
-   
-   
-   /**
-    * Private constructor.
-    */
-   private IdleRemover()
-   {
-      this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory());
-      this.executorService.execute(new JBossConnectionValidator());
-   }
-   
-   /**
-    * Register pool for connection validation.
-    * @param mcp managed connection pool
-    * @param interval validation interval
-    */
-   public static void registerPool(IdleConnectionRemovalSupport mcp, long interval)
-   {
-      instance.internalRegisterPool(mcp, interval);
-   }
-   
-   /**
-    * Unregister pool instance for connection validation.
-    * @param mcp pool instance
-    */
-   public static void unregisterPool(IdleConnectionRemovalSupport mcp)
-   {
-      instance.internalUnregisterPool(mcp);
-   }
-   
-   private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval)
-   {
-      try
-      {
-         this.lock.lock();
-         
-         this.registeredPools.addIfAbsent(mcp);
-         
-         if (interval > 1 && interval / 2 < this.interval) 
-         {
-            this.interval = interval / 2;
-            long maybeNext = System.currentTimeMillis() + this.interval;
-            if (next > maybeNext && maybeNext > 0) 
-            {
-               next = maybeNext;
-               if (logger.isDebugEnabled())
-               {
-                  logger.debug("internalRegisterPool: about to notify thread: old next: " +
-                        next + ", new next: " + maybeNext);  
-               }               
-               
-               this.condition.signal();
-               
-            }
-         }
-         
-      } 
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-   
-   private void internalUnregisterPool(IdleConnectionRemovalSupport mcp)
-   {
-      this.registeredPools.remove(mcp);
-      
-      if (this.registeredPools.size() == 0) 
-      {
-         if (logger.isDebugEnabled())
-         {
-            logger.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE");  
-         }
-         
-         interval = Long.MAX_VALUE;
-      }
-   }
-   
-   /**
-    * Setup context class loader.
-    */
-   private void setupContextClassLoader()
-   {
-      // Could be null if loaded from system classloader
-      final ClassLoader cl = IdleRemover.class.getClassLoader();
-      if (cl == null)
-      {
-         return;  
-      }
-      
-      SecurityManager sm = System.getSecurityManager();
-      
-      if (sm == null)
-      {
-         Thread.currentThread().setContextClassLoader(cl);
-         
-         return;
-      }
-      
-      AccessController.doPrivileged(new ClassLoaderAction(cl));
-      
-   }
-   
-   /**
-    * Priviledge action. 
-    */
-   private static class ClassLoaderAction implements PrivilegedAction<Object>
-   {
-      private ClassLoader classLoader;
-      
-      public ClassLoaderAction(ClassLoader cl)
-      {
-         this.classLoader = cl;
-      }
-      
-      public Object run()
-      {
-         Thread.currentThread().setContextClassLoader(classLoader);
-         
-         return null;
-      }
-      
-   }   
-   
-   
-   /**
-    * Wait for background thread.
-    */
-   public static void waitForBackgroundThread()
-   {
-      try
-      {
-         instance.lock.lock();
-         
-      }
-      finally
-      {
-         instance.lock.unlock();  
-      }
-   }
-   
-   
-   /**
-    * Thread factory.
-    */
-   private static class ValidatorThreadFactory implements ThreadFactory
-   {
-      /**
-       * {@inheritDoc}
-       */
-      public Thread newThread(Runnable r)
-      {
-         Thread thread = new Thread(r, IdleRemover.VALIDATOR_THREAD_NAME);
-         thread.setDaemon(true);
-         
-         return thread;
-      }      
-   }
-   
-   /**
-    * JBossConnectionValidator.
-    *
-    */
-   private class JBossConnectionValidator implements Runnable
-   {
-      
-      /**
-       * {@inheritDoc}
-       */
-      public void run()
-      {
-         setupContextClassLoader();
-         
-         try
-         {
-            lock.lock();
-            
-            while (true)
-            {
-               boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS);
-
-               if (logger.isTraceEnabled())
-               {
-                  logger.trace("Result of await ConnectionValidator: " + result);
-               }
-
-               if (logger.isDebugEnabled())
-               {
-                  logger.debug("run: ConnectionValidator notifying pools, interval: " + interval);  
-               }
-     
-               for (IdleConnectionRemovalSupport mcp : registeredPools)
-               {
-                  mcp.removeIdleConnections();
-               }
-
-               next = System.currentTimeMillis() + interval;
-               
-               if (next < 0)
-               {
-                  next = Long.MAX_VALUE;  
-               }              
-            }            
-         }
-         catch (InterruptedException e)
-         {
-            logger.info("run: ConnectionValidator has been interrupted, returning");
-            
-            return;  
-         }
-         catch (RuntimeException e)
-         {
-            logger.warn("run: ConnectionValidator ignored unexpected runtime exception", e);
-         }
-         catch (Exception e)
-         {
-            logger.warn("run: ConnectionValidator ignored unexpected error", e);
-         }         
-         finally
-         {
-            lock.unlock();  
-         }         
-      }      
-   }
-}

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/KeyConnectionAssociation.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/KeyConnectionAssociation.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/KeyConnectionAssociation.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -1,104 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jca.core.connectionmanager;
-
-import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.util.Strings;
-
-
-/**
- * The class <code>KeyConnectionAssociation</code> wraps objects so they may be used in hashmaps
- * based on their object identity rather than equals implementation. Used for keys.
- * 
- * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
- * @version $Rev$
- */
-final class KeyConnectionAssociation
-{
-   //key
-   private final Object metaAwareObject;
-
-   //map of cm to list of connections for that cm.
-   private Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap;
-
-   /**
-    * Creates a new instance.
-    * @param metaAwareObject meta aware object
-    */
-   KeyConnectionAssociation(final Object metaAwareObject)
-   {
-      this.metaAwareObject = metaAwareObject;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public boolean equals(Object other)
-   {
-      return (other instanceof KeyConnectionAssociation) && 
-            this.metaAwareObject == ((KeyConnectionAssociation) other).metaAwareObject;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   public String toString()
-   {
-      return Strings.defaultToString(this.metaAwareObject);
-   }
-   
-   /**
-    * {@inheritDoc}
-    */
-   public int hashCode()
-   {
-      return System.identityHashCode(this.metaAwareObject);
-   }
-
-   /**
-    * Set map instance.
-    * @param cmToConnectionsMap connection manager to connections
-    */
-   public void setCMToConnectionsMap(Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap)
-   {
-      this.cmToConnectionsMap = cmToConnectionsMap;
-   }
-
-   /**
-    * 
-    * @return map instance
-    */
-   public Map<ConnectionCacheListener, Collection<ConnectionRecord>> getCMToConnectionsMap()
-   {
-      if (cmToConnectionsMap == null)
-      {
-         cmToConnectionsMap = new HashMap<ConnectionCacheListener, Collection<ConnectionRecord>>();
-      }
-      
-      return cmToConnectionsMap;
-   }
-}

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManager.java (from rev 106765, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/CachedConnectionManager.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManager.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManager.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,643 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.ccm;
+
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer;
+import org.jboss.jca.spi.ComponentStack;
+
+import java.lang.reflect.Method;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.jboss.logging.Logger;
+
+import org.jboss.tm.TxUtils;
+import org.jboss.tm.usertx.UserTransactionListener;
+import org.jboss.tm.usertx.client.ServerVMClientUserTransaction.UserTransactionStartedListener;
+import org.jboss.util.Strings;
+
+/**
+ * CacheConnectionManager.
+ * @version $Rev$
+ *
+ */
+public class CachedConnectionManager implements
+   UserTransactionStartedListener,
+   UserTransactionListener,
+   ComponentStack
+{
+   /**Log instance*/
+   private static Logger log = Logger.getLogger(CachedConnectionManager.class);
+   
+   /**Log trace*/
+   private boolean trace;
+   
+   /**Debug flag*/
+   private boolean debug;
+   
+   /**Error flag*/
+   private boolean error;
+   
+   /**Transaction Manager instance*/
+   private TransactionManager transactionManager;
+   
+   /**
+    * ThreadLocal that holds current calling meta-programming aware
+    * object, used in case someone is idiotic enough to cache a
+    * connection between invocations.and want the spec required
+    * behavior of it getting hooked up to an appropriate
+    * ManagedConnection on each method invocation.
+    */
+   private final ThreadLocal<LinkedList<Object>> currentObjects = new ThreadLocal<LinkedList<Object>>();
+
+   /**
+    * The variable <code>objectToConnectionManagerMap</code> holds the
+    * map of meta-aware object to set of connections it holds, used by
+    * the idiot spec compliant behavior.
+    */
+   private final Map<KeyConnectionAssociation, Map<ConnectionCacheListener, Collection<ConnectionRecord>>> 
+   objectToConnectionManagerMap = new HashMap<KeyConnectionAssociation, 
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>>>();
+
+   /**
+    * Connection stacktraces
+    */
+   private Map<Object, Throwable> connectionStackTraces = new WeakHashMap<Object, Throwable>();
+
+   /**
+    * Creates a new instance.
+    */
+   public CachedConnectionManager()
+   {
+      this.trace = log.isTraceEnabled();
+   }
+   
+   /**
+    * Gets transaction manager.
+    * @return transaction manager
+    */
+   public TransactionManager getTransactionManager()
+   {
+      return transactionManager;
+   }
+
+   /**
+    * Sets transaction manager.
+    * @param transactionManager transaction manager
+    */
+   public void setTransactionManager(TransactionManager transactionManager)
+   {
+      this.transactionManager = transactionManager;
+   }
+   
+   
+   /**
+    * {@inheritDoc}
+    */
+   public void userTransactionStarted() throws SystemException
+   {
+      KeyConnectionAssociation key = peekMetaAwareObject();
+      if (trace)
+      {
+         log.trace("user tx started, key: " + key);  
+      }
+      if (key == null)
+      {
+         return; //not participating properly in this management scheme.  
+      }
+
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
+      Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
+         cmToConnectionsMap.entrySet().iterator();
+      
+      while (cmToConnectionsMapIterator.hasNext())
+      {
+         Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
+         ConnectionCacheListener cm = entry.getKey();
+         Collection<ConnectionRecord> conns = entry.getValue();
+         
+         cm.transactionStarted(conns);
+      }
+   }
+   
+   /**
+    * 
+    * @return stack last meta-aware object
+    */
+   KeyConnectionAssociation peekMetaAwareObject()
+   {
+      LinkedList<Object> stack = currentObjects.get();
+      if (stack == null)
+      {
+         return null;  
+      }
+      
+      if (!stack.isEmpty())
+      {
+         return (KeyConnectionAssociation) stack.getLast();  
+      }
+      
+      else
+      {
+         return null;  
+      }
+   }
+   
+   
+   /**
+    * {@inheritDoc}
+    */
+   @SuppressWarnings("unchecked")
+   public void popMetaAwareObject(Set unsharableResources) throws ResourceException
+   {
+      LinkedList<Object> stack = currentObjects.get();
+      KeyConnectionAssociation oldKey = (KeyConnectionAssociation) stack.removeLast();
+      if (trace)
+      {
+         log.trace("popped object: " + Strings.defaultToString(oldKey));  
+      }
+
+      if (!stack.contains(oldKey))
+      {
+         disconnect(oldKey, unsharableResources);
+      } // end of if ()
+       
+      if (debug)
+      {
+         if (closeAll(oldKey.getCMToConnectionsMap()) && error)
+         {
+            throw new ResourceException("Some connections were not closed, " +
+                  "see the log for the allocation stacktraces");  
+         }
+      }
+      
+   }
+
+   /**
+    * Register connection.
+    * @param cm connection manager
+    * @param cl connection listener
+    * @param connection connection handle
+    * @param cri connection request info.
+    */
+   public void registerConnection(ConnectionCacheListener cm, ConnectionListener cl, 
+         Object connection, ConnectionRequestInfo cri)
+   {
+      if (debug)
+      {
+         synchronized (connectionStackTraces)
+         {
+            connectionStackTraces.put(connection, new Throwable("STACKTRACE"));
+         }
+      }
+
+      KeyConnectionAssociation key = peekMetaAwareObject();
+      
+      if (trace)
+      {
+         log.trace("registering connection from connection manager " + cm +
+               ", connection : " + connection + ", key: " + key);  
+      }
+      
+      if (key == null)
+      {
+         return; //not participating properly in this management scheme.  
+      }
+
+      ConnectionRecord cr = new ConnectionRecord(cl, connection, cri);
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
+      Collection<ConnectionRecord> conns = cmToConnectionsMap.get(cm);
+      if (conns == null)
+      {
+         conns = new ArrayList<ConnectionRecord>();
+         cmToConnectionsMap.put(cm, conns);
+      }
+      
+      conns.add(cr);
+   }
+
+   /**
+    * Unregister connection.
+    * @param cm connection manager
+    * @param connection connection handle
+    */
+   public void unregisterConnection(ConnectionCacheListener cm, Object connection)
+   {
+      if (debug)
+      {
+         CloseConnectionSynchronization cas = getCloseConnectionSynchronization(false);
+         if (cas != null)
+         {
+            cas.remove(connection);  
+         }
+         
+         synchronized (connectionStackTraces)
+         {
+            connectionStackTraces.remove(connection);
+         }
+      }
+
+      KeyConnectionAssociation key = peekMetaAwareObject();
+      
+      if (trace)
+      {
+         log.trace("unregistering connection from connection manager " + cm +
+               ", object: " + connection + ", key: " + key);  
+      }
+      
+      if (key == null)
+      {
+         return; //not participating properly in this management scheme.  
+      }
+
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = key.getCMToConnectionsMap();
+      Collection<ConnectionRecord> conns = cmToConnectionsMap.get(cm);
+      if (conns == null)
+      {
+         return; // Can happen if connections are "passed" between contexts  
+      }
+      
+      for (Iterator<ConnectionRecord> i = conns.iterator(); i.hasNext();)
+      {
+         if ((i.next()).getConnection() == connection)
+         {
+            i.remove();
+            return;
+         }
+      }
+      
+      throw new IllegalStateException("Trying to return an unknown connection2! " + connection);
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @SuppressWarnings("unchecked")
+   public void pushMetaAwareObject(final Object rawKey, Set unsharableResources) throws ResourceException
+   {
+      LinkedList<Object> stack = currentObjects.get();
+      if (stack == null)
+      {
+         if (trace)
+         {
+            log.trace("new stack for key: " + Strings.defaultToString(rawKey));  
+         }
+         
+         stack = new LinkedList<Object>();         
+         currentObjects.set(stack);         
+      }
+      else
+      {
+         if (trace)
+         {
+            log.trace("old stack for key: " + Strings.defaultToString(rawKey));  
+         }
+      }
+      
+      KeyConnectionAssociation key = new KeyConnectionAssociation(rawKey);
+      if (!stack.contains(key))
+      {
+         reconnect(key, unsharableResources);
+      }
+      
+      stack.addLast(key);      
+   }
+   
+   /**
+    * The <code>reconnect</code> method gets the cmToConnectionsMap
+    * from objectToConnectionManagerMap, copies it to the key, and
+    * reconnects all the connections in it.
+    *
+    * @param key a <code>KeyConnectionAssociation</code> value
+    * @param unsharableResources a <code>Set</code> value
+    * @exception ResourceException if an error occurs
+    */
+   @SuppressWarnings("unchecked")
+   private void reconnect(KeyConnectionAssociation key, Set unsharableResources) throws ResourceException
+   {
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = null;
+      synchronized (objectToConnectionManagerMap)
+      {
+         cmToConnectionsMap = objectToConnectionManagerMap.get(key);
+         if (cmToConnectionsMap == null)
+         {
+            return;  
+         }
+      }
+      key.setCMToConnectionsMap(cmToConnectionsMap);
+      Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
+         cmToConnectionsMap.entrySet().iterator();
+      
+      while (cmToConnectionsMapIterator.hasNext())
+      {
+         Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
+         ConnectionCacheListener cm = entry.getKey();
+         Collection<ConnectionRecord> conns =  entry.getValue();
+         
+         cm.reconnect(conns, unsharableResources);
+      }
+   }
+   
+   /**
+    * Disconnect connections.
+    * @param key key
+    * @param unsharableResources resource
+    * @throws ResourceException exception
+    */
+   @SuppressWarnings("unchecked")
+   private void disconnect(KeyConnectionAssociation key, Set unsharableResources) throws ResourceException
+   {
+      Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = null;
+      cmToConnectionsMap = key.getCMToConnectionsMap();
+      if (!cmToConnectionsMap.isEmpty())
+      {
+         synchronized (objectToConnectionManagerMap)
+         {
+            objectToConnectionManagerMap.put(key, cmToConnectionsMap);
+         }
+         Iterator<Entry<ConnectionCacheListener, Collection<ConnectionRecord>>> cmToConnectionsMapIterator = 
+            cmToConnectionsMap.entrySet().iterator();
+         
+         while (cmToConnectionsMapIterator.hasNext())
+         {
+            Entry<ConnectionCacheListener, Collection<ConnectionRecord>> entry = cmToConnectionsMapIterator.next();
+            ConnectionCacheListener cm = entry.getKey();
+            Collection<ConnectionRecord> conns =  entry.getValue();
+            
+            cm.disconnect(conns, unsharableResources);
+         }
+      }
+   }
+   
+   /**
+    * Describe <code>unregisterConnectionCacheListener</code> method here.
+    * This is a shutdown method called by a connection manager.  It will remove all reference
+    * to that connection manager from the cache, so cached connections from that manager
+    * will never be recoverable.
+    * Possibly this method should not exist.
+    * 
+    * @param cm a <code>ConnectionCacheListener</code> value
+    */   
+   public void unregisterConnectionCacheListener(ConnectionCacheListener cm)
+   {
+      if (trace)
+      {
+         log.trace("unregisterConnectionCacheListener: " + cm);  
+      }
+      
+      synchronized (objectToConnectionManagerMap)
+      {
+         Iterator<Map<ConnectionCacheListener, Collection<ConnectionRecord>>> it = 
+               objectToConnectionManagerMap.values().iterator();
+         
+         while (it.hasNext())
+         {
+            Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap = it.next();
+            if (cmToConnectionsMap != null)
+            {
+               cmToConnectionsMap.remove(cm);  
+            }
+         }
+      }
+   }
+   
+   
+   /**
+    * Close all connections.
+    * @param cmToConnectionsMap connection manager to connections
+    * @return true if close
+    */
+   private boolean closeAll(Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap)
+   {
+      if (!debug)
+      {
+         return false;  
+      }
+
+      boolean unclosed = false;
+
+      Collection<Collection<ConnectionRecord>> connections = cmToConnectionsMap.values();
+      if (connections.size() != 0)
+      {
+         for (Iterator<Collection<ConnectionRecord>> i = connections.iterator(); i.hasNext();)
+         {
+            Collection<ConnectionRecord> conns = i.next();
+            for (Iterator<ConnectionRecord> j = conns.iterator(); j.hasNext();)
+            {
+               Object c = (j.next()).getConnection();
+               CloseConnectionSynchronization cas = getCloseConnectionSynchronization(true);
+               if (cas == null)
+               {
+                  unclosed = true;
+                  closeConnection(c);
+               }
+               else
+               {
+                  cas.add(c);  
+               }
+            }
+         }
+      }
+      
+      return unclosed;
+   }
+   
+   /**
+    * Gets close sync. instance.
+    * @param createIfNotFound create if not found
+    * @return sync. instance
+    */
+   private CloseConnectionSynchronization getCloseConnectionSynchronization(boolean createIfNotFound)
+   {
+      try
+      {
+         Transaction tx = null;
+         if (transactionManager != null)
+         {
+            tx = transactionManager.getTransaction();  
+         }
+        
+         if (tx != null)
+         {
+            TransactionSynchronizer.lock(tx);
+            try
+            {
+               CloseConnectionSynchronization cas = (CloseConnectionSynchronization) 
+                                                   TransactionSynchronizer.getCCMSynchronization(tx);
+               
+               if (cas == null && createIfNotFound && TxUtils.isActive(tx))
+               {
+                  cas = new CloseConnectionSynchronization();
+                  TransactionSynchronizer.registerCCMSynchronization(tx, cas);
+               }
+               
+               return cas;
+            }
+            finally
+            {
+               TransactionSynchronizer.unlock(tx);
+            }
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Unable to synchronize with transaction", t);
+      }
+      
+      return null;
+   }
+   
+   
+   /**
+    * Close connection handle.
+    * @param connectionHandle connection handle
+    */
+   private void closeConnection(Object connectionHandle)
+   {
+      try
+      {
+         Throwable exception;
+         
+         synchronized (connectionStackTraces)
+         {
+            exception = connectionStackTraces.remove(connectionHandle);
+         }
+         
+         Method m = connectionHandle.getClass().getMethod("close", new Class[]{});
+         
+         try
+         {
+            if (exception != null)
+            {
+               log.info("Closing a connection for you.  Please close them yourself: " + connectionHandle, exception);  
+            }
+            else
+            {
+               log.info("Closing a connection for you.  Please close them yourself: " + connectionHandle);  
+            }
+            
+            m.invoke(connectionHandle, new Object[]{});
+         }
+         catch (Throwable t)
+         {
+            log.info("Throwable trying to close a connection for you, please close it yourself", t);
+         }
+      }
+      catch (NoSuchMethodException nsme)
+      {
+         log.info("Could not find a close method on alleged connection objects.  Please close your own connections.");
+      }
+   }
+   
+   
+   /**
+    * Close synch. class. 
+    */
+   private class CloseConnectionSynchronization implements Synchronization
+   {
+      /**Connection handles*/
+      CopyOnWriteArraySet<Object> connections = new CopyOnWriteArraySet<Object>();
+      
+      /**Closing flag*/
+      AtomicBoolean closing = new AtomicBoolean(false);
+
+      /**
+       * Creates a new instance.
+       */
+      public CloseConnectionSynchronization()
+      {
+         
+      }
+
+      /**
+       * Add new connection handle.
+       * @param c connection handle
+       */
+      public  void add(Object c)
+      {
+         if (closing.get())
+         {
+            return;  
+         }
+         connections.add(c);
+      }
+
+      /**
+       * Removes connection handle.
+       * @param c connection handle
+       */
+      public  void remove(Object c)
+      {
+         if (closing.get())
+         {
+            return;  
+         }
+         
+         connections.remove(c);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void beforeCompletion()
+      {
+         //No-action
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void afterCompletion(int status)
+      {
+         closing.set(true);
+         
+         for (Iterator<Object> i = connections.iterator(); i.hasNext();)
+         {
+            closeConnection(i.next());  
+         }
+        
+         connections.clear();
+      }
+   }
+   
+}

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java (from rev 106765, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/KeyConnectionAssociation.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.ccm;
+
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.util.Strings;
+
+
+/**
+ * The class <code>KeyConnectionAssociation</code> wraps objects so they may be used in hashmaps
+ * based on their object identity rather than equals implementation. Used for keys.
+ * 
+ * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
+ * @version $Rev$
+ */
+final class KeyConnectionAssociation
+{
+   //key
+   private final Object metaAwareObject;
+
+   //map of cm to list of connections for that cm.
+   private Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap;
+
+   /**
+    * Creates a new instance.
+    * @param metaAwareObject meta aware object
+    */
+   KeyConnectionAssociation(final Object metaAwareObject)
+   {
+      this.metaAwareObject = metaAwareObject;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean equals(Object other)
+   {
+      return (other instanceof KeyConnectionAssociation) && 
+            this.metaAwareObject == ((KeyConnectionAssociation) other).metaAwareObject;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return Strings.defaultToString(this.metaAwareObject);
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   public int hashCode()
+   {
+      return System.identityHashCode(this.metaAwareObject);
+   }
+
+   /**
+    * Set map instance.
+    * @param cmToConnectionsMap connection manager to connections
+    */
+   public void setCMToConnectionsMap(Map<ConnectionCacheListener, Collection<ConnectionRecord>> cmToConnectionsMap)
+   {
+      this.cmToConnectionsMap = cmToConnectionsMap;
+   }
+
+   /**
+    * 
+    * @return map instance
+    */
+   public Map<ConnectionCacheListener, Collection<ConnectionRecord>> getCMToConnectionsMap()
+   {
+      if (cmToConnectionsMap == null)
+      {
+         cmToConnectionsMap = new HashMap<ConnectionCacheListener, Collection<ConnectionRecord>>();
+      }
+      
+      return cmToConnectionsMap;
+   }
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/package.html
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/package.html	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ccm/package.html	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,3 @@
+<body>
+This package contains the cached connection manager.
+</body>

Modified: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -22,7 +22,7 @@
 package org.jboss.jca.core.connectionmanager.listener;
 
 import org.jboss.jca.core.connectionmanager.AbstractConnectionManager;
-import org.jboss.jca.core.connectionmanager.CachedConnectionManager;
+import org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManager;
 import org.jboss.jca.core.connectionmanager.pool.api.ManagedConnectionPool;
 
 import java.util.Iterator;

Modified: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -23,7 +23,6 @@
 package org.jboss.jca.core.connectionmanager.pool;
 
 import org.jboss.jca.common.JBossResourceException;
-import org.jboss.jca.core.connectionmanager.exception.RetryableResourceException;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListenerFactory;
 import org.jboss.jca.core.connectionmanager.pool.api.ManagedConnectionPool;
@@ -35,6 +34,7 @@
 import javax.resource.ResourceException;
 import javax.resource.spi.ConnectionRequestInfo;
 import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.RetryableException;
 import javax.security.auth.Subject;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
@@ -279,31 +279,32 @@
          return cl;
 
       }
-      catch (RetryableResourceException e)
+      catch (ResourceException re)
       {
-         if (log.isDebugEnabled())
+         if (re instanceof RetryableException)
          {
-            log.debug("Got a RetryableResourceException - trying to reinitialize the pool");  
-         }
+            if (log.isDebugEnabled())
+               log.debug("Got a RetryableException - trying to reinitialize the pool");  
 
-         // The IMCP is down - retry
-         imcp = subPoolContext.getSubPool();
+            // The IMCP is down - retry
+            imcp = subPoolContext.getSubPool();
 
-         // Make sure that IMCP is running
-         if (!imcp.isRunning())
-         {
-            imcp.initialize();  
+            // Make sure that IMCP is running
+            if (!imcp.isRunning())
+               imcp.initialize();  
+         
+            //Getting connection from pool
+            cl = imcp.getConnection(subject, cri);
+            if (trace)
+               dump("Got connection from pool (retried) " + cl);  
+
+            return cl;
          }
-         
-         //Getting connection from pool
-         cl = imcp.getConnection(subject, cri);
-         if (trace)
+         else
          {
-            dump("Got connection from pool (retried) " + cl);  
+            throw re;
          }
-
-         return cl;            
-      } //end of catch
+      }
       
    }
    

Modified: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/InternalManagedConnectionPool.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/InternalManagedConnectionPool.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/InternalManagedConnectionPool.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -23,13 +23,12 @@
 package org.jboss.jca.core.connectionmanager.pool;
 
 import org.jboss.jca.common.JBossResourceException;
-import org.jboss.jca.core.connectionmanager.ConnectionValidator;
-import org.jboss.jca.core.connectionmanager.IdleConnectionRemovalSupport;
-import org.jboss.jca.core.connectionmanager.IdleRemover;
-import org.jboss.jca.core.connectionmanager.exception.RetryableResourceException;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListenerFactory;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionState;
+import org.jboss.jca.core.connectionmanager.pool.idle.IdleConnectionRemovalSupport;
+import org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover;
+import org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -46,6 +45,7 @@
 import javax.resource.spi.ConnectionRequestInfo;
 import javax.resource.spi.ManagedConnection;
 import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.RetryableUnavailableException;
 import javax.resource.spi.ValidatingManagedConnectionFactory;
 import javax.security.auth.Subject;
 
@@ -185,7 +185,7 @@
                if (this.shutdown.get())
                {
                   permits.release();
-                  throw new RetryableResourceException("The pool has been shut down");
+                  throw new RetryableUnavailableException("The pool has been shut down");
                }
                
                if (cls.size() > 0)

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+/**
+ * A IdleConnectionRemovalSupport specified contract for a pool that is able
+ * to remove an idle connection.
+ * 
+ * @author gurkanerdogdu
+ * @author <a href="weston.price at jboss.com">Weston Price</a>
+ * @version $Revision$
+ */
+public interface IdleConnectionRemovalSupport
+{
+   /**
+    * Pool removes idle connections.
+    */
+   public void removeIdleConnections();
+   
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Connection validator class.
+ * 
+ * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public class IdleRemover
+{
+   /**Logger instance*/
+   private static Logger logger = Logger.getLogger(IdleRemover.class);
+   
+   /**Validator thread name*/
+   private static final String VALIDATOR_THREAD_NAME = "JBossConnectionValidator";
+   
+   /**Singleton instance*/
+   private static final IdleRemover INSTANCE = new IdleRemover();
+   
+   /**Registered internal pool instances*/
+   private CopyOnWriteArrayList<IdleConnectionRemovalSupport> registeredPools = 
+      new CopyOnWriteArrayList<IdleConnectionRemovalSupport>();
+   
+   /**Validator executor service*/
+   private ExecutorService executorService = null;
+   
+   /** The interval */
+   private long interval = Long.MAX_VALUE;
+
+   /** The next - important initialization! */
+   private long next = Long.MAX_VALUE;
+   
+   /**Lock for condition*/
+   private Lock lock = new ReentrantLock();
+   
+   /**Condition*/
+   private Condition condition = lock.newCondition();
+   
+   /**
+    * Private constructor.
+    */
+   private IdleRemover()
+   {
+      this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory());
+      this.executorService.execute(new JBossConnectionValidator());
+   }
+   
+   /**
+    * Register pool for connection validation.
+    * @param mcp managed connection pool
+    * @param interval validation interval
+    */
+   public static void registerPool(IdleConnectionRemovalSupport mcp, long interval)
+   {
+      INSTANCE.internalRegisterPool(mcp, interval);
+   }
+   
+   /**
+    * Unregister pool instance for connection validation.
+    * @param mcp pool instance
+    */
+   public static void unregisterPool(IdleConnectionRemovalSupport mcp)
+   {
+      INSTANCE.internalUnregisterPool(mcp);
+   }
+   
+   private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval)
+   {
+      try
+      {
+         this.lock.lock();
+         
+         this.registeredPools.addIfAbsent(mcp);
+         
+         if (interval > 1 && interval / 2 < this.interval) 
+         {
+            this.interval = interval / 2;
+            long maybeNext = System.currentTimeMillis() + this.interval;
+            if (next > maybeNext && maybeNext > 0) 
+            {
+               next = maybeNext;
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("internalRegisterPool: about to notify thread: old next: " +
+                        next + ", new next: " + maybeNext);  
+               }               
+               
+               this.condition.signal();
+               
+            }
+         }         
+      } 
+      finally
+      {
+         this.lock.unlock();
+      }
+   }
+   
+   private void internalUnregisterPool(IdleConnectionRemovalSupport mcp)
+   {
+      this.registeredPools.remove(mcp);
+      
+      if (this.registeredPools.size() == 0) 
+      {
+         if (logger.isDebugEnabled())
+         {
+            logger.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE");  
+         }
+         
+         interval = Long.MAX_VALUE;
+      }
+   }
+         
+   /**
+    * Wait for background thread.
+    */
+   public static void waitForBackgroundThread()
+   {
+      try
+      {
+         INSTANCE.lock.lock();
+         
+      }
+      finally
+      {
+         INSTANCE.lock.unlock();  
+      }
+   }
+   
+   /**
+    * Thread factory.
+    */
+   private static class ValidatorThreadFactory implements ThreadFactory
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public Thread newThread(Runnable r)
+      {
+         Thread thread = new Thread(r, IdleRemover.VALIDATOR_THREAD_NAME);
+         thread.setDaemon(true);
+         
+         return thread;
+      }      
+   }
+   
+   /**
+    * JBossConnectionValidator.
+    *
+    */
+   private class JBossConnectionValidator implements Runnable
+   {
+      /**
+       * Constructor
+       */
+      public JBossConnectionValidator()
+      {
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void run()
+      {
+         SecurityActions.setThreadContextClassLoader(IdleRemover.class.getClassLoader());
+         
+         try
+         {
+            lock.lock();
+            
+            while (true)
+            {
+               boolean result = INSTANCE.condition.await(INSTANCE.interval, TimeUnit.MILLISECONDS);
+
+               if (logger.isTraceEnabled())
+               {
+                  logger.trace("Result of await ConnectionValidator: " + result);
+               }
+
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("run: ConnectionValidator notifying pools, interval: " + interval);  
+               }
+     
+               for (IdleConnectionRemovalSupport mcp : registeredPools)
+               {
+                  mcp.removeIdleConnections();
+               }
+
+               next = System.currentTimeMillis() + interval;
+               
+               if (next < 0)
+               {
+                  next = Long.MAX_VALUE;  
+               }              
+            }            
+         }
+         catch (InterruptedException e)
+         {
+            logger.info("run: ConnectionValidator has been interrupted, returning");
+            
+            return;  
+         }
+         catch (RuntimeException e)
+         {
+            logger.warn("run: ConnectionValidator ignored unexpected runtime exception", e);
+         }
+         catch (Exception e)
+         {
+            logger.warn("run: ConnectionValidator ignored unexpected error", e);
+         }         
+         finally
+         {
+            lock.unlock();  
+         }         
+      }      
+   }
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+class SecurityActions
+{
+   /**
+    * Set the context classloader.
+    * @param cl classloader
+    */
+   public static void setThreadContextClassLoader(final ClassLoader cl)
+   {
+      if (cl == null)
+         return;
+
+      if (System.getSecurityManager() == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+      }
+      else
+      {
+         AccessController.doPrivileged(new PrivilegedAction<Object>()
+         {
+            public Object run()
+            {
+               Thread.currentThread().setContextClassLoader(cl);
+
+               return null;
+            }
+         });
+      }
+   }
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/package.html
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/package.html	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/idle/package.html	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,3 @@
+<body>
+This package contains the infrastructure for removing idle connections.
+</body>

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java (from rev 106765, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/ConnectionValidator.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,299 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.validator;
+
+import org.jboss.jca.core.connectionmanager.pool.InternalManagedConnectionPool;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Connection validator class.
+ * 
+ * @author <a href="mailto:gurkanerdogdu at yahoo.com">Gurkan Erdogdu</a>
+ * @version $Rev: $
+ */
+public class ConnectionValidator
+{
+   /**Logger instance*/
+   private static Logger logger = Logger.getLogger(ConnectionValidator.class);
+   
+   /**Validator thread name*/
+   private static final String VALIDATOR_THREAD_NAME = "JBossConnectionValidator";
+   
+   /**Registered internal pool instances*/
+   private CopyOnWriteArrayList<InternalManagedConnectionPool> registeredPools = 
+      new CopyOnWriteArrayList<InternalManagedConnectionPool>();
+   
+   /**Validator executor service*/
+   private ExecutorService executorService = null;
+   
+   /**Singleton instance*/
+   private static ConnectionValidator instance = new ConnectionValidator();
+   
+   /** The interval */
+   private long interval = Long.MAX_VALUE;
+
+   /** The next */
+ //important initialization!
+   private long next = Long.MAX_VALUE;
+   
+   /**Lock for condition*/
+   private Lock lock = new ReentrantLock();
+   
+   /**Condition*/
+   private Condition condition = lock.newCondition();
+   
+   
+   /**
+    * Private constructor.
+    */
+   private ConnectionValidator()
+   {
+      this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory());
+      this.executorService.execute(new JBossConnectionValidator());
+   }
+   
+   /**
+    * Register pool for connection validation.
+    * @param mcp managed connection pool
+    * @param interval validation interval
+    */
+   public static void registerPool(InternalManagedConnectionPool mcp, long interval)
+   {
+      instance.internalRegisterPool(mcp, interval);
+   }
+   
+   /**
+    * Unregister pool instance for connection validation.
+    * @param mcp pool instance
+    */
+   public static void unregisterPool(InternalManagedConnectionPool mcp)
+   {
+      instance.internalUnregisterPool(mcp);
+   }
+   
+   private void internalRegisterPool(InternalManagedConnectionPool mcp, long interval)
+   {
+      try
+      {
+         this.lock.lock();
+         
+         this.registeredPools.addIfAbsent(mcp);
+         
+         if (interval > 1 && interval / 2 < this.interval) 
+         {
+            this.interval = interval / 2;
+            long maybeNext = System.currentTimeMillis() + this.interval;
+            if (next > maybeNext && maybeNext > 0) 
+            {
+               next = maybeNext;
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("internalRegisterPool: about to notify thread: old next: " +
+                        next + ", new next: " + maybeNext);  
+               }               
+               
+               this.condition.signal();
+               
+            }
+         }
+         
+      } 
+      finally
+      {
+         this.lock.unlock();
+      }
+   }
+   
+   private void internalUnregisterPool(InternalManagedConnectionPool mcp)
+   {
+      this.registeredPools.remove(mcp);
+      
+      if (this.registeredPools.size() == 0) 
+      {
+         if (logger.isDebugEnabled())
+         {
+            logger.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE");  
+         }
+         
+         interval = Long.MAX_VALUE;
+      }
+   }
+   
+   /**
+    * Setup context class loader.
+    */
+   private void setupContextClassLoader()
+   {
+      // Could be null if loaded from system classloader
+      final ClassLoader cl = ConnectionValidator.class.getClassLoader();
+      if (cl == null)
+      {
+         return;  
+      }
+      
+      SecurityManager sm = System.getSecurityManager();
+      
+      if (sm == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+         
+         return;
+      }
+      
+      AccessController.doPrivileged(new ClassLoaderAction(cl));
+ 
+   }
+   
+   /**
+    * Priviledge action. 
+    */
+   private static class ClassLoaderAction implements PrivilegedAction<Object>
+   {
+      private ClassLoader classLoader;
+      
+      public ClassLoaderAction(ClassLoader cl)
+      {
+         this.classLoader = cl;
+      }
+      
+      public Object run()
+      {
+         Thread.currentThread().setContextClassLoader(classLoader);
+         
+         return null;
+      }
+      
+   }
+   
+   /**
+    * Wait for background thread.
+    */
+   public static void waitForBackgroundThread()
+   {
+      try
+      {
+         instance.lock.lock();
+         
+      }
+      finally
+      {
+         instance.lock.unlock();  
+      }
+   }
+   
+   
+   /**
+    * Thread factory.
+    */
+   private static class ValidatorThreadFactory implements ThreadFactory
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public Thread newThread(Runnable r)
+      {
+         Thread thread = new Thread(r, ConnectionValidator.VALIDATOR_THREAD_NAME);
+         thread.setDaemon(true);
+         
+         return thread;
+      }      
+   }
+   
+   /**
+    * JBossConnectionValidator.
+    *
+    */
+   private class JBossConnectionValidator implements Runnable
+   {
+      
+      /**
+       * {@inheritDoc}
+       */
+      public void run()
+      {
+         setupContextClassLoader();
+         
+         try
+         {
+            lock.lock();
+            
+            while (true)
+            {
+               boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS);
+               
+               if (logger.isTraceEnabled())
+               {
+                  logger.trace("Result of await ConnectionValidator: " + result);
+               }
+               
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("run: ConnectionValidator notifying pools, interval: " + interval);  
+               }
+     
+               for (InternalManagedConnectionPool mcp : registeredPools)
+               {
+                  mcp.validateConnections();
+               }
+
+               next = System.currentTimeMillis() + interval;
+               
+               if (next < 0)
+               {
+                  next = Long.MAX_VALUE;  
+               }              
+            }            
+         }
+         catch (InterruptedException e)
+         {
+            logger.info("run: ConnectionValidator has been interrupted, returning");
+            
+            return;  
+         }
+         catch (RuntimeException e)
+         {
+            logger.warn("run: ConnectionValidator ignored unexpected runtime exception", e);
+         }
+         catch (Exception e)
+         {
+            logger.warn("run: ConnectionValidator ignored unexpected error", e);
+         }         
+         finally
+         {
+            lock.unlock();  
+         }         
+      }      
+   }
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/package.html
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/package.html	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/pool/validator/package.html	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,3 @@
+<body>
+This package contains the connection validator logic.
+</body>

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAException.java (from rev 106765, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/exception/JBossLocalXAException.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAException.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAException.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,173 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.xa;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import javax.transaction.xa.XAException;
+
+import org.jboss.util.NestedThrowable;
+
+/**
+ * JBossLocalXAException
+ *
+ * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class JBossLocalXAException extends XAException implements NestedThrowable
+{
+   /**Serial version UID*/
+   private static final long serialVersionUID = -6208145503935506281L;
+   
+   /**Cause*/
+   private final Throwable t;
+
+   /**
+    * Creates a new instance.
+    */
+   public JBossLocalXAException()
+   {
+      super();
+      t = null;
+   }
+
+   /**
+    * Creates a new instance.
+    * @param errcode error code
+    */   
+   public JBossLocalXAException(int errcode)
+   {
+      super(errcode);
+      t = null;
+   }
+
+   /**
+    * Creates a new instance.
+    * @param message message
+    */   
+   public JBossLocalXAException(String message)
+   {
+      super(message);
+      t = null;
+   }
+
+   /**
+    * Creates a new instance.
+    * @param message message
+    * @param errorcode error code
+    */   
+   public JBossLocalXAException(String message, int errorcode)
+   {
+      super(message);
+      this.errorCode = errorcode;
+      t = null;
+   }
+
+   /**
+    * Creates a new instance.
+    * @param message message
+    * @param t cause
+    */
+   public JBossLocalXAException(String message, Throwable t)
+   {
+      super(message);
+      this.t = t;
+   }
+
+   /**
+    * Creates a new instance.
+    * @param message message
+    * @param t cause
+    * @param errorcode error code
+    */   
+   public JBossLocalXAException(String message, int errorcode, Throwable t)
+   {
+      super(message);
+      this.errorCode = errorcode;
+      this.t = t;
+   }
+
+   // Implementation of org.jboss.util.NestedThrowable
+
+   /**
+    * {@inheritDoc}
+    */
+   public Throwable getNested()
+   {
+      return t;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Throwable getCause()
+   {
+      return t;
+   }
+
+   /**
+    * Returns the composite throwable message.
+    *
+    * @return  The composite throwable message.
+    */
+   public String getMessage()
+   {
+      return NestedThrowable.Util.getMessage(super.getMessage(), t);
+   }
+
+   /**
+    * Prints the composite message and the embedded stack trace to the
+    * specified print stream.
+    *
+    * @param stream  Stream to print to.
+    */
+   public void printStackTrace(final PrintStream stream)
+   {
+      if (t == null || NestedThrowable.PARENT_TRACE_ENABLED)
+         super.printStackTrace(stream);
+      NestedThrowable.Util.print(t, stream);
+   }
+
+   /**
+    * Prints the composite message and the embedded stack trace to the
+    * specified print writer.
+    *
+    * @param writer  Writer to print to.
+    */
+   public void printStackTrace(final PrintWriter writer)
+   {
+      if (t == null || NestedThrowable.PARENT_TRACE_ENABLED)
+         super.printStackTrace(writer);
+      NestedThrowable.Util.print(t, writer);
+   }
+
+   /**
+    * Prints the composite message and the embedded stack trace to
+    * <tt>System.err</tt>.
+    */
+   public void printStackTrace()
+   {
+      printStackTrace(System.err);
+   }
+}

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAExceptionFormatter.java (from rev 106765, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/exception/JBossLocalXAExceptionFormatter.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAExceptionFormatter.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/JBossLocalXAExceptionFormatter.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.xa;
+
+import javax.transaction.xa.XAException;
+
+import org.jboss.logging.Logger;
+import org.jboss.tm.XAExceptionFormatter;
+
+/**
+ * JBossLocalXAExceptionFormatter.java
+ *
+ * @author <a href="mailto:igorfie at yahoo dot com">Igor Fedorenko</a>.
+ * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+
+public class JBossLocalXAExceptionFormatter implements XAExceptionFormatter
+{
+
+   /**
+    * Creates a new formatter.
+    */
+   public JBossLocalXAExceptionFormatter()
+   {
+      
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   public void formatXAException(XAException xae, Logger log)
+   {
+      if (xae instanceof JBossLocalXAException)
+      {
+         log.warn("JBoss Local XA wrapper error: ", ((JBossLocalXAException) xae).getCause());   
+      }
+      else
+      {
+         log.warn("Problem trying to format XAException: ", xae);     
+      }
+   }
+}

Modified: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/LocalXAResource.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/LocalXAResource.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/LocalXAResource.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -22,7 +22,6 @@
 package org.jboss.jca.core.connectionmanager.xa;
 
 import org.jboss.jca.core.connectionmanager.AbstractConnectionManager;
-import org.jboss.jca.core.connectionmanager.exception.JBossLocalXAException;
 import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
 
 import javax.resource.ResourceException;

Modified: projects/jboss-jca/trunk/core/src/test/java/org/jboss/jca/core/connectionmanager/unit/AbstractConnectionManagerTestCase.java
===================================================================
--- projects/jboss-jca/trunk/core/src/test/java/org/jboss/jca/core/connectionmanager/unit/AbstractConnectionManagerTestCase.java	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/test/java/org/jboss/jca/core/connectionmanager/unit/AbstractConnectionManagerTestCase.java	2010-07-15 21:04:07 UTC (rev 106768)
@@ -22,7 +22,7 @@
 package org.jboss.jca.core.connectionmanager.unit;
 
 import org.jboss.jca.core.connectionmanager.AbstractConnectionManager;
-import org.jboss.jca.core.connectionmanager.CachedConnectionManager;
+import org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManager;
 import org.jboss.jca.core.connectionmanager.common.MockConnectionManager;
 import org.jboss.jca.core.connectionmanager.common.MockManagedConnectionFactory;
 import org.jboss.jca.core.connectionmanager.pool.strategy.OnePool;

Modified: projects/jboss-jca/trunk/core/src/test/resources/connectionmanager-jboss-beans.xml
===================================================================
--- projects/jboss-jca/trunk/core/src/test/resources/connectionmanager-jboss-beans.xml	2010-07-15 19:43:40 UTC (rev 106767)
+++ projects/jboss-jca/trunk/core/src/test/resources/connectionmanager-jboss-beans.xml	2010-07-15 21:04:07 UTC (rev 106768)
@@ -15,7 +15,7 @@
   </bean>
   
   <bean name="CachedConnectionManager" 
-        class="org.jboss.jca.core.connectionmanager.CachedConnectionManager">
+        class="org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManager">
   </bean>
 
 </deployment>



More information about the jboss-cvs-commits mailing list