[dna-commits] DNA SVN: r394 - in trunk: connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor and 15 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Wed Aug 6 15:38:47 EDT 2008


Author: rhauch
Date: 2008-08-06 15:38:46 -0400 (Wed, 06 Aug 2008)
New Revision: 394

Added:
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceRegistry.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperation.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperations.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java
Removed:
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/ManagedRepositoryConnectionFactory.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactories.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactory.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperation.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperations.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/
Modified:
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepository.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConfig.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConnection.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/Projection.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java
   trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/SingleProjectionCommandExecutor.java
   trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryConnectionTest.java
   trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceTest.java
   trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryTest.java
   trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionPathRuleTest.java
   trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionTest.java
   trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java
   trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java
   trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
   trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
   trunk/connectors/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectionTest.java
   trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
   trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositorySourceManager.java
   trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/BasicJcrExecutionContext.java
   trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/DelegatingCommandExecutor.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/LoggingCommandExecutor.java
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/NoOpCommandExecutor.java
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java
Log:
DNA-192 - Clean up the repository connector SPI
http://jira.jboss.com/jira/browse/DNA-192

Renamed the "org.jboss.dna.spi.graph.connection" package to "org.jboss.dna.spi.connector", and removed the notion of a RepositoryConnectionFactory and a ManagedRepositoryConnectionFactory.  Instead, RepositorySource now defines all of the methods previously inherited, and RepositoryConnectionPool no longer inherits any interfaces and defines its own ConnectionFactory interface that only it uses.  RepositoryConnectionFactories was renamed to RepositorySourceRegistry, and its single method was changed to use RepositorySource rather than a RepositoryConnectionFactory.  AbstractRepositorySource now properly implements Serializable methods to rebuild the pool upon deserialization.  Several of the RepositoryOperation interfaces were moved to the test source, since they're only used in the test harness.

Numerous files were touched because of the package and class renaming/refactoring.

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepository.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepository.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepository.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -31,11 +31,11 @@
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.connector.federation.executor.FederatingCommandExecutor;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 
 /**
  * The component that represents a single federated repository. The federated repository uses a set of {@link RepositorySource
@@ -48,7 +48,7 @@
 public class FederatedRepository {
 
     private final ExecutionContext context;
-    private final RepositoryConnectionFactories connectionFactories;
+    private final RepositorySourceRegistry sources;
     private FederatedRepositoryConfig config;
     private final AtomicInteger openExecutors = new AtomicInteger(0);
     private final CountDownLatch shutdownLatch = new CountDownLatch(1);
@@ -59,18 +59,18 @@
      * Create a federated repository instance.
      * 
      * @param context the execution context
-     * @param connectionFactories the set of connection factories that should be used
+     * @param sources the registry of {@link RepositorySource} instances that should be used
      * @param config the configuration for this repository
      * @throws IllegalArgumentException if any of the parameters are null, or if the name is blank
      */
     public FederatedRepository( ExecutionContext context,
-                                RepositoryConnectionFactories connectionFactories,
+                                RepositorySourceRegistry sources,
                                 FederatedRepositoryConfig config ) {
-        ArgCheck.isNotNull(connectionFactories, "connectionFactories");
+        ArgCheck.isNotNull(sources, "sources");
         ArgCheck.isNotNull(context, "context");
         ArgCheck.isNotNull(config, "config");
         this.context = context;
-        this.connectionFactories = connectionFactories;
+        this.sources = sources;
         this.config = config;
     }
 
@@ -91,10 +91,10 @@
     }
 
     /**
-     * @return connectionFactories
+     * @return the sources
      */
-    protected RepositoryConnectionFactories getConnectionFactories() {
-        return connectionFactories;
+    protected RepositorySourceRegistry getRepositorySourceRegistry() {
+        return sources;
     }
 
     /**
@@ -232,7 +232,7 @@
                                            String sourceName ) {
         FederatedRepositoryConfig config = this.getConfiguration();
         return new FederatingCommandExecutor(context, sourceName, config.getCacheProjection(), config.getDefaultCachePolicy(),
-                                             config.getSourceProjections(), getConnectionFactories());
+                                             config.getSourceProjections(), getRepositorySourceRegistry());
     }
 
     /**

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConfig.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConfig.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConfig.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -30,7 +30,7 @@
 import org.jboss.dna.common.collection.ThreadSafeProblems;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySource;
 
 /**
  * The configuration of a federated repository. The configuration defines, among other things, the set of

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConnection.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConnection.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositoryConnection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -27,11 +27,11 @@
 import net.jcip.annotations.ThreadSafe;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
 import org.jboss.dna.spi.graph.commands.GraphCommand;
 import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 
 /**
  * @author Randall Hauch

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -52,6 +52,12 @@
 import org.jboss.dna.spi.ExecutionContextFactory;
 import org.jboss.dna.spi.cache.BasicCachePolicy;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.AbstractRepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceCapabilities;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 import org.jboss.dna.spi.graph.InvalidPathException;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.NameFactory;
@@ -67,12 +73,6 @@
 import org.jboss.dna.spi.graph.commands.impl.BasicCompositeCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetChildrenCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetNodeCommand;
-import org.jboss.dna.spi.graph.connection.AbstractRepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositorySourceCapabilities;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch
@@ -92,7 +92,7 @@
     protected static final String PASSWORD = "password";
     protected static final String CONFIGURATION_SOURCE_NAME = "configurationSourceName";
     protected static final String CONFIGURATION_SOURCE_PROJECTION_RULES = "configurationSourceProjectionRules";
-    protected static final String CONNECTION_FACTORIES_JNDI_NAME = "connectionFactoriesJndiName";
+    protected static final String REPOSITORY_SOURCE_REGISTRY_JNDI_NAME = "repositorySourceRegistryJndiName";
     protected static final String EXECUTION_CONTEXT_FACTORY_JNDI_NAME = "executionContextFacotryJndiName";
     protected static final String REPOSITORY_JNDI_NAME = "repositoryJndiName";
     protected static final String SECURITY_DOMAIN = "securityDomain";
@@ -107,7 +107,7 @@
     private String password;
     private String configurationSourceName;
     private String[] configurationSourceProjectionRules = DEFAULT_CONFIGURATION_SOURCE_PROJECTION_RULES;
-    private String connectionFactoriesJndiName;
+    private String repositorySourceRegistryJndiName;
     private String executionContextFactoryJndiName;
     private String securityDomain;
     private String repositoryJndiName;
@@ -149,7 +149,7 @@
      * 
      * @param sourceName the name of this repository source
      * @see #setConfigurationSourceName(String)
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setPassword(String)
      * @see #setUsername(String)
@@ -219,8 +219,8 @@
 
     /**
      * Get the name of a {@link RepositorySource} instance that should be used by the {@link FederatedRepository federated
-     * repository} as the configuration repository. The instance will be retrieved from the {@link RepositoryConnectionFactories}
-     * instance {@link #getConnectionFactoriesJndiName() found in JDNI}.
+     * repository} as the configuration repository. The instance will be retrieved from the {@link RepositorySourceRegistry}
+     * instance {@link #getRepositorySourceRegistryJndiName() found in JDNI}.
      * <p>
      * This is a required property (unless the {@link #getRepositoryJndiName() federated repository is to be found in JDNI}).
      * </p>
@@ -228,7 +228,7 @@
      * @param sourceName the name of the {@link RepositorySource} instance that should be used for the configuration, or null if
      *        the federated repository instance is to be found in JNDI
      * @see #getConfigurationSourceName()
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setPassword(String)
      * @see #setUsername(String)
@@ -270,7 +270,7 @@
      * @param projectionRules the string array of projection rules, or null if the projection rules haven't yet been set or if the
      *        federated repository instance is to be found in JNDI
      * @see #setConfigurationSourceProjectionRules(String[])
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setConfigurationSourceName(String)
      * @see #setPassword(String)
      * @see #setUsername(String)
@@ -316,7 +316,7 @@
      * @see #getExecutionContextFactoryJndiName()
      * @see #setConfigurationSourceName(String)
      * @see #setConfigurationSourceProjectionRules(String[])
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setPassword(String)
      * @see #setUsername(String)
      * @see #setRepositoryName(String)
@@ -329,32 +329,32 @@
     }
 
     /**
-     * Get the name in JNDI where the {@link RepositoryConnectionFactories} instance that can be used by the
+     * Get the name in JNDI where the {@link RepositorySourceRegistry} instance that can be used by the
      * {@link FederatedRepository federated repository} can find any {@link RepositorySource} sources it needs, including those
      * used for {@link Projection sources} and that used for it's {@link #getConfigurationSourceName() configuration}.
      * <p>
      * This is a required property (unless the {@link #getRepositoryJndiName() federated repository is to be found in JDNI}).
      * </p>
      * 
-     * @return the JNDI name where the {@link RepositoryConnectionFactories} instance can be found, or null if the federated
-     *         repository instance is to be found in JNDI
-     * @see #setConnectionFactoriesJndiName(String)
+     * @return the JNDI name where the {@link RepositorySourceRegistry} instance can be found, or null if the federated repository
+     *         instance is to be found in JNDI
+     * @see #setRepositorySourceRegistryJndiName(String)
      */
-    public String getConnectionFactoriesJndiName() {
-        return connectionFactoriesJndiName;
+    public String getRepositorySourceRegistryJndiName() {
+        return repositorySourceRegistryJndiName;
     }
 
     /**
-     * Set the name in JNDI where the {@link RepositoryConnectionFactories} instance that can be used by the
+     * Set the name in JNDI where the {@link RepositorySourceRegistry} instance that can be used by the
      * {@link FederatedRepository federated repository} can find any {@link RepositorySource} sources it needs, including those
      * used for {@link Projection sources} and that used for it's {@link #getConfigurationSourceName() configuration}.
      * <p>
      * This is a required property (unless the {@link #getRepositoryJndiName() federated repository is to be found in JDNI}).
      * </p>
      * 
-     * @param jndiName the JNDI name where the {@link RepositoryConnectionFactories} instance can be found, or null if the
-     *        federated repository instance is to be found in JNDI
-     * @see #getConnectionFactoriesJndiName()
+     * @param jndiName the JNDI name where the {@link RepositorySourceRegistry} instance can be found, or null if the federated
+     *        repository instance is to be found in JNDI
+     * @see #getRepositorySourceRegistryJndiName()
      * @see #setConfigurationSourceName(String)
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setPassword(String)
@@ -363,10 +363,10 @@
      * @see #setExecutionContextFactoryJndiName(String)
      * @see #setName(String)
      */
-    public synchronized void setConnectionFactoriesJndiName( String jndiName ) {
-        if (this.connectionFactoriesJndiName == jndiName || this.connectionFactoriesJndiName != null
-            && this.connectionFactoriesJndiName.equals(jndiName)) return; // unchanged
-        this.connectionFactoriesJndiName = jndiName;
+    public synchronized void setRepositorySourceRegistryJndiName( String jndiName ) {
+        if (this.repositorySourceRegistryJndiName == jndiName || this.repositorySourceRegistryJndiName != null
+            && this.repositorySourceRegistryJndiName.equals(jndiName)) return; // unchanged
+        this.repositorySourceRegistryJndiName = jndiName;
         changeRepositoryConfig();
     }
 
@@ -418,7 +418,7 @@
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setPassword(String)
      * @see #setUsername(String)
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setExecutionContextFactoryJndiName(String)
      * @see #setName(String)
      */
@@ -455,7 +455,7 @@
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setPassword(String)
      * @see #setRepositoryName(String)
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setExecutionContextFactoryJndiName(String)
      * @see #setName(String)
      */
@@ -490,7 +490,7 @@
      * @see #setConfigurationSourceProjectionRules(String[])
      * @see #setUsername(String)
      * @see #setRepositoryName(String)
-     * @see #setConnectionFactoriesJndiName(String)
+     * @see #setRepositorySourceRegistryJndiName(String)
      * @see #setExecutionContextFactoryJndiName(String)
      * @see #setName(String)
      */
@@ -503,16 +503,16 @@
     /**
      * This method is called to signal that some aspect of the configuration has changed. If a {@link #getRepository() repository}
      * instance has been created, it's configuration is
-     * {@link #getRepositoryConfiguration(ExecutionContext, RepositoryConnectionFactories) rebuilt} and updated. Nothing is done,
+     * {@link #getRepositoryConfiguration(ExecutionContext, RepositorySourceRegistry) rebuilt} and updated. Nothing is done,
      * however, if there is currently no {@link #getRepository() repository}.
      */
     protected synchronized void changeRepositoryConfig() {
         if (this.repository != null) {
-            // Find in JNDI the repository connection factories and the environment ...
+            // Find in JNDI the repository source registry and the environment ...
             ExecutionContext context = getExecutionContext();
-            RepositoryConnectionFactories factories = getRepositoryConnectionFactories();
+            RepositorySourceRegistry registry = getRepositorySourceRegistry();
             // Compute a new repository config and set it on the repository ...
-            FederatedRepositoryConfig newConfig = getRepositoryConfiguration(context, factories);
+            FederatedRepositoryConfig newConfig = getRepositoryConfiguration(context, registry);
             this.repository.setConfiguration(newConfig);
         }
     }
@@ -520,7 +520,7 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.AbstractRepositorySource#createConnection()
+     * @see org.jboss.dna.spi.connector.AbstractRepositorySource#createConnection()
      */
     @Override
     protected synchronized RepositoryConnection createConnection() throws RepositorySourceException {
@@ -533,8 +533,8 @@
         if (getSecurityDomain() == null) {
             throw new RepositorySourceException(FederationI18n.propertyIsRequired.text("security domain"));
         }
-        if (getConnectionFactoriesJndiName() == null) {
-            throw new RepositorySourceException(FederationI18n.propertyIsRequired.text("connection factories JNDI name"));
+        if (getRepositorySourceRegistryJndiName() == null) {
+            throw new RepositorySourceException(FederationI18n.propertyIsRequired.text("repository source registry JNDI name"));
         }
         // Find the repository ...
         FederatedRepository repository = getRepository();
@@ -555,7 +555,7 @@
      * <ol>
      * <li>If a {@link FederatedRepository} already was obtained from a prior call, the same instance is returned.</li>
      * <li>A {@link FederatedRepository} is created using a {@link FederatedRepositoryConfig} is created from this instance's
-     * properties and {@link ExecutionContext} and {@link RepositoryConnectionFactories} instances obtained from JNDI.</li>
+     * properties and {@link ExecutionContext} and {@link RepositorySourceRegistry} instances obtained from JNDI.</li>
      * <li></li>
      * <li></li>
      * </ol>
@@ -579,12 +579,12 @@
             }
 
             if (repository == null) {
-                // Find in JNDI the repository connection factories and the environment ...
+                // Find in JNDI the repository source registry and the environment ...
                 ExecutionContext context = getExecutionContext();
-                RepositoryConnectionFactories factories = getRepositoryConnectionFactories();
+                RepositorySourceRegistry registry = getRepositorySourceRegistry();
                 // And create the configuration and the repository ...
-                FederatedRepositoryConfig config = getRepositoryConfiguration(context, factories);
-                repository = new FederatedRepository(context, factories, config);
+                FederatedRepositoryConfig config = getRepositoryConfiguration(context, registry);
+                repository = new FederatedRepository(context, registry, config);
             }
         }
         return repository;
@@ -617,14 +617,14 @@
         }
     }
 
-    protected RepositoryConnectionFactories getRepositoryConnectionFactories() {
-        RepositoryConnectionFactories factories = null;
+    protected RepositorySourceRegistry getRepositorySourceRegistry() {
+        RepositorySourceRegistry factories = null;
         Context context = getContext();
-        String jndiName = getConnectionFactoriesJndiName();
+        String jndiName = getRepositorySourceRegistryJndiName();
         if (jndiName != null && jndiName.trim().length() != 0) {
             try {
                 if (context == null) context = new InitialContext();
-                factories = (RepositoryConnectionFactories)context.lookup(jndiName);
+                factories = (RepositorySourceRegistry)context.lookup(jndiName);
             } catch (Throwable err) {
                 I18n msg = FederationI18n.unableToFindRepositoryConnectionFactoriesInJndi;
                 throw new RepositorySourceException(msg.text(this.sourceName, jndiName), err);
@@ -667,12 +667,11 @@
      * <i>not</i> modify the state of this instance.
      * 
      * @param context the execution context that should be used to read the configuration; may not be null
-     * @param factories the factories from which can be obtained the RepositoryConnectionFactory instances for each name source;
-     *        may not be null
+     * @param registry the registry from which {@link RepositorySource} instances can be obtained; may not be null
      * @return a configuration reflecting the current state of this instance
      */
     protected synchronized FederatedRepositoryConfig getRepositoryConfiguration( ExecutionContext context,
-                                                                                 RepositoryConnectionFactories factories ) {
+                                                                                 RepositorySourceRegistry registry ) {
         Problems problems = new SimpleProblems();
         ValueFactories valueFactories = context.getValueFactories();
         PathFactory pathFactory = valueFactories.getPathFactory();
@@ -695,10 +694,10 @@
         } else if (configurationProjection.isSimple()) {
             // There is just a single projection for the configuration repository, so just use an executor that
             // translates the paths using the projection
-            executor = new SingleProjectionCommandExecutor(context, configurationSourceName, configurationProjection, factories);
+            executor = new SingleProjectionCommandExecutor(context, configurationSourceName, configurationProjection, registry);
         } else {
             // The configuration repository has more than one projection, so we need to merge the results
-            executor = new FederatingCommandExecutor(context, configurationSourceName, projections, factories);
+            executor = new FederatingCommandExecutor(context, configurationSourceName, projections, registry);
         }
         // Wrap the executor with a logging executor ...
         executor = new LoggingCommandExecutor(executor, Logger.getLogger(getClass()), Logger.Level.INFO);
@@ -854,8 +853,8 @@
             }
             ref.add(new StringRefAddr(CONFIGURATION_SOURCE_PROJECTION_RULES, sb.toString()));
         }
-        if (getConnectionFactoriesJndiName() != null) {
-            ref.add(new StringRefAddr(CONNECTION_FACTORIES_JNDI_NAME, getConnectionFactoriesJndiName()));
+        if (getRepositorySourceRegistryJndiName() != null) {
+            ref.add(new StringRefAddr(REPOSITORY_SOURCE_REGISTRY_JNDI_NAME, getRepositorySourceRegistryJndiName()));
         }
         if (getExecutionContextFactoryJndiName() != null) {
             ref.add(new StringRefAddr(EXECUTION_CONTEXT_FACTORY_JNDI_NAME, getExecutionContextFactoryJndiName()));
@@ -900,7 +899,7 @@
                 String password = values.get(FederatedRepositorySource.PASSWORD);
                 String configurationSourceName = values.get(FederatedRepositorySource.CONFIGURATION_SOURCE_NAME);
                 String projectionRules = values.get(FederatedRepositorySource.CONFIGURATION_SOURCE_PROJECTION_RULES);
-                String connectionFactoriesJndiName = values.get(FederatedRepositorySource.CONNECTION_FACTORIES_JNDI_NAME);
+                String connectionFactoriesJndiName = values.get(FederatedRepositorySource.REPOSITORY_SOURCE_REGISTRY_JNDI_NAME);
                 String environmentJndiName = values.get(FederatedRepositorySource.EXECUTION_CONTEXT_FACTORY_JNDI_NAME);
                 String repositoryJndiName = values.get(FederatedRepositorySource.REPOSITORY_JNDI_NAME);
                 String securityDomain = values.get(FederatedRepositorySource.SECURITY_DOMAIN);
@@ -917,7 +916,7 @@
                     List<String> rules = StringUtil.splitLines(projectionRules);
                     source.setConfigurationSourceProjectionRules(rules.toArray(new String[rules.size()]));
                 }
-                if (connectionFactoriesJndiName != null) source.setConnectionFactoriesJndiName(connectionFactoriesJndiName);
+                if (connectionFactoriesJndiName != null) source.setRepositorySourceRegistryJndiName(connectionFactoriesJndiName);
                 if (environmentJndiName != null) source.setExecutionContextFactoryJndiName(environmentJndiName);
                 if (repositoryJndiName != null) source.setRepositoryJndiName(repositoryJndiName);
                 if (securityDomain != null) source.setSecurityDomain(securityDomain);
@@ -959,7 +958,7 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getCapabilities()
+     * @see org.jboss.dna.spi.connector.RepositorySource#getCapabilities()
      */
     public RepositorySourceCapabilities getCapabilities() {
         return new Capabilities();

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/Projection.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/Projection.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/Projection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -39,10 +39,10 @@
 import org.jboss.dna.common.util.HashCode;
 import org.jboss.dna.common.util.Logger;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySource;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
 
 /**
  * A projection of content from a source into the integrated/federated repository. Each project consists of a set of {@link Rule

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/FederatingCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -42,6 +42,10 @@
 import org.jboss.dna.spi.DnaLexicon;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 import org.jboss.dna.spi.graph.DateTime;
 import org.jboss.dna.spi.graph.DateTimeFactory;
 import org.jboss.dna.spi.graph.Name;
@@ -59,11 +63,6 @@
 import org.jboss.dna.spi.graph.commands.impl.BasicCreateNodeCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetChildrenCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetNodeCommand;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 import org.jboss.dna.spi.graph.impl.BasicSingleValueProperty;
 
 /**
@@ -78,7 +77,7 @@
     private final Projection cacheProjection;
     private final List<Projection> sourceProjections;
     private final Set<String> sourceNames;
-    private final RepositoryConnectionFactories connectionFactories;
+    private final RepositorySourceRegistry sourceRegistry;
     private final MergeStrategy mergingStrategy;
     /** The set of all connections, including the cache connection */
     private final Map<String, RepositoryConnection> connectionsBySourceName;
@@ -89,19 +88,19 @@
      * Create a command executor that federates (merges) the information from multiple sources described by the source
      * projections. The resulting command executor does not first consult a cache for the merged information; if a cache is
      * desired, see
-     * {@link #FederatingCommandExecutor(ExecutionContext, String, Projection, CachePolicy, List, RepositoryConnectionFactories)
+     * {@link #FederatingCommandExecutor(ExecutionContext, String, Projection, CachePolicy, List, RepositorySourceRegistry)
      * constructor} that takes a {@link Projection cache projection}.
      * 
      * @param context the execution context in which the executor will be run; may not be null
      * @param sourceName the name of the {@link RepositorySource} that is making use of this executor; may not be null or empty
      * @param sourceProjections the source projections; may not be null
-     * @param connectionFactories the factory for connection factory instances
+     * @param sourceRegistry the registry of {@link RepositorySource} instances
      */
     public FederatingCommandExecutor( ExecutionContext context,
                                       String sourceName,
                                       List<Projection> sourceProjections,
-                                      RepositoryConnectionFactories connectionFactories ) {
-        this(context, sourceName, null, null, sourceProjections, connectionFactories);
+                                      RepositorySourceRegistry sourceRegistry ) {
+        this(context, sourceName, null, null, sourceProjections, sourceRegistry);
     }
 
     /**
@@ -117,22 +116,22 @@
      * @param defaultCachePolicy the default caching policy that outlines the length of time that information should be cached, or
      *        null if there is no cache or no specific cache policy
      * @param sourceProjections the source projections; may not be null
-     * @param connectionFactories the factory for connection factory instances
+     * @param sourceRegistry the registry of {@link RepositorySource} instances
      */
     public FederatingCommandExecutor( ExecutionContext context,
                                       String sourceName,
                                       Projection cacheProjection,
                                       CachePolicy defaultCachePolicy,
                                       List<Projection> sourceProjections,
-                                      RepositoryConnectionFactories connectionFactories ) {
+                                      RepositorySourceRegistry sourceRegistry ) {
         super(context, sourceName);
         assert sourceProjections != null;
-        assert connectionFactories != null;
+        assert sourceRegistry != null;
         assert cacheProjection != null ? defaultCachePolicy != null : defaultCachePolicy == null;
         this.cacheProjection = cacheProjection;
         this.defaultCachePolicy = defaultCachePolicy;
         this.sourceProjections = sourceProjections;
-        this.connectionFactories = connectionFactories;
+        this.sourceRegistry = sourceRegistry;
         this.connectionsBySourceName = new HashMap<String, RepositoryConnection>();
         this.uuidPropertyName = context.getValueFactories().getNameFactory().create(DnaLexicon.PropertyNames.UUID);
         this.mergePlanPropertyName = context.getValueFactories().getNameFactory().create(DnaLexicon.PropertyNames.MERGE_PLAN);
@@ -182,9 +181,9 @@
         String sourceName = projection.getSourceName();
         RepositoryConnection connection = connectionsBySourceName.get(sourceName);
         if (connection == null) {
-            RepositoryConnectionFactory connectionFactory = connectionFactories.getConnectionFactory(sourceName);
-            if (connectionFactory != null) {
-                connection = connectionFactory.getConnection();
+            RepositorySource source = sourceRegistry.getRepositorySource(sourceName);
+            if (source != null) {
+                connection = source.getConnection();
             }
             connectionsBySourceName.put(sourceName, connection);
         }

Modified: trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/SingleProjectionCommandExecutor.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/SingleProjectionCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/executor/SingleProjectionCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -25,6 +25,10 @@
 import net.jcip.annotations.NotThreadSafe;
 import org.jboss.dna.connector.federation.Projection;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 import org.jboss.dna.spi.graph.DateTime;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
@@ -39,11 +43,6 @@
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
 import org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch
@@ -53,7 +52,7 @@
 
     private final Projection projection;
     private final PathFactory pathFactory;
-    private final RepositoryConnectionFactories factories;
+    private final RepositorySourceRegistry registry;
     private RepositoryConnection connection;
 
     /**
@@ -61,13 +60,13 @@
      * @param sourceName the name of the {@link RepositorySource} that is making use of this executor; may not be null or empty
      * @param projection the projection used for the cached information; may not be null and must have exactly one
      *        {@link Projection#getRules() rule}
-     * @param connectionFactories the factory for connection factory instances
+     * @param sourceRegistry the registry of {@link RepositorySource} instances
      */
     public SingleProjectionCommandExecutor( ExecutionContext context,
                                             String sourceName,
                                             Projection projection,
-                                            RepositoryConnectionFactories connectionFactories ) {
-        this(context, sourceName, null, projection, connectionFactories);
+                                            RepositorySourceRegistry sourceRegistry ) {
+        this(context, sourceName, null, projection, sourceRegistry);
     }
 
     /**
@@ -76,19 +75,19 @@
      * @param now the current time; may be null if the system time is to be used
      * @param projection the projection used for the cached information; may not be null and must have exactly one
      *        {@link Projection#getRules() rule}
-     * @param connectionFactories the factory for connection factory instances
+     * @param sourceRegistry the registry of {@link RepositorySource} instances
      */
     public SingleProjectionCommandExecutor( ExecutionContext context,
                                             String sourceName,
                                             DateTime now,
                                             Projection projection,
-                                            RepositoryConnectionFactories connectionFactories ) {
+                                            RepositorySourceRegistry sourceRegistry ) {
         super(context, sourceName, now);
-        assert connectionFactories != null;
+        assert sourceRegistry != null;
         assert projection != null;
         assert projection.getRules().size() == 1;
         this.projection = projection;
-        this.factories = connectionFactories;
+        this.registry = sourceRegistry;
         this.pathFactory = context.getValueFactories().getPathFactory();
         assert this.pathFactory != null;
     }
@@ -96,8 +95,8 @@
     protected RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
         if (connection == null) {
             // Create a connection ...
-            RepositoryConnectionFactory connectionFactory = this.factories.getConnectionFactory(this.projection.getSourceName());
-            connection = connectionFactory.getConnection();
+            RepositorySource source = this.registry.getRepositorySource(this.projection.getSourceName());
+            connection = source.getConnection();
         }
         return connection;
     }
@@ -194,7 +193,8 @@
     public void execute( MoveBranchCommand command ) throws RepositorySourceException, InterruptedException {
         Path pathInSource = getPathInSource(command.getPath());
         Path newPathInSource = getPathInSource(command.getNewPath());
-        getConnection().execute(this.getExecutionContext(), new ProjectedMoveBranchCommand(command, pathInSource, newPathInSource));
+        getConnection().execute(this.getExecutionContext(),
+                                new ProjectedMoveBranchCommand(command, pathInSource, newPathInSource));
     }
 
     /**
@@ -217,7 +217,8 @@
     public void execute( CopyBranchCommand command ) throws RepositorySourceException, InterruptedException {
         Path pathInSource = getPathInSource(command.getPath());
         Path newPathInSource = getPathInSource(command.getNewPath());
-        getConnection().execute(this.getExecutionContext(), new ProjectedCopyBranchCommand(command, pathInSource, newPathInSource));
+        getConnection().execute(this.getExecutionContext(),
+                                new ProjectedCopyBranchCommand(command, pathInSource, newPathInSource));
     }
 
     /**

Modified: trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryConnectionTest.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryConnectionTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryConnectionTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -30,10 +30,10 @@
 import static org.mockito.Mockito.verify;
 import java.util.concurrent.TimeUnit;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
 import org.jboss.dna.spi.graph.commands.GraphCommand;
 import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;

Modified: trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceTest.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositorySourceTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -42,12 +42,12 @@
 import org.jboss.dna.spi.DnaLexicon;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.ExecutionContextFactory;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
-import org.jboss.dna.spi.graph.connection.SimpleRepository;
-import org.jboss.dna.spi.graph.connection.SimpleRepositorySource;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
+import org.jboss.dna.spi.connector.SimpleRepository;
+import org.jboss.dna.spi.connector.SimpleRepositorySource;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -66,7 +66,7 @@
     private String username;
     private String credentials;
     private String executionContextFactoryJndiName;
-    private String connectionFactoriesJndiName;
+    private String repositorySourceRegistryJndiName;
     private String configurationSourceName;
     private String securityDomain;
     private SimpleRepository configRepository;
@@ -77,7 +77,7 @@
     @Mock
     private Context jndiContext;
     @Mock
-    private RepositoryConnectionFactories connectionFactories;
+    private RepositorySourceRegistry sourceRegistry;
     @Mock
     private ExecutionContextFactory executionContextFactory;
 
@@ -90,7 +90,7 @@
         context = new BasicExecutionContext();
         context.getNamespaceRegistry().register(DnaLexicon.NAMESPACE_PREFIX, DnaLexicon.NAMESPACE_URI);
         executionContextFactoryJndiName = "context factory jndi name";
-        connectionFactoriesJndiName = "connection factories jndi name";
+        repositorySourceRegistryJndiName = "repository source registry jndi name";
         configurationSourceName = "configuration source name";
         repositoryName = "Test Repository";
         securityDomain = "security domain";
@@ -103,7 +103,7 @@
         source.setPassword(credentials);
         source.setConfigurationSourceName(configurationSourceName);
         source.setConfigurationSourceProjectionRules(new String[] {"/dna:system/dna:federation/ => /dna:repositories/Test Repository"});
-        source.setConnectionFactoriesJndiName(connectionFactoriesJndiName);
+        source.setRepositorySourceRegistryJndiName(repositorySourceRegistryJndiName);
         source.setExecutionContextFactoryJndiName(executionContextFactoryJndiName);
         source.setContext(jndiContext);
         source.setSecurityDomain(securityDomain);
@@ -122,9 +122,9 @@
         configRepositorySource = new SimpleRepositorySource();
         configRepositorySource.setRepositoryName(configRepository.getRepositoryName());
         configRepositorySource.setName(configurationSourceName);
-        stub(connectionFactories.getConnectionFactory(configurationSourceName)).toReturn(configRepositorySource);
+        stub(sourceRegistry.getRepositorySource(configurationSourceName)).toReturn(configRepositorySource);
         stub(jndiContext.lookup(executionContextFactoryJndiName)).toReturn(executionContextFactory);
-        stub(jndiContext.lookup(connectionFactoriesJndiName)).toReturn(connectionFactories);
+        stub(jndiContext.lookup(repositorySourceRegistryJndiName)).toReturn(sourceRegistry);
         stub(executionContextFactory.create(eq(securityDomain), anyCallbackHandler())).toReturn(context);
     }
 
@@ -266,7 +266,7 @@
         source.setName("Some source");
         source.setConfigurationSourceName("config source");
         source.setConfigurationSourceProjectionRules(new String[] {"/dna:system => /a/b/c"});
-        source.setConnectionFactoriesJndiName("connection factories jndi name");
+        source.setRepositorySourceRegistryJndiName("repository source registry jndi name");
         source.setRepositoryJndiName("repository jndi name");
         source.setExecutionContextFactoryJndiName("env jndi name");
 
@@ -290,8 +290,8 @@
                    is(source.getConfigurationSourceName()));
         assertThat((String)refAttributes.remove(FederatedRepositorySource.CONFIGURATION_SOURCE_PROJECTION_RULES),
                    is("/dna:system => /a/b/c"));
-        assertThat((String)refAttributes.remove(FederatedRepositorySource.CONNECTION_FACTORIES_JNDI_NAME),
-                   is(source.getConnectionFactoriesJndiName()));
+        assertThat((String)refAttributes.remove(FederatedRepositorySource.REPOSITORY_SOURCE_REGISTRY_JNDI_NAME),
+                   is(source.getRepositorySourceRegistryJndiName()));
         assertThat((String)refAttributes.remove(FederatedRepositorySource.EXECUTION_CONTEXT_FACTORY_JNDI_NAME),
                    is(source.getExecutionContextFactoryJndiName()));
         assertThat((String)refAttributes.remove(FederatedRepositorySource.REPOSITORY_JNDI_NAME),
@@ -314,7 +314,7 @@
         assertThat(recoveredSource.getRetryLimit(), is(source.getRetryLimit()));
         assertThat(recoveredSource.getConfigurationSourceName(), is(source.getConfigurationSourceName()));
         assertThat(recoveredSource.getConfigurationSourceProjectionRules(), is(source.getConfigurationSourceProjectionRules()));
-        assertThat(recoveredSource.getConnectionFactoriesJndiName(), is(source.getConnectionFactoriesJndiName()));
+        assertThat(recoveredSource.getRepositorySourceRegistryJndiName(), is(source.getRepositorySourceRegistryJndiName()));
         assertThat(recoveredSource.getExecutionContextFactoryJndiName(), is(source.getExecutionContextFactoryJndiName()));
         assertThat(recoveredSource.getRepositoryJndiName(), is(source.getRepositoryJndiName()));
         assertThat(recoveredSource.getSecurityDomain(), is(source.getSecurityDomain()));

Modified: trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryTest.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/FederatedRepositoryTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -28,9 +28,9 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.matchers.JUnitMatchers.hasItems;
 import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;
@@ -50,15 +50,13 @@
     @Mock
     private RepositorySourceListener listener2;
     @Mock
-    private RepositoryConnectionFactories connectionFactories;
+    private RepositorySourceRegistry registry;
 
-    // private RepositoryConnectionPool connectionPool;
-
     @Before
     public void beforeEach() {
         MockitoAnnotations.initMocks(this);
         context = new BasicExecutionContext();
-        repository = new FederatedRepository(context, connectionFactories, config);
+        repository = new FederatedRepository(context, registry, config);
     }
 
     @Test

Modified: trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionPathRuleTest.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionPathRuleTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionPathRuleTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -29,10 +29,10 @@
 import org.jboss.dna.common.text.TextEncoder;
 import org.jboss.dna.common.text.UrlEncoder;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
 import org.junit.Before;
 import org.junit.Test;
 

Modified: trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionTest.java
===================================================================
--- trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-federation/src/test/java/org/jboss/dna/connector/federation/ProjectionTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -27,9 +27,9 @@
 import static org.mockito.Mockito.stub;
 import java.util.Set;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;

Modified: trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java
===================================================================
--- trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -26,12 +26,12 @@
 import javax.transaction.xa.XAResource;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
 import org.jboss.dna.spi.graph.commands.ActsAsUpdate;
 import org.jboss.dna.spi.graph.commands.GraphCommand;
 import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 
 /**
  * @author Randall Hauch

Modified: trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java
===================================================================
--- trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -40,14 +40,13 @@
 import net.jcip.annotations.GuardedBy;
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.connection.AbstractRepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceCapabilities;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
+import org.jboss.dna.spi.connector.AbstractRepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceCapabilities;
+import org.jboss.dna.spi.connector.RepositorySourceException;
 
 /**
  * @author Randall Hauch
- * @author John Verhaeg
  */
 public class InMemoryRepositorySource extends AbstractRepositorySource implements ObjectFactory {
 
@@ -96,7 +95,6 @@
     private String jndiName;
     private UUID rootNodeUuid = UUID.randomUUID();
     private CachePolicy defaultCachePolicy;
-    // private String configurationName;
     private transient InMemoryRepository repository;
 
     /**
@@ -225,7 +223,7 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.AbstractRepositorySource#createConnection()
+     * @see org.jboss.dna.spi.connector.AbstractRepositorySource#createConnection()
      */
     @Override
     protected synchronized RepositoryConnection createConnection() throws RepositorySourceException {
@@ -265,7 +263,7 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getCapabilities()
+     * @see org.jboss.dna.spi.connector.RepositorySource#getCapabilities()
      */
     public RepositorySourceCapabilities getCapabilities() {
         return new Capabilities();

Modified: trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
===================================================================
--- trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -32,6 +32,9 @@
 import org.jboss.cache.Node;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.NameFactory;
 import org.jboss.dna.spi.graph.Path;
@@ -53,9 +56,6 @@
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
 import org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor;
 import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 
 /**
  * @author Randall Hauch

Modified: trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
===================================================================
--- trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -45,10 +45,10 @@
 import org.jboss.dna.common.util.ArgCheck;
 import org.jboss.dna.spi.DnaLexicon;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.AbstractRepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceCapabilities;
 import org.jboss.dna.spi.graph.Name;
-import org.jboss.dna.spi.graph.connection.AbstractRepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceCapabilities;
 
 /**
  * @author Randall Hauch
@@ -282,7 +282,7 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getCapabilities()
+     * @see org.jboss.dna.spi.connector.RepositorySource#getCapabilities()
      */
     public RepositorySourceCapabilities getCapabilities() {
         return new Capabilities();

Modified: trunk/connectors/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectionTest.java
===================================================================
--- trunk/connectors/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectionTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/connectors/dna-connector-jbosscache/src/test/java/org/jboss/dna/connector/jbosscache/JBossCacheConnectionTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -42,12 +42,12 @@
 import org.jboss.dna.spi.DnaLexicon;
 import org.jboss.dna.spi.ExecutionContext;
 import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
 import org.jboss.dna.spi.graph.PathNotFoundException;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
-import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;

Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -45,6 +45,7 @@
 import org.jboss.dna.repository.services.AdministeredService;
 import org.jboss.dna.repository.services.ServiceAdministrator;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySource;
 import org.jboss.dna.spi.graph.Name;
 import org.jboss.dna.spi.graph.NameFactory;
 import org.jboss.dna.spi.graph.Path;
@@ -58,8 +59,6 @@
 import org.jboss.dna.spi.graph.commands.impl.BasicCompositeCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetChildrenCommand;
 import org.jboss.dna.spi.graph.commands.impl.BasicGetNodeCommand;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
 
 /**
  * @author Randall Hauch
@@ -197,8 +196,7 @@
             NameFactory nameFactory = valueFactories.getNameFactory();
 
             final String configurationSourceName = configurationProjection.getSourceName();
-            RepositoryConnectionFactory factory = sources.getConnectionFactory(configurationSourceName);
-            if (factory == null) {
+            if (sources.getRepositorySource(configurationSourceName) == null) {
                 throw new FederationException(RepositoryI18n.unableToFindRepositorySourceWithName.text(configurationSourceName));
             }
 

Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositorySourceManager.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositorySourceManager.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositorySourceManager.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -29,15 +29,14 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.jboss.dna.repository.services.AbstractServiceAdministrator;
 import org.jboss.dna.repository.services.ServiceAdministrator;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories;
-import org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceRegistry;
 
 /**
  * @author Randall Hauch
  */
-public class RepositorySourceManager implements RepositoryConnectionFactories {
+public class RepositorySourceManager implements RepositorySourceRegistry {
 
     /**
      * The administrative component for this service.
@@ -89,29 +88,35 @@
     private final ServiceAdministrator administrator = new Administrator();
     private final ReadWriteLock sourcesLock = new ReentrantReadWriteLock();
     private final CopyOnWriteArrayList<RepositorySource> sources = new CopyOnWriteArrayList<RepositorySource>();
-    private RepositoryConnectionFactories delegate;
+    private RepositorySourceRegistry delegate;
 
     /**
      * Create a new manager instance.
      * 
-     * @param delegate the factories object that this instance should delegate to in the event that a source is not found in this
+     * @param delegate the registry to which this instance should delegate in the event that a source is not found in this
      *        manager; may be null if there is no delegate
      */
-    public RepositorySourceManager( RepositoryConnectionFactories delegate ) {
+    public RepositorySourceManager( RepositorySourceRegistry delegate ) {
         this.delegate = delegate;
     }
 
     /**
-     * @return delegate
+     * Get the delegate registry.
+     * 
+     * @return the registry to which this instance should delegate in the event that a source is not found in this manager, or
+     *         null if there is no delegate
      */
-    public RepositoryConnectionFactories getDelegate() {
+    public RepositorySourceRegistry getDelegate() {
         return delegate;
     }
 
     /**
-     * @param delegate Sets delegate to the specified value.
+     * Set the delegate registry.
+     * 
+     * @param delegate the registry to which this instance should delegate in the event that a source is not found in this
+     *        manager; may be null if there is no delegate
      */
-    public void setDelegate( RepositoryConnectionFactories delegate ) {
+    public void setDelegate( RepositorySourceRegistry delegate ) {
         this.delegate = delegate;
     }
 
@@ -305,17 +310,17 @@
     /**
      * {@inheritDoc}
      * 
-     * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactories#getConnectionFactory(java.lang.String)
+     * @see org.jboss.dna.spi.connector.RepositorySourceRegistry#getRepositorySource(java.lang.String)
      */
-    public RepositoryConnectionFactory getConnectionFactory( String sourceName ) {
+    public RepositorySource getRepositorySource( String sourceName ) {
         try {
             this.sourcesLock.readLock().lock();
             for (RepositorySource existingSource : this.sources) {
                 if (existingSource.getName().equals(sourceName)) return existingSource;
             }
-            RepositoryConnectionFactories delegate = this.delegate;
+            RepositorySourceRegistry delegate = this.delegate;
             if (delegate != null) {
-                return delegate.getConnectionFactory(sourceName);
+                return delegate.getRepositorySource(sourceName);
             }
         } finally {
             this.sourcesLock.readLock().unlock();

Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/BasicJcrExecutionContext.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/BasicJcrExecutionContext.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/BasicJcrExecutionContext.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -22,10 +22,10 @@
 package org.jboss.dna.repository.util;
 
 import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.PropertyFactory;
 import org.jboss.dna.spi.graph.ValueFactories;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
 
 /**
  * @author Randall Hauch

Modified: trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java
===================================================================
--- trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-repository/src/test/java/org/jboss/dna/repository/RepositoryServiceTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -41,13 +41,13 @@
 import org.jboss.dna.repository.services.ServiceAdministrator;
 import org.jboss.dna.spi.DnaLexicon;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.SimpleRepository;
+import org.jboss.dna.spi.connector.SimpleRepositorySource;
 import org.jboss.dna.spi.graph.NamespaceRegistry;
 import org.jboss.dna.spi.graph.Path;
 import org.jboss.dna.spi.graph.PathFactory;
 import org.jboss.dna.spi.graph.PropertyFactory;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.SimpleRepository;
-import org.jboss.dna.spi.graph.connection.SimpleRepositorySource;
 import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
 import org.jboss.dna.spi.graph.impl.BasicPropertyFactory;
 import org.jboss.dna.spi.graph.impl.StandardValueFactories;
@@ -98,7 +98,7 @@
         configRepositorySource = new SimpleRepositorySource();
         configRepositorySource.setRepositoryName(configRepository.getRepositoryName());
         configRepositorySource.setName(configSourceName);
-        stub(sources.getConnectionFactory(configSourceName)).toReturn(configRepositorySource);
+        stub(sources.getRepositorySource(configSourceName)).toReturn(configRepositorySource);
         stub(context.getValueFactories()).toReturn(valueFactories);
         stub(context.getPropertyFactory()).toReturn(propertyFactory);
         stub(context.getNamespaceRegistry()).toReturn(registry);
@@ -158,14 +158,14 @@
 
     @Test( expected = FederationException.class )
     public void shouldFailToStartUpIfConfigurationRepositorySourceIsNotFound() {
-        stub(sources.getConnectionFactory(configSourceName)).toReturn(null);
+        stub(sources.getRepositorySource(configSourceName)).toReturn(null);
         service.getAdministrator().start();
     }
 
     @Test( expected = FederationException.class )
     public void shouldFailToStartUpIfUnableToConnectToConfigurationRepository() throws Exception {
         RepositorySource mockSource = mock(RepositorySource.class);
-        stub(sources.getConnectionFactory(configSourceName)).toReturn(mockSource);
+        stub(sources.getRepositorySource(configSourceName)).toReturn(mockSource);
         stub(mockSource.getConnection()).toThrow(new UnsupportedOperationException());
         service.getAdministrator().start();
     }
@@ -173,7 +173,7 @@
     @Test( expected = FederationException.class )
     public void shouldFailToStartUpIfInterruptedWhileConnectingToConfigurationRepository() throws Exception {
         RepositorySource mockSource = mock(RepositorySource.class);
-        stub(sources.getConnectionFactory(configSourceName)).toReturn(mockSource);
+        stub(sources.getRepositorySource(configSourceName)).toReturn(mockSource);
         stub(mockSource.getConnection()).toThrow(new InterruptedException());
         service.getAdministrator().start();
     }
@@ -207,21 +207,21 @@
 
         // and verify that the sources were added to the manager...
         assertThat(sources.getSources().size(), is(4));
-        assertThat(sources.getConnectionFactory("source A"), is(instanceOf(SimpleRepositorySource.class)));
-        assertThat(sources.getConnectionFactory("source B"), is(instanceOf(SimpleRepositorySource.class)));
-        assertThat(sources.getConnectionFactory("source C"), is(instanceOf(SimpleRepositorySource.class)));
+        assertThat(sources.getRepositorySource("source A"), is(instanceOf(SimpleRepositorySource.class)));
+        assertThat(sources.getRepositorySource("source B"), is(instanceOf(SimpleRepositorySource.class)));
+        assertThat(sources.getRepositorySource("source C"), is(instanceOf(SimpleRepositorySource.class)));
 
-        SimpleRepositorySource sourceA = (SimpleRepositorySource)sources.getConnectionFactory("source A");
+        SimpleRepositorySource sourceA = (SimpleRepositorySource)sources.getRepositorySource("source A");
         assertThat(sourceA.getName(), is("source A"));
         assertThat(sourceA.getRepositoryName(), is("sourceReposA"));
         assertThat(sourceA.getRetryLimit(), is(3));
 
-        SimpleRepositorySource sourceB = (SimpleRepositorySource)sources.getConnectionFactory("source B");
+        SimpleRepositorySource sourceB = (SimpleRepositorySource)sources.getRepositorySource("source B");
         assertThat(sourceB.getName(), is("source B"));
         assertThat(sourceB.getRepositoryName(), is("sourceReposB"));
         assertThat(sourceB.getRetryLimit(), is(SimpleRepositorySource.DEFAULT_RETRY_LIMIT));
 
-        SimpleRepositorySource sourceC = (SimpleRepositorySource)sources.getConnectionFactory("source C");
+        SimpleRepositorySource sourceC = (SimpleRepositorySource)sources.getRepositorySource("source C");
         assertThat(sourceC.getName(), is("source C"));
         assertThat(sourceC.getRepositoryName(), is("sourceReposC"));
         assertThat(sourceC.getRetryLimit(), is(SimpleRepositorySource.DEFAULT_RETRY_LIMIT));
@@ -236,7 +236,7 @@
         service.getAdministrator().start();
 
         // and verify that the configuration source was obtained from the manager ...
-        verify(sources, times(2)).getConnectionFactory(configSourceName); // once for checking source, second for getting
+        verify(sources, times(2)).getRepositorySource(configSourceName); // once for checking source, second for getting
 
         // and verify that the sources were never added to the manager...
         verifyNoMoreInteractions(sources);

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector (from rev 389, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection)

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/AbstractRepositorySource.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,203 +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.dna.spi.graph.connection;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import net.jcip.annotations.ThreadSafe;
-
-/**
- * An abstract implementation of {@link RepositorySource} that may serve as a foundation for most implementations, since it
- * automatically manages the {@link RepositoryConnection connections} using an internal {@link ManagedRepositoryConnectionFactory pool}.
- * 
- * @author Randall Hauch
- */
- at ThreadSafe
-public abstract class AbstractRepositorySource implements RepositorySource {
-
-    /**
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * The default limit is {@value} for retrying {@link RepositoryConnection connection} calls to the underlying source.
-     */
-    public static final int DEFAULT_RETRY_LIMIT = 0;
-
-    private final AtomicInteger retryLimit = new AtomicInteger(DEFAULT_RETRY_LIMIT);
-    private final RepositoryConnectionPool connections;
-    private final RepositoryConnectionFactory connectionFactory;
-
-    /**
-     * Create a new instance of the repository source, relying upon the {@link #createConnection()} method to do the actual
-     * creation of the {@link RepositoryConnection connections}.
-     */
-    protected AbstractRepositorySource() {
-        this(null);
-    }
-
-    /**
-     * Create a new instance of the repository source, relying upon the supplied factory to do the actual creation of the
-     * {@link RepositoryConnection connections}. If the supplied factory is null, then this class will use the
-     * {@link #createConnection()} method to do the actual creation of the {@link RepositoryConnection connections}.
-     * 
-     * @param factory the connection factory that creates the connections, or null if the {@link #createConnection()} method
-     *        should be used to create connections
-     */
-    protected AbstractRepositorySource( RepositoryConnectionFactory factory ) {
-        this.connectionFactory = factory != null ? factory : new ConnectionFactory();
-        this.connections = new RepositoryConnectionPool(this.connectionFactory);
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getRetryLimit()
-     */
-    public int getRetryLimit() {
-        return retryLimit.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#setRetryLimit(int)
-     */
-    public void setRetryLimit( int limit ) {
-        retryLimit.set(limit < 0 ? 0 : limit);
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isRunning()
-     */
-    public boolean isRunning() {
-        return this.connections.isRunning();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isShutdown()
-     */
-    public boolean isShutdown() {
-        return this.connections.isShutdown();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory#getConnection()
-     */
-    public RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
-        return this.connections.getConnection();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#shutdown()
-     */
-    public void shutdown() {
-        this.connections.shutdown();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#shutdownNow()
-     */
-    public void shutdownNow() {
-        this.connections.shutdownNow();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isTerminated()
-     */
-    public boolean isTerminated() {
-        return this.connections.isTerminated();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isTerminating()
-     */
-    public boolean isTerminating() {
-        return this.connections.isTerminating();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#awaitTermination(long, java.util.concurrent.TimeUnit)
-     */
-    public boolean awaitTermination( long timeout,
-                                     TimeUnit unit ) throws InterruptedException {
-        return this.connections.awaitTermination(timeout, unit);
-    }
-
-    /**
-     * Method to create a new {@link RepositoryConnection} instance. This method is called only when this instance was
-     * {@link #AbstractRepositorySource(RepositoryConnectionFactory) constructed} with a null {@link RepositoryConnectionFactory}
-     * reference. This makes it easy for subclasses to simply override this method can not be required to implement a separate
-     * connection factory.
-     * 
-     * @return the new connection
-     * @throws RepositorySourceException
-     * @throws InterruptedException
-     */
-    protected RepositoryConnection createConnection() throws RepositorySourceException, InterruptedException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Class that is used by the {@link AbstractRepositorySource} and it's pool to create connections as needed, by delegating to
-     * the {@link AbstractRepositorySource}'s {@link AbstractRepositorySource#createConnection()} method.
-     * 
-     * @author Randall Hauch
-     */
-    protected class ConnectionFactory implements RepositoryConnectionFactory {
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory#getConnection()
-         */
-        public RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
-            return AbstractRepositorySource.this.createConnection();
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory#getName()
-         */
-        public String getName() {
-            return AbstractRepositorySource.this.getName();
-        }
-
-    }
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/AbstractRepositorySource.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/AbstractRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,221 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import net.jcip.annotations.ThreadSafe;
+
+/**
+ * An abstract implementation of {@link RepositorySource} that may serve as a foundation for most implementations, since it
+ * automatically manages the {@link RepositoryConnection connections} using an internal {@link RepositoryConnectionPool pool}.
+ * 
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public abstract class AbstractRepositorySource implements RepositorySource {
+
+    /**
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The default limit is {@value} for retrying {@link RepositoryConnection connection} calls to the underlying source.
+     */
+    public static final int DEFAULT_RETRY_LIMIT = 0;
+
+    private final AtomicInteger retryLimit = new AtomicInteger(DEFAULT_RETRY_LIMIT);
+    private RepositoryConnectionPool.ConnectionFactory connectionFactory;
+    private transient RepositoryConnectionPool connections;
+
+    /**
+     * Create a new instance of the repository source. This constructor calls relying upon the {@link #createConnectionFactory()}
+     * method, which creation of the {@link RepositoryConnection connections}.
+     */
+    protected AbstractRepositorySource() {
+        this.connectionFactory = createConnectionFactory();
+        assert this.connectionFactory != null;
+        this.connections = new RepositoryConnectionPool(this.connectionFactory);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#getRetryLimit()
+     */
+    public int getRetryLimit() {
+        return retryLimit.get();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#setRetryLimit(int)
+     */
+    public void setRetryLimit( int limit ) {
+        retryLimit.set(limit < 0 ? 0 : limit);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#isRunning()
+     */
+    public boolean isRunning() {
+        return this.connections.isRunning();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#isShutdown()
+     */
+    public boolean isShutdown() {
+        return this.connections.isShutdown();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#getConnection()
+     */
+    public RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
+        return this.connections.getConnection();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#shutdown()
+     */
+    public void shutdown() {
+        this.connections.shutdown();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#shutdownNow()
+     */
+    public void shutdownNow() {
+        this.connections.shutdownNow();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#isTerminated()
+     */
+    public boolean isTerminated() {
+        return this.connections.isTerminated();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#isTerminating()
+     */
+    public boolean isTerminating() {
+        return this.connections.isTerminating();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#awaitTermination(long, java.util.concurrent.TimeUnit)
+     */
+    public boolean awaitTermination( long timeout,
+                                     TimeUnit unit ) throws InterruptedException {
+        return this.connections.awaitTermination(timeout, unit);
+    }
+
+    private void writeObject( java.io.ObjectOutputStream out ) throws IOException {
+        out.writeInt(this.getRetryLimit());
+        // Write out the pool's state, since the pool is not serializable ...
+        out.writeLong(connections.getKeepAliveTime(TimeUnit.NANOSECONDS));
+        out.writeInt(connections.getCorePoolSize());
+        out.writeInt(connections.getMaximumPoolSize());
+        out.writeInt(connections.getMaxFailedAttemptsBeforeError());
+        out.writeBoolean(connections.getValidateConnectionBeforeUse());
+        out.writeLong(connections.getPingTimeoutInNanos());
+    }
+
+    private void readObject( java.io.ObjectInputStream in ) throws IOException {
+        setRetryLimit(in.readInt());
+        connectionFactory = createConnectionFactory();
+        // Read the pool state parameters ...
+        final long keepAliveTimeInNanos = in.readLong();
+        final int corePoolSize = in.readInt();
+        final int maxPoolSize = in.readInt();
+        final int maxFailedAttemptsBeforeError = in.readInt();
+        final boolean validateConnections = in.readBoolean();
+        final long pingTimeoutInNanos = in.readLong();
+        // Create a new pool and set it's parameters ...
+        connections = new RepositoryConnectionPool(connectionFactory, corePoolSize, maxPoolSize, keepAliveTimeInNanos,
+                                                   TimeUnit.NANOSECONDS);
+        connections.setMaxFailedAttemptsBeforeError(maxFailedAttemptsBeforeError);
+        connections.setValidateConnectionBeforeUse(validateConnections);
+        connections.setPingTimeout(pingTimeoutInNanos, TimeUnit.NANOSECONDS);
+    }
+
+    /**
+     * Create a connection factory that should be used. The default implementation returns a factory that delegates to the
+     * {@link #createConnection()} method, which should be overridden.
+     * 
+     * @return the connection factory; never null
+     */
+    protected RepositoryConnectionPool.ConnectionFactory createConnectionFactory() {
+        return new RepositoryConnectionPool.ConnectionFactory() {
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.jboss.dna.spi.connector.RepositoryConnectionPool.ConnectionFactory#createConnection()
+             */
+            public RepositoryConnection createConnection() throws RepositorySourceException, InterruptedException {
+                return AbstractRepositorySource.this.createConnection();
+            }
+
+            /**
+             * {@inheritDoc}
+             * 
+             * @see org.jboss.dna.spi.connector.RepositoryConnectionPool#getSourceName()
+             */
+            public String getSourceName() {
+                return AbstractRepositorySource.this.getName();
+            }
+        };
+    }
+
+    /**
+     * Method to create a new {@link RepositoryConnection} instance. This method is called by the
+     * {@link RepositoryConnectionPool.ConnectionFactory} returned by the default implementation of
+     * {@link #createConnectionFactory()}. If the {@link #createConnectionFactory()} method is overridden, this method will not be
+     * called.
+     * 
+     * @return the new connection
+     * @throws RepositorySourceException
+     * @throws InterruptedException
+     */
+    protected abstract RepositoryConnection createConnection() throws RepositorySourceException, InterruptedException;
+
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionContext.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,108 +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.dna.spi.graph.connection;
-
-import javax.security.auth.Subject;
-import org.jboss.dna.common.util.ArgCheck;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.graph.NamespaceRegistry;
-import org.jboss.dna.spi.graph.PropertyFactory;
-import org.jboss.dna.spi.graph.ValueFactories;
-import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
-import org.jboss.dna.spi.graph.impl.BasicPropertyFactory;
-import org.jboss.dna.spi.graph.impl.StandardValueFactories;
-
-/**
- * @author Randall Hauch
- */
-public class BasicExecutionContext implements ExecutionContext {
-
-    private final Subject subject;
-    private final PropertyFactory propertyFactory;
-    private final ValueFactories valueFactories;
-    private final NamespaceRegistry namespaceRegistry;
-
-    public BasicExecutionContext() {
-        this(new Subject(), new BasicNamespaceRegistry());
-    }
-
-    public BasicExecutionContext( NamespaceRegistry namespaceRegistry ) {
-        this(new Subject(), namespaceRegistry, null, null);
-    }
-
-    public BasicExecutionContext( NamespaceRegistry namespaceRegistry,
-                                  ValueFactories valueFactories,
-                                  PropertyFactory propertyFactory ) {
-        this(new Subject(), namespaceRegistry, valueFactories, propertyFactory);
-    }
-
-    public BasicExecutionContext( Subject subject ) {
-        this(subject, new BasicNamespaceRegistry());
-    }
-
-    public BasicExecutionContext( Subject subject,
-                                  NamespaceRegistry namespaceRegistry ) {
-        this(subject, namespaceRegistry, null, null);
-    }
-
-    public BasicExecutionContext( Subject subject,
-                                  NamespaceRegistry namespaceRegistry,
-                                  ValueFactories valueFactories,
-                                  PropertyFactory propertyFactory ) {
-        ArgCheck.isNotNull(subject, "subject");
-        ArgCheck.isNotNull(namespaceRegistry, "namespace registry");
-        this.subject = subject;
-        this.namespaceRegistry = namespaceRegistry;
-        this.valueFactories = valueFactories != null ? valueFactories : new StandardValueFactories(this.namespaceRegistry);
-        this.propertyFactory = propertyFactory != null ? propertyFactory : new BasicPropertyFactory(this.valueFactories);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public NamespaceRegistry getNamespaceRegistry() {
-        return this.namespaceRegistry;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public ValueFactories getValueFactories() {
-        return this.valueFactories;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public PropertyFactory getPropertyFactory() {
-        return this.propertyFactory;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.ExecutionContext#getSubject()
-     */
-    public Subject getSubject() {
-        return this.subject;
-    }
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/BasicExecutionContext.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/BasicExecutionContext.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,161 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.graph.NamespaceRegistry;
+import org.jboss.dna.spi.graph.PropertyFactory;
+import org.jboss.dna.spi.graph.ValueFactories;
+import org.jboss.dna.spi.graph.impl.BasicNamespaceRegistry;
+import org.jboss.dna.spi.graph.impl.BasicPropertyFactory;
+import org.jboss.dna.spi.graph.impl.StandardValueFactories;
+
+/**
+ * @author Randall Hauch
+ * @author John Verhaeg
+ */
+public class BasicExecutionContext implements ExecutionContext {
+
+    private final LoginContext loginContext;
+    private final AccessControlContext accessControlContext;
+    private final Subject subject;
+    private final PropertyFactory propertyFactory;
+    private final ValueFactories valueFactories;
+    private final NamespaceRegistry namespaceRegistry;
+
+    public BasicExecutionContext() {
+        this(new BasicNamespaceRegistry());
+    }
+
+    public BasicExecutionContext( NamespaceRegistry namespaceRegistry ) {
+        this(namespaceRegistry, null, null);
+    }
+
+    public BasicExecutionContext( LoginContext loginContext ) {
+        this(loginContext, new BasicNamespaceRegistry());
+    }
+
+    public BasicExecutionContext( AccessControlContext accessControlContext ) {
+        this(accessControlContext, new BasicNamespaceRegistry());
+    }
+
+    public BasicExecutionContext( LoginContext loginContext,
+                                  NamespaceRegistry namespaceRegistry ) {
+        this(loginContext, namespaceRegistry, null, null);
+    }
+
+    public BasicExecutionContext( AccessControlContext accessControlContext,
+                                  NamespaceRegistry namespaceRegistry ) {
+        this(accessControlContext, namespaceRegistry, null, null);
+    }
+
+    public BasicExecutionContext( NamespaceRegistry namespaceRegistry,
+                                  ValueFactories valueFactories,
+                                  PropertyFactory propertyFactory ) {
+        this(null, null, namespaceRegistry, valueFactories, propertyFactory);
+    }
+
+    public BasicExecutionContext( LoginContext loginContext,
+                                  NamespaceRegistry namespaceRegistry,
+                                  ValueFactories valueFactories,
+                                  PropertyFactory propertyFactory ) {
+        this(loginContext, null, namespaceRegistry, valueFactories, propertyFactory);
+    }
+
+    public BasicExecutionContext( AccessControlContext accessControlContext,
+                                  NamespaceRegistry namespaceRegistry,
+                                  ValueFactories valueFactories,
+                                  PropertyFactory propertyFactory ) {
+        this(null, accessControlContext, namespaceRegistry, valueFactories, propertyFactory);
+    }
+
+    private BasicExecutionContext( LoginContext loginContext,
+                                   AccessControlContext accessControlContext,
+                                   NamespaceRegistry namespaceRegistry,
+                                   ValueFactories valueFactories,
+                                   PropertyFactory propertyFactory ) {
+        ArgCheck.isNotNull(namespaceRegistry, "namespaceRegistry");
+        this.loginContext = loginContext;
+        this.accessControlContext = accessControlContext;
+        if (loginContext == null) {
+            this.subject = Subject.getSubject(accessControlContext == null ? AccessController.getContext() : accessControlContext);
+        } else {
+            this.subject = loginContext.getSubject();
+        }
+        this.namespaceRegistry = namespaceRegistry;
+        this.valueFactories = valueFactories != null ? valueFactories : new StandardValueFactories(this.namespaceRegistry);
+        this.propertyFactory = propertyFactory != null ? propertyFactory : new BasicPropertyFactory(this.valueFactories);
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.ExecutionContext#getAccessControlContext()
+     */
+    public AccessControlContext getAccessControlContext() {
+        return accessControlContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.ExecutionContext#getLoginContext()
+     */
+    public LoginContext getLoginContext() {
+        return loginContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NamespaceRegistry getNamespaceRegistry() {
+        return namespaceRegistry;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyFactory getPropertyFactory() {
+        return propertyFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.ExecutionContext#getSubject()
+     */
+    public Subject getSubject() {
+        return subject;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ValueFactories getValueFactories() {
+        return valueFactories;
+    }
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/ManagedRepositoryConnectionFactory.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/ManagedRepositoryConnectionFactory.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/ManagedRepositoryConnectionFactory.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,111 +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.dna.spi.graph.connection;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author Randall Hauch
- */
-public interface ManagedRepositoryConnectionFactory extends RepositoryConnectionFactory {
-
-    /**
-     * Initiates an orderly shutdown in which connections that are currently in use are allowed to be used and closed as normal,
-     * but no new connections will be created. Invocation has no additional effect if already shut down.
-     * <p>
-     * Once the pool has been shutdown, it may not be used to {@link #getConnection() get connections}.
-     * </p>
-     * 
-     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
-     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     *         or the security manager's <tt>checkAccess</tt> method denies access.
-     * @see #shutdownNow()
-     */
-    void shutdown();
-
-    /**
-     * Attempts to close all connections, including those connections currently in use, and prevent the use of other connections.
-     * 
-     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
-     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     *         or the security manager's <tt>checkAccess</tt> method denies access.
-     * @see #shutdown()
-     */
-    void shutdownNow();
-
-    /**
-     * Return whether this connection pool is running and is able to {@link #getConnection() provide connections}. Note that this
-     * method is effectively <code>!isShutdown()</code>.
-     * 
-     * @return true if this pool is running, or false otherwise
-     * @see #isShutdown()
-     * @see #isTerminated()
-     * @see #isTerminating()
-     */
-    boolean isRunning();
-
-    /**
-     * Return whether this connection pool is in the process of shutting down or has already been shut down. A result of
-     * <code>true</code> signals that the pool may no longer be used. Note that this method is effectively
-     * <code>!isRunning()</code>.
-     * 
-     * @return true if this pool has been shut down, or false otherwise
-     * @see #isShutdown()
-     * @see #isTerminated()
-     * @see #isTerminating()
-     */
-    boolean isShutdown();
-
-    /**
-     * Returns true if this pool is in the process of terminating after {@link #shutdown()} or {@link #shutdownNow()} has been
-     * called but has not completely terminated. This method may be useful for debugging. A return of <tt>true</tt> reported a
-     * sufficient period after shutdown may indicate that submitted tasks have ignored or suppressed interruption, causing this
-     * executor not to properly terminate.
-     * 
-     * @return true if terminating but not yet terminated, or false otherwise
-     * @see #isTerminated()
-     */
-    boolean isTerminating();
-
-    /**
-     * Return true if this pool has completed its termination and no longer has any open connections.
-     * 
-     * @return true if terminated, or false otherwise
-     * @see #isTerminating()
-     */
-    boolean isTerminated();
-
-    /**
-     * Method that can be called after {@link #shutdown()} or {@link #shutdownNow()} to wait until all connections in use at the
-     * time those methods were called have been closed normally. This method accepts a maximum time duration, after which it will
-     * return even if all connections have not been closed.
-     * 
-     * @param timeout the maximum time to wait for all connections to be closed and returned to the pool
-     * @param unit the time unit for <code>timeout</code>
-     * @return true if the pool was terminated in the supplied time (or was already terminated), or false if the timeout occurred
-     *         before all the connections were closed
-     * @throws InterruptedException if the thread was interrupted
-     */
-    boolean awaitTermination( long timeout,
-                              TimeUnit unit ) throws InterruptedException;
-
-}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnection.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,99 +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.dna.spi.graph.connection;
-
-import java.util.concurrent.TimeUnit;
-import javax.transaction.xa.XAResource;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.commands.GraphCommand;
-
-/**
- * A connection to a repository source.
- * <p>
- * These connections need not support concurrent operations by multiple threads, since the federation engine never uses them this
- * way.
- * </p>
- * 
- * @author Randall Hauch
- */
-public interface RepositoryConnection {
-
-    /**
-     * Get the name for this repository source. This value should be the same as that {@link RepositorySource#getName() returned}
-     * by the same {@link RepositorySource} that created this connection.
-     * 
-     * @return the identifier; never null or empty
-     */
-    String getSourceName();
-
-    /**
-     * Return the transactional resource associated with this connection. The transaction manager will use this resource to manage
-     * the participation of this connection in a distributed transaction.
-     * 
-     * @return the XA resource, or null if this connection is not aware of distributed transactions
-     */
-    XAResource getXAResource();
-
-    /**
-     * Ping the underlying system to determine if the connection is still valid and alive.
-     * 
-     * @param time the length of time to wait before timing out
-     * @param unit the time unit to use; may not be null
-     * @return true if this connection is still valid and can still be used, or false otherwise
-     * @throws InterruptedException if the thread has been interrupted during the operation
-     */
-    boolean ping( long time,
-                  TimeUnit unit ) throws InterruptedException;
-
-    /**
-     * Set the listener that is to receive notifications to changes to content within this source.
-     * 
-     * @param listener the new listener, or null if no component is interested in the change notifications
-     */
-    void setListener( RepositorySourceListener listener );
-
-    /**
-     * Get the default cache policy for this repository. If none is provided, a global cache policy will be used.
-     * 
-     * @return the default cache policy
-     */
-    CachePolicy getDefaultCachePolicy();
-
-    /**
-     * Execute the supplied commands against this repository source.
-     * 
-     * @param context the environment in which the commands are being executed; never null
-     * @param commands the commands to be executed; never null
-     * @throws RepositorySourceException if there is a problem loading the node data
-     * @throws InterruptedException if the thread has been interrupted during the operation
-     */
-    void execute( ExecutionContext context,
-                  GraphCommand... commands ) throws RepositorySourceException, InterruptedException;
-
-    /**
-     * Close this connection to signal that it is no longer needed and that any accumulated resources are to be released.
-     * 
-     * @throws InterruptedException if the thread has been interrupted while the close was in progress
-     */
-    void close() throws InterruptedException;
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnection.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnection.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,100 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.concurrent.TimeUnit;
+import javax.transaction.xa.XAResource;
+import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+
+/**
+ * A connection to a repository source.
+ * <p>
+ * These connections need not support concurrent operations by multiple threads.
+ * </p>
+ * 
+ * @author Randall Hauch
+ */
+ at NotThreadSafe
+public interface RepositoryConnection {
+
+    /**
+     * Get the name for this repository source. This value should be the same as that {@link RepositorySource#getName() returned}
+     * by the same {@link RepositorySource} that created this connection.
+     * 
+     * @return the identifier; never null or empty
+     */
+    String getSourceName();
+
+    /**
+     * Return the transactional resource associated with this connection. The transaction manager will use this resource to manage
+     * the participation of this connection in a distributed transaction.
+     * 
+     * @return the XA resource, or null if this connection is not aware of distributed transactions
+     */
+    XAResource getXAResource();
+
+    /**
+     * Ping the underlying system to determine if the connection is still valid and alive.
+     * 
+     * @param time the length of time to wait before timing out
+     * @param unit the time unit to use; may not be null
+     * @return true if this connection is still valid and can still be used, or false otherwise
+     * @throws InterruptedException if the thread has been interrupted during the operation
+     */
+    boolean ping( long time,
+                  TimeUnit unit ) throws InterruptedException;
+
+    /**
+     * Set the listener that is to receive notifications to changes to content within this source.
+     * 
+     * @param listener the new listener, or null if no component is interested in the change notifications
+     */
+    void setListener( RepositorySourceListener listener );
+
+    /**
+     * Get the default cache policy for this repository. If none is provided, a global cache policy will be used.
+     * 
+     * @return the default cache policy
+     */
+    CachePolicy getDefaultCachePolicy();
+
+    /**
+     * Execute the supplied commands against this repository source.
+     * 
+     * @param context the environment in which the commands are being executed; never null
+     * @param commands the commands to be executed; never null
+     * @throws RepositorySourceException if there is a problem loading the node data
+     * @throws InterruptedException if the thread has been interrupted during the operation
+     */
+    void execute( ExecutionContext context,
+                  GraphCommand... commands ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Close this connection to signal that it is no longer needed and that any accumulated resources are to be released.
+     * 
+     * @throws InterruptedException if the thread has been interrupted while the close was in progress
+     */
+    void close() throws InterruptedException;
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactories.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionFactories.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactories.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,32 +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.dna.spi.graph.connection;
-
-
-/**
- * @author Randall Hauch
- */
-public interface RepositoryConnectionFactories {
-
-    RepositoryConnectionFactory getConnectionFactory( String sourceName );
-
-}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactory.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionFactory.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionFactory.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,43 +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.dna.spi.graph.connection;
-
-/**
- * @author Randall Hauch
- */
-public interface RepositoryConnectionFactory {
-
-    /**
-     * Get the name for this repository source.
-     * @return the name; never null or empty
-     */
-    String getName();
-
-    /**
-     * Get a connection from this factory.
-     * @return a connection
-     * @throws RepositorySourceException if there is a problem obtaining a connection
-     * @throws InterruptedException if the thread is interrupted while attempting to get a connection
-     * @throws IllegalStateException if the factory is not in a state to create or return connections
-     */
-    RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException;
-}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,969 +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.dna.spi.graph.connection;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.transaction.xa.XAResource;
-import net.jcip.annotations.GuardedBy;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.dna.common.util.ArgCheck;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.SpiI18n;
-import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.commands.GraphCommand;
-
-/**
- * @author Randall Hauch
- */
- at ThreadSafe
-public class RepositoryConnectionPool implements ManagedRepositoryConnectionFactory {
-
-    /**
-     * The core pool size for default-constructed pools is {@value} .
-     */
-    public static final int DEFAULT_CORE_POOL_SIZE = 1;
-
-    /**
-     * The maximum pool size for default-constructed pools is {@value} .
-     */
-    public static final int DEFAULT_MAXIMUM_POOL_SIZE = 10;
-
-    /**
-     * The keep-alive time for connections in default-constructed pools is {@value} seconds.
-     */
-    public static final long DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS = 30;
-
-    /**
-     * Permission for checking shutdown
-     */
-    private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread");
-
-    /**
-     * The factory that this pool uses to create new connections.
-     */
-    private final RepositoryConnectionFactory connectionFactory;
-
-    /**
-     * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and workers set.
-     */
-    private final ReentrantLock mainLock = new ReentrantLock();
-
-    /**
-     * Wait condition to support awaitTermination
-     */
-    private final Condition termination = mainLock.newCondition();
-
-    /**
-     * Set containing all connections that are available for use.
-     */
-    @GuardedBy( "mainLock" )
-    private final BlockingQueue<ConnectionWrapper> availableConnections = new LinkedBlockingQueue<ConnectionWrapper>();
-
-    /**
-     * The connections that are currently in use.
-     */
-    @GuardedBy( "mainLock" )
-    private final Set<ConnectionWrapper> inUseConnections = new HashSet<ConnectionWrapper>();
-
-    /**
-     * Timeout in nanoseconds for idle connections waiting to be used. Threads use this timeout only when there are more than
-     * corePoolSize present. Otherwise they wait forever to be used.
-     */
-    private volatile long keepAliveTime;
-
-    /**
-     * The target pool size, updated only while holding mainLock, but volatile to allow concurrent readability even during
-     * updates.
-     */
-    @GuardedBy( "mainLock" )
-    private volatile int corePoolSize;
-
-    /**
-     * Maximum pool size, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
-     */
-    @GuardedBy( "mainLock" )
-    private volatile int maximumPoolSize;
-
-    /**
-     * Current pool size, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
-     */
-    @GuardedBy( "mainLock" )
-    private volatile int poolSize;
-
-    /**
-     * Lifecycle state, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
-     */
-    @GuardedBy( "mainLock" )
-    private volatile int runState;
-
-    // Special values for runState
-    /** Normal, not-shutdown mode */
-    static final int RUNNING = 0;
-    /** Controlled shutdown mode */
-    static final int SHUTDOWN = 1;
-    /** Immediate shutdown mode */
-    static final int STOP = 2;
-    /** Final state */
-    static final int TERMINATED = 3;
-
-    /**
-     * Flag specifying whether a connection should be validated before returning it from the {@link #getConnection()} method.
-     */
-    private final AtomicBoolean validateConnectionBeforeUse = new AtomicBoolean(false);
-
-    /**
-     * The time in nanoseconds that ping should wait before timing out and failing.
-     */
-    private final AtomicLong pingTimeout = new AtomicLong(0);
-
-    /**
-     * The number of times an attempt to obtain a connection should fail with invalid connections before throwing an exception.
-     */
-    private final AtomicInteger maxFailedAttemptsBeforeError = new AtomicInteger(10);
-
-    private final AtomicLong totalConnectionsCreated = new AtomicLong(0);
-
-    private final AtomicLong totalConnectionsUsed = new AtomicLong(0);
-
-    private final Logger logger = Logger.getLogger(this.getClass());
-
-    /**
-     * Create the pool to use the supplied connection factory, which is typically a {@link RepositorySource}. This constructor
-     * uses the {@link #DEFAULT_CORE_POOL_SIZE default core pool size}, {@link #DEFAULT_MAXIMUM_POOL_SIZE default maximum pool
-     * size}, and {@link #DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS default keep-alive time (in seconds)}.
-     * 
-     * @param connectionFactory the factory for connections
-     * @throws IllegalArgumentException if the connection factory is null or any of the supplied arguments are invalid
-     */
-    public RepositoryConnectionPool( RepositoryConnectionFactory connectionFactory ) {
-        this(connectionFactory, DEFAULT_CORE_POOL_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS,
-             TimeUnit.SECONDS);
-    }
-
-    /**
-     * Create the pool to use the supplied connection factory, which is typically a {@link RepositorySource}.
-     * 
-     * @param connectionFactory the factory for connections
-     * @param corePoolSize the number of connections to keep in the pool, even if they are idle.
-     * @param maximumPoolSize the maximum number of connections to allow in the pool.
-     * @param keepAliveTime when the number of connection is greater than the core, this is the maximum time that excess idle
-     *        connections will be kept before terminating.
-     * @param unit the time unit for the keepAliveTime argument.
-     * @throws IllegalArgumentException if the connection factory is null or any of the supplied arguments are invalid
-     */
-    public RepositoryConnectionPool( RepositoryConnectionFactory connectionFactory,
-                                     int corePoolSize,
-                                     int maximumPoolSize,
-                                     long keepAliveTime,
-                                     TimeUnit unit ) {
-        ArgCheck.isNonNegative(corePoolSize, "corePoolSize");
-        ArgCheck.isPositive(maximumPoolSize, "maximumPoolSize");
-        ArgCheck.isNonNegative(keepAliveTime, "keepAliveTime");
-        ArgCheck.isNotNull(connectionFactory, "repository connection factory");
-        if (maximumPoolSize < corePoolSize) {
-            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
-        }
-        this.connectionFactory = connectionFactory;
-        this.corePoolSize = corePoolSize;
-        this.maximumPoolSize = maximumPoolSize;
-        this.keepAliveTime = unit.toNanos(keepAliveTime);
-        this.setPingTimeout(100, TimeUnit.MILLISECONDS);
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory#getName()
-     */
-    public String getName() {
-        return this.connectionFactory.getName();
-    }
-
-    // -------------------------------------------------
-    // Property settings ...
-    // -------------------------------------------------
-
-    /**
-     * @return validateConnectionBeforeUse
-     */
-    public boolean getValidateConnectionBeforeUse() {
-        return this.validateConnectionBeforeUse.get();
-    }
-
-    /**
-     * @param validateConnectionBeforeUse Sets validateConnectionBeforeUse to the specified value.
-     */
-    public void setValidateConnectionBeforeUse( boolean validateConnectionBeforeUse ) {
-        this.validateConnectionBeforeUse.set(validateConnectionBeforeUse);
-    }
-
-    /**
-     * @return pingTimeout
-     */
-    public long getPingTimeoutInNanos() {
-        return this.pingTimeout.get();
-    }
-
-    /**
-     * @param pingTimeout the time to wait for a ping to complete
-     * @param unit the time unit of the time argument
-     */
-    public void setPingTimeout( long pingTimeout,
-                                TimeUnit unit ) {
-        ArgCheck.isNonNegative(pingTimeout, "time");
-        this.pingTimeout.set(unit.toNanos(pingTimeout));
-    }
-
-    /**
-     * @return maxFailedAttemptsBeforeError
-     */
-    public int getMaxFailedAttemptsBeforeError() {
-        return this.maxFailedAttemptsBeforeError.get();
-    }
-
-    /**
-     * @param maxFailedAttemptsBeforeError Sets maxFailedAttemptsBeforeError to the specified value.
-     */
-    public void setMaxFailedAttemptsBeforeError( int maxFailedAttemptsBeforeError ) {
-        this.maxFailedAttemptsBeforeError.set(maxFailedAttemptsBeforeError);
-    }
-
-    /**
-     * Sets the time limit for which connections may remain idle before being closed. If there are more than the core number of
-     * connections currently in the pool, after waiting this amount of time without being used, excess threads will be terminated.
-     * This overrides any value set in the constructor.
-     * 
-     * @param time the time to wait. A time value of zero will cause excess connections to terminate immediately after being
-     *        returned.
-     * @param unit the time unit of the time argument
-     * @throws IllegalArgumentException if time less than zero
-     * @see #getKeepAliveTime
-     */
-    public void setKeepAliveTime( long time,
-                                  TimeUnit unit ) {
-        ArgCheck.isNonNegative(time, "time");
-        this.keepAliveTime = unit.toNanos(time);
-    }
-
-    /**
-     * Returns the connection keep-alive time, which is the amount of time which connections in excess of the core pool size may
-     * remain idle before being closed.
-     * 
-     * @param unit the desired time unit of the result
-     * @return the time limit
-     * @see #setKeepAliveTime
-     */
-    public long getKeepAliveTime( TimeUnit unit ) {
-        assert unit != null;
-        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
-    }
-
-    /**
-     * @return maximumPoolSize
-     */
-    public int getMaximumPoolSize() {
-        return this.maximumPoolSize;
-    }
-
-    /**
-     * Sets the maximum allowed number of connections. This overrides any value set in the constructor. If the new value is
-     * smaller than the current value, excess existing but unused connections will be closed.
-     * 
-     * @param maximumPoolSize the new maximum
-     * @throws IllegalArgumentException if maximumPoolSize less than zero or the {@link #getCorePoolSize() core pool size}
-     * @see #getMaximumPoolSize
-     */
-    public void setMaximumPoolSize( int maximumPoolSize ) {
-        ArgCheck.isPositive(maximumPoolSize, "maximum pool size");
-        if (maximumPoolSize < corePoolSize) {
-            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
-        }
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            int extra = this.maximumPoolSize - maximumPoolSize;
-            this.maximumPoolSize = maximumPoolSize;
-            if (extra > 0 && poolSize > maximumPoolSize) {
-                // Drain the extra connections from those available ...
-                drainUnusedConnections(extra);
-            }
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * Returns the core number of connections.
-     * 
-     * @return the core number of connections
-     * @see #setCorePoolSize(int)
-     */
-    public int getCorePoolSize() {
-        return this.corePoolSize;
-    }
-
-    /**
-     * Sets the core number of connections. This overrides any value set in the constructor. If the new value is smaller than the
-     * current value, excess existing and unused connections will be closed. If larger, new connections will, if needed, be
-     * created.
-     * 
-     * @param corePoolSize the new core size
-     * @throws RepositorySourceException if there was an error obtaining the new connection
-     * @throws InterruptedException if the thread was interrupted during the operation
-     * @throws IllegalArgumentException if <tt>corePoolSize</tt> less than zero
-     * @see #getCorePoolSize()
-     */
-    public void setCorePoolSize( int corePoolSize ) throws RepositorySourceException, InterruptedException {
-        ArgCheck.isNonNegative(corePoolSize, "core pool size");
-        if (maximumPoolSize < corePoolSize) {
-            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
-        }
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            int extra = this.corePoolSize - corePoolSize;
-            this.corePoolSize = corePoolSize;
-            if (extra < 0) {
-                // Add connections ...
-                addConnectionsIfUnderCorePoolSize();
-            } else if (extra > 0 && poolSize > corePoolSize) {
-                // Drain the extra connections from those available ...
-                drainUnusedConnections(extra);
-            }
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    // -------------------------------------------------
-    // Statistics ...
-    // -------------------------------------------------
-
-    /**
-     * Returns the current number of connections in the pool, including those that are checked out (in use) and those that are not
-     * being used.
-     * 
-     * @return the number of connections
-     */
-    public int getPoolSize() {
-        return poolSize;
-    }
-
-    /**
-     * Returns the approximate number of connections that are currently checked out from the pool.
-     * 
-     * @return the number of checked-out connections
-     */
-    public int getInUseCount() {
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            return this.inUseConnections.size();
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * Get the total number of connections that have been created by this pool.
-     * 
-     * @return the total number of connections created by this pool
-     */
-    public long getTotalConnectionsCreated() {
-        return this.totalConnectionsCreated.get();
-    }
-
-    /**
-     * Get the total number of times connections have been {@link #getConnection()} used.
-     * 
-     * @return the total number
-     */
-    public long getTotalConnectionsUsed() {
-        return this.totalConnectionsUsed.get();
-    }
-
-    // -------------------------------------------------
-    // State management methods ...
-    // -------------------------------------------------
-
-    /**
-     * Starts a core connection, causing it to idly wait for use. This overrides the default policy of starting core connections
-     * only when they are {@link #getConnection() needed}. This method will return <tt>false</tt> if all core connections have
-     * already been started.
-     * 
-     * @return true if a connection was started
-     * @throws RepositorySourceException if there was an error obtaining the new connection
-     * @throws InterruptedException if the thread was interrupted during the operation
-     */
-    public boolean prestartCoreConnection() throws RepositorySourceException, InterruptedException {
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            return addConnectionIfUnderCorePoolSize();
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * Starts all core connections, causing them to idly wait for use. This overrides the default policy of starting core
-     * connections only when they are {@link #getConnection() needed}.
-     * 
-     * @return the number of connections started.
-     * @throws RepositorySourceException if there was an error obtaining the new connection
-     * @throws InterruptedException if the thread was interrupted during the operation
-     */
-    public int prestartAllCoreConnections() throws RepositorySourceException, InterruptedException {
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            return addConnectionsIfUnderCorePoolSize();
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#shutdown()
-     */
-    public void shutdown() {
-        // Fail if caller doesn't have modifyThread permission. We
-        // explicitly check permissions directly because we can't trust
-        // implementations of SecurityManager to correctly override
-        // the "check access" methods such that our documented
-        // security policy is implemented.
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) java.security.AccessController.checkPermission(shutdownPerm);
-
-        this.logger.debug("Shutting down repository connection pool for {0}", getName());
-        boolean fullyTerminated = false;
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            int state = this.runState;
-            if (state == RUNNING) {
-                // don't override shutdownNow
-                this.runState = SHUTDOWN;
-            }
-
-            // Kill the maintenance thread ...
-
-            // Remove and close all available connections ...
-            if (!this.availableConnections.isEmpty()) {
-                // Drain the extra connections from those available ...
-                drainUnusedConnections(this.availableConnections.size());
-            }
-
-            // If there are no connections being used, trigger full termination now ...
-            if (this.inUseConnections.isEmpty()) {
-                fullyTerminated = true;
-                this.logger.trace("Signalling termination of repository connection pool for {0}", getName());
-                runState = TERMINATED;
-                termination.signalAll();
-                this.logger.debug("Terminated repository connection pool for {0}", getName());
-            }
-            // Otherwise the last connection that is closed will transition the runState to TERMINATED ...
-        } finally {
-            mainLock.unlock();
-        }
-        if (fullyTerminated) terminated();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#shutdownNow()
-     */
-    public void shutdownNow() {
-        // Almost the same code as shutdown()
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) java.security.AccessController.checkPermission(shutdownPerm);
-
-        this.logger.debug("Shutting down (immediately) repository connection pool for {0}", getName());
-        boolean fullyTerminated = false;
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            int state = this.runState;
-            if (state != TERMINATED) {
-                // don't override shutdownNow
-                this.runState = STOP;
-            }
-
-            // Kill the maintenance thread ...
-
-            // Remove and close all available connections ...
-            if (!this.availableConnections.isEmpty()) {
-                // Drain the extra connections from those available ...
-                drainUnusedConnections(this.availableConnections.size());
-            }
-
-            // If there are connections being used, close them now ...
-            if (!this.inUseConnections.isEmpty()) {
-                for (ConnectionWrapper connectionInUse : this.inUseConnections) {
-                    try {
-                        this.logger.trace("Closing repository connection to {0}", getName());
-                        connectionInUse.getOriginal().close();
-                    } catch (InterruptedException e) {
-                        // Ignore this ...
-                    }
-                }
-                this.poolSize -= this.inUseConnections.size();
-                // The last connection that is closed will transition the runState to TERMINATED ...
-            } else {
-                // There are no connections in use, so trigger full termination now ...
-                fullyTerminated = true;
-                this.logger.trace("Signalling termination of repository connection pool for {0}", getName());
-                runState = TERMINATED;
-                termination.signalAll();
-                this.logger.debug("Terminated repository connection pool for {0}", getName());
-            }
-
-        } finally {
-            mainLock.unlock();
-        }
-        if (fullyTerminated) terminated();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isRunning()
-     */
-    public boolean isRunning() {
-        return runState == RUNNING;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isShutdown()
-     */
-    public boolean isShutdown() {
-        return runState != RUNNING;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isTerminating()
-     */
-    public boolean isTerminating() {
-        return runState == STOP;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#isTerminated()
-     */
-    public boolean isTerminated() {
-        return runState == TERMINATED;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.ManagedRepositoryConnectionFactory#awaitTermination(long,
-     *      java.util.concurrent.TimeUnit)
-     */
-    public boolean awaitTermination( long timeout,
-                                     TimeUnit unit ) throws InterruptedException {
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            for (;;) {
-                // this.logger.debug("---> Run state = {}; condition = {}", runState, termination);
-                if (runState == TERMINATED) return true;
-                if (nanos <= 0) return false;
-                nanos = termination.awaitNanos(nanos);
-                // this.logger.debug("---> Done waiting: run state = {}; condition = {}", runState, termination);
-            }
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * Method invoked when the pool has terminated. Default implementation does nothing. Note: To properly nest multiple
-     * overridings, subclasses should generally invoke <tt>super.terminated</tt> within this method.
-     */
-    protected void terminated() {
-    }
-
-    /**
-     * Invokes <tt>shutdown</tt> when this pool is no longer referenced.
-     */
-    @Override
-    protected void finalize() {
-        shutdown();
-    }
-
-    // -------------------------------------------------
-    // Connection management methods ...
-    // -------------------------------------------------
-
-    /**
-     * {@inheritDoc}
-     */
-    public RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
-        int attemptsAllowed = this.maxFailedAttemptsBeforeError.get();
-        ConnectionWrapper connection = null;
-        // Do this until we get a good connection ...
-        int attemptsRemaining = attemptsAllowed;
-        while (connection == null && attemptsRemaining > 0) {
-            --attemptsRemaining;
-            ReentrantLock mainLock = this.mainLock;
-            try {
-                mainLock.lock();
-                // If we're shutting down the pool, then just close the connection ...
-                if (this.runState != RUNNING) {
-                    throw new IllegalStateException(SpiI18n.repositoryConnectionPoolIsNotRunning.text());
-                }
-                // If there are fewer total connections than the core size ...
-                if (this.poolSize < this.corePoolSize) {
-                    // Immediately create a wrapped connection and return it ...
-                    connection = newWrappedConnection();
-                }
-                // Peek to see if there is a connection available ...
-                else if (this.availableConnections.peek() != null) {
-                    // There is, so take it and return it ...
-                    connection = this.availableConnections.take();
-                }
-                // There is no connection available. If there are fewer total connections than the maximum size ...
-                else if (this.poolSize < this.maximumPoolSize) {
-                    // Immediately create a wrapped connection and return it ...
-                    connection = newWrappedConnection();
-                }
-                if (connection != null) {
-                    this.inUseConnections.add(connection);
-                }
-            } finally {
-                mainLock.unlock();
-            }
-            if (connection == null) {
-                // There are not enough connections, so wait in line for the next available connection ...
-                this.logger.trace("Waiting for a repository connection from pool {0}", getName());
-                connection = this.availableConnections.take();
-                mainLock = this.mainLock;
-                mainLock.lock();
-                try {
-                    if (connection != null) {
-                        this.inUseConnections.add(connection);
-                    }
-                } finally {
-                    mainLock.unlock();
-                }
-                this.logger.trace("Recieved a repository connection from pool {0}", getName());
-            }
-            if (connection != null && this.validateConnectionBeforeUse.get()) {
-                connection = validateConnection(connection);
-            }
-        }
-        if (connection == null) {
-            // We were unable to obtain a usable connection, so fail ...
-            throw new RepositorySourceException(SpiI18n.unableToObtainValidRepositoryAfterAttempts.text(attemptsAllowed));
-        }
-        this.totalConnectionsUsed.incrementAndGet();
-        return connection;
-    }
-
-    /**
-     * This method is automatically called by the {@link ConnectionWrapper} when it is {@link ConnectionWrapper#close() closed}.
-     * 
-     * @param wrapper the wrapper to the connection that is being returned to the pool
-     */
-    protected void returnConnection( ConnectionWrapper wrapper ) {
-        assert wrapper != null;
-        ConnectionWrapper wrapperToClose = null;
-        final ReentrantLock mainLock = this.mainLock;
-        try {
-            mainLock.lock();
-            // Remove the connection from the in-use set ...
-            boolean removed = this.inUseConnections.remove(wrapper);
-            assert removed;
-
-            // If we're shutting down the pool, then just close the connection ...
-            if (this.runState != RUNNING) {
-                wrapperToClose = wrapper;
-            }
-            // If there are more connections than the maximum size...
-            else if (this.poolSize > this.maximumPoolSize) {
-                // Immediately close this connection ...
-                wrapperToClose = wrapper;
-            }
-            // Attempt to make the connection available (this should generally work, unless there is an upper limit
-            // to the number of available connections) ...
-            else if (!this.availableConnections.offer(new ConnectionWrapper(wrapper.getOriginal()))) {
-                // The pool of available connection is full, so release it ...
-                wrapperToClose = wrapper;
-            }
-        } finally {
-            mainLock.unlock();
-        }
-        // Close the connection if we're supposed to (do it outside of the main lock)...
-        if (wrapperToClose != null) {
-            try {
-                closeConnection(wrapper);
-            } catch (InterruptedException e) {
-                // catch this, as there's not much we can do and the caller doesn't care or know how to handle it
-                this.logger.trace(e, "Interrupted while closing a repository connection");
-            }
-        }
-    }
-
-    /**
-     * Validate the supplied connection, returning the connection if valid or null if the connection is not valid.
-     * 
-     * @param connection the connection to be validated; may not be null
-     * @return the validated connection, or null if the connection did not validate and was removed from the pool
-     */
-    protected ConnectionWrapper validateConnection( ConnectionWrapper connection ) {
-        assert connection != null;
-        ConnectionWrapper invalidConnection = null;
-        try {
-            if (!connection.ping(this.pingTimeout.get(), TimeUnit.NANOSECONDS)) {
-                invalidConnection = connection;
-            }
-        } catch (InterruptedException e) {
-            // catch this, as there's not much we can do and the caller doesn't care or know how to handle it
-            this.logger.trace(e, "Interrupted while pinging a repository connection");
-            invalidConnection = connection;
-        } finally {
-            if (invalidConnection != null) {
-                connection = null;
-                returnConnection(invalidConnection);
-            }
-        }
-        return connection;
-    }
-
-    /**
-     * Obtain a new connection wrapped in a {@link ConnectionWrapper}. This method does not check whether creating the new
-     * connection would violate the {@link #maximumPoolSize maximum pool size} nor does it add the new connection to the
-     * {@link #availableConnections available connections} (as the caller may want it immediately), but it does increment the
-     * {@link #poolSize pool size}.
-     * 
-     * @return the connection wrapper with a new connection
-     * @throws RepositorySourceException if there was an error obtaining the new connection
-     * @throws InterruptedException if the thread was interrupted during the operation
-     */
-    @GuardedBy( "mainLock" )
-    protected ConnectionWrapper newWrappedConnection() throws RepositorySourceException, InterruptedException {
-        RepositoryConnection connection = this.connectionFactory.getConnection();
-        ++this.poolSize;
-        this.totalConnectionsCreated.incrementAndGet();
-        return new ConnectionWrapper(connection);
-    }
-
-    /**
-     * Close a connection that is in the pool but no longer in the {@link #availableConnections available connections}. This
-     * method does decrement the {@link #poolSize pool size}.
-     * 
-     * @param wrapper the wrapper for the connection to be closed
-     * @throws InterruptedException if the thread was interrupted during the operation
-     */
-    protected void closeConnection( ConnectionWrapper wrapper ) throws InterruptedException {
-        assert wrapper != null;
-        RepositoryConnection original = wrapper.getOriginal();
-        assert original != null;
-        try {
-            this.logger.debug("Closing repository connection to {0}", getName());
-            original.close();
-        } finally {
-            final ReentrantLock mainLock = this.mainLock;
-            try {
-                mainLock.lock();
-                // No matter what reduce the pool size count
-                --this.poolSize;
-                // And if shutting down and this was the last connection being used...
-                if (this.runState == SHUTDOWN && this.poolSize <= 0) {
-                    // then signal anybody that has called "awaitTermination(...)"
-                    this.logger.trace("Signalling termination of repository connection pool for {0}", getName());
-                    this.runState = TERMINATED;
-                    this.termination.signalAll();
-                    this.logger.trace("Terminated repository connection pool for {0}", getName());
-
-                    // fall through to call terminate() outside of lock.
-                }
-            } finally {
-                mainLock.unlock();
-            }
-        }
-    }
-
-    @GuardedBy( "mainLock" )
-    protected int drainUnusedConnections( int count ) {
-        if (count <= 0) return 0;
-        this.logger.trace("Draining up to {0} unused repository connections to {1}", count, getName());
-        // Drain the extra connections from those available ...
-        Collection<ConnectionWrapper> extraConnections = new LinkedList<ConnectionWrapper>();
-        this.availableConnections.drainTo(extraConnections, count);
-        for (ConnectionWrapper connection : extraConnections) {
-            try {
-                this.logger.trace("Closing repository connection to {0}", getName());
-                connection.getOriginal().close();
-            } catch (InterruptedException e) {
-                // Ignore this ...
-            }
-        }
-        int numClosed = extraConnections.size();
-        this.poolSize -= numClosed;
-        this.logger.trace("Drained {0} unused connections", numClosed);
-        return numClosed;
-    }
-
-    @GuardedBy( "mainLock" )
-    protected boolean addConnectionIfUnderCorePoolSize() throws RepositorySourceException, InterruptedException {
-        // Add connection ...
-        if (this.poolSize < this.corePoolSize) {
-            this.availableConnections.offer(newWrappedConnection());
-            this.logger.trace("Added connection to {0} in undersized pool", getName());
-            return true;
-        }
-        return false;
-    }
-
-    @GuardedBy( "mainLock" )
-    protected int addConnectionsIfUnderCorePoolSize() throws RepositorySourceException, InterruptedException {
-        // Add connections ...
-        int n = 0;
-        while (this.poolSize < this.corePoolSize) {
-            this.availableConnections.offer(newWrappedConnection());
-            ++n;
-        }
-        this.logger.trace("Added {0} connection(s) to {1} in undersized pool", n, getName());
-        return n;
-    }
-
-    protected class ConnectionWrapper implements RepositoryConnection {
-
-        private final RepositoryConnection original;
-        private final long timeCreated;
-        private long lastUsed;
-        private boolean closed = false;
-
-        protected ConnectionWrapper( RepositoryConnection connection ) {
-            assert connection != null;
-            this.original = connection;
-            this.timeCreated = System.currentTimeMillis();
-        }
-
-        /**
-         * @return original
-         */
-        protected RepositoryConnection getOriginal() {
-            return this.original;
-        }
-
-        /**
-         * @return lastUsed
-         */
-        public long getTimeLastUsed() {
-            return this.lastUsed;
-        }
-
-        /**
-         * @return timeCreated
-         */
-        public long getTimeCreated() {
-            return this.timeCreated;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public String getSourceName() {
-            return this.original.getSourceName();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public XAResource getXAResource() {
-            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
-            return this.original.getXAResource();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public CachePolicy getDefaultCachePolicy() {
-            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
-            return this.original.getDefaultCachePolicy();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void execute( ExecutionContext context,
-                             GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
-            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
-            this.original.execute(context, commands);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public boolean ping( long time,
-                             TimeUnit unit ) throws InterruptedException {
-            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
-            return this.original.ping(time, unit);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void close() throws InterruptedException {
-            if (!closed) {
-                this.lastUsed = System.currentTimeMillis();
-                this.original.close();
-                this.closed = true;
-                returnConnection(this);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void setListener( RepositorySourceListener listener ) {
-            if (!closed) this.original.setListener(listener);
-        }
-
-    }
-
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPool.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryConnectionPool.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,1032 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.transaction.xa.XAResource;
+import net.jcip.annotations.GuardedBy;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.SpiI18n;
+import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+
+/**
+ * A reusable implementation of a managed pool of connections that is optimized for safe concurrent operations.
+ * 
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class RepositoryConnectionPool {
+
+    /**
+     * A factory that is used by the connection pool to create new connections.
+     * 
+     * @author Randall Hauch
+     */
+    public interface ConnectionFactory {
+
+        /**
+         * Get the name for the source that owns the pool.
+         * 
+         * @return the name; never null or empty
+         */
+        String getSourceName();
+
+        /**
+         * Create a new connection to the underlying source.
+         * 
+         * @return the new connection
+         * @throws RepositorySourceException if there is a problem obtaining a connection
+         * @throws InterruptedException if the thread is interrupted while attempting to get a connection
+         */
+        RepositoryConnection createConnection() throws RepositorySourceException, InterruptedException;
+    }
+
+    /**
+     * The core pool size for default-constructed pools is {@value} .
+     */
+    public static final int DEFAULT_CORE_POOL_SIZE = 1;
+
+    /**
+     * The maximum pool size for default-constructed pools is {@value} .
+     */
+    public static final int DEFAULT_MAXIMUM_POOL_SIZE = 10;
+
+    /**
+     * The keep-alive time for connections in default-constructed pools is {@value} seconds.
+     */
+    public static final long DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS = 30;
+
+    /**
+     * Permission for checking shutdown
+     */
+    private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread");
+
+    /**
+     * The factory that this pool uses to create new connections.
+     */
+    private final ConnectionFactory connectionFactory;
+
+    /**
+     * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and workers set.
+     */
+    private final ReentrantLock mainLock = new ReentrantLock();
+
+    /**
+     * Wait condition to support awaitTermination
+     */
+    private final Condition termination = mainLock.newCondition();
+
+    /**
+     * Set containing all connections that are available for use.
+     */
+    @GuardedBy( "mainLock" )
+    private final BlockingQueue<ConnectionWrapper> availableConnections = new LinkedBlockingQueue<ConnectionWrapper>();
+
+    /**
+     * The connections that are currently in use.
+     */
+    @GuardedBy( "mainLock" )
+    private final Set<ConnectionWrapper> inUseConnections = new HashSet<ConnectionWrapper>();
+
+    /**
+     * Timeout in nanoseconds for idle connections waiting to be used. Threads use this timeout only when there are more than
+     * corePoolSize present. Otherwise they wait forever to be used.
+     */
+    private volatile long keepAliveTime;
+
+    /**
+     * The target pool size, updated only while holding mainLock, but volatile to allow concurrent readability even during
+     * updates.
+     */
+    @GuardedBy( "mainLock" )
+    private volatile int corePoolSize;
+
+    /**
+     * Maximum pool size, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
+     */
+    @GuardedBy( "mainLock" )
+    private volatile int maximumPoolSize;
+
+    /**
+     * Current pool size, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
+     */
+    @GuardedBy( "mainLock" )
+    private volatile int poolSize;
+
+    /**
+     * Lifecycle state, updated only while holding mainLock but volatile to allow concurrent readability even during updates.
+     */
+    @GuardedBy( "mainLock" )
+    private volatile int runState;
+
+    // Special values for runState
+    /** Normal, not-shutdown mode */
+    static final int RUNNING = 0;
+    /** Controlled shutdown mode */
+    static final int SHUTDOWN = 1;
+    /** Immediate shutdown mode */
+    static final int STOP = 2;
+    /** Final state */
+    static final int TERMINATED = 3;
+
+    /**
+     * Flag specifying whether a connection should be validated before returning it from the {@link #getConnection()} method.
+     */
+    private final AtomicBoolean validateConnectionBeforeUse = new AtomicBoolean(false);
+
+    /**
+     * The time in nanoseconds that ping should wait before timing out and failing.
+     */
+    private final AtomicLong pingTimeout = new AtomicLong(0);
+
+    /**
+     * The number of times an attempt to obtain a connection should fail with invalid connections before throwing an exception.
+     */
+    private final AtomicInteger maxFailedAttemptsBeforeError = new AtomicInteger(10);
+
+    private final AtomicLong totalConnectionsCreated = new AtomicLong(0);
+
+    private final AtomicLong totalConnectionsUsed = new AtomicLong(0);
+
+    private final Logger logger = Logger.getLogger(this.getClass());
+
+    /**
+     * Create the pool to use the supplied connection factory, which is typically a {@link RepositorySource}. This constructor
+     * uses the {@link #DEFAULT_CORE_POOL_SIZE default core pool size}, {@link #DEFAULT_MAXIMUM_POOL_SIZE default maximum pool
+     * size}, and {@link #DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS default keep-alive time (in seconds)}.
+     * 
+     * @param connectionFactory the factory for connections
+     * @throws IllegalArgumentException if the connection factory is null or any of the supplied arguments are invalid
+     */
+    public RepositoryConnectionPool( ConnectionFactory connectionFactory ) {
+        this(connectionFactory, DEFAULT_CORE_POOL_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME_IN_SECONDS,
+             TimeUnit.SECONDS);
+    }
+
+    /**
+     * Create the pool to use the supplied connection factory, which is typically a {@link RepositorySource}.
+     * 
+     * @param connectionFactory the factory for connections
+     * @param corePoolSize the number of connections to keep in the pool, even if they are idle.
+     * @param maximumPoolSize the maximum number of connections to allow in the pool.
+     * @param keepAliveTime when the number of connection is greater than the core, this is the maximum time that excess idle
+     *        connections will be kept before terminating.
+     * @param unit the time unit for the keepAliveTime argument.
+     * @throws IllegalArgumentException if the connection factory is null or any of the supplied arguments are invalid
+     */
+    public RepositoryConnectionPool( ConnectionFactory connectionFactory,
+                                     int corePoolSize,
+                                     int maximumPoolSize,
+                                     long keepAliveTime,
+                                     TimeUnit unit ) {
+        ArgCheck.isNonNegative(corePoolSize, "corePoolSize");
+        ArgCheck.isPositive(maximumPoolSize, "maximumPoolSize");
+        ArgCheck.isNonNegative(keepAliveTime, "keepAliveTime");
+        ArgCheck.isNotNull(connectionFactory, "repository connection factory");
+        if (maximumPoolSize < corePoolSize) {
+            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
+        }
+        this.connectionFactory = connectionFactory;
+        this.corePoolSize = corePoolSize;
+        this.maximumPoolSize = maximumPoolSize;
+        this.keepAliveTime = unit.toNanos(keepAliveTime);
+        this.setPingTimeout(100, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Get the name of this pool, which delegates to the connection factory.
+     * 
+     * @return the name of the source
+     */
+    protected String getSourceName() {
+        return connectionFactory.getSourceName();
+    }
+
+    // -------------------------------------------------
+    // Property settings ...
+    // -------------------------------------------------
+
+    /**
+     * @return validateConnectionBeforeUse
+     */
+    public boolean getValidateConnectionBeforeUse() {
+        return this.validateConnectionBeforeUse.get();
+    }
+
+    /**
+     * @param validateConnectionBeforeUse Sets validateConnectionBeforeUse to the specified value.
+     */
+    public void setValidateConnectionBeforeUse( boolean validateConnectionBeforeUse ) {
+        this.validateConnectionBeforeUse.set(validateConnectionBeforeUse);
+    }
+
+    /**
+     * @return pingTimeout
+     */
+    public long getPingTimeoutInNanos() {
+        return this.pingTimeout.get();
+    }
+
+    /**
+     * @param pingTimeout the time to wait for a ping to complete
+     * @param unit the time unit of the time argument
+     */
+    public void setPingTimeout( long pingTimeout,
+                                TimeUnit unit ) {
+        ArgCheck.isNonNegative(pingTimeout, "time");
+        this.pingTimeout.set(unit.toNanos(pingTimeout));
+    }
+
+    /**
+     * @return maxFailedAttemptsBeforeError
+     */
+    public int getMaxFailedAttemptsBeforeError() {
+        return this.maxFailedAttemptsBeforeError.get();
+    }
+
+    /**
+     * @param maxFailedAttemptsBeforeError Sets maxFailedAttemptsBeforeError to the specified value.
+     */
+    public void setMaxFailedAttemptsBeforeError( int maxFailedAttemptsBeforeError ) {
+        this.maxFailedAttemptsBeforeError.set(maxFailedAttemptsBeforeError);
+    }
+
+    /**
+     * Sets the time limit for which connections may remain idle before being closed. If there are more than the core number of
+     * connections currently in the pool, after waiting this amount of time without being used, excess threads will be terminated.
+     * This overrides any value set in the constructor.
+     * 
+     * @param time the time to wait. A time value of zero will cause excess connections to terminate immediately after being
+     *        returned.
+     * @param unit the time unit of the time argument
+     * @throws IllegalArgumentException if time less than zero
+     * @see #getKeepAliveTime
+     */
+    public void setKeepAliveTime( long time,
+                                  TimeUnit unit ) {
+        ArgCheck.isNonNegative(time, "time");
+        this.keepAliveTime = unit.toNanos(time);
+    }
+
+    /**
+     * Returns the connection keep-alive time, which is the amount of time which connections in excess of the core pool size may
+     * remain idle before being closed.
+     * 
+     * @param unit the desired time unit of the result
+     * @return the time limit
+     * @see #setKeepAliveTime
+     */
+    public long getKeepAliveTime( TimeUnit unit ) {
+        assert unit != null;
+        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
+    }
+
+    /**
+     * @return maximumPoolSize
+     */
+    public int getMaximumPoolSize() {
+        return this.maximumPoolSize;
+    }
+
+    /**
+     * Sets the maximum allowed number of connections. This overrides any value set in the constructor. If the new value is
+     * smaller than the current value, excess existing but unused connections will be closed.
+     * 
+     * @param maximumPoolSize the new maximum
+     * @throws IllegalArgumentException if maximumPoolSize less than zero or the {@link #getCorePoolSize() core pool size}
+     * @see #getMaximumPoolSize
+     */
+    public void setMaximumPoolSize( int maximumPoolSize ) {
+        ArgCheck.isPositive(maximumPoolSize, "maximum pool size");
+        if (maximumPoolSize < corePoolSize) {
+            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
+        }
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            int extra = this.maximumPoolSize - maximumPoolSize;
+            this.maximumPoolSize = maximumPoolSize;
+            if (extra > 0 && poolSize > maximumPoolSize) {
+                // Drain the extra connections from those available ...
+                drainUnusedConnections(extra);
+            }
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Returns the core number of connections.
+     * 
+     * @return the core number of connections
+     * @see #setCorePoolSize(int)
+     */
+    public int getCorePoolSize() {
+        return this.corePoolSize;
+    }
+
+    /**
+     * Sets the core number of connections. This overrides any value set in the constructor. If the new value is smaller than the
+     * current value, excess existing and unused connections will be closed. If larger, new connections will, if needed, be
+     * created.
+     * 
+     * @param corePoolSize the new core size
+     * @throws RepositorySourceException if there was an error obtaining the new connection
+     * @throws InterruptedException if the thread was interrupted during the operation
+     * @throws IllegalArgumentException if <tt>corePoolSize</tt> less than zero
+     * @see #getCorePoolSize()
+     */
+    public void setCorePoolSize( int corePoolSize ) throws RepositorySourceException, InterruptedException {
+        ArgCheck.isNonNegative(corePoolSize, "core pool size");
+        if (maximumPoolSize < corePoolSize) {
+            throw new IllegalArgumentException(SpiI18n.maximumPoolSizeMayNotBeSmallerThanCorePoolSize.text());
+        }
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            int extra = this.corePoolSize - corePoolSize;
+            this.corePoolSize = corePoolSize;
+            if (extra < 0) {
+                // Add connections ...
+                addConnectionsIfUnderCorePoolSize();
+            } else if (extra > 0 && poolSize > corePoolSize) {
+                // Drain the extra connections from those available ...
+                drainUnusedConnections(extra);
+            }
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    // -------------------------------------------------
+    // Statistics ...
+    // -------------------------------------------------
+
+    /**
+     * Returns the current number of connections in the pool, including those that are checked out (in use) and those that are not
+     * being used.
+     * 
+     * @return the number of connections
+     */
+    public int getPoolSize() {
+        return poolSize;
+    }
+
+    /**
+     * Returns the approximate number of connections that are currently checked out from the pool.
+     * 
+     * @return the number of checked-out connections
+     */
+    public int getInUseCount() {
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            return this.inUseConnections.size();
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Get the total number of connections that have been created by this pool.
+     * 
+     * @return the total number of connections created by this pool
+     */
+    public long getTotalConnectionsCreated() {
+        return this.totalConnectionsCreated.get();
+    }
+
+    /**
+     * Get the total number of times connections have been {@link #getConnection()} used.
+     * 
+     * @return the total number
+     */
+    public long getTotalConnectionsUsed() {
+        return this.totalConnectionsUsed.get();
+    }
+
+    // -------------------------------------------------
+    // State management methods ...
+    // -------------------------------------------------
+
+    /**
+     * Starts a core connection, causing it to idly wait for use. This overrides the default policy of starting core connections
+     * only when they are {@link #getConnection() needed}. This method will return <tt>false</tt> if all core connections have
+     * already been started.
+     * 
+     * @return true if a connection was started
+     * @throws RepositorySourceException if there was an error obtaining the new connection
+     * @throws InterruptedException if the thread was interrupted during the operation
+     */
+    public boolean prestartCoreConnection() throws RepositorySourceException, InterruptedException {
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            return addConnectionIfUnderCorePoolSize();
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Starts all core connections, causing them to idly wait for use. This overrides the default policy of starting core
+     * connections only when they are {@link #getConnection() needed}.
+     * 
+     * @return the number of connections started.
+     * @throws RepositorySourceException if there was an error obtaining the new connection
+     * @throws InterruptedException if the thread was interrupted during the operation
+     */
+    public int prestartAllCoreConnections() throws RepositorySourceException, InterruptedException {
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            return addConnectionsIfUnderCorePoolSize();
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Initiates an orderly shutdown of the pool in which connections that are currently in use are allowed to be used and closed
+     * as normal, but no new connections will be created. Invocation has no additional effect if already shut down.
+     * <p>
+     * Once the pool has been shutdown, it may not be used to {@link #getConnection() get connections}.
+     * </p>
+     * 
+     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
+     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method denies access.
+     * @see #shutdownNow()
+     */
+    public void shutdown() {
+        // Fail if caller doesn't have modifyThread permission. We
+        // explicitly check permissions directly because we can't trust
+        // implementations of SecurityManager to correctly override
+        // the "check access" methods such that our documented
+        // security policy is implemented.
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) java.security.AccessController.checkPermission(shutdownPerm);
+
+        this.logger.debug("Shutting down repository connection pool for {0}", getSourceName());
+        boolean fullyTerminated = false;
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            int state = this.runState;
+            if (state == RUNNING) {
+                // don't override shutdownNow
+                this.runState = SHUTDOWN;
+            }
+
+            // Kill the maintenance thread ...
+
+            // Remove and close all available connections ...
+            if (!this.availableConnections.isEmpty()) {
+                // Drain the extra connections from those available ...
+                drainUnusedConnections(this.availableConnections.size());
+            }
+
+            // If there are no connections being used, trigger full termination now ...
+            if (this.inUseConnections.isEmpty()) {
+                fullyTerminated = true;
+                this.logger.trace("Signalling termination of repository connection pool for {0}", getSourceName());
+                runState = TERMINATED;
+                termination.signalAll();
+                this.logger.debug("Terminated repository connection pool for {0}", getSourceName());
+            }
+            // Otherwise the last connection that is closed will transition the runState to TERMINATED ...
+        } finally {
+            mainLock.unlock();
+        }
+        if (fullyTerminated) terminated();
+    }
+
+    /**
+     * Attempts to close all connections in the pool, including those connections currently in use, and prevent the use of other
+     * connections.
+     * 
+     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
+     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method denies access.
+     * @see #shutdown()
+     */
+    public void shutdownNow() {
+        // Almost the same code as shutdown()
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) java.security.AccessController.checkPermission(shutdownPerm);
+
+        this.logger.debug("Shutting down (immediately) repository connection pool for {0}", getSourceName());
+        boolean fullyTerminated = false;
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            int state = this.runState;
+            if (state != TERMINATED) {
+                // don't override shutdownNow
+                this.runState = STOP;
+            }
+
+            // Kill the maintenance thread ...
+
+            // Remove and close all available connections ...
+            if (!this.availableConnections.isEmpty()) {
+                // Drain the extra connections from those available ...
+                drainUnusedConnections(this.availableConnections.size());
+            }
+
+            // If there are connections being used, close them now ...
+            if (!this.inUseConnections.isEmpty()) {
+                for (ConnectionWrapper connectionInUse : this.inUseConnections) {
+                    try {
+                        this.logger.trace("Closing repository connection to {0}", getSourceName());
+                        connectionInUse.getOriginal().close();
+                    } catch (InterruptedException e) {
+                        // Ignore this ...
+                    }
+                }
+                this.poolSize -= this.inUseConnections.size();
+                // The last connection that is closed will transition the runState to TERMINATED ...
+            } else {
+                // There are no connections in use, so trigger full termination now ...
+                fullyTerminated = true;
+                this.logger.trace("Signalling termination of repository connection pool for {0}", getSourceName());
+                runState = TERMINATED;
+                termination.signalAll();
+                this.logger.debug("Terminated repository connection pool for {0}", getSourceName());
+            }
+
+        } finally {
+            mainLock.unlock();
+        }
+        if (fullyTerminated) terminated();
+    }
+
+    /**
+     * Return whether this connection pool is running and is able to {@link #getConnection() provide connections}. Note that this
+     * method is effectively <code>!isShutdown()</code>.
+     * 
+     * @return true if this pool is running, or false otherwise
+     * @see #isShutdown()
+     * @see #isTerminated()
+     * @see #isTerminating()
+     */
+    public boolean isRunning() {
+        return runState == RUNNING;
+    }
+
+    /**
+     * Return whether this connection pool is in the process of shutting down or has already been shut down. A result of
+     * <code>true</code> signals that the pool may no longer be used. Note that this method is effectively
+     * <code>!isRunning()</code>.
+     * 
+     * @return true if this pool has been shut down, or false otherwise
+     * @see #isShutdown()
+     * @see #isTerminated()
+     * @see #isTerminating()
+     */
+    public boolean isShutdown() {
+        return runState != RUNNING;
+    }
+
+    /**
+     * Returns true if this pool is in the process of terminating after {@link #shutdown()} or {@link #shutdownNow()} has been
+     * called but has not completely terminated. This method may be useful for debugging. A return of <tt>true</tt> reported a
+     * sufficient period after shutdown may indicate that submitted tasks have ignored or suppressed interruption, causing this
+     * executor not to properly terminate.
+     * 
+     * @return true if terminating but not yet terminated, or false otherwise
+     * @see #isTerminated()
+     */
+    public boolean isTerminating() {
+        return runState == STOP;
+    }
+
+    /**
+     * Return true if this pool has completed its termination and no longer has any open connections.
+     * 
+     * @return true if terminated, or false otherwise
+     * @see #isTerminating()
+     */
+    public boolean isTerminated() {
+        return runState == TERMINATED;
+    }
+
+    /**
+     * Method that can be called after {@link #shutdown()} or {@link #shutdownNow()} to wait until all connections in use at the
+     * time those methods were called have been closed normally. This method accepts a maximum time duration, after which it will
+     * return even if all connections have not been closed.
+     * 
+     * @param timeout the maximum time to wait for all connections to be closed and returned to the pool
+     * @param unit the time unit for <code>timeout</code>
+     * @return true if the pool was terminated in the supplied time (or was already terminated), or false if the timeout occurred
+     *         before all the connections were closed
+     * @throws InterruptedException if the thread was interrupted
+     */
+    public boolean awaitTermination( long timeout,
+                                     TimeUnit unit ) throws InterruptedException {
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            for (;;) {
+                // this.logger.debug("---> Run state = {}; condition = {}", runState, termination);
+                if (runState == TERMINATED) return true;
+                if (nanos <= 0) return false;
+                nanos = termination.awaitNanos(nanos);
+                // this.logger.debug("---> Done waiting: run state = {}; condition = {}", runState, termination);
+            }
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Method invoked when the pool has terminated. Default implementation does nothing. Note: To properly nest multiple
+     * overridings, subclasses should generally invoke <tt>super.terminated</tt> within this method.
+     */
+    protected void terminated() {
+    }
+
+    /**
+     * Invokes <tt>shutdown</tt> when this pool is no longer referenced.
+     */
+    @Override
+    protected void finalize() {
+        shutdown();
+    }
+
+    // -------------------------------------------------
+    // Connection management methods ...
+    // -------------------------------------------------
+
+    /**
+     * Get a connection from the pool. This method either returns an unused connection if one is available, creates a connection
+     * if there is still room in the pool, or blocks until a connection becomes available if the pool already contains the maximum
+     * number of connections and all connections are currently being used.
+     * 
+     * @return a connection
+     * @throws RepositorySourceException if there is a problem obtaining a connection
+     * @throws InterruptedException if the thread is interrupted while attempting to get a connection
+     * @throws IllegalStateException if the factory is not in a state to create or return connections
+     */
+    public RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException {
+        int attemptsAllowed = this.maxFailedAttemptsBeforeError.get();
+        ConnectionWrapper connection = null;
+        // Do this until we get a good connection ...
+        int attemptsRemaining = attemptsAllowed;
+        while (connection == null && attemptsRemaining > 0) {
+            --attemptsRemaining;
+            ReentrantLock mainLock = this.mainLock;
+            try {
+                mainLock.lock();
+                // If we're shutting down the pool, then just close the connection ...
+                if (this.runState != RUNNING) {
+                    throw new IllegalStateException(SpiI18n.repositoryConnectionPoolIsNotRunning.text());
+                }
+                // If there are fewer total connections than the core size ...
+                if (this.poolSize < this.corePoolSize) {
+                    // Immediately create a wrapped connection and return it ...
+                    connection = newWrappedConnection();
+                }
+                // Peek to see if there is a connection available ...
+                else if (this.availableConnections.peek() != null) {
+                    // There is, so take it and return it ...
+                    connection = this.availableConnections.take();
+                }
+                // There is no connection available. If there are fewer total connections than the maximum size ...
+                else if (this.poolSize < this.maximumPoolSize) {
+                    // Immediately create a wrapped connection and return it ...
+                    connection = newWrappedConnection();
+                }
+                if (connection != null) {
+                    this.inUseConnections.add(connection);
+                }
+            } finally {
+                mainLock.unlock();
+            }
+            if (connection == null) {
+                // There are not enough connections, so wait in line for the next available connection ...
+                this.logger.trace("Waiting for a repository connection from pool {0}", getSourceName());
+                connection = this.availableConnections.take();
+                mainLock = this.mainLock;
+                mainLock.lock();
+                try {
+                    if (connection != null) {
+                        this.inUseConnections.add(connection);
+                    }
+                } finally {
+                    mainLock.unlock();
+                }
+                this.logger.trace("Recieved a repository connection from pool {0}", getSourceName());
+            }
+            if (connection != null && this.validateConnectionBeforeUse.get()) {
+                connection = validateConnection(connection);
+            }
+        }
+        if (connection == null) {
+            // We were unable to obtain a usable connection, so fail ...
+            throw new RepositorySourceException(SpiI18n.unableToObtainValidRepositoryAfterAttempts.text(attemptsAllowed));
+        }
+        this.totalConnectionsUsed.incrementAndGet();
+        return connection;
+    }
+
+    /**
+     * This method is automatically called by the {@link ConnectionWrapper} when it is {@link ConnectionWrapper#close() closed}.
+     * 
+     * @param wrapper the wrapper to the connection that is being returned to the pool
+     */
+    protected void returnConnection( ConnectionWrapper wrapper ) {
+        assert wrapper != null;
+        ConnectionWrapper wrapperToClose = null;
+        final ReentrantLock mainLock = this.mainLock;
+        try {
+            mainLock.lock();
+            // Remove the connection from the in-use set ...
+            boolean removed = this.inUseConnections.remove(wrapper);
+            assert removed;
+
+            // If we're shutting down the pool, then just close the connection ...
+            if (this.runState != RUNNING) {
+                wrapperToClose = wrapper;
+            }
+            // If there are more connections than the maximum size...
+            else if (this.poolSize > this.maximumPoolSize) {
+                // Immediately close this connection ...
+                wrapperToClose = wrapper;
+            }
+            // Attempt to make the connection available (this should generally work, unless there is an upper limit
+            // to the number of available connections) ...
+            else if (!this.availableConnections.offer(new ConnectionWrapper(wrapper.getOriginal()))) {
+                // The pool of available connection is full, so release it ...
+                wrapperToClose = wrapper;
+            }
+        } finally {
+            mainLock.unlock();
+        }
+        // Close the connection if we're supposed to (do it outside of the main lock)...
+        if (wrapperToClose != null) {
+            try {
+                closeConnection(wrapper);
+            } catch (InterruptedException e) {
+                // catch this, as there's not much we can do and the caller doesn't care or know how to handle it
+                this.logger.trace(e, "Interrupted while closing a repository connection");
+            }
+        }
+    }
+
+    /**
+     * Validate the supplied connection, returning the connection if valid or null if the connection is not valid.
+     * 
+     * @param connection the connection to be validated; may not be null
+     * @return the validated connection, or null if the connection did not validate and was removed from the pool
+     */
+    protected ConnectionWrapper validateConnection( ConnectionWrapper connection ) {
+        assert connection != null;
+        ConnectionWrapper invalidConnection = null;
+        try {
+            if (!connection.ping(this.pingTimeout.get(), TimeUnit.NANOSECONDS)) {
+                invalidConnection = connection;
+            }
+        } catch (InterruptedException e) {
+            // catch this, as there's not much we can do and the caller doesn't care or know how to handle it
+            this.logger.trace(e, "Interrupted while pinging a repository connection");
+            invalidConnection = connection;
+        } finally {
+            if (invalidConnection != null) {
+                connection = null;
+                returnConnection(invalidConnection);
+            }
+        }
+        return connection;
+    }
+
+    /**
+     * Obtain a new connection wrapped in a {@link ConnectionWrapper}. This method does not check whether creating the new
+     * connection would violate the {@link #maximumPoolSize maximum pool size} nor does it add the new connection to the
+     * {@link #availableConnections available connections} (as the caller may want it immediately), but it does increment the
+     * {@link #poolSize pool size}.
+     * 
+     * @return the connection wrapper with a new connection
+     * @throws RepositorySourceException if there was an error obtaining the new connection
+     * @throws InterruptedException if the thread was interrupted during the operation
+     */
+    @GuardedBy( "mainLock" )
+    protected ConnectionWrapper newWrappedConnection() throws RepositorySourceException, InterruptedException {
+        RepositoryConnection connection = this.connectionFactory.createConnection();
+        ++this.poolSize;
+        this.totalConnectionsCreated.incrementAndGet();
+        return new ConnectionWrapper(connection);
+    }
+
+    /**
+     * Close a connection that is in the pool but no longer in the {@link #availableConnections available connections}. This
+     * method does decrement the {@link #poolSize pool size}.
+     * 
+     * @param wrapper the wrapper for the connection to be closed
+     * @throws InterruptedException if the thread was interrupted during the operation
+     */
+    protected void closeConnection( ConnectionWrapper wrapper ) throws InterruptedException {
+        assert wrapper != null;
+        RepositoryConnection original = wrapper.getOriginal();
+        assert original != null;
+        try {
+            this.logger.debug("Closing repository connection to {0}", getSourceName());
+            original.close();
+        } finally {
+            final ReentrantLock mainLock = this.mainLock;
+            try {
+                mainLock.lock();
+                // No matter what reduce the pool size count
+                --this.poolSize;
+                // And if shutting down and this was the last connection being used...
+                if (this.runState == SHUTDOWN && this.poolSize <= 0) {
+                    // then signal anybody that has called "awaitTermination(...)"
+                    this.logger.trace("Signalling termination of repository connection pool for {0}", getSourceName());
+                    this.runState = TERMINATED;
+                    this.termination.signalAll();
+                    this.logger.trace("Terminated repository connection pool for {0}", getSourceName());
+
+                    // fall through to call terminate() outside of lock.
+                }
+            } finally {
+                mainLock.unlock();
+            }
+        }
+    }
+
+    @GuardedBy( "mainLock" )
+    protected int drainUnusedConnections( int count ) {
+        if (count <= 0) return 0;
+        this.logger.trace("Draining up to {0} unused repository connections to {1}", count, getSourceName());
+        // Drain the extra connections from those available ...
+        Collection<ConnectionWrapper> extraConnections = new LinkedList<ConnectionWrapper>();
+        this.availableConnections.drainTo(extraConnections, count);
+        for (ConnectionWrapper connection : extraConnections) {
+            try {
+                this.logger.trace("Closing repository connection to {0}", getSourceName());
+                connection.getOriginal().close();
+            } catch (InterruptedException e) {
+                // Ignore this ...
+            }
+        }
+        int numClosed = extraConnections.size();
+        this.poolSize -= numClosed;
+        this.logger.trace("Drained {0} unused connections", numClosed);
+        return numClosed;
+    }
+
+    @GuardedBy( "mainLock" )
+    protected boolean addConnectionIfUnderCorePoolSize() throws RepositorySourceException, InterruptedException {
+        // Add connection ...
+        if (this.poolSize < this.corePoolSize) {
+            this.availableConnections.offer(newWrappedConnection());
+            this.logger.trace("Added connection to {0} in undersized pool", getSourceName());
+            return true;
+        }
+        return false;
+    }
+
+    @GuardedBy( "mainLock" )
+    protected int addConnectionsIfUnderCorePoolSize() throws RepositorySourceException, InterruptedException {
+        // Add connections ...
+        int n = 0;
+        while (this.poolSize < this.corePoolSize) {
+            this.availableConnections.offer(newWrappedConnection());
+            ++n;
+        }
+        this.logger.trace("Added {0} connection(s) to {1} in undersized pool", n, getSourceName());
+        return n;
+    }
+
+    protected class ConnectionWrapper implements RepositoryConnection {
+
+        private final RepositoryConnection original;
+        private final long timeCreated;
+        private long lastUsed;
+        private boolean closed = false;
+
+        protected ConnectionWrapper( RepositoryConnection connection ) {
+            assert connection != null;
+            this.original = connection;
+            this.timeCreated = System.currentTimeMillis();
+        }
+
+        /**
+         * @return original
+         */
+        protected RepositoryConnection getOriginal() {
+            return this.original;
+        }
+
+        /**
+         * @return lastUsed
+         */
+        public long getTimeLastUsed() {
+            return this.lastUsed;
+        }
+
+        /**
+         * @return timeCreated
+         */
+        public long getTimeCreated() {
+            return this.timeCreated;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String getSourceName() {
+            return this.original.getSourceName();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public XAResource getXAResource() {
+            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
+            return this.original.getXAResource();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public CachePolicy getDefaultCachePolicy() {
+            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
+            return this.original.getDefaultCachePolicy();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void execute( ExecutionContext context,
+                             GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
+            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
+            this.original.execute(context, commands);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean ping( long time,
+                             TimeUnit unit ) throws InterruptedException {
+            if (closed) throw new IllegalStateException(SpiI18n.closedConnectionMayNotBeUsed.text());
+            return this.original.ping(time, unit);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void close() throws InterruptedException {
+            if (!closed) {
+                this.lastUsed = System.currentTimeMillis();
+                this.original.close();
+                this.closed = true;
+                returnConnection(this);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void setListener( RepositorySourceListener listener ) {
+            if (!closed) this.original.setListener(listener);
+        }
+
+    }
+
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperation.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryOperation.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperation.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,68 +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.dna.spi.graph.connection;
-
-import org.jboss.dna.spi.ExecutionContext;
-
-/**
- * An operation that runs against a repository connection.
- * 
- * @author Randall Hauch
- * @param <T> the type of result returned by the client
- */
-public interface RepositoryOperation<T> {
-
-    /**
-     * Get the name of this operation.
-     * 
-     * @return the operation's name
-     */
-    String getName();
-
-    /**
-     * Run the operation using the supplied connection.
-     * 
-     * @param context the environment in which this operation is executing; may not be null
-     * @param connection the connection; may not be null
-     * @return the result of the operation
-     * @throws RepositorySourceException if there is a problem with the connection
-     * @throws InterruptedException if this thread was interrupted
-     */
-    T run( ExecutionContext context,
-           RepositoryConnection connection ) throws RepositorySourceException, InterruptedException;
-
-    /**
-     * A factory interface for creating repository operations.
-     * 
-     * @param <T> the type of result for the operations
-     * @author Randall Hauch
-     */
-    public static interface Factory<T> {
-
-        /**
-         * Create a repository operation that returns the result of type T.
-         * 
-         * @return the operation
-         */
-        RepositoryOperation<T> create();
-    }
-}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperations.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryOperations.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositoryOperations.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,171 +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.dna.spi.graph.connection;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Callable;
-import org.jboss.dna.common.util.ArgCheck;
-import org.jboss.dna.common.util.LogContext;
-import org.jboss.dna.spi.ExecutionContext;
-
-/**
- * @author Randall Hauch
- */
-public class RepositoryOperations {
-
-    /**
-     * Call the supplied operation, using a connection from this pool.
-     * 
-     * @param <T> the return type for the operation
-     * @param context the context in which the operation is to execute; may not be null
-     * @param connectionFactory the factory for the connection to use
-     * @param operation the operation to be run using a new connection obtained from the factory
-     * @return the results from the operation
-     * @throws RepositorySourceException if there was an error obtaining the new connection
-     * @throws InterruptedException if the thread was interrupted during the operation
-     * @throws IllegalArgumentException if the operation is null
-     * @see #createCallable(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, Iterable)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation...)
-     */
-    public static <T> T call( ExecutionContext context,
-                              RepositoryConnectionFactory connectionFactory,
-                              RepositoryOperation<T> operation ) throws RepositorySourceException, InterruptedException {
-        ArgCheck.isNotNull(operation, "repository operation");
-        // Get a connection ...
-        T result = null;
-        LogContext.set("context", operation.getName());
-        RepositoryConnection conn = connectionFactory.getConnection();
-        try {
-            // And run the client with the connection ...
-            result = operation.run(context, conn);
-        } finally {
-            conn.close();
-        }
-        LogContext.clear();
-        return result;
-    }
-
-    /**
-     * Return a callable object that, when run, performs the supplied repository operation against a connection obtained from the
-     * supplied factory.
-     * 
-     * @param <T> the return type for the operation
-     * @param context the context in which the operation is to execute; may not be null
-     * @param connectionFactory the factory for the connection to use
-     * @param operation the operation to be run using a new connection obtained from the factory
-     * @return the callable
-     * @see #call(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, Iterable)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation...)
-     */
-    public static <T> Callable<T> createCallable( final ExecutionContext context,
-                                                  final RepositoryConnectionFactory connectionFactory,
-                                                  final RepositoryOperation<T> operation ) {
-        ArgCheck.isNotNull(operation, "repository operation");
-        return new Callable<T>() {
-
-            /**
-             * Execute by getting a connection from this pool, running the client, and return the connection to the pool.
-             * 
-             * @return the operation's result
-             * @throws Exception
-             */
-            public T call() throws Exception {
-                return RepositoryOperations.call(context, connectionFactory, operation);
-            }
-        };
-    }
-
-    /**
-     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
-     * this pool.
-     * 
-     * @param <T> the return type for the operations
-     * @param context the context in which the operation is to execute; may not be null
-     * @param connectionFactory the factory for the connection to use
-     * @param operations the operations to be run using connections from the factory
-     * @return the collection of callables
-     * @see #call(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallable(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, Iterable)
-     */
-    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
-                                                         final RepositoryConnectionFactory connectionFactory,
-                                                         final RepositoryOperation<T>... operations ) {
-        List<Callable<T>> callables = new ArrayList<Callable<T>>();
-        for (final RepositoryOperation<T> operation : operations) {
-            callables.add(createCallable(context, connectionFactory, operation));
-        }
-        return callables;
-    }
-
-    /**
-     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
-     * this pool.
-     * 
-     * @param <T> the return type for the operations
-     * @param context the context in which the operation is to execute; may not be null
-     * @param connectionFactory the factory for the connection to use
-     * @param operations the operations to be run using connections from the factory
-     * @return the collection of callables
-     * @see #call(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallable(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation...)
-     */
-    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
-                                                         final RepositoryConnectionFactory connectionFactory,
-                                                         Iterable<RepositoryOperation<T>> operations ) {
-        List<Callable<T>> callables = new ArrayList<Callable<T>>();
-        for (final RepositoryOperation<T> operation : operations) {
-            callables.add(createCallable(context, connectionFactory, operation));
-        }
-        return callables;
-    }
-
-    /**
-     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
-     * this pool.
-     * 
-     * @param <T> the return type for the operations
-     * @param context the context in which the operation is to execute; may not be null
-     * @param connectionFactory the factory for the connection to use
-     * @param operations the operations to be run using connections from the factory
-     * @return the collection of callables
-     * @see #call(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallable(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation)
-     * @see #createCallables(ExecutionContext, RepositoryConnectionFactory, RepositoryOperation...)
-     */
-    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
-                                                         final RepositoryConnectionFactory connectionFactory,
-                                                         Iterator<RepositoryOperation<T>> operations ) {
-        List<Callable<T>> callables = new ArrayList<Callable<T>>();
-        while (operations.hasNext()) {
-            final RepositoryOperation<T> operation = operations.next();
-            callables.add(createCallable(context, connectionFactory, operation));
-        }
-        return callables;
-    }
-
-}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySource.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,75 +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.dna.spi.graph.connection;
-
-import java.io.Serializable;
-import javax.naming.Referenceable;
-
-/**
- * A repository source is a description of a resource that can be used to access or store repository information. This class
- * serves as a factory for {@link RepositoryConnection} instances and provides some basic configuration information.
- * <p>
- * Typically this interface is implemented by classes that provide standard-style getters and setters for the various properties
- * necessary for proper configuration via reflection or introspection. This interface expects nor defines any such properties,
- * leaving that entirely to the implementation classes.
- * </p>
- * <p>
- * Implementations should also provide a no-arg constructor so that it is possible to easily create instances and initialize using
- * the standard getters and setters. One example where this is required is when a RepositorySource instance is recorded in a
- * repository (e.g., in a configuration area), and needs to be reinstantiated.
- * </p>
- * <p>
- * Objects that implement this <code>RepositorySource</code> interface are typically registered with a naming service such as Java
- * Naming and Directory Interface<sup><font size=-3>TM</font></sup> (JNDI). This interface extends both {@link Referenceable} and
- * {@link Serializable} so that such objects can be stored in any JNDI naming context and enable proper system recovery,
- * </p>
- * 
- * @author Randall Hauch
- */
-public interface RepositorySource extends ManagedRepositoryConnectionFactory, Referenceable, Serializable {
-
-    /**
-     * Get the maximum number of retries that may be performed on a given operation when using {@link #getConnection()
-     * connections} created by this source. This value does not constitute a minimum number of retries; in fact, the connection
-     * user is not required to retry any operations.
-     * 
-     * @return the maximum number of allowable retries, or 0 if the source has no limit
-     */
-    int getRetryLimit();
-
-    /**
-     * Set the maximum number of retries that may be performed on a given operation when using {@link #getConnection()
-     * connections} created by this source. This value does not constitute a minimum number of retries; in fact, the connection
-     * user is not required to retry any operations.
-     * 
-     * @param limit the maximum number of allowable retries, or 0 if the source has no limit
-     */
-    void setRetryLimit( int limit );
-
-    /**
-     * Get the capabilities for this source.
-     * 
-     * @return the capabilities for this source; never null
-     */
-    RepositorySourceCapabilities getCapabilities();
-
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySource.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,178 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+import javax.naming.Referenceable;
+
+/**
+ * A repository source is a description of a resource that can be used to access or store repository information. This class
+ * serves as a factory for {@link RepositoryConnection} instances and provides some basic configuration information.
+ * <p>
+ * Typically this interface is implemented by classes that provide standard-style getters and setters for the various properties
+ * necessary for proper configuration via reflection or introspection. This interface expects nor defines any such properties,
+ * leaving that entirely to the implementation classes.
+ * </p>
+ * <p>
+ * Implementations should also provide a no-arg constructor so that it is possible to easily create instances and initialize using
+ * the standard getters and setters. One example where this is required is when a RepositorySource instance is recorded in a
+ * repository (e.g., in a configuration area), and needs to be reinstantiated.
+ * </p>
+ * <p>
+ * Objects that implement this <code>RepositorySource</code> interface are typically registered with a naming service such as Java
+ * Naming and Directory Interface<sup><font size=-3>TM</font></sup> (JNDI). This interface extends both {@link Referenceable} and
+ * {@link Serializable} so that such objects can be stored in any JNDI naming context and enable proper system recovery,
+ * </p>
+ * <p>
+ * Pooling connections is not done above or outside of the RepositorySource implementations. Therefore, if an implementation would
+ * benefit from pooling connections, it should use a pool within the implementation (and expose any pool parameters as desired).
+ * If this is the case, the implementation class may benefit from subclassing {@link AbstractRepositorySource} (which manages a
+ * pool of connections).
+ * </p>
+ * 
+ * @author Randall Hauch
+ */
+public interface RepositorySource extends Referenceable, Serializable {
+
+    /**
+     * Get the name for this repository source.
+     * 
+     * @return the name; never null or empty
+     */
+    String getName();
+
+    /**
+     * Get a connection from this source.
+     * 
+     * @return a connection
+     * @throws RepositorySourceException if there is a problem obtaining a connection
+     * @throws InterruptedException if the thread is interrupted while attempting to get a connection
+     * @throws IllegalStateException if the factory is not in a state to create or return connections
+     */
+    RepositoryConnection getConnection() throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Initiates an orderly shutdown in which connections that are currently in use are allowed to be used and closed as normal,
+     * but no new connections will be created. Invocation has no additional effect if already shut down.
+     * <p>
+     * Once the source has been shutdown, it may not be used to {@link #getConnection() get connections}.
+     * </p>
+     * 
+     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
+     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method denies access.
+     * @see #shutdownNow()
+     */
+    void shutdown();
+
+    /**
+     * Attempts to close all connections, including those connections currently in use, and prevent the use of other connections.
+     * 
+     * @throws SecurityException if a security manager exists and shutting down this pool may manipulate threads that the caller
+     *         is not permitted to modify because it does not hold {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method denies access.
+     * @see #shutdown()
+     */
+    void shutdownNow();
+
+    /**
+     * Return whether this source is running and is able to {@link #getConnection() provide connections}. Note that this method is
+     * effectively <code>!isShutdown()</code>.
+     * 
+     * @return true if this source is running, or false otherwise
+     * @see #isShutdown()
+     * @see #isTerminated()
+     * @see #isTerminating()
+     */
+    boolean isRunning();
+
+    /**
+     * Return whether this source is in the process of shutting down or has already been shut down. A result of <code>true</code>
+     * signals that the pool may no longer be used. Note that this method is effectively <code>!isRunning()</code>.
+     * 
+     * @return true if this source has been shut down, or false otherwise
+     * @see #isShutdown()
+     * @see #isTerminated()
+     * @see #isTerminating()
+     */
+    boolean isShutdown();
+
+    /**
+     * Returns true if this source is in the process of terminating after {@link #shutdown()} or {@link #shutdownNow()} has been
+     * called but has not completely terminated. This method may be useful for debugging. A return of <tt>true</tt> reported a
+     * sufficient period after shutdown may indicate that submitted tasks have ignored or suppressed interruption, causing this
+     * executor not to properly terminate.
+     * 
+     * @return true if terminating but not yet terminated, or false otherwise
+     * @see #isTerminated()
+     */
+    boolean isTerminating();
+
+    /**
+     * Return true if this pool has completed its termination and no longer has any open connections.
+     * 
+     * @return true if terminated, or false otherwise
+     * @see #isTerminating()
+     */
+    boolean isTerminated();
+
+    /**
+     * Method that can be called after {@link #shutdown()} or {@link #shutdownNow()} to wait until all connections in use at the
+     * time those methods were called have been closed normally. This method accepts a maximum time duration, after which it will
+     * return even if all connections have not been closed.
+     * 
+     * @param timeout the maximum time to wait for all connections to be closed and returned to the pool
+     * @param unit the time unit for <code>timeout</code>
+     * @return true if the pool was terminated in the supplied time (or was already terminated), or false if the timeout occurred
+     *         before all the connections were closed
+     * @throws InterruptedException if the thread was interrupted
+     */
+    boolean awaitTermination( long timeout,
+                              TimeUnit unit ) throws InterruptedException;
+
+    /**
+     * Get the maximum number of retries that may be performed on a given operation when using {@link #getConnection()
+     * connections} created by this source. This value does not constitute a minimum number of retries; in fact, the connection
+     * user is not required to retry any operations.
+     * 
+     * @return the maximum number of allowable retries, or 0 if the source has no limit
+     */
+    int getRetryLimit();
+
+    /**
+     * Set the maximum number of retries that may be performed on a given operation when using {@link #getConnection()
+     * connections} created by this source. This value does not constitute a minimum number of retries; in fact, the connection
+     * user is not required to retry any operations.
+     * 
+     * @param limit the maximum number of allowable retries, or 0 if the source has no limit
+     */
+    void setRetryLimit( int limit );
+
+    /**
+     * Get the capabilities for this source.
+     * 
+     * @return the capabilities for this source; never null
+     */
+    RepositorySourceCapabilities getCapabilities();
+
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceCapabilities.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,44 +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.dna.spi.graph.connection;
-
-/**
- * The capabilities of a {@link RepositorySource}.
- * 
- * @author Randall Hauch
- */
-public interface RepositorySourceCapabilities {
-
-    /**
-     * Return whether the source supports same name siblings. If not, then no two siblings may share the same name.
-     * 
-     * @return true if same name siblings are supported, or false otherwise
-     */
-    boolean supportsSameNameSiblings();
-
-    /**
-     * Return whether the source supports updates.
-     * 
-     * @return true if updates are supported, or false if the source only supports reads.
-     */
-    boolean supportsUpdates();
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceCapabilities.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceCapabilities.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,44 @@
+/*
+ * 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.dna.spi.connector;
+
+/**
+ * The capabilities of a {@link RepositorySource}.
+ * 
+ * @author Randall Hauch
+ */
+public interface RepositorySourceCapabilities {
+
+    /**
+     * Return whether the source supports same name siblings. If not, then no two siblings may share the same name.
+     * 
+     * @return true if same name siblings are supported, or false otherwise
+     */
+    boolean supportsSameNameSiblings();
+
+    /**
+     * Return whether the source supports updates.
+     * 
+     * @return true if updates are supported, or false if the source only supports reads.
+     */
+    boolean supportsUpdates();
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceException.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,84 +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.dna.spi.graph.connection;
-
-/**
- * @author Randall Hauch
- */
-public class RepositorySourceException extends RuntimeException {
-
-    /**
-     */
-    private static final long serialVersionUID = -7704170453962924565L;
-    private final String sourceName;
-
-    /**
-     * @param sourceName the identifier of the source from which this exception eminates
-     */
-    public RepositorySourceException( String sourceName ) {
-        this.sourceName = sourceName;
-    }
-
-    /**
-     * @param sourceName the identifier of the source from which this exception eminates
-     * @param message
-     */
-    public RepositorySourceException( String sourceName, String message ) {
-        super(message);
-        this.sourceName = sourceName;
-    }
-
-    /**
-     * @param sourceName the identifier of the source from which this exception eminates
-     * @param cause
-     */
-    public RepositorySourceException( String sourceName, Throwable cause ) {
-        super(cause);
-        this.sourceName = sourceName;
-    }
-
-    /**
-     * @param sourceName the identifier of the source from which this exception eminates
-     * @param message
-     * @param cause
-     */
-    public RepositorySourceException( String sourceName, String message, Throwable cause ) {
-        super(message, cause);
-        this.sourceName = sourceName;
-    }
-
-    /**
-     * @return sourceName
-     */
-    public String getSourceName() {
-        return this.sourceName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-        return super.toString();
-    }
-
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceException.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceException.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,84 @@
+/*
+ * 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.dna.spi.connector;
+
+/**
+ * @author Randall Hauch
+ */
+public class RepositorySourceException extends RuntimeException {
+
+    /**
+     */
+    private static final long serialVersionUID = -7704170453962924565L;
+    private final String sourceName;
+
+    /**
+     * @param sourceName the identifier of the source from which this exception eminates
+     */
+    public RepositorySourceException( String sourceName ) {
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * @param sourceName the identifier of the source from which this exception eminates
+     * @param message
+     */
+    public RepositorySourceException( String sourceName, String message ) {
+        super(message);
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * @param sourceName the identifier of the source from which this exception eminates
+     * @param cause
+     */
+    public RepositorySourceException( String sourceName, Throwable cause ) {
+        super(cause);
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * @param sourceName the identifier of the source from which this exception eminates
+     * @param message
+     * @param cause
+     */
+    public RepositorySourceException( String sourceName, String message, Throwable cause ) {
+        super(message, cause);
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * @return sourceName
+     */
+    public String getSourceName() {
+        return this.sourceName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return super.toString();
+    }
+
+}

Deleted: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceListener.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,30 +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.dna.spi.graph.connection;
-
-/**
- * @author Randall Hauch
- */
-public interface RepositorySourceListener {
-
-    void notify( String sourceName, Object... events );
-}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java (from rev 393, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositorySourceListener.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceListener.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,30 @@
+/*
+ * 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.dna.spi.connector;
+
+/**
+ * @author Randall Hauch
+ */
+public interface RepositorySourceListener {
+
+    void notify( String sourceName, Object... events );
+}

Copied: trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceRegistry.java (from rev 389, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionFactories.java)
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceRegistry.java	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/connector/RepositorySourceRegistry.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -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.dna.spi.connector;
+
+/**
+ * An interface for any collection of {@link RepositorySource} instances that are accessed by their name.
+ * 
+ * @author Randall Hauch
+ */
+public interface RepositorySourceRegistry {
+
+    /**
+     * Obtain a {@link RepositorySource} given its name.
+     * 
+     * @param sourceName the name of the source to obtain
+     * @return the source, or null if no such source could be found (or created)
+     */
+    RepositorySource getRepositorySource( String sourceName );
+
+}

Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -22,6 +22,8 @@
 package org.jboss.dna.spi.graph.commands.executor;
 
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.DateTime;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
@@ -35,8 +37,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.RepositoryConnection;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * Abstract implementation of the {@link CommandExecutor} interface that provides implementations for all methods, making this a

Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -21,6 +21,7 @@
  */
 package org.jboss.dna.spi.graph.commands.executor;
 
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
 import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
@@ -33,7 +34,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch

Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/DelegatingCommandExecutor.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/DelegatingCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/DelegatingCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -21,6 +21,7 @@
  */
 package org.jboss.dna.spi.graph.commands.executor;
 
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
 import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
@@ -33,7 +34,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch

Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/LoggingCommandExecutor.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/LoggingCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/LoggingCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -23,6 +23,7 @@
 
 import org.jboss.dna.common.util.Logger;
 import org.jboss.dna.spi.SpiI18n;
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
 import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
@@ -35,7 +36,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch

Modified: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/NoOpCommandExecutor.java
===================================================================
--- trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/NoOpCommandExecutor.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/NoOpCommandExecutor.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -22,6 +22,8 @@
 package org.jboss.dna.spi.graph.commands.executor;
 
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.DateTime;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
@@ -35,8 +37,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.RepositorySource;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector (from rev 389, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection)

Deleted: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPoolTest.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,219 +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.dna.spi.graph.connection;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNull.notNullValue;
-import static org.jboss.dna.spi.graph.connection.RepositorySourceLoadHarness.runLoadTest;
-import static org.junit.Assert.assertThat;
-import java.util.List;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import org.jboss.dna.spi.ExecutionContext;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-/**
- * @author Randall Hauch
- */
-public class RepositoryConnectionPoolTest {
-
-    private RepositoryConnectionPool pool;
-    private TimeDelayingRepositorySource repositorySource;
-    private ExecutionContext context;
-
-    @Before
-    public void beforeEach() {
-        this.repositorySource = new TimeDelayingRepositorySource("source 1");
-        this.pool = new RepositoryConnectionPool(this.repositorySource, 1, 1, 100, TimeUnit.SECONDS);
-        this.context = null;
-    }
-
-    @After
-    public void afterEach() throws Exception {
-        pool.shutdown();
-        pool.awaitTermination(2, TimeUnit.SECONDS);
-    }
-
-    @Test
-    public void shouldBeCreatedInRunningState() {
-        assertThat(pool.isShutdown(), is(false));
-        assertThat(pool.isTerminating(), is(false));
-        assertThat(pool.isTerminated(), is(false));
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-    }
-
-    @Test
-    public void shouldShutdownWhenNoConnectionsWereCreatedOrUsed() throws InterruptedException {
-        assertThat(pool.isShutdown(), is(false));
-        assertThat(pool.isTerminating(), is(false));
-        assertThat(pool.isTerminated(), is(false));
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-
-        for (int i = 0; i != 4; ++i) {
-            pool.shutdown();
-            assertThat(pool.isShutdown() || pool.isTerminating() || pool.isTerminated(), is(true));
-            pool.awaitTermination(2, TimeUnit.SECONDS);
-            assertThat(pool.isTerminated(), is(true));
-            assertThat(pool.getTotalConnectionsCreated(), is(0l));
-            assertThat(pool.getTotalConnectionsUsed(), is(0l));
-        }
-    }
-
-    @Test
-    public void shouldCreateConnectionAndRecoverWhenClosed() throws RepositorySourceException, InterruptedException {
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-
-        RepositoryConnection conn = pool.getConnection();
-        assertThat(conn, is(notNullValue()));
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        assertThat(pool.getPoolSize(), is(1));
-
-        conn.close();
-
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        assertThat(pool.getPoolSize(), is(1));
-    }
-
-    @Test
-    public void shouldAllowShutdownToBeCalledMultipleTimesEvenWhenShutdown()
-        throws RepositorySourceException, InterruptedException {
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-
-        RepositoryConnection conn = pool.getConnection();
-        assertThat(conn, is(notNullValue()));
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        assertThat(pool.getPoolSize(), is(1));
-
-        conn.close();
-
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        assertThat(pool.getPoolSize(), is(1));
-
-        pool.shutdown();
-        pool.shutdown();
-        pool.awaitTermination(2, TimeUnit.SECONDS);
-        assertThat(pool.isTerminated(), is(true));
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        pool.shutdown();
-        pool.awaitTermination(2, TimeUnit.SECONDS);
-        pool.shutdown();
-        pool.awaitTermination(2, TimeUnit.SECONDS);
-    }
-
-    @Test( expected = IllegalStateException.class )
-    public void shouldNotCreateConnectionIfPoolIsNotRunning() throws RepositorySourceException, InterruptedException {
-        pool.shutdown();
-        pool.awaitTermination(2, TimeUnit.SECONDS);
-        assertThat(pool.isTerminated(), is(true));
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-        pool.getConnection(); // this should fail with illegal state
-    }
-
-    @Test
-    public void shouldAllowConnectionsToBeClosedMoreThanOnceWithNoIllEffects()
-        throws RepositorySourceException, InterruptedException {
-        assertThat(pool.getTotalConnectionsCreated(), is(0l));
-        assertThat(pool.getTotalConnectionsUsed(), is(0l));
-
-        RepositoryConnection conn = pool.getConnection();
-        assertThat(conn, is(notNullValue()));
-        assertThat(pool.getTotalConnectionsCreated(), is(1l));
-        assertThat(pool.getTotalConnectionsUsed(), is(1l));
-        assertThat(pool.getPoolSize(), is(1));
-
-        conn.close();
-        conn.close();
-    }
-
-    @Test
-    public void shouldBlockClientsWhenNotEnoughConnections() throws Exception {
-        int numConnectionsInPool = 1;
-        int numClients = 2;
-        RepositoryConnectionPool pool = new RepositoryConnectionPool(repositorySource);
-        pool.setCorePoolSize(numConnectionsInPool);
-        pool.setMaximumPoolSize(numConnectionsInPool);
-        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
-        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
-        pool.shutdown();
-        pool.awaitTermination(4, TimeUnit.SECONDS);
-    }
-
-    @Test
-    public void shouldLimitClientsToRunSequentiallyWithOneConnectionInPool() throws Exception {
-        int numConnectionsInPool = 1;
-        int numClients = 3;
-        RepositoryConnectionPool pool = new RepositoryConnectionPool(repositorySource);
-        pool.setCorePoolSize(numConnectionsInPool);
-        pool.setMaximumPoolSize(numConnectionsInPool);
-        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
-        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
-        pool.shutdown();
-        pool.awaitTermination(4, TimeUnit.SECONDS);
-    }
-
-    @Test
-    public void shouldClientsToRunConncurrentlyWithTwoConnectionsInPool() throws Exception {
-        int numConnectionsInPool = 2;
-        int numClients = 10;
-        RepositoryConnectionPool pool = new RepositoryConnectionPool(repositorySource);
-        pool.setCorePoolSize(numConnectionsInPool);
-        pool.setMaximumPoolSize(numConnectionsInPool);
-        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
-        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
-        pool.shutdown();
-        pool.awaitTermination(4, TimeUnit.SECONDS);
-    }
-
-    @Ignore( "doesn't run on hudson" )
-    @Test
-    public void shouldClientsToRunConncurrentlyWithMultipleConnectionInPool() throws Exception {
-        int numConnectionsInPool = 10;
-        int numClients = 50;
-        RepositoryConnectionPool pool = new RepositoryConnectionPool(repositorySource);
-        pool.setCorePoolSize(numConnectionsInPool);
-        pool.setMaximumPoolSize(numConnectionsInPool);
-        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(20);
-        List<Future<Integer>> results = runLoadTest(context, pool, numClients, 200, TimeUnit.MILLISECONDS, operationFactory);
-        int total = 0;
-        for (Future<Integer> result : results) {
-            assertThat(result.isDone(), is(true));
-            if (result.isDone()) total += result.get();
-        }
-        assertThat(total, is(20 * numClients));
-        pool.shutdown();
-        pool.awaitTermination(4, TimeUnit.SECONDS);
-    }
-
-}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java (from rev 393, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/RepositoryConnectionPoolTest.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryConnectionPoolTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,232 @@
+/*
+ * 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.dna.spi.connector;
+
+import static org.jboss.dna.spi.connector.RepositorySourceLoadHarness.runLoadTest;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositoryConnectionPool;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class RepositoryConnectionPoolTest {
+
+    private RepositoryConnectionPool pool;
+    private RepositoryConnectionPool.ConnectionFactory connectionFactory;
+    private ExecutionContext context;
+
+    @Before
+    public void beforeEach() {
+        final RepositorySource repositorySource = new TimeDelayingRepositorySource("source 1");
+        this.connectionFactory = new RepositoryConnectionPool.ConnectionFactory() {
+            public RepositoryConnection createConnection() throws RepositorySourceException, InterruptedException {
+                return repositorySource.getConnection();
+            }
+
+            public String getSourceName() {
+                return repositorySource.getName();
+            }
+        };
+        this.pool = new RepositoryConnectionPool(this.connectionFactory, 1, 1, 100, TimeUnit.SECONDS);
+        this.context = null;
+    }
+
+    @After
+    public void afterEach() throws Exception {
+        pool.shutdown();
+        pool.awaitTermination(2, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void shouldBeCreatedInRunningState() {
+        assertThat(pool.isShutdown(), is(false));
+        assertThat(pool.isTerminating(), is(false));
+        assertThat(pool.isTerminated(), is(false));
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+    }
+
+    @Test
+    public void shouldShutdownWhenNoConnectionsWereCreatedOrUsed() throws InterruptedException {
+        assertThat(pool.isShutdown(), is(false));
+        assertThat(pool.isTerminating(), is(false));
+        assertThat(pool.isTerminated(), is(false));
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+
+        for (int i = 0; i != 4; ++i) {
+            pool.shutdown();
+            assertThat(pool.isShutdown() || pool.isTerminating() || pool.isTerminated(), is(true));
+            pool.awaitTermination(2, TimeUnit.SECONDS);
+            assertThat(pool.isTerminated(), is(true));
+            assertThat(pool.getTotalConnectionsCreated(), is(0l));
+            assertThat(pool.getTotalConnectionsUsed(), is(0l));
+        }
+    }
+
+    @Test
+    public void shouldCreateConnectionAndRecoverWhenClosed() throws RepositorySourceException, InterruptedException {
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+
+        RepositoryConnection conn = pool.getConnection();
+        assertThat(conn, is(notNullValue()));
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        assertThat(pool.getPoolSize(), is(1));
+
+        conn.close();
+
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        assertThat(pool.getPoolSize(), is(1));
+    }
+
+    @Test
+    public void shouldAllowShutdownToBeCalledMultipleTimesEvenWhenShutdown()
+        throws RepositorySourceException, InterruptedException {
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+
+        RepositoryConnection conn = pool.getConnection();
+        assertThat(conn, is(notNullValue()));
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        assertThat(pool.getPoolSize(), is(1));
+
+        conn.close();
+
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        assertThat(pool.getPoolSize(), is(1));
+
+        pool.shutdown();
+        pool.shutdown();
+        pool.awaitTermination(2, TimeUnit.SECONDS);
+        assertThat(pool.isTerminated(), is(true));
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        pool.shutdown();
+        pool.awaitTermination(2, TimeUnit.SECONDS);
+        pool.shutdown();
+        pool.awaitTermination(2, TimeUnit.SECONDS);
+    }
+
+    @Test( expected = IllegalStateException.class )
+    public void shouldNotCreateConnectionIfPoolIsNotRunning() throws RepositorySourceException, InterruptedException {
+        pool.shutdown();
+        pool.awaitTermination(2, TimeUnit.SECONDS);
+        assertThat(pool.isTerminated(), is(true));
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+        pool.getConnection(); // this should fail with illegal state
+    }
+
+    @Test
+    public void shouldAllowConnectionsToBeClosedMoreThanOnceWithNoIllEffects()
+        throws RepositorySourceException, InterruptedException {
+        assertThat(pool.getTotalConnectionsCreated(), is(0l));
+        assertThat(pool.getTotalConnectionsUsed(), is(0l));
+
+        RepositoryConnection conn = pool.getConnection();
+        assertThat(conn, is(notNullValue()));
+        assertThat(pool.getTotalConnectionsCreated(), is(1l));
+        assertThat(pool.getTotalConnectionsUsed(), is(1l));
+        assertThat(pool.getPoolSize(), is(1));
+
+        conn.close();
+        conn.close();
+    }
+
+    @Test
+    public void shouldBlockClientsWhenNotEnoughConnections() throws Exception {
+        int numConnectionsInPool = 1;
+        int numClients = 2;
+        RepositoryConnectionPool pool = new RepositoryConnectionPool(connectionFactory);
+        pool.setCorePoolSize(numConnectionsInPool);
+        pool.setMaximumPoolSize(numConnectionsInPool);
+        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
+        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
+        pool.shutdown();
+        pool.awaitTermination(4, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void shouldLimitClientsToRunSequentiallyWithOneConnectionInPool() throws Exception {
+        int numConnectionsInPool = 1;
+        int numClients = 3;
+        RepositoryConnectionPool pool = new RepositoryConnectionPool(connectionFactory);
+        pool.setCorePoolSize(numConnectionsInPool);
+        pool.setMaximumPoolSize(numConnectionsInPool);
+        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
+        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
+        pool.shutdown();
+        pool.awaitTermination(4, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void shouldClientsToRunConncurrentlyWithTwoConnectionsInPool() throws Exception {
+        int numConnectionsInPool = 2;
+        int numClients = 10;
+        RepositoryConnectionPool pool = new RepositoryConnectionPool(connectionFactory);
+        pool.setCorePoolSize(numConnectionsInPool);
+        pool.setMaximumPoolSize(numConnectionsInPool);
+        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(10);
+        runLoadTest(context, pool, numClients, 100, TimeUnit.MILLISECONDS, operationFactory);
+        pool.shutdown();
+        pool.awaitTermination(4, TimeUnit.SECONDS);
+    }
+
+    @Ignore( "doesn't run on hudson" )
+    @Test
+    public void shouldClientsToRunConncurrentlyWithMultipleConnectionInPool() throws Exception {
+        int numConnectionsInPool = 10;
+        int numClients = 50;
+        RepositoryConnectionPool pool = new RepositoryConnectionPool(connectionFactory);
+        pool.setCorePoolSize(numConnectionsInPool);
+        pool.setMaximumPoolSize(numConnectionsInPool);
+        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(20);
+        List<Future<Integer>> results = runLoadTest(context, pool, numClients, 200, TimeUnit.MILLISECONDS, operationFactory);
+        int total = 0;
+        for (Future<Integer> result : results) {
+            assertThat(result.isDone(), is(true));
+            if (result.isDone()) total += result.get();
+        }
+        assertThat(total, is(20 * numClients));
+        pool.shutdown();
+        pool.awaitTermination(4, TimeUnit.SECONDS);
+    }
+
+}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperation.java (from rev 389, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryOperation.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperation.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperation.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,70 @@
+/*
+ * 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.dna.spi.connector;
+
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+
+/**
+ * An operation that runs against a repository connection.
+ * 
+ * @author Randall Hauch
+ * @param <T> the type of result returned by the client
+ */
+public interface RepositoryOperation<T> {
+
+    /**
+     * Get the name of this operation.
+     * 
+     * @return the operation's name
+     */
+    String getName();
+
+    /**
+     * Run the operation using the supplied connection.
+     * 
+     * @param context the environment in which this operation is executing; may not be null
+     * @param connection the connection; may not be null
+     * @return the result of the operation
+     * @throws RepositorySourceException if there is a problem with the connection
+     * @throws InterruptedException if this thread was interrupted
+     */
+    T run( ExecutionContext context,
+           RepositoryConnection connection ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * A factory interface for creating repository operations.
+     * 
+     * @param <T> the type of result for the operations
+     * @author Randall Hauch
+     */
+    public static interface Factory<T> {
+
+        /**
+         * Create a repository operation that returns the result of type T.
+         * 
+         * @return the operation
+         */
+        RepositoryOperation<T> create();
+    }
+}


Property changes on: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperation.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperations.java (from rev 389, trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/connection/RepositoryOperations.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperations.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperations.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,174 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.jboss.dna.common.util.ArgCheck;
+import org.jboss.dna.common.util.LogContext;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositoryConnectionPool;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+
+/**
+ * @author Randall Hauch
+ */
+public class RepositoryOperations {
+
+    /**
+     * Call the supplied operation, using a connection from this pool.
+     * 
+     * @param <T> the return type for the operation
+     * @param context the context in which the operation is to execute; may not be null
+     * @param pool the pool to use
+     * @param operation the operation to be run using a new connection obtained from the factory
+     * @return the results from the operation
+     * @throws RepositorySourceException if there was an error obtaining the new connection
+     * @throws InterruptedException if the thread was interrupted during the operation
+     * @throws IllegalArgumentException if the operation is null
+     * @see #createCallable(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, Iterable)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, RepositoryOperation...)
+     */
+    public static <T> T call( ExecutionContext context,
+                              RepositoryConnectionPool pool,
+                              RepositoryOperation<T> operation ) throws RepositorySourceException, InterruptedException {
+        ArgCheck.isNotNull(operation, "repository operation");
+        // Get a connection ...
+        T result = null;
+        LogContext.set("context", operation.getName());
+        RepositoryConnection conn = pool.getConnection();
+        try {
+            // And run the client with the connection ...
+            result = operation.run(context, conn);
+        } finally {
+            conn.close();
+        }
+        LogContext.clear();
+        return result;
+    }
+
+    /**
+     * Return a callable object that, when run, performs the supplied repository operation against a connection obtained from the
+     * supplied factory.
+     * 
+     * @param <T> the return type for the operation
+     * @param context the context in which the operation is to execute; may not be null
+     * @param pool the pool to use
+     * @param operation the operation to be run using a new connection obtained from the factory
+     * @return the callable
+     * @see #call(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, Iterable)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, RepositoryOperation...)
+     */
+    public static <T> Callable<T> createCallable( final ExecutionContext context,
+                                                  final RepositoryConnectionPool pool,
+                                                  final RepositoryOperation<T> operation ) {
+        ArgCheck.isNotNull(operation, "repository operation");
+        return new Callable<T>() {
+
+            /**
+             * Execute by getting a connection from this pool, running the client, and return the connection to the pool.
+             * 
+             * @return the operation's result
+             * @throws Exception
+             */
+            public T call() throws Exception {
+                return RepositoryOperations.call(context, pool, operation);
+            }
+        };
+    }
+
+    /**
+     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
+     * this pool.
+     * 
+     * @param <T> the return type for the operations
+     * @param context the context in which the operation is to execute; may not be null
+     * @param pool the pool to use
+     * @param operations the operations to be run using connections from the factory
+     * @return the collection of callables
+     * @see #call(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallable(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, Iterable)
+     */
+    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
+                                                         final RepositoryConnectionPool pool,
+                                                         final RepositoryOperation<T>... operations ) {
+        List<Callable<T>> callables = new ArrayList<Callable<T>>();
+        for (final RepositoryOperation<T> operation : operations) {
+            callables.add(createCallable(context, pool, operation));
+        }
+        return callables;
+    }
+
+    /**
+     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
+     * this pool.
+     * 
+     * @param <T> the return type for the operations
+     * @param context the context in which the operation is to execute; may not be null
+     * @param pool the pool to use
+     * @param operations the operations to be run using connections from the factory
+     * @return the collection of callables
+     * @see #call(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallable(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, RepositoryOperation...)
+     */
+    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
+                                                         final RepositoryConnectionPool pool,
+                                                         Iterable<RepositoryOperation<T>> operations ) {
+        List<Callable<T>> callables = new ArrayList<Callable<T>>();
+        for (final RepositoryOperation<T> operation : operations) {
+            callables.add(createCallable(context, pool, operation));
+        }
+        return callables;
+    }
+
+    /**
+     * Return a collection of callable objects that, when run, perform the supplied repository operations against connections in
+     * this pool.
+     * 
+     * @param <T> the return type for the operations
+     * @param context the context in which the operation is to execute; may not be null
+     * @param pool the pool to use
+     * @param operations the operations to be run using connections from the factory
+     * @return the collection of callables
+     * @see #call(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallable(ExecutionContext, RepositoryConnectionPool, RepositoryOperation)
+     * @see #createCallables(ExecutionContext, RepositoryConnectionPool, RepositoryOperation...)
+     */
+    public static <T> List<Callable<T>> createCallables( final ExecutionContext context,
+                                                         final RepositoryConnectionPool pool,
+                                                         Iterator<RepositoryOperation<T>> operations ) {
+        List<Callable<T>> callables = new ArrayList<Callable<T>>();
+        while (operations.hasNext()) {
+            final RepositoryOperation<T> operation = operations.next();
+            callables.add(createCallable(context, pool, operation));
+        }
+        return callables;
+    }
+
+}


Property changes on: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositoryOperations.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Deleted: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/RepositorySourceLoadHarness.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,246 +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.dna.spi.graph.connection;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import org.jboss.dna.common.i18n.MockI18n;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.spi.ExecutionContext;
-
-/**
- * A test harness for using repository connections under load.
- * 
- * @author Randall Hauch
- */
-public class RepositorySourceLoadHarness {
-
-    public static Future<Integer> execute( RepositoryConnectionFactory connectionFactory,
-                                           ExecutionContext context,
-                                           long maxTime,
-                                           TimeUnit maxTimeUnit ) throws InterruptedException {
-        int numTimes = 1;
-        int numClients = 1;
-        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(numTimes);
-        List<Future<Integer>> results = runLoadTest(context,
-                                                    connectionFactory,
-                                                    numClients,
-                                                    maxTime,
-                                                    maxTimeUnit,
-                                                    operationFactory);
-        return results.get(0);
-    }
-
-    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
-                                                   RepositoryConnectionFactory connectionFactory,
-                                                   int numClients,
-                                                   long maxTime,
-                                                   TimeUnit maxTimeUnit,
-                                                   RepositoryOperation.Factory<T> clientFactory ) throws InterruptedException {
-        // Create the clients ...
-        Collection<RepositoryOperation<T>> clients = new ArrayList<RepositoryOperation<T>>();
-        for (int i = 0; i != numClients; ++i) {
-            clients.add(clientFactory.create());
-        }
-
-        // and run the test ...
-        return runLoadTest(context, connectionFactory, maxTime, maxTimeUnit, clients);
-    }
-
-    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
-                                                   RepositoryConnectionFactory connectionFactory,
-                                                   long maxTime,
-                                                   TimeUnit maxTimeUnit,
-                                                   RepositoryOperation<T>... clients ) throws InterruptedException {
-        // Create the client collection ...
-        Collection<RepositoryOperation<T>> clientCollection = new ArrayList<RepositoryOperation<T>>();
-        for (RepositoryOperation<T> client : clients) {
-            if (client != null) clientCollection.add(client);
-        }
-        // and run the test ...
-        return runLoadTest(context, connectionFactory, maxTime, maxTimeUnit, clientCollection);
-    }
-
-    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
-                                                   RepositoryConnectionFactory connectionFactory,
-                                                   long maxTime,
-                                                   TimeUnit maxTimeUnit,
-                                                   Collection<RepositoryOperation<T>> clients ) throws InterruptedException {
-        assert connectionFactory != null;
-        assert clients != null;
-        assert clients.size() > 0;
-
-        // Create an Executor Service, using a thread factory that makes the first 'n' thread all wait for each other ...
-        ExecutorService clientPool = null;
-        if (clients.size() == 1) {
-            clientPool = Executors.newSingleThreadExecutor();
-        } else {
-            final ThreadFactory threadFactory = new TestThreadFactory(clients.size());
-            clientPool = Executors.newFixedThreadPool(clients.size(), threadFactory);
-        }
-
-        try {
-            // Wrap each client by a callable and by another that uses a latch ...
-            List<Callable<T>> callables = RepositoryOperations.createCallables(context, connectionFactory, clients);
-
-            // Run the tests ...
-            List<Future<T>> futures = clientPool.invokeAll(callables, maxTime, maxTimeUnit);
-            return futures;
-        } finally {
-            // Shut down the pool of clients ...
-            clientPool.shutdown();
-            if (!clientPool.awaitTermination(5, TimeUnit.SECONDS)) {
-                String msg = "Unable to shutdown clients after 5 seconds";
-                Logger.getLogger(RepositorySourceLoadHarness.class).error(MockI18n.passthrough, msg);
-            }
-        }
-
-    }
-
-    /**
-     * A thread factory that makes an initial set of threads wait until all of those threads are created and ready. This is useful
-     * in testing to ensure that the first threads created don't get a jump start.
-     * 
-     * @author Randall Hauch
-     */
-    protected static class TestThreadFactory implements ThreadFactory {
-
-        protected final int totalNumberOfThreads;
-        protected final CountDownLatch latch;
-
-        public TestThreadFactory( int numberOfThreadsToWait ) {
-            this.latch = new CountDownLatch(numberOfThreadsToWait);
-            this.totalNumberOfThreads = numberOfThreadsToWait;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public Thread newThread( Runnable runnable ) {
-            return new Thread(runnable) {
-
-                /**
-                 * {@inheritDoc}
-                 */
-                @Override
-                public void run() {
-                    if (totalNumberOfThreads > 1) {
-                        // There are other threads, and we want to synchronize with them ...
-                        try {
-                            // Count down the number of threads that are to reach this point (if 0, this doesn't do anything)
-                            latch.countDown();
-                            // Wait for all threads to reach this point ...
-                            latch.await();
-                        } catch (InterruptedException e) {
-                            throw new RuntimeException(e);
-                        }
-                    }
-                    super.run();
-                }
-            };
-        }
-    }
-
-    /**
-     * Return an operation factory that produces {@link RepositoryOperation} instances that each call
-     * {@link RepositoryConnection#execute(ExecutionContext, org.jboss.dna.spi.graph.commands.GraphCommand...)} the supplied
-     * number of times, intermixed with random math operations and {@link Thread#yield() yielding}.
-     * 
-     * @param callsPerOperation the number of <code>load</code> calls per RepositoryOperation
-     * @return the factory
-     */
-    public static RepositoryOperation.Factory<Integer> createMultipleLoadOperationFactory( final int callsPerOperation ) {
-        return new RepositoryOperation.Factory<Integer>() {
-
-            public RepositoryOperation<Integer> create() {
-                return new CallLoadMultipleTimes(callsPerOperation);
-            }
-        };
-    }
-
-    public static class CallLoadMultipleTimes implements RepositoryOperation<Integer> {
-
-        private final int count;
-
-        public CallLoadMultipleTimes( int count ) {
-            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Creating repository operation to call {0} times", count);
-            this.count = count;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public String getName() {
-            return Thread.currentThread().getName() + "-CallLoadMultipleTimes";
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryOperation#run(org.jboss.dna.spi.ExecutionContext,
-         *      org.jboss.dna.spi.graph.connection.RepositoryConnection)
-         */
-        public Integer run( ExecutionContext context,
-                            RepositoryConnection connection ) throws RepositorySourceException, InterruptedException {
-            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Running {0} operation", this.getClass().getSimpleName());
-            int total = count;
-            for (int i = 0; i != count; ++i) {
-                // Add two random numbers ...
-                int int1 = random(this.hashCode() ^ (int)System.nanoTime() * i);
-                if (i % 2 == 0) {
-                    Thread.yield();
-                }
-                connection.execute(context);
-                int int2 = random(this.hashCode() ^ (int)System.nanoTime() + i);
-                total += Math.min(Math.abs(Math.max(int1, int2) + int1 * int2 / 3), count);
-            }
-            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Finishing {0} operation", this.getClass().getSimpleName());
-            return total < count ? total : count; // should really always return count
-        }
-    }
-
-    /**
-     * A "random-enough" number generator that is cheap and that has no synchronization issues (like some other random number
-     * generators).
-     * <p>
-     * This was taken from <a href="http://wwww.jcip.org">Java Concurrency In Practice</a> (page 253).
-     * </p>
-     * 
-     * @param seed the seed, typically based on a hash code and nanoTime
-     * @return a number that is "random enough"
-     */
-    public static int random( int seed ) {
-        seed ^= (seed << 6);
-        seed ^= (seed >>> 21);
-        seed ^= (seed << 7);
-        return seed;
-    }
-
-}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java (from rev 393, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/RepositorySourceLoadHarness.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/RepositorySourceLoadHarness.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,244 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import org.jboss.dna.common.i18n.MockI18n;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositoryConnectionPool;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+
+/**
+ * A test harness for using repository connections under load.
+ * 
+ * @author Randall Hauch
+ */
+public class RepositorySourceLoadHarness {
+
+    public static Future<Integer> execute( RepositoryConnectionPool pool,
+                                           ExecutionContext context,
+                                           long maxTime,
+                                           TimeUnit maxTimeUnit ) throws InterruptedException {
+        int numTimes = 1;
+        int numClients = 1;
+        RepositoryOperation.Factory<Integer> operationFactory = RepositorySourceLoadHarness.createMultipleLoadOperationFactory(numTimes);
+        List<Future<Integer>> results = runLoadTest(context, pool, numClients, maxTime, maxTimeUnit, operationFactory);
+        return results.get(0);
+    }
+
+    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
+                                                   RepositoryConnectionPool pool,
+                                                   int numClients,
+                                                   long maxTime,
+                                                   TimeUnit maxTimeUnit,
+                                                   RepositoryOperation.Factory<T> clientFactory ) throws InterruptedException {
+        // Create the clients ...
+        Collection<RepositoryOperation<T>> clients = new ArrayList<RepositoryOperation<T>>();
+        for (int i = 0; i != numClients; ++i) {
+            clients.add(clientFactory.create());
+        }
+
+        // and run the test ...
+        return runLoadTest(context, pool, maxTime, maxTimeUnit, clients);
+    }
+
+    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
+                                                   RepositoryConnectionPool pool,
+                                                   long maxTime,
+                                                   TimeUnit maxTimeUnit,
+                                                   RepositoryOperation<T>... clients ) throws InterruptedException {
+        // Create the client collection ...
+        Collection<RepositoryOperation<T>> clientCollection = new ArrayList<RepositoryOperation<T>>();
+        for (RepositoryOperation<T> client : clients) {
+            if (client != null) clientCollection.add(client);
+        }
+        // and run the test ...
+        return runLoadTest(context, pool, maxTime, maxTimeUnit, clientCollection);
+    }
+
+    public static <T> List<Future<T>> runLoadTest( ExecutionContext context,
+                                                   RepositoryConnectionPool pool,
+                                                   long maxTime,
+                                                   TimeUnit maxTimeUnit,
+                                                   Collection<RepositoryOperation<T>> clients ) throws InterruptedException {
+        assert pool != null;
+        assert clients != null;
+        assert clients.size() > 0;
+
+        // Create an Executor Service, using a thread factory that makes the first 'n' thread all wait for each other ...
+        ExecutorService clientPool = null;
+        if (clients.size() == 1) {
+            clientPool = Executors.newSingleThreadExecutor();
+        } else {
+            final ThreadFactory threadFactory = new TestThreadFactory(clients.size());
+            clientPool = Executors.newFixedThreadPool(clients.size(), threadFactory);
+        }
+
+        try {
+            // Wrap each client by a callable and by another that uses a latch ...
+            List<Callable<T>> callables = RepositoryOperations.createCallables(context, pool, clients);
+
+            // Run the tests ...
+            List<Future<T>> futures = clientPool.invokeAll(callables, maxTime, maxTimeUnit);
+            return futures;
+        } finally {
+            // Shut down the pool of clients ...
+            clientPool.shutdown();
+            if (!clientPool.awaitTermination(5, TimeUnit.SECONDS)) {
+                String msg = "Unable to shutdown clients after 5 seconds";
+                Logger.getLogger(RepositorySourceLoadHarness.class).error(MockI18n.passthrough, msg);
+            }
+        }
+
+    }
+
+    /**
+     * A thread factory that makes an initial set of threads wait until all of those threads are created and ready. This is useful
+     * in testing to ensure that the first threads created don't get a jump start.
+     * 
+     * @author Randall Hauch
+     */
+    protected static class TestThreadFactory implements ThreadFactory {
+
+        protected final int totalNumberOfThreads;
+        protected final CountDownLatch latch;
+
+        public TestThreadFactory( int numberOfThreadsToWait ) {
+            this.latch = new CountDownLatch(numberOfThreadsToWait);
+            this.totalNumberOfThreads = numberOfThreadsToWait;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Thread newThread( Runnable runnable ) {
+            return new Thread(runnable) {
+
+                /**
+                 * {@inheritDoc}
+                 */
+                @Override
+                public void run() {
+                    if (totalNumberOfThreads > 1) {
+                        // There are other threads, and we want to synchronize with them ...
+                        try {
+                            // Count down the number of threads that are to reach this point (if 0, this doesn't do anything)
+                            latch.countDown();
+                            // Wait for all threads to reach this point ...
+                            latch.await();
+                        } catch (InterruptedException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                    super.run();
+                }
+            };
+        }
+    }
+
+    /**
+     * Return an operation factory that produces {@link RepositoryOperation} instances that each call
+     * {@link RepositoryConnection#execute(ExecutionContext, org.jboss.dna.spi.graph.commands.GraphCommand...)} the supplied
+     * number of times, intermixed with random math operations and {@link Thread#yield() yielding}.
+     * 
+     * @param callsPerOperation the number of <code>load</code> calls per RepositoryOperation
+     * @return the factory
+     */
+    public static RepositoryOperation.Factory<Integer> createMultipleLoadOperationFactory( final int callsPerOperation ) {
+        return new RepositoryOperation.Factory<Integer>() {
+
+            public RepositoryOperation<Integer> create() {
+                return new CallLoadMultipleTimes(callsPerOperation);
+            }
+        };
+    }
+
+    public static class CallLoadMultipleTimes implements RepositoryOperation<Integer> {
+
+        private final int count;
+
+        public CallLoadMultipleTimes( int count ) {
+            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Creating repository operation to call {0} times", count);
+            this.count = count;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String getName() {
+            return Thread.currentThread().getName() + "-CallLoadMultipleTimes";
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryOperation#run(org.jboss.dna.spi.ExecutionContext,
+         *      org.jboss.dna.spi.connector.RepositoryConnection)
+         */
+        public Integer run( ExecutionContext context,
+                            RepositoryConnection connection ) throws RepositorySourceException, InterruptedException {
+            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Running {0} operation", this.getClass().getSimpleName());
+            int total = count;
+            for (int i = 0; i != count; ++i) {
+                // Add two random numbers ...
+                int int1 = random(this.hashCode() ^ (int)System.nanoTime() * i);
+                if (i % 2 == 0) {
+                    Thread.yield();
+                }
+                connection.execute(context);
+                int int2 = random(this.hashCode() ^ (int)System.nanoTime() + i);
+                total += Math.min(Math.abs(Math.max(int1, int2) + int1 * int2 / 3), count);
+            }
+            Logger.getLogger(RepositorySourceLoadHarness.class).debug("Finishing {0} operation", this.getClass().getSimpleName());
+            return total < count ? total : count; // should really always return count
+        }
+    }
+
+    /**
+     * A "random-enough" number generator that is cheap and that has no synchronization issues (like some other random number
+     * generators).
+     * <p>
+     * This was taken from <a href="http://wwww.jcip.org">Java Concurrency In Practice</a> (page 253).
+     * </p>
+     * 
+     * @param seed the seed, typically based on a hash code and nanoTime
+     * @return a number that is "random enough"
+     */
+    public static int random( int seed ) {
+        seed ^= (seed << 6);
+        seed ^= (seed >>> 21);
+        seed ^= (seed << 7);
+        return seed;
+    }
+
+}

Deleted: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/SimpleRepository.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,202 +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.dna.spi.graph.connection;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.dna.spi.DnaLexicon;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.graph.Name;
-import org.jboss.dna.spi.graph.NameFactory;
-import org.jboss.dna.spi.graph.Path;
-import org.jboss.dna.spi.graph.PathFactory;
-import org.jboss.dna.spi.graph.Property;
-import org.jboss.dna.spi.graph.PropertyFactory;
-
-/**
- * A very simple repository that maintains properties for nodes identified by a path, and computes the children based upon the set
- * of paths registered in the {@link #getData() data}.
- * <p>
- * Note that the repository does not automatically rename same-name siblings when nodes are
- * {@link #delete(ExecutionContext, String) deleted} or {@link #create(ExecutionContext, String) explicitly} or
- * {@link #setProperty(ExecutionContext, String, String, Object...) implicitly} created.
- * </p>
- * 
- * @author Randall Hauch
- */
- at ThreadSafe
-public class SimpleRepository {
-
-    public static final String DEFAULT_UUID_PROPERTY_NAME = DnaLexicon.PropertyNames.UUID;
-
-    private static final ConcurrentMap<String, SimpleRepository> repositoriesByName = new ConcurrentHashMap<String, SimpleRepository>();
-
-    public static SimpleRepository get( String name ) {
-        return repositoriesByName.get(name);
-    }
-
-    public static void shutdownAll() {
-        for (SimpleRepository repository : repositoriesByName.values()) {
-            repository.shutdown();
-        }
-    }
-
-    private ConcurrentMap<Path, Map<Name, Property>> data = new ConcurrentHashMap<Path, Map<Name, Property>>();
-    private final String repositoryName;
-    private String uuidPropertyName = DEFAULT_UUID_PROPERTY_NAME;
-    private boolean shutdown = false;
-
-    public SimpleRepository( String repositoryName ) {
-        this.repositoryName = repositoryName;
-        if (repositoriesByName.putIfAbsent(repositoryName, this) != null) {
-            throw new IllegalArgumentException("Repository \"" + repositoryName + "\" already exists and may not be recreated");
-        }
-    }
-
-    /**
-     * @return repositoryName
-     */
-    public String getRepositoryName() {
-        return repositoryName;
-    }
-
-    /**
-     * @return uuidPropertyName
-     */
-    public String getUuidPropertyName() {
-        return uuidPropertyName;
-    }
-
-    /**
-     * @param uuidPropertyName Sets uuidPropertyName to the specified value.
-     */
-    public void setUuidPropertyName( String uuidPropertyName ) {
-        if (uuidPropertyName == null || uuidPropertyName.trim().length() == 0) uuidPropertyName = DEFAULT_UUID_PROPERTY_NAME;
-        this.uuidPropertyName = uuidPropertyName;
-    }
-
-    /**
-     * Get the current modifiable map of property data
-     * 
-     * @return data
-     */
-    public ConcurrentMap<Path, Map<Name, Property>> getData() {
-        return data;
-    }
-
-    /**
-     * Utility method to help set the property on the node given by the supplied path. If the node does not exist, it will be
-     * created.
-     * 
-     * @param context the execution context; may not be null
-     * @param path the path to the node; may not be null
-     * @param propertyName the property name; may not be null
-     * @param values the values of the property
-     * @return this repository, for method chaining
-     */
-    public SimpleRepository setProperty( ExecutionContext context,
-                                         String path,
-                                         String propertyName,
-                                         Object... values ) {
-        PathFactory pathFactory = context.getValueFactories().getPathFactory();
-        NameFactory nameFactory = context.getValueFactories().getNameFactory();
-        PropertyFactory propertyFactory = context.getPropertyFactory();
-        Path pathObj = pathFactory.create(path);
-        create(context, pathObj.getAncestor().getString(context.getNamespaceRegistry()));
-        Property property = propertyFactory.create(nameFactory.create(propertyName), values);
-        Map<Name, Property> properties = new HashMap<Name, Property>();
-        Map<Name, Property> existingProperties = data.putIfAbsent(pathObj, properties);
-        if (existingProperties == null) existingProperties = properties;
-        existingProperties.put(property.getName(), property);
-        return this;
-    }
-
-    /**
-     * Create the node if it does not exist.
-     * 
-     * @param context the execution context; may not be null
-     * @param path the path to the node; may not be null
-     * @return this repository, for method chaining
-     */
-    public SimpleRepository create( ExecutionContext context,
-                                    String path ) {
-        PathFactory pathFactory = context.getValueFactories().getPathFactory();
-        Path pathObj = pathFactory.create(path);
-        Path ancestorPath = pathObj.getAncestor();
-        while (!ancestorPath.isRoot()) {
-            data.putIfAbsent(ancestorPath, new HashMap<Name, Property>());
-            ancestorPath = ancestorPath.getAncestor();
-        }
-        data.putIfAbsent(pathObj, new HashMap<Name, Property>());
-        Name uuidName = context.getValueFactories().getNameFactory().create(this.getUuidPropertyName());
-        UUID uuid = context.getValueFactories().getUuidFactory().create();
-        Property uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
-        data.get(pathObj).put(uuidProperty.getName(), uuidProperty);
-        return this;
-    }
-
-    /**
-     * Delete the branch rooted at the supplied path, if it exists.
-     * 
-     * @param context the execution context; may not be null
-     * @param path the path to the branch's top node; may not be null
-     * @return this repository, for method chaining
-     */
-    public SimpleRepository delete( ExecutionContext context,
-                                    String path ) {
-        PathFactory pathFactory = context.getValueFactories().getPathFactory();
-        Path pathObj = pathFactory.create(path);
-        List<Path> pathsToRemove = new LinkedList<Path>();
-        for (Path nodePath : data.keySet()) {
-            if (nodePath.equals(pathObj) || nodePath.isDecendantOf(pathObj)) {
-                pathsToRemove.add(nodePath);
-            }
-        }
-        for (Path pathToRemove : pathsToRemove) {
-            data.remove(pathToRemove);
-        }
-        return this;
-    }
-
-    /**
-     * @param data new new map of property data
-     */
-    public void setData( ConcurrentMap<Path, Map<Name, Property>> data ) {
-        this.data = data;
-    }
-
-    public boolean isShutdown() {
-        return shutdown;
-    }
-
-    public void shutdown() {
-        shutdown = true;
-        repositoriesByName.remove(this.repositoryName);
-    }
-
-}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java (from rev 393, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/SimpleRepository.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepository.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,202 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.spi.DnaLexicon;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.NameFactory;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.PathFactory;
+import org.jboss.dna.spi.graph.Property;
+import org.jboss.dna.spi.graph.PropertyFactory;
+
+/**
+ * A very simple repository that maintains properties for nodes identified by a path, and computes the children based upon the set
+ * of paths registered in the {@link #getData() data}.
+ * <p>
+ * Note that the repository does not automatically rename same-name siblings when nodes are
+ * {@link #delete(ExecutionContext, String) deleted} or {@link #create(ExecutionContext, String) explicitly} or
+ * {@link #setProperty(ExecutionContext, String, String, Object...) implicitly} created.
+ * </p>
+ * 
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class SimpleRepository {
+
+    public static final String DEFAULT_UUID_PROPERTY_NAME = DnaLexicon.PropertyNames.UUID;
+
+    private static final ConcurrentMap<String, SimpleRepository> repositoriesByName = new ConcurrentHashMap<String, SimpleRepository>();
+
+    public static SimpleRepository get( String name ) {
+        return repositoriesByName.get(name);
+    }
+
+    public static void shutdownAll() {
+        for (SimpleRepository repository : repositoriesByName.values()) {
+            repository.shutdown();
+        }
+    }
+
+    private ConcurrentMap<Path, Map<Name, Property>> data = new ConcurrentHashMap<Path, Map<Name, Property>>();
+    private final String repositoryName;
+    private String uuidPropertyName = DEFAULT_UUID_PROPERTY_NAME;
+    private boolean shutdown = false;
+
+    public SimpleRepository( String repositoryName ) {
+        this.repositoryName = repositoryName;
+        if (repositoriesByName.putIfAbsent(repositoryName, this) != null) {
+            throw new IllegalArgumentException("Repository \"" + repositoryName + "\" already exists and may not be recreated");
+        }
+    }
+
+    /**
+     * @return repositoryName
+     */
+    public String getRepositoryName() {
+        return repositoryName;
+    }
+
+    /**
+     * @return uuidPropertyName
+     */
+    public String getUuidPropertyName() {
+        return uuidPropertyName;
+    }
+
+    /**
+     * @param uuidPropertyName Sets uuidPropertyName to the specified value.
+     */
+    public void setUuidPropertyName( String uuidPropertyName ) {
+        if (uuidPropertyName == null || uuidPropertyName.trim().length() == 0) uuidPropertyName = DEFAULT_UUID_PROPERTY_NAME;
+        this.uuidPropertyName = uuidPropertyName;
+    }
+
+    /**
+     * Get the current modifiable map of property data
+     * 
+     * @return data
+     */
+    public ConcurrentMap<Path, Map<Name, Property>> getData() {
+        return data;
+    }
+
+    /**
+     * Utility method to help set the property on the node given by the supplied path. If the node does not exist, it will be
+     * created.
+     * 
+     * @param context the execution context; may not be null
+     * @param path the path to the node; may not be null
+     * @param propertyName the property name; may not be null
+     * @param values the values of the property
+     * @return this repository, for method chaining
+     */
+    public SimpleRepository setProperty( ExecutionContext context,
+                                         String path,
+                                         String propertyName,
+                                         Object... values ) {
+        PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        NameFactory nameFactory = context.getValueFactories().getNameFactory();
+        PropertyFactory propertyFactory = context.getPropertyFactory();
+        Path pathObj = pathFactory.create(path);
+        create(context, pathObj.getAncestor().getString(context.getNamespaceRegistry()));
+        Property property = propertyFactory.create(nameFactory.create(propertyName), values);
+        Map<Name, Property> properties = new HashMap<Name, Property>();
+        Map<Name, Property> existingProperties = data.putIfAbsent(pathObj, properties);
+        if (existingProperties == null) existingProperties = properties;
+        existingProperties.put(property.getName(), property);
+        return this;
+    }
+
+    /**
+     * Create the node if it does not exist.
+     * 
+     * @param context the execution context; may not be null
+     * @param path the path to the node; may not be null
+     * @return this repository, for method chaining
+     */
+    public SimpleRepository create( ExecutionContext context,
+                                    String path ) {
+        PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        Path pathObj = pathFactory.create(path);
+        Path ancestorPath = pathObj.getAncestor();
+        while (!ancestorPath.isRoot()) {
+            data.putIfAbsent(ancestorPath, new HashMap<Name, Property>());
+            ancestorPath = ancestorPath.getAncestor();
+        }
+        data.putIfAbsent(pathObj, new HashMap<Name, Property>());
+        Name uuidName = context.getValueFactories().getNameFactory().create(this.getUuidPropertyName());
+        UUID uuid = context.getValueFactories().getUuidFactory().create();
+        Property uuidProperty = context.getPropertyFactory().create(uuidName, uuid);
+        data.get(pathObj).put(uuidProperty.getName(), uuidProperty);
+        return this;
+    }
+
+    /**
+     * Delete the branch rooted at the supplied path, if it exists.
+     * 
+     * @param context the execution context; may not be null
+     * @param path the path to the branch's top node; may not be null
+     * @return this repository, for method chaining
+     */
+    public SimpleRepository delete( ExecutionContext context,
+                                    String path ) {
+        PathFactory pathFactory = context.getValueFactories().getPathFactory();
+        Path pathObj = pathFactory.create(path);
+        List<Path> pathsToRemove = new LinkedList<Path>();
+        for (Path nodePath : data.keySet()) {
+            if (nodePath.equals(pathObj) || nodePath.isDecendantOf(pathObj)) {
+                pathsToRemove.add(nodePath);
+            }
+        }
+        for (Path pathToRemove : pathsToRemove) {
+            data.remove(pathToRemove);
+        }
+        return this;
+    }
+
+    /**
+     * @param data new new map of property data
+     */
+    public void setData( ConcurrentMap<Path, Map<Name, Property>> data ) {
+        this.data = data;
+    }
+
+    public boolean isShutdown() {
+        return shutdown;
+    }
+
+    public void shutdown() {
+        shutdown = true;
+        repositoriesByName.remove(this.repositoryName);
+    }
+
+}

Deleted: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/SimpleRepositorySource.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,316 +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.dna.spi.graph.connection;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import javax.naming.Reference;
-import javax.transaction.xa.XAResource;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.InvalidPathException;
-import org.jboss.dna.spi.graph.Name;
-import org.jboss.dna.spi.graph.Path;
-import org.jboss.dna.spi.graph.Property;
-import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
-import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
-import org.jboss.dna.spi.graph.commands.GraphCommand;
-import org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor;
-import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
-
-/**
- * A {@link RepositorySource} for a {@link SimpleRepository simple repository}.
- * 
- * @author Randall Hauch
- */
- at ThreadSafe
-public class SimpleRepositorySource extends AbstractRepositorySource {
-
-    private static final long serialVersionUID = 1L;
-
-    private String repositoryName;
-    private String name;
-
-    public SimpleRepositorySource() {
-        super();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositoryConnectionFactory#getName()
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @param name Sets name to the specified value.
-     */
-    public void setName( String name ) {
-        this.name = name;
-    }
-
-    /**
-     * @return repositoryName
-     */
-    public String getRepositoryName() {
-        return repositoryName;
-    }
-
-    /**
-     * @param repositoryName Sets repositoryName to the specified value.
-     */
-    public void setRepositoryName( String repositoryName ) {
-        this.repositoryName = repositoryName;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see javax.naming.Referenceable#getReference()
-     */
-    public Reference getReference() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals( Object obj ) {
-        if (obj == this) return true;
-        if (obj instanceof SimpleRepositorySource) {
-            SimpleRepositorySource that = (SimpleRepositorySource)obj;
-            if (!this.getName().equals(that.getName())) return false;
-            if (!this.getRepositoryName().equals(that.getRepositoryName())) return false;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getCapabilities()
-     */
-    public RepositorySourceCapabilities getCapabilities() {
-        return new Capabilities();
-    }
-
-    protected class Capabilities implements RepositorySourceCapabilities {
-        public boolean supportsSameNameSiblings() {
-            return true;
-        }
-
-        public boolean supportsUpdates() {
-            return true;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.AbstractRepositorySource#createConnection()
-     */
-    @Override
-    protected synchronized RepositoryConnection createConnection() throws RepositorySourceException {
-        String reposName = this.getRepositoryName();
-        SimpleRepository repository = SimpleRepository.get(reposName);
-        if (repository == null) {
-            throw new RepositorySourceException(this.getName(), "Unable to find repository \"" + reposName + "\"");
-        }
-        return new Connection(repository);
-    }
-
-    protected class Connection implements RepositoryConnection {
-
-        private RepositorySourceListener listener;
-        private final SimpleRepository repository;
-
-        protected Connection( SimpleRepository repository ) {
-            assert repository != null;
-            this.repository = repository;
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#close()
-         */
-        public void close() {
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#execute(org.jboss.dna.spi.ExecutionContext,
-         *      org.jboss.dna.spi.graph.commands.GraphCommand[])
-         */
-        public void execute( ExecutionContext context,
-                             GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
-            assert context != null;
-            if (repository.isShutdown()) {
-                throw new RepositorySourceException(getName(), "The repository \"" + repository.getRepositoryName()
-                                                               + "\" is no longer available");
-            }
-            // Now execute the commands ...
-            CommandExecutor executor = new Executor(this.repository, context, this.getSourceName());
-            for (GraphCommand command : commands) {
-                executor.execute(command);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#getDefaultCachePolicy()
-         */
-        public CachePolicy getDefaultCachePolicy() {
-            return null;
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#getSourceName()
-         */
-        public String getSourceName() {
-            return SimpleRepositorySource.this.getName();
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#getXAResource()
-         */
-        public XAResource getXAResource() {
-            return null;
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#ping(long, java.util.concurrent.TimeUnit)
-         */
-        public boolean ping( long time,
-                             TimeUnit unit ) {
-            return true;
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.connection.RepositoryConnection#setListener(org.jboss.dna.spi.graph.connection.RepositorySourceListener)
-         */
-        public void setListener( RepositorySourceListener listener ) {
-            this.listener = listener;
-        }
-
-        /**
-         * @return listener
-         */
-        public RepositorySourceListener getListener() {
-            return listener;
-        }
-
-    }
-
-    protected class Executor extends AbstractCommandExecutor {
-        private final SimpleRepository repository;
-        private final Name uuidPropertyName;
-
-        protected Executor( SimpleRepository repository,
-                            ExecutionContext context,
-                            String sourceName ) {
-            super(context, sourceName);
-            this.repository = repository;
-            this.uuidPropertyName = context.getValueFactories().getNameFactory().create(this.repository.getUuidPropertyName());
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetChildrenCommand)
-         */
-        @Override
-        public void execute( GetChildrenCommand command ) throws RepositorySourceException {
-            Path targetPath = command.getPath();
-            Map<Path, Map<Name, Property>> data = repository.getData();
-            if (data.get(targetPath) == null) {
-                command.setError(new InvalidPathException("Non-existant node: " + targetPath));
-                return;
-            }
-            // Iterate through all of the properties, looking for any paths that are children of the path ...
-            List<Path.Segment> childSegments = new LinkedList<Path.Segment>();
-            for (Path path : data.keySet()) {
-                if (path.getAncestor().equals(targetPath)) {
-                    childSegments.add(path.getLastSegment());
-                }
-            }
-            // This does not store children order, so sort ...
-            Collections.sort(childSegments);
-            for (Path.Segment childSegment : childSegments) {
-                Map<Name, Property> properties = repository.getData().get(targetPath);
-                Property uuidProperty = properties.get(uuidPropertyName);
-                command.addChild(childSegment, uuidProperty);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         * 
-         * @see org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetPropertiesCommand)
-         */
-        @Override
-        public void execute( GetPropertiesCommand command ) throws RepositorySourceException {
-            Path targetPath = command.getPath();
-            Map<Name, Property> properties = repository.getData().get(targetPath);
-            if (properties == null) {
-                command.setError(new InvalidPathException("Non-existant node: " + targetPath));
-                return;
-            }
-            for (Property property : properties.values()) {
-                if (!property.getName().equals(this.uuidPropertyName)) {
-                    command.setProperty(property);
-                }
-            }
-        }
-    }
-
-}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java (from rev 393, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/SimpleRepositorySource.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/SimpleRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,322 @@
+/*
+ * 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.dna.spi.connector;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.naming.Reference;
+import javax.transaction.xa.XAResource;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.AbstractRepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceCapabilities;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
+import org.jboss.dna.spi.graph.InvalidPathException;
+import org.jboss.dna.spi.graph.Name;
+import org.jboss.dna.spi.graph.Path;
+import org.jboss.dna.spi.graph.Property;
+import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
+import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+import org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor;
+import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
+
+/**
+ * A {@link RepositorySource} for a {@link SimpleRepository simple repository}.
+ * 
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class SimpleRepositorySource extends AbstractRepositorySource {
+
+    private static final long serialVersionUID = 1L;
+
+    private String repositoryName;
+    private String name;
+
+    public SimpleRepositorySource() {
+        super();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#getName()
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name Sets name to the specified value.
+     */
+    public void setName( String name ) {
+        this.name = name;
+    }
+
+    /**
+     * @return repositoryName
+     */
+    public String getRepositoryName() {
+        return repositoryName;
+    }
+
+    /**
+     * @param repositoryName Sets repositoryName to the specified value.
+     */
+    public void setRepositoryName( String repositoryName ) {
+        this.repositoryName = repositoryName;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see javax.naming.Referenceable#getReference()
+     */
+    public Reference getReference() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals( Object obj ) {
+        if (obj == this) return true;
+        if (obj instanceof SimpleRepositorySource) {
+            SimpleRepositorySource that = (SimpleRepositorySource)obj;
+            if (!this.getName().equals(that.getName())) return false;
+            if (!this.getRepositoryName().equals(that.getRepositoryName())) return false;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#getCapabilities()
+     */
+    public RepositorySourceCapabilities getCapabilities() {
+        return new Capabilities();
+    }
+
+    protected class Capabilities implements RepositorySourceCapabilities {
+        public boolean supportsSameNameSiblings() {
+            return true;
+        }
+
+        public boolean supportsUpdates() {
+            return true;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.AbstractRepositorySource#createConnection()
+     */
+    @Override
+    protected synchronized RepositoryConnection createConnection() throws RepositorySourceException {
+        String reposName = this.getRepositoryName();
+        SimpleRepository repository = SimpleRepository.get(reposName);
+        if (repository == null) {
+            throw new RepositorySourceException(this.getName(), "Unable to find repository \"" + reposName + "\"");
+        }
+        return new Connection(repository);
+    }
+
+    protected class Connection implements RepositoryConnection {
+
+        private RepositorySourceListener listener;
+        private final SimpleRepository repository;
+
+        protected Connection( SimpleRepository repository ) {
+            assert repository != null;
+            this.repository = repository;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#close()
+         */
+        public void close() {
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#execute(org.jboss.dna.spi.ExecutionContext,
+         *      org.jboss.dna.spi.graph.commands.GraphCommand[])
+         */
+        public void execute( ExecutionContext context,
+                             GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
+            assert context != null;
+            if (repository.isShutdown()) {
+                throw new RepositorySourceException(getName(), "The repository \"" + repository.getRepositoryName()
+                                                               + "\" is no longer available");
+            }
+            // Now execute the commands ...
+            CommandExecutor executor = new Executor(this.repository, context, this.getSourceName());
+            for (GraphCommand command : commands) {
+                executor.execute(command);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#getDefaultCachePolicy()
+         */
+        public CachePolicy getDefaultCachePolicy() {
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#getSourceName()
+         */
+        public String getSourceName() {
+            return SimpleRepositorySource.this.getName();
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#getXAResource()
+         */
+        public XAResource getXAResource() {
+            return null;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#ping(long, java.util.concurrent.TimeUnit)
+         */
+        public boolean ping( long time,
+                             TimeUnit unit ) {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.connector.RepositoryConnection#setListener(org.jboss.dna.spi.connector.RepositorySourceListener)
+         */
+        public void setListener( RepositorySourceListener listener ) {
+            this.listener = listener;
+        }
+
+        /**
+         * @return listener
+         */
+        public RepositorySourceListener getListener() {
+            return listener;
+        }
+
+    }
+
+    protected class Executor extends AbstractCommandExecutor {
+        private final SimpleRepository repository;
+        private final Name uuidPropertyName;
+
+        protected Executor( SimpleRepository repository,
+                            ExecutionContext context,
+                            String sourceName ) {
+            super(context, sourceName);
+            this.repository = repository;
+            this.uuidPropertyName = context.getValueFactories().getNameFactory().create(this.repository.getUuidPropertyName());
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetChildrenCommand)
+         */
+        @Override
+        public void execute( GetChildrenCommand command ) throws RepositorySourceException {
+            Path targetPath = command.getPath();
+            Map<Path, Map<Name, Property>> data = repository.getData();
+            if (data.get(targetPath) == null) {
+                command.setError(new InvalidPathException("Non-existant node: " + targetPath));
+                return;
+            }
+            // Iterate through all of the properties, looking for any paths that are children of the path ...
+            List<Path.Segment> childSegments = new LinkedList<Path.Segment>();
+            for (Path path : data.keySet()) {
+                if (path.getAncestor().equals(targetPath)) {
+                    childSegments.add(path.getLastSegment());
+                }
+            }
+            // This does not store children order, so sort ...
+            Collections.sort(childSegments);
+            for (Path.Segment childSegment : childSegments) {
+                Map<Name, Property> properties = repository.getData().get(targetPath);
+                Property uuidProperty = properties.get(uuidPropertyName);
+                command.addChild(childSegment, uuidProperty);
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         * 
+         * @see org.jboss.dna.spi.graph.commands.executor.AbstractCommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetPropertiesCommand)
+         */
+        @Override
+        public void execute( GetPropertiesCommand command ) throws RepositorySourceException {
+            Path targetPath = command.getPath();
+            Map<Name, Property> properties = repository.getData().get(targetPath);
+            if (properties == null) {
+                command.setError(new InvalidPathException("Non-existant node: " + targetPath));
+                return;
+            }
+            for (Property property : properties.values()) {
+                if (!property.getName().equals(this.uuidPropertyName)) {
+                    command.setProperty(property);
+                }
+            }
+        }
+    }
+
+}

Deleted: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/TimeDelayingRepositorySource.java	2008-08-06 16:39:00 UTC (rev 389)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -1,329 +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.dna.spi.graph.connection;
-
-import static org.mockito.Mockito.mock;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.naming.Reference;
-import javax.transaction.xa.XAResource;
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.dna.spi.ExecutionContext;
-import org.jboss.dna.spi.cache.CachePolicy;
-import org.jboss.dna.spi.graph.commands.GraphCommand;
-
-/**
- * A simple {@link RepositorySource} that simulates an imaginary source with a built-in delay mechanism.
- * 
- * @author Randall Hauch
- */
- at ThreadSafe
-public class TimeDelayingRepositorySource extends AbstractRepositorySource {
-
-    /**
-     */
-    private static final long serialVersionUID = -2756725117087437347L;
-    private String name;
-    private final AtomicInteger connectionsOpenedCount = new AtomicInteger(0);
-    private final AtomicInteger connectionsClosedCount = new AtomicInteger(0);
-    private final Set<Connection> openConnections = new CopyOnWriteArraySet<Connection>();
-    private final AtomicLong loadCount = new AtomicLong(0);
-    private final AtomicLong loadDelay = new AtomicLong(0);
-    private final AtomicLong pingCount = new AtomicLong(0);
-    private final AtomicLong pingDelay = new AtomicLong(0);
-    private CachePolicy defaultCachePolicy;
-
-    public TimeDelayingRepositorySource( String identifier ) {
-        super();
-        this.name = identifier;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getName() {
-        return this.name;
-    }
-
-    /**
-     * @param name the identifier
-     */
-    public void setName( String name ) {
-        this.name = name;
-    }
-
-    public CachePolicy getDefaultCachePolicy() {
-        return defaultCachePolicy;
-    }
-
-    public void setDefaultCachePolicy( CachePolicy defaultCachePolicy ) {
-        this.defaultCachePolicy = defaultCachePolicy;
-    }
-
-    /**
-     * @return loadCount
-     */
-    public long getTotalExecuteCount() {
-        return this.loadCount.get();
-    }
-
-    /**
-     * @return pingCount
-     */
-    public long getTotalPingCount() {
-        return this.pingCount.get();
-    }
-
-    /**
-     * @return loadDelay
-     */
-    public long getConnectionExecuteDelayInMillis() {
-        return this.loadDelay.get();
-    }
-
-    public void setConnectionExecuteDelay( long time,
-                                           TimeUnit unit ) {
-        this.loadDelay.set(unit.toMillis(time));
-    }
-
-    /**
-     * @return pingDelay
-     */
-    public long getConnectionPingDelayInMillis() {
-        return this.pingDelay.get();
-    }
-
-    public void setConnectionPingDelay( long time,
-                                        TimeUnit unit ) {
-        this.pingDelay.set(unit.toMillis(time));
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.AbstractRepositorySource#createConnection()
-     */
-    @Override
-    protected RepositoryConnection createConnection() throws RepositorySourceException {
-        int connectionNumber = this.connectionsOpenedCount.incrementAndGet();
-        String connectionName = "Connection " + connectionNumber;
-        XAResource xaResource = newXaResource(connectionName);
-        Connection c = newConnection(connectionName, xaResource);
-        this.openConnections.add(c);
-        return c;
-    }
-
-    /**
-     * Factory method that can be overridden by subclasses. This method implementation simply creates a mock {@link XAResource}.
-     * 
-     * @param connectionName the name of the connection
-     * @return the XAResource, or null if this source does not support XA
-     */
-    protected XAResource newXaResource( String connectionName ) {
-        return mock(XAResource.class);
-    }
-
-    /**
-     * Factory method that can be overridden by subclasses. This method implementation creates a new {@link Connection} that uses
-     * standard bean properties for the various delays and counts.
-     * 
-     * @param connectionName
-     * @param xaResource
-     * @return a new Connection
-     * @throws RepositorySourceException
-     */
-    protected Connection newConnection( String connectionName,
-                                        XAResource xaResource ) throws RepositorySourceException {
-        Connection c = new Connection(connectionName, this.loadDelay.get(), this.pingDelay.get());
-        c.setXaResource(xaResource);
-        return c;
-    }
-
-    protected void close( Connection conn ) {
-        if (conn != null && this.openConnections.remove(conn)) {
-            this.connectionsClosedCount.incrementAndGet();
-            this.loadCount.addAndGet(conn.getLoadCount());
-            this.pingCount.addAndGet(conn.getPingCount());
-        }
-    }
-
-    public int getOpenConnectionCount() {
-        return this.openConnections.size();
-    }
-
-    public int getTotalConnectionsCreated() {
-        return this.connectionsOpenedCount.get();
-    }
-
-    public int getTotalConnectionsClosed() {
-        return this.connectionsClosedCount.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Reference getReference() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @see org.jboss.dna.spi.graph.connection.RepositorySource#getCapabilities()
-     */
-    public RepositorySourceCapabilities getCapabilities() {
-        return new Capabilities();
-    }
-
-    protected class Capabilities implements RepositorySourceCapabilities {
-        public boolean supportsSameNameSiblings() {
-            return true;
-        }
-
-        public boolean supportsUpdates() {
-            return true;
-        }
-    }
-
-    public class Connection implements RepositoryConnection {
-
-        private final String connectionName;
-        private final AtomicBoolean closed = new AtomicBoolean(false);
-        private final AtomicBoolean loadResponse = new AtomicBoolean(true);
-        private final AtomicBoolean pingResponse = new AtomicBoolean(true);
-        private final AtomicLong closeCount = new AtomicLong(0);
-        private final AtomicLong loadCount = new AtomicLong(0);
-        private final AtomicLong loadDelay;
-        private final AtomicLong pingCount = new AtomicLong(0);
-        private final AtomicLong pingDelay;
-        private final AtomicReference<XAResource> xaResource = new AtomicReference<XAResource>();
-
-        protected Connection( String connectionName,
-                              long loadDelay,
-                              long pingDelay ) {
-            assert connectionName != null && connectionName.trim().length() != 0;
-            this.loadDelay = new AtomicLong(loadDelay);
-            this.pingDelay = new AtomicLong(pingDelay);
-            this.connectionName = connectionName;
-        }
-
-        public String getConnectionName() {
-            return this.connectionName;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void close() {
-            this.closeCount.incrementAndGet();
-            this.closed.set(true);
-            TimeDelayingRepositorySource.this.close(this);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public String getSourceName() {
-            return TimeDelayingRepositorySource.this.getName();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public CachePolicy getDefaultCachePolicy() {
-            return TimeDelayingRepositorySource.this.getDefaultCachePolicy();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public XAResource getXAResource() {
-            return this.xaResource.get();
-        }
-
-        public void setXaResource( XAResource xaResource ) {
-            this.xaResource.set(xaResource);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void execute( ExecutionContext context,
-                             GraphCommand... commands ) throws InterruptedException {
-            long delay = this.loadDelay.get();
-            if (delay > 0l) Thread.sleep(delay);
-            this.loadCount.incrementAndGet();
-        }
-
-        public void setLoadResponse( boolean response ) {
-            this.loadResponse.set(response);
-        }
-
-        public void setLoadDelay( long time,
-                                  TimeUnit unit ) {
-            this.loadDelay.set(unit.toMillis(time));
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public boolean ping( long time,
-                             TimeUnit unit ) throws InterruptedException {
-            Thread.sleep(this.pingDelay.get());
-            return this.pingResponse.get();
-        }
-
-        public void setPingResponse( boolean pingResponse ) {
-            this.pingResponse.set(pingResponse);
-        }
-
-        public void setPingDelay( long time,
-                                  TimeUnit unit ) {
-            this.pingDelay.set(unit.toMillis(time));
-        }
-
-        public long getPingCount() {
-            return this.pingCount.get();
-        }
-
-        public long getLoadCount() {
-            return this.loadCount.get();
-        }
-
-        public long getCloseCount() {
-            return this.closeCount.get();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void setListener( RepositorySourceListener listener ) {
-        }
-
-    }
-
-}

Copied: trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java (from rev 393, trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/connection/TimeDelayingRepositorySource.java)
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/connector/TimeDelayingRepositorySource.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -0,0 +1,335 @@
+/*
+ * 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.dna.spi.connector;
+
+import static org.mockito.Mockito.mock;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.naming.Reference;
+import javax.transaction.xa.XAResource;
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.cache.CachePolicy;
+import org.jboss.dna.spi.connector.AbstractRepositorySource;
+import org.jboss.dna.spi.connector.RepositoryConnection;
+import org.jboss.dna.spi.connector.RepositorySource;
+import org.jboss.dna.spi.connector.RepositorySourceCapabilities;
+import org.jboss.dna.spi.connector.RepositorySourceException;
+import org.jboss.dna.spi.connector.RepositorySourceListener;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+
+/**
+ * A simple {@link RepositorySource} that simulates an imaginary source with a built-in delay mechanism.
+ * 
+ * @author Randall Hauch
+ */
+ at ThreadSafe
+public class TimeDelayingRepositorySource extends AbstractRepositorySource {
+
+    /**
+     */
+    private static final long serialVersionUID = -2756725117087437347L;
+    private String name;
+    private final AtomicInteger connectionsOpenedCount = new AtomicInteger(0);
+    private final AtomicInteger connectionsClosedCount = new AtomicInteger(0);
+    private final Set<Connection> openConnections = new CopyOnWriteArraySet<Connection>();
+    private final AtomicLong loadCount = new AtomicLong(0);
+    private final AtomicLong loadDelay = new AtomicLong(0);
+    private final AtomicLong pingCount = new AtomicLong(0);
+    private final AtomicLong pingDelay = new AtomicLong(0);
+    private CachePolicy defaultCachePolicy;
+
+    public TimeDelayingRepositorySource( String identifier ) {
+        super();
+        this.name = identifier;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * @param name the identifier
+     */
+    public void setName( String name ) {
+        this.name = name;
+    }
+
+    public CachePolicy getDefaultCachePolicy() {
+        return defaultCachePolicy;
+    }
+
+    public void setDefaultCachePolicy( CachePolicy defaultCachePolicy ) {
+        this.defaultCachePolicy = defaultCachePolicy;
+    }
+
+    /**
+     * @return loadCount
+     */
+    public long getTotalExecuteCount() {
+        return this.loadCount.get();
+    }
+
+    /**
+     * @return pingCount
+     */
+    public long getTotalPingCount() {
+        return this.pingCount.get();
+    }
+
+    /**
+     * @return loadDelay
+     */
+    public long getConnectionExecuteDelayInMillis() {
+        return this.loadDelay.get();
+    }
+
+    public void setConnectionExecuteDelay( long time,
+                                           TimeUnit unit ) {
+        this.loadDelay.set(unit.toMillis(time));
+    }
+
+    /**
+     * @return pingDelay
+     */
+    public long getConnectionPingDelayInMillis() {
+        return this.pingDelay.get();
+    }
+
+    public void setConnectionPingDelay( long time,
+                                        TimeUnit unit ) {
+        this.pingDelay.set(unit.toMillis(time));
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.AbstractRepositorySource#createConnection()
+     */
+    @Override
+    protected RepositoryConnection createConnection() throws RepositorySourceException {
+        int connectionNumber = this.connectionsOpenedCount.incrementAndGet();
+        String connectionName = "Connection " + connectionNumber;
+        XAResource xaResource = newXaResource(connectionName);
+        Connection c = newConnection(connectionName, xaResource);
+        this.openConnections.add(c);
+        return c;
+    }
+
+    /**
+     * Factory method that can be overridden by subclasses. This method implementation simply creates a mock {@link XAResource}.
+     * 
+     * @param connectionName the name of the connection
+     * @return the XAResource, or null if this source does not support XA
+     */
+    protected XAResource newXaResource( String connectionName ) {
+        return mock(XAResource.class);
+    }
+
+    /**
+     * Factory method that can be overridden by subclasses. This method implementation creates a new {@link Connection} that uses
+     * standard bean properties for the various delays and counts.
+     * 
+     * @param connectionName
+     * @param xaResource
+     * @return a new Connection
+     * @throws RepositorySourceException
+     */
+    protected Connection newConnection( String connectionName,
+                                        XAResource xaResource ) throws RepositorySourceException {
+        Connection c = new Connection(connectionName, this.loadDelay.get(), this.pingDelay.get());
+        c.setXaResource(xaResource);
+        return c;
+    }
+
+    protected void close( Connection conn ) {
+        if (conn != null && this.openConnections.remove(conn)) {
+            this.connectionsClosedCount.incrementAndGet();
+            this.loadCount.addAndGet(conn.getLoadCount());
+            this.pingCount.addAndGet(conn.getPingCount());
+        }
+    }
+
+    public int getOpenConnectionCount() {
+        return this.openConnections.size();
+    }
+
+    public int getTotalConnectionsCreated() {
+        return this.connectionsOpenedCount.get();
+    }
+
+    public int getTotalConnectionsClosed() {
+        return this.connectionsClosedCount.get();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Reference getReference() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.connector.RepositorySource#getCapabilities()
+     */
+    public RepositorySourceCapabilities getCapabilities() {
+        return new Capabilities();
+    }
+
+    protected class Capabilities implements RepositorySourceCapabilities {
+        public boolean supportsSameNameSiblings() {
+            return true;
+        }
+
+        public boolean supportsUpdates() {
+            return true;
+        }
+    }
+
+    public class Connection implements RepositoryConnection {
+
+        private final String connectionName;
+        private final AtomicBoolean closed = new AtomicBoolean(false);
+        private final AtomicBoolean loadResponse = new AtomicBoolean(true);
+        private final AtomicBoolean pingResponse = new AtomicBoolean(true);
+        private final AtomicLong closeCount = new AtomicLong(0);
+        private final AtomicLong loadCount = new AtomicLong(0);
+        private final AtomicLong loadDelay;
+        private final AtomicLong pingCount = new AtomicLong(0);
+        private final AtomicLong pingDelay;
+        private final AtomicReference<XAResource> xaResource = new AtomicReference<XAResource>();
+
+        protected Connection( String connectionName,
+                              long loadDelay,
+                              long pingDelay ) {
+            assert connectionName != null && connectionName.trim().length() != 0;
+            this.loadDelay = new AtomicLong(loadDelay);
+            this.pingDelay = new AtomicLong(pingDelay);
+            this.connectionName = connectionName;
+        }
+
+        public String getConnectionName() {
+            return this.connectionName;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void close() {
+            this.closeCount.incrementAndGet();
+            this.closed.set(true);
+            TimeDelayingRepositorySource.this.close(this);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String getSourceName() {
+            return TimeDelayingRepositorySource.this.getName();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public CachePolicy getDefaultCachePolicy() {
+            return TimeDelayingRepositorySource.this.getDefaultCachePolicy();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public XAResource getXAResource() {
+            return this.xaResource.get();
+        }
+
+        public void setXaResource( XAResource xaResource ) {
+            this.xaResource.set(xaResource);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void execute( ExecutionContext context,
+                             GraphCommand... commands ) throws InterruptedException {
+            long delay = this.loadDelay.get();
+            if (delay > 0l) Thread.sleep(delay);
+            this.loadCount.incrementAndGet();
+        }
+
+        public void setLoadResponse( boolean response ) {
+            this.loadResponse.set(response);
+        }
+
+        public void setLoadDelay( long time,
+                                  TimeUnit unit ) {
+            this.loadDelay.set(unit.toMillis(time));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean ping( long time,
+                             TimeUnit unit ) throws InterruptedException {
+            Thread.sleep(this.pingDelay.get());
+            return this.pingResponse.get();
+        }
+
+        public void setPingResponse( boolean pingResponse ) {
+            this.pingResponse.set(pingResponse);
+        }
+
+        public void setPingDelay( long time,
+                                  TimeUnit unit ) {
+            this.pingDelay.set(unit.toMillis(time));
+        }
+
+        public long getPingCount() {
+            return this.pingCount.get();
+        }
+
+        public long getLoadCount() {
+            return this.loadCount.get();
+        }
+
+        public long getCloseCount() {
+            return this.closeCount.get();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void setListener( RepositorySourceListener listener ) {
+        }
+
+    }
+
+}

Modified: trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java
===================================================================
--- trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java	2008-08-06 19:25:58 UTC (rev 393)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java	2008-08-06 19:38:46 UTC (rev 394)
@@ -33,6 +33,8 @@
 import java.util.Collections;
 import java.util.List;
 import org.jboss.dna.spi.ExecutionContext;
+import org.jboss.dna.spi.connector.BasicExecutionContext;
+import org.jboss.dna.spi.connector.RepositorySourceException;
 import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
 import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
@@ -45,8 +47,6 @@
 import org.jboss.dna.spi.graph.commands.MoveBranchCommand;
 import org.jboss.dna.spi.graph.commands.RecordBranchCommand;
 import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
-import org.jboss.dna.spi.graph.connection.BasicExecutionContext;
-import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;




More information about the dna-commits mailing list