[dna-commits] DNA SVN: r340 - in trunk: connectors/dna-connector-jbosscache and 6 other directories.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Thu Jul 3 14:23:41 EDT 2008


Author: rhauch
Date: 2008-07-03 14:23:41 -0400 (Thu, 03 Jul 2008)
New Revision: 340

Added:
   trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/
   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/test/java/org/jboss/dna/spi/graph/commands/
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/
   trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java
Modified:
   trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java
   trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java
   trunk/connectors/dna-connector-jbosscache/pom.xml
   trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java
Log:
DNA-171 - Create basic command executor 
http://jira.jboss.com/jira/browse/DNA-171

Created CommandExecutor interface and an AbstractCommandExecutor abstract (but complete) implementation.  The unit tests verify that the 'execute(GraphCommand)' method properly delegates to the other more specific 'execute(...)' methods, and that the 'execute(CompositeCommand)' method properly iterates over the nested commands.

Modified: trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java
===================================================================
--- trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java	2008-07-03 15:42:34 UTC (rev 339)
+++ trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepository.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -21,6 +21,7 @@
  */
 package org.jboss.dna.connector.inmemory;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -32,7 +33,22 @@
 import org.jboss.dna.common.util.ArgCheck;
 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.Path.Segment;
+import org.jboss.dna.spi.graph.commands.ActsOnPath;
+import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
+import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
+import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
+import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
+import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
+import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
+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.commands.executor.AbstractCommandExecutor;
+import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
 import org.jboss.dna.spi.graph.connection.ExecutionEnvironment;
+import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 
 /**
  * @author Randall Hauch
@@ -263,4 +279,136 @@
         }
         return numNodesCopied;
     }
+
+    /**
+     * Get a command executor given the supplied environment and source name.
+     * 
+     * @param env the environment in which the commands are to be executed
+     * @param sourceName the name of the repository source
+     * @return the executor; never null
+     */
+    public CommandExecutor getCommandExecutor( ExecutionEnvironment env,
+                                               String sourceName ) {
+        return new Executor(env, sourceName);
+    }
+
+    protected class Executor extends AbstractCommandExecutor {
+
+        protected Executor( ExecutionEnvironment env,
+                            String sourceName ) {
+            super(env, sourceName);
+        }
+
+        @Override
+        public void execute( CreateNodeCommand command ) {
+            Path path = command.getPath();
+            Path parent = path.getAncestor();
+            // Look up the parent node, which must exist ...
+            Node parentNode = getNode(parent);
+            Node node = createNode(getEnvironment(), parentNode, path.getLastSegment().getName());
+            // Now add the properties to the supplied node ...
+            for (Property property : command.getProperties()) {
+                Name propName = property.getName();
+                if (property.size() == 0) {
+                    node.getProperties().remove(propName);
+                    continue;
+                }
+                node.getProperties().put(propName, property);
+            }
+            assert node != null;
+        }
+
+        @Override
+        public void execute( GetChildrenCommand command ) {
+            Node node = getTargetNode(command);
+            // Get the names of the children ...
+            List<Node> children = node.getChildren();
+            List<Segment> childSegments = new ArrayList<Segment>(children.size());
+            for (Node child : children) {
+                childSegments.add(child.getName());
+            }
+            command.setChildren(childSegments);
+        }
+
+        @Override
+        public void execute( GetPropertiesCommand command ) {
+            Node node = getTargetNode(command);
+            for (Property property : node.getProperties().values()) {
+                command.setProperty(property);
+            }
+        }
+
+        @Override
+        public void execute( SetPropertiesCommand command ) {
+            Node node = getTargetNode(command);
+            // Now set (or remove) the properties to the supplied node ...
+            for (Property property : command.getProperties()) {
+                Name propName = property.getName();
+                if (property.size() == 0) {
+                    node.getProperties().remove(propName);
+                    continue;
+                }
+                node.getProperties().put(propName, property);
+            }
+        }
+
+        @Override
+        public void execute( DeleteBranchCommand command ) {
+            Node node = getTargetNode(command);
+            removeNode(getEnvironment(), node);
+        }
+
+        @Override
+        public void execute( CopyNodeCommand command ) {
+            Node node = getTargetNode(command);
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node newParent = getNode(newPath.getAncestor());
+            copyNode(getEnvironment(), node, newParent, false);
+        }
+
+        @Override
+        public void execute( CopyBranchCommand command ) {
+            Node node = getTargetNode(command);
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node newParent = getNode(newPath.getAncestor());
+            copyNode(getEnvironment(), node, newParent, true);
+        }
+
+        @Override
+        public void execute( MoveBranchCommand command ) {
+            Node node = getTargetNode(command);
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node newParent = getNode(newPath.getAncestor());
+            node.setParent(newParent);
+        }
+
+        @Override
+        public void execute( RecordBranchCommand command ) {
+            Node node = getTargetNode(command);
+            recordNode(command, node);
+        }
+
+        protected void recordNode( RecordBranchCommand command,
+                                   Node node ) {
+            command.record(command.getPath(), node.getProperties().values());
+            for (Node child : node.getChildren()) {
+                recordNode(command, child);
+            }
+        }
+
+        protected Node getTargetNode( ActsOnPath command ) {
+            Path path = command.getPath();
+            // Look up the node with the supplied path ...
+            Node node = InMemoryRepository.this.getNode(path);
+            if (node == null) {
+                throw new RepositorySourceException(getSourceName(), InMemoryConnectorI18n.nodeDoesNotExist.text(path));
+            }
+            return null;
+        }
+
+    }
+
 }

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-07-03 15:42:34 UTC (rev 339)
+++ trunk/connectors/dna-connector-inmemory/src/main/java/org/jboss/dna/connector/inmemory/InMemoryRepositoryConnection.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -21,31 +21,16 @@
  */
 package org.jboss.dna.connector.inmemory;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 import javax.transaction.xa.XAResource;
 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.Path.Segment;
 import org.jboss.dna.spi.graph.commands.ActsAsUpdate;
-import org.jboss.dna.spi.graph.commands.ActsOnPath;
-import org.jboss.dna.spi.graph.commands.CompositeCommand;
-import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
-import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
-import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
-import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
-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.MoveBranchCommand;
-import org.jboss.dna.spi.graph.commands.SetPropertiesCommand;
+import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
 import org.jboss.dna.spi.graph.connection.ExecutionEnvironment;
 import org.jboss.dna.spi.graph.connection.RepositoryConnection;
+import org.jboss.dna.spi.graph.connection.RepositorySourceException;
 import org.jboss.dna.spi.graph.connection.RepositorySourceListener;
 
 /**
@@ -122,9 +107,12 @@
 
     /**
      * {@inheritDoc}
+     * 
+     * @throws InterruptedException
+     * @throws RepositorySourceException
      */
     public void execute( ExecutionEnvironment env,
-                         GraphCommand... commands ) {
+                         GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
         // Do any commands update/write?
         Lock lock = this.content.getLock().readLock();
         for (GraphCommand command : commands) {
@@ -135,126 +123,19 @@
         }
 
         try {
-            // Obtain the lock ...
+            // Obtain the lock and execute the commands ...
+            CommandExecutor executor = this.content.getCommandExecutor(env, this.getSourceName());
             lock.lock();
-            // Now execute the commands ...
             for (GraphCommand command : commands) {
-                executeCommand(env, command);
+                executor.execute(command);
             }
         } finally {
             lock.unlock();
         }
     }
 
-    /**
-     * @param env
-     * @param command
-     */
-    protected void executeCommand( ExecutionEnvironment env,
-                                   GraphCommand command ) {
-        // This node reference is available for any command that extends ActsOnPath ...
-        Node node = null;
-
-        if (command instanceof CompositeCommand) {
-            CompositeCommand theCommand = (CompositeCommand)command;
-            for (GraphCommand containedCommand : theCommand) {
-                executeCommand(env, containedCommand);
-            }
-        }
-
-        // First, process the commands that create a new node ...
-        if (command instanceof CreateNodeCommand) {
-            CreateNodeCommand theCommand = (CreateNodeCommand)command;
-            Path path = theCommand.getPath();
-            Path parent = path.getAncestor();
-            // Look up the parent node, which must exist ...
-            Node parentNode = content.getNode(parent);
-            node = content.createNode(env, parentNode, path.getLastSegment().getName());
-            // Now add the properties to the supplied node ...
-            for (Property property : theCommand.getProperties()) {
-                Name propName = property.getName();
-                if (property.size() == 0) {
-                    node.getProperties().remove(propName);
-                    continue;
-                }
-                node.getProperties().put(propName, property);
-            }
-            assert node != null;
-        }
-
-        // Otherwise, check whether the command is applies to a path; all the remaining commands
-        // that do so expect the node to exist ...
-        else if (command instanceof ActsOnPath) {
-            ActsOnPath theCommand = (ActsOnPath)command;
-            Path path = theCommand.getPath();
-            // Look up the node with the supplied path ...
-            node = content.getNode(path);
-            if (node == null) throw new InvalidPathException(InMemoryConnectorI18n.nodeDoesNotExist.text(path));
-        }
-
-        if (command instanceof GetChildrenCommand) {
-            GetChildrenCommand theCommand = (GetChildrenCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            // Get the names of the children ...
-            List<Node> children = node.getChildren();
-            List<Segment> childSegments = new ArrayList<Segment>(children.size());
-            for (Node child : children) {
-                childSegments.add(child.getName());
-            }
-            theCommand.setChildren(childSegments);
-
-        }
-        if (command instanceof GetPropertiesCommand) {
-            GetPropertiesCommand theCommand = (GetPropertiesCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            for (Property property : node.getProperties().values()) {
-                theCommand.setProperty(property);
-            }
-        }
-        if (command instanceof SetPropertiesCommand) {
-            SetPropertiesCommand theCommand = (SetPropertiesCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            // Now set (or remove) the properties to the supplied node ...
-            for (Property property : theCommand.getProperties()) {
-                Name propName = property.getName();
-                if (property.size() == 0) {
-                    node.getProperties().remove(propName);
-                    continue;
-                }
-                node.getProperties().put(propName, property);
-            }
-        }
-        if (command instanceof DeleteBranchCommand) {
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            content.removeNode(env, node);
-        }
-        if (command instanceof CopyNodeCommand) {
-            CopyNodeCommand theCommand = (CopyNodeCommand)command;
-            boolean recursive = command instanceof CopyBranchCommand;
-            // Look up the new parent, which must exist ...
-            Path newPath = theCommand.getNewPath();
-            Node newParent = content.getNode(newPath.getAncestor());
-            if (newParent == null) {
-                throw new InvalidPathException(InMemoryConnectorI18n.nodeDoesNotExist.text(newPath.getAncestor()));
-            }
-            content.copyNode(env, node, newParent, recursive);
-        }
-        if (command instanceof MoveBranchCommand) {
-            MoveBranchCommand theCommand = (MoveBranchCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            // Look up the new parent, which must exist ...
-            Path newPath = theCommand.getNewPath();
-            Node newParent = content.getNode(newPath.getAncestor());
-            if (newParent == null) {
-                throw new InvalidPathException(InMemoryConnectorI18n.nodeDoesNotExist.text(newPath.getAncestor()));
-            }
-            node.setParent(newParent);
-        }
+    protected InMemoryRepository getContent() {
+        return content;
     }
 
     /**

Modified: trunk/connectors/dna-connector-jbosscache/pom.xml
===================================================================
--- trunk/connectors/dna-connector-jbosscache/pom.xml	2008-07-03 15:42:34 UTC (rev 339)
+++ trunk/connectors/dna-connector-jbosscache/pom.xml	2008-07-03 18:23:41 UTC (rev 340)
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>org.jboss.cache</groupId>
       <artifactId>jbosscache-core</artifactId>
-      <version>2.2.0.CR1</version>
+      <version>2.2.0.CR6</version>
     </dependency>
     <!-- 
     Testing (note the scope)

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-07-03 15:42:34 UTC (rev 339)
+++ trunk/connectors/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheConnection.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -22,6 +22,7 @@
 package org.jboss.dna.connector.jbosscache;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -34,9 +35,8 @@
 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.PropertyFactory;
 import org.jboss.dna.spi.graph.Path.Segment;
-import org.jboss.dna.spi.graph.commands.ActsOnPath;
-import org.jboss.dna.spi.graph.commands.CompositeCommand;
 import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
 import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
 import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
@@ -45,7 +45,10 @@
 import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
 import org.jboss.dna.spi.graph.commands.GraphCommand;
 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.commands.executor.AbstractCommandExecutor;
+import org.jboss.dna.spi.graph.commands.executor.CommandExecutor;
 import org.jboss.dna.spi.graph.connection.ExecutionEnvironment;
 import org.jboss.dna.spi.graph.connection.RepositoryConnection;
 import org.jboss.dna.spi.graph.connection.RepositorySourceException;
@@ -136,145 +139,15 @@
      * {@inheritDoc}
      */
     public void execute( ExecutionEnvironment env,
-                         GraphCommand... commands ) {
-        // Set up the workspace ...
-
+                         GraphCommand... commands ) throws RepositorySourceException, InterruptedException {
         // Now execute the commands ...
+        CommandExecutor executor = new Executor(env, this.getSourceName());
         for (GraphCommand command : commands) {
-            executeCommand(env, command);
+            executor.execute(command);
         }
     }
 
     /**
-     * @param env
-     * @param command
-     */
-    protected void executeCommand( ExecutionEnvironment env,
-                                   GraphCommand command ) {
-        // This node reference is available for any command that extends ActsOnPath ...
-        Node<Name, Object> node = null;
-
-        if (command instanceof CompositeCommand) {
-            CompositeCommand theCommand = (CompositeCommand)command;
-            for (GraphCommand containedCommand : theCommand) {
-                executeCommand(env, containedCommand);
-            }
-        }
-
-        // First, process the commands that create a new node ...
-        if (command instanceof CreateNodeCommand) {
-            CreateNodeCommand theCommand = (CreateNodeCommand)command;
-            Path path = theCommand.getPath();
-            Path parent = path.getAncestor();
-            Fqn<Segment> childFqn = getFullyQualifiedName(path.getLastSegment());
-            // Look up the parent node, which must exist ...
-            Node<Name, Object> parentNode = getNode(env, parent);
-            node = parentNode.addChild(childFqn);
-            // Add the UUID property (if required), which may be overwritten by a supplied property ...
-            Name uuidPropertyName = getUuidProperty(env);
-            if (uuidPropertyName != null) {
-                node.put(uuidPropertyName, generateUuid());
-            }
-            // Now add the properties to the supplied node ...
-            for (Property property : theCommand.getProperties()) {
-                if (property.size() == 0) continue;
-                Name propName = property.getName();
-                Object value = null;
-                if (property.size() == 1) {
-                    value = property.iterator().next();
-                } else {
-                    value = property.getValuesAsArray();
-                }
-                node.put(propName, value);
-            }
-            assert node != null;
-        }
-
-        // Otherwise, check whether the command is applies to a path; all the remaining commands
-        // that do so expect the node to exist ...
-        else if (command instanceof ActsOnPath) {
-            ActsOnPath theCommand = (ActsOnPath)command;
-            Path path = theCommand.getPath();
-            // Look up the node with the supplied path ...
-            node = getNode(env, path);
-            assert node != null;
-        }
-
-        if (command instanceof GetChildrenCommand) {
-            GetChildrenCommand theCommand = (GetChildrenCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            // Get the names of the children ...
-            List<Segment> childSegments = new ArrayList<Segment>();
-            for (Node<Name, Object> child : node.getChildren()) {
-                childSegments.add((Segment)child.getFqn().getLastElement());
-            }
-            theCommand.setChildren(childSegments);
-
-        }
-        if (command instanceof GetPropertiesCommand) {
-            GetPropertiesCommand theCommand = (GetPropertiesCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            Map<Name, Object> dataMap = node.getData();
-            for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
-                Name propertyName = data.getKey();
-                Object values = data.getValue();
-                Property property = env.getPropertyFactory().create(propertyName, values);
-                theCommand.setProperty(property);
-            }
-        }
-        if (command instanceof SetPropertiesCommand) {
-            SetPropertiesCommand theCommand = (SetPropertiesCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            // Now set (or remove) the properties to the supplied node ...
-            for (Property property : theCommand.getProperties()) {
-                Name propName = property.getName();
-                if (property.size() == 0) {
-                    node.remove(propName);
-                    continue;
-                }
-                Object value = null;
-                if (property.size() == 1) {
-                    value = property.iterator().next();
-                } else {
-                    value = property.getValuesAsArray();
-                }
-                node.put(propName, value);
-            }
-        }
-        if (command instanceof DeleteBranchCommand) {
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            node.getParent().removeChild(node.getFqn().getLastElement());
-        }
-        if (command instanceof CopyNodeCommand) {
-            CopyNodeCommand theCommand = (CopyNodeCommand)command;
-            boolean recursive = command instanceof CopyBranchCommand;
-            // Look up the new parent, which must exist ...
-            Path newPath = theCommand.getNewPath();
-            Node<Name, Object> newParent = getNode(env, newPath.getAncestor());
-            copyNode(node, newParent, recursive, null);
-        }
-        if (command instanceof MoveBranchCommand) {
-            MoveBranchCommand theCommand = (MoveBranchCommand)command;
-            assert command instanceof ActsOnPath;
-            assert node != null;
-            boolean recursive = true;
-            Name uuidProperty = getUuidProperty(env);
-            // Look up the new parent, which must exist ...
-            Path newPath = theCommand.getNewPath();
-            Node<Name, Object> newParent = getNode(env, newPath.getAncestor());
-            copyNode(node, newParent, recursive, uuidProperty);
-            // Now delete the old node ...
-            Node<Name, Object> oldParent = node.getParent();
-            boolean removed = oldParent.removeChild(node.getFqn().getLastElement());
-            assert removed;
-        }
-    }
-
-    /**
      * @return listener
      */
     protected RepositorySourceListener getListener() {
@@ -351,4 +224,154 @@
         }
         return numNodesCopied;
     }
+
+    protected class Executor extends AbstractCommandExecutor {
+
+        private final PropertyFactory propertyFactory;
+
+        protected Executor( ExecutionEnvironment env,
+                            String sourceName ) {
+            super(env, sourceName);
+            this.propertyFactory = env.getPropertyFactory();
+        }
+
+        @Override
+        public void execute( CreateNodeCommand command ) {
+            Path path = command.getPath();
+            Path parent = path.getAncestor();
+            Fqn<Segment> childFqn = getFullyQualifiedName(path.getLastSegment());
+            // Look up the parent node, which must exist ...
+            Node<Name, Object> parentNode = getNode(parent);
+            Node<Name, Object> node = parentNode.addChild(childFqn);
+            // Add the UUID property (if required), which may be overwritten by a supplied property ...
+            Name uuidPropertyName = getUuidProperty(getEnvironment());
+            if (uuidPropertyName != null) {
+                node.put(uuidPropertyName, generateUuid());
+            }
+            // Now add the properties to the supplied node ...
+            for (Property property : command.getProperties()) {
+                if (property.size() == 0) continue;
+                Name propName = property.getName();
+                Object value = null;
+                if (property.size() == 1) {
+                    value = property.iterator().next();
+                } else {
+                    value = property.getValuesAsArray();
+                }
+                node.put(propName, value);
+            }
+        }
+
+        @Override
+        public void execute( GetChildrenCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            // Get the names of the children ...
+            List<Segment> childSegments = new ArrayList<Segment>();
+            for (Node<Name, Object> child : node.getChildren()) {
+                childSegments.add((Segment)child.getFqn().getLastElement());
+            }
+            command.setChildren(childSegments);
+        }
+
+        @Override
+        public void execute( GetPropertiesCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            Map<Name, Object> dataMap = node.getData();
+            for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
+                Name propertyName = data.getKey();
+                Object values = data.getValue();
+                Property property = propertyFactory.create(propertyName, values);
+                command.setProperty(property);
+            }
+        }
+
+        @Override
+        public void execute( SetPropertiesCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            // Now set (or remove) the properties to the supplied node ...
+            for (Property property : command.getProperties()) {
+                Name propName = property.getName();
+                if (property.size() == 0) {
+                    node.remove(propName);
+                    continue;
+                }
+                Object value = null;
+                if (property.size() == 1) {
+                    value = property.iterator().next();
+                } else {
+                    value = property.getValuesAsArray();
+                }
+                node.put(propName, value);
+            }
+        }
+
+        @Override
+        public void execute( DeleteBranchCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            node.getParent().removeChild(node.getFqn().getLastElement());
+        }
+
+        @Override
+        public void execute( CopyNodeCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node<Name, Object> newParent = getNode(newPath.getAncestor());
+            copyNode(node, newParent, false, null);
+        }
+
+        @Override
+        public void execute( CopyBranchCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node<Name, Object> newParent = getNode(newPath.getAncestor());
+            copyNode(node, newParent, true, null);
+        }
+
+        @Override
+        public void execute( MoveBranchCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            boolean recursive = true;
+            Name uuidProperty = getUuidProperty(getEnvironment());
+            // Look up the new parent, which must exist ...
+            Path newPath = command.getNewPath();
+            Node<Name, Object> newParent = getNode(newPath.getAncestor());
+            copyNode(node, newParent, recursive, uuidProperty);
+            // Now delete the old node ...
+            Node<Name, Object> oldParent = node.getParent();
+            boolean removed = oldParent.removeChild(node.getFqn().getLastElement());
+            assert removed;
+        }
+
+        @Override
+        public void execute( RecordBranchCommand command ) {
+            Node<Name, Object> node = getNode(command.getPath());
+            recordNode(command, node);
+        }
+
+        protected void recordNode( RecordBranchCommand command,
+                                   Node<Name, Object> node ) {
+            // Record the properties ...
+            Map<Name, Object> dataMap = node.getData();
+            List<Property> properties = new LinkedList<Property>();
+            for (Map.Entry<Name, Object> data : dataMap.entrySet()) {
+                Name propertyName = data.getKey();
+                Object values = data.getValue();
+                Property property = propertyFactory.create(propertyName, values);
+                properties.add(property);
+            }
+            command.record(command.getPath(), properties);
+            // Now record the children ...
+            for (Node<Name, Object> child : node.getChildren()) {
+                recordNode(command, child);
+            }
+        }
+
+        protected Node<Name, Object> getNode( Path path ) {
+            return JBossCacheConnection.this.getNode(getEnvironment(), path);
+        }
+
+    }
+
 }

Added: 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	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -0,0 +1,227 @@
+/*
+ * 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.commands.executor;
+
+import org.jboss.dna.spi.graph.commands.CompositeCommand;
+import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
+import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
+import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
+import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
+import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
+import org.jboss.dna.spi.graph.commands.GetNodeCommand;
+import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+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.ExecutionEnvironment;
+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
+ * useful base class for all {@link CommandExecutor} implementations. Because all methods are implemented, subclasses only need to
+ * override methods that are appropriate or applicable, and all other commands will be processed correctly (even if new command
+ * interfaces are added in later versions). In some cases, as with {@link CompositeCommand} and {@link GetNodeCommand}, these
+ * implementations attempt to process the command. In other cases (e.g., {@link GetPropertiesCommand}, and
+ * {@link DeleteBranchCommand}), the methods do nothing and should be overridden if the command is to be processed.
+ * <p>
+ * The implementation is also designed to be instantated as needed. This may be once per call to
+ * {@link RepositoryConnection#execute(ExecutionEnvironment, GraphCommand...)}, or may be once per transaction. Either way, this
+ * class is designed to allow subclasses to store additional state that may otherwise be expensive or undesirable to obtain
+ * repeatedly. However, this state should be independent of the commands that are processed, meaning that implementations should
+ * generally not change state as a result of processing specific commands.
+ * </p>
+ * 
+ * @author Randall Hauch
+ */
+public abstract class AbstractCommandExecutor implements CommandExecutor {
+
+    private final ExecutionEnvironment env;
+    private final String sourceName;
+
+    protected AbstractCommandExecutor( ExecutionEnvironment env,
+                                       String sourceName ) {
+        assert env != null;
+        assert sourceName != null && sourceName.trim().length() != 0;
+        this.env = env;
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * Get the environment in which these commands are being executed.
+     * 
+     * @return the execution environment; never null
+     */
+    public ExecutionEnvironment getEnvironment() {
+        return env;
+    }
+
+    /**
+     * Get the name of the repository source.
+     * 
+     * @return the source name; never null or empty
+     */
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * This implementation examines the instance to see which {@link GraphCommand command interfaces} are implemented by the
+     * command, and delegates to the appropriate methods.
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.GraphCommand)
+     */
+    public void execute( GraphCommand command ) throws RepositorySourceException, InterruptedException {
+        if (command == null) return;
+        if (command instanceof CompositeCommand) {
+            execute((CompositeCommand)command);
+            // A composite command should only contain other commands and should not do anything on its own
+            return;
+        }
+        // The command could implement multiple "get" behaviors
+        if (command instanceof GetPropertiesCommand) {
+            execute((GetPropertiesCommand)command);
+        }
+        if (command instanceof GetChildrenCommand) {
+            execute((GetChildrenCommand)command);
+        }
+        // The command could record the branch even if deleting or moving ...
+        if (command instanceof RecordBranchCommand) {
+            execute((RecordBranchCommand)command);
+        }
+        // If the command createa a node, it will have properties to set
+        if (command instanceof CreateNodeCommand) {
+            execute((CreateNodeCommand)command);
+        } else if (command instanceof SetPropertiesCommand) {
+            execute((SetPropertiesCommand)command);
+        }
+        // A copy command will either copy a branch or a node, but not both
+        if (command instanceof CopyBranchCommand) {
+            execute((CopyBranchCommand)command);
+        } else if (command instanceof CopyNodeCommand) {
+            execute((CopyNodeCommand)command);
+        }
+        // The command can either delete or move a branch, but a command can't do both (the move does delete)
+        if (command instanceof DeleteBranchCommand) {
+            execute((DeleteBranchCommand)command);
+        } else if (command instanceof MoveBranchCommand) {
+            execute((MoveBranchCommand)command);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.CompositeCommand)
+     */
+    public void execute( CompositeCommand command ) throws RepositorySourceException, InterruptedException {
+        assert command != null;
+        for (GraphCommand nestedCommand : command) {
+            execute(nestedCommand);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetPropertiesCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( GetPropertiesCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.GetChildrenCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( GetChildrenCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.CreateNodeCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( CreateNodeCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.SetPropertiesCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( SetPropertiesCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.CopyNodeCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( CopyNodeCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.CopyBranchCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( CopyBranchCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.DeleteBranchCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( DeleteBranchCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.MoveBranchCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( MoveBranchCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.jboss.dna.spi.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.spi.graph.commands.RecordBranchCommand)
+     */
+    @SuppressWarnings( "unused" )
+    public void execute( RecordBranchCommand command ) throws RepositorySourceException, InterruptedException {
+    }
+
+}


Property changes on: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutor.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: 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	                        (rev 0)
+++ trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -0,0 +1,143 @@
+/*
+ * 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.commands.executor;
+
+import org.jboss.dna.spi.graph.commands.CompositeCommand;
+import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
+import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
+import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
+import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
+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.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
+ */
+public interface CommandExecutor {
+
+    /**
+     * Execute a graph command. This method should examine the command's types to determine which other <code>execute</code>
+     * methods should be called, and should then call those methods. This method should also do nothing if the command is null.
+     * 
+     * @param command the command to be executed
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( GraphCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a composite command that contains other commands. This method should simply obtain and execute each of the nested
+     * commands.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( CompositeCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to get the properties of a node.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( GetPropertiesCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to get the children of a node.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( GetChildrenCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to create a node and set the node's properties.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( CreateNodeCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to set some (or all) of the properties on a node.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( SetPropertiesCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to copy a node to a new location.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( CopyNodeCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to copy an entire branch to a new location.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( CopyBranchCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to record the structure of a branch.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( RecordBranchCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to delete an entire branch.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( DeleteBranchCommand command ) throws RepositorySourceException, InterruptedException;
+
+    /**
+     * Execute a command to move a branch from one location to another.
+     * 
+     * @param command the command to be executed; may not be null
+     * @throws RepositorySourceException if there is an error executing the command
+     * @throws InterruptedException if the thread is interrupted during execution
+     */
+    void execute( MoveBranchCommand command ) throws RepositorySourceException, InterruptedException;
+
+}


Property changes on: trunk/dna-spi/src/main/java/org/jboss/dna/spi/graph/commands/executor/CommandExecutor.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: 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	                        (rev 0)
+++ trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java	2008-07-03 18:23:41 UTC (rev 340)
@@ -0,0 +1,278 @@
+/*
+ * 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.commands.executor;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.stub;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.jboss.dna.spi.graph.commands.CompositeCommand;
+import org.jboss.dna.spi.graph.commands.CopyBranchCommand;
+import org.jboss.dna.spi.graph.commands.CopyNodeCommand;
+import org.jboss.dna.spi.graph.commands.CreateNodeCommand;
+import org.jboss.dna.spi.graph.commands.DeleteBranchCommand;
+import org.jboss.dna.spi.graph.commands.GetChildrenCommand;
+import org.jboss.dna.spi.graph.commands.GetNodeCommand;
+import org.jboss.dna.spi.graph.commands.GetPropertiesCommand;
+import org.jboss.dna.spi.graph.commands.GraphCommand;
+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.ExecutionEnvironment;
+import org.jboss.dna.spi.graph.connection.RepositorySourceException;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class AbstractCommandExecutorTest {
+
+    private static final List<GraphCommand> EMPTY_COMMAND_LIST = Collections.emptyList();
+    private static final List<GraphCommand> NULL_COMMAND_LIST = Collections.singletonList(null);
+
+    private AbstractCommandExecutor executor;
+    private GraphCommand command;
+    @Mock
+    private ExecutionEnvironment env;
+    @Mock
+    protected CommandExecutor validator;
+
+    @Before
+    public void beforeEach() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        executor = new ExecutorImpl(env, "Source X", validator);
+    }
+
+    @Test
+    public void shouldHaveEnvironment() {
+        assertThat(executor.getEnvironment(), is(sameInstance(env)));
+    }
+
+    @Test
+    public void shouldIgnoreNullCommands() throws Exception {
+        executor.execute(command);
+        verify(validator, times(1)).execute(command);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test( expected = AssertionError.class )
+    public void shouldNotAllowNullCompositeCommand() throws Exception {
+        executor.execute((CompositeCommand)null);
+    }
+
+    @Test
+    public void shouldCorrectlyExecuteEmptyCompositeCommandByCallingNoOtherExecuteMethods() throws Exception {
+        CompositeCommand command = mock(CompositeCommand.class);
+        stub(command.iterator()).toReturn(EMPTY_COMMAND_LIST.iterator());
+        executor.execute(command);
+        verify(validator, times(1)).execute(command);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldCorrectlyExecuteCompositeCommandWithSingleNullValueByCallingNoOtherExecuteMethods() throws Exception {
+        CompositeCommand command = mock(CompositeCommand.class);
+        stub(command.iterator()).toReturn(NULL_COMMAND_LIST.iterator());
+        executor.execute(command);
+        verify(validator, times(1)).execute((GraphCommand)null);
+        verify(validator, times(1)).execute(command);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldCorrectlyExecuteCompositeCommandWithNullValueByCallingNoOtherExecuteMethods() throws Exception {
+        CreateNodeCommand createNodeCommand = mock(CreateNodeCommand.class);
+        GetNodeCommand getNodeCommand = mock(GetNodeCommand.class);
+        CompositeCommand command = mock(CompositeCommand.class);
+        stub(command.iterator()).toReturn(Arrays.asList(new GraphCommand[] {createNodeCommand, getNodeCommand, null,
+            getNodeCommand}).iterator());
+        executor.execute(command);
+        verify(validator, times(1)).execute(command);
+        verify(validator, times(1)).execute((GraphCommand)null);
+        verify(validator, times(1)).execute((GraphCommand)createNodeCommand);
+        verify(validator, times(2)).execute((GraphCommand)getNodeCommand);
+        verify(validator, times(2)).execute((GetPropertiesCommand)getNodeCommand);
+        verify(validator, times(2)).execute((GetChildrenCommand)getNodeCommand);
+        verify(validator, times(1)).execute(createNodeCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldCorrectlyDelegateCompositeCommands() throws Exception {
+        CreateNodeCommand createNodeCommand = mock(CreateNodeCommand.class);
+        GetNodeCommand getNodeCommand = mock(GetNodeCommand.class);
+        CompositeCommand command = mock(CompositeCommand.class);
+        stub(command.iterator()).toReturn(Arrays.asList(new GraphCommand[] {createNodeCommand, getNodeCommand, getNodeCommand}).iterator());
+        executor.execute(command);
+        verify(validator, times(1)).execute(command);
+        verify(validator, times(1)).execute((GraphCommand)createNodeCommand);
+        verify(validator, times(2)).execute((GraphCommand)getNodeCommand);
+        verify(validator, times(2)).execute((GetPropertiesCommand)getNodeCommand);
+        verify(validator, times(2)).execute((GetChildrenCommand)getNodeCommand);
+        verify(validator, times(1)).execute(createNodeCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldExecuteGetPropertiesAndGetChildrenCommandsForGetNodeCommand() throws Exception {
+        GetNodeCommand getNodeCommand = mock(GetNodeCommand.class);
+        executor.execute((GraphCommand)getNodeCommand);
+        verify(validator, times(1)).execute((GraphCommand)getNodeCommand);
+        verify(validator, times(1)).execute((GetPropertiesCommand)getNodeCommand);
+        verify(validator, times(1)).execute((GetChildrenCommand)getNodeCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldExecuteEitherCopyBranchOrCopyNodeCommandButNotBoth() throws Exception {
+        CopyBranchCommand copyBranchCommand = mock(CopyBranchCommand.class);
+        CopyNodeCommand copyNodeCommand = mock(CopyNodeCommand.class);
+        executor.execute((GraphCommand)copyBranchCommand);
+        verify(validator, times(1)).execute((GraphCommand)copyBranchCommand);
+        verify(validator, times(1)).execute(copyBranchCommand);
+        verify(validator, times(0)).execute(copyNodeCommand);
+        executor.execute((GraphCommand)copyNodeCommand);
+        verify(validator, times(1)).execute((GraphCommand)copyNodeCommand);
+        verify(validator, times(1)).execute(copyBranchCommand);
+        verify(validator, times(1)).execute(copyNodeCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldExecuteEitherCreateNodeOrSetPropertiesCommandButNotBoth() throws Exception {
+        CreateNodeCommand createNodeCommand = mock(CreateNodeCommand.class);
+        SetPropertiesCommand setPropertiesCommand = mock(SetPropertiesCommand.class);
+        executor.execute((GraphCommand)createNodeCommand);
+        verify(validator, times(1)).execute((GraphCommand)createNodeCommand);
+        verify(validator, times(1)).execute(createNodeCommand);
+        verify(validator, times(0)).execute(setPropertiesCommand);
+        executor.execute((GraphCommand)setPropertiesCommand);
+        verify(validator, times(1)).execute((GraphCommand)setPropertiesCommand);
+        verify(validator, times(1)).execute(createNodeCommand);
+        verify(validator, times(1)).execute(setPropertiesCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldExecuteEitherDeleteOrMoveBranchComamndButNotBoth() throws Exception {
+        DeleteBranchCommand deleteBranchCommand = mock(DeleteBranchCommand.class);
+        MoveBranchCommand moveBranchCommand = mock(MoveBranchCommand.class);
+        executor.execute((GraphCommand)deleteBranchCommand);
+        verify(validator, times(1)).execute((GraphCommand)deleteBranchCommand);
+        verify(validator, times(1)).execute(deleteBranchCommand);
+        verify(validator, times(0)).execute(moveBranchCommand);
+        executor.execute((GraphCommand)moveBranchCommand);
+        verify(validator, times(1)).execute((GraphCommand)moveBranchCommand);
+        verify(validator, times(1)).execute(deleteBranchCommand);
+        verify(validator, times(1)).execute(moveBranchCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    @Test
+    public void shouldExecuteRecordBranchCommand() throws Exception {
+        RecordBranchCommand recordBranchCommand = mock(RecordBranchCommand.class);
+        executor.execute((GraphCommand)recordBranchCommand);
+        verify(validator, times(1)).execute((GraphCommand)recordBranchCommand);
+        verify(validator, times(1)).execute(recordBranchCommand);
+        verifyNoMoreInteractions(validator);
+    }
+
+    protected static class ExecutorImpl extends AbstractCommandExecutor {
+
+        private final CommandExecutor validator;
+
+        protected ExecutorImpl( ExecutionEnvironment env,
+                                String name,
+                                CommandExecutor validator ) {
+            super(env, name);
+            this.validator = validator;
+        }
+
+        @Override
+        public void execute( GraphCommand command ) throws RepositorySourceException, InterruptedException {
+            super.execute(command);
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( CompositeCommand command ) throws RepositorySourceException, InterruptedException {
+            super.execute(command);
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( CopyBranchCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( CopyNodeCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( CreateNodeCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( DeleteBranchCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( GetChildrenCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( GetPropertiesCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( MoveBranchCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( RecordBranchCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+
+        @Override
+        public void execute( SetPropertiesCommand command ) throws RepositorySourceException, InterruptedException {
+            validator.execute(command);
+        }
+    }
+
+}


Property changes on: trunk/dna-spi/src/test/java/org/jboss/dna/spi/graph/commands/executor/AbstractCommandExecutorTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain




More information about the dna-commits mailing list