Author: rombert
Date: Wed Sep 30 17:53:31 2015
New Revision: 1706096

URL: http://svn.apache.org/viewvc?rev=1706096&view=rev
Log:
SLING-4438 - Don't execute duplicate or out-of-order commands

- introduce a Batcher abstraction backed by a VltBatcher ; this Batcher
(for now) compacts deletions when applicable
- add a Kind to the Command interface to allow distinguishing between
  command types

Added:
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Batcher.java
    
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/BatcherFactory.java
      - copied, changed from r1706046, 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java
    
sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/
    
sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/VltBatcherTest.java
    sling/trunk/tooling/ide/impl-vlt/OSGI-INF/VltBatcherFactory.xml
    
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/
    
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcher.java
    
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcherFactory.java
      - copied, changed from r1706046, 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java
Modified:
    
sling/trunk/tooling/ide/api-test/src/test/java/org/apache/sling/ide/util/PathUtilTest.java
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java
    
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/TracingCommand.java
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/util/PathUtil.java
    
sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/Activator.java
    
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ResourceChangeCommandFactoryTest.java
    
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
    
sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
    sling/trunk/tooling/ide/impl-vlt-test/pom.xml
    
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
    
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/JcrCommand.java

Modified: 
sling/trunk/tooling/ide/api-test/src/test/java/org/apache/sling/ide/util/PathUtilTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api-test/src/test/java/org/apache/sling/ide/util/PathUtilTest.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/api-test/src/test/java/org/apache/sling/ide/util/PathUtilTest.java
 (original)
+++ 
sling/trunk/tooling/ide/api-test/src/test/java/org/apache/sling/ide/util/PathUtilTest.java
 Wed Sep 30 17:53:31 2015
@@ -65,5 +65,31 @@ public class PathUtilTest {
 
         PathUtil.getParent(null);
     }
+    
+    @Test
+    public void isAncestor_root() {
+        
+        assertThat(PathUtil.isAncestor("/", "/content"), equalTo(true));
+        assertThat(PathUtil.isAncestor("/", "/content/child"), equalTo(true));
+    }
+    
+    @Test
+    public void isAncestor_same() {
+        assertThat(PathUtil.isAncestor("/", "/"), equalTo(false));
+        assertThat(PathUtil.isAncestor("/content", "/content"), 
equalTo(false));
+    }
+
+    @Test
+    public void isAncestor_oneLevelBelow() {
+        
+        assertThat(PathUtil.isAncestor("/content", "/content/child"), 
equalTo(true));
+        assertThat(PathUtil.isAncestor("/content/child", 
"/content/child/grand-child"), equalTo(true));
+    }
+
+    @Test
+    public void isAncestor_moreLevelsBelow() {
+        
+        assertThat(PathUtil.isAncestor("/content", 
"/content/child/granchild"), equalTo(true));
+    }
 
 }

Added: 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Batcher.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Batcher.java?rev=1706096&view=auto
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Batcher.java 
(added)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Batcher.java 
Wed Sep 30 17:53:31 2015
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.transport;
+
+import java.util.List;
+
+/**
+ * The <tt>Batcher</tt> potentially optimises the way multiple commands are 
executed
+ *
+ * <p>Some potential optimisations:
+ * 
+ * <ol>
+ *   <li>Filter out duplicate commands</li>
+ *   <li>Compact multiple delete commands into a large one with the same 
semantics</li>
+ * </ol>
+ * 
+ * </p>
+ */
+public interface Batcher {
+    
+    /**
+     * Adds a command to the current processing session
+     * 
+     * @param command the command, must not be <code>null</code>
+     */
+    void add(Command<?> command);
+    
+    /**
+     * Returns a list of optimised commands, based on the commands added so far
+     * 
+     * <p>Once the list is returned, the added commands are removed and will 
not be
+     * returned by subsequent invocations of this method.</p>
+     * 
+     * @return the list of potentially optimised commands
+     */
+    List<Command<?>> get();
+}

Copied: 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/BatcherFactory.java
 (from r1706046, 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java)
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/BatcherFactory.java?p2=sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/BatcherFactory.java&p1=sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java&r1=1706046&r2=1706096&rev=1706096&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java 
(original)
+++ 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/BatcherFactory.java
 Wed Sep 30 17:53:31 2015
@@ -16,15 +16,12 @@
  */
 package org.apache.sling.ide.transport;
 
-import java.util.Set;
+public interface BatcherFactory {
 
-import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
-
-public interface Command<T> {
-
-       Result<T> execute();
-
-    String getPath();
-
-    Set<CommandExecutionFlag> getFlags();
+    /**
+     * Creates a new Batcher instance
+     * 
+     * @return a new {@link Batcher} instance
+     */
+    Batcher createBatcher();
 }

Modified: 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java 
(original)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java 
Wed Sep 30 17:53:31 2015
@@ -21,10 +21,23 @@ import java.util.Set;
 import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
 
 public interface Command<T> {
+    
+    /**
+     * Defines the major kinds of commands
+     *
+     */
+    enum Kind {
+        DELETE
+    }
 
        Result<T> execute();
 
     String getPath();
 
     Set<CommandExecutionFlag> getFlags();
+    
+    /**
+     * @return the kind, possibly <code>null</code>
+     */
+    Kind getKind();
 }

Modified: 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/TracingCommand.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/TracingCommand.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/TracingCommand.java
 (original)
+++ 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/TracingCommand.java
 Wed Sep 30 17:53:31 2015
@@ -83,5 +83,10 @@ public class TracingCommand<T> implement
     public Set<CommandExecutionFlag> getFlags() {
         return command.getFlags();
     }
+    
+    @Override
+    public Kind getKind() {
+        return command.getKind();
+    }
 
 }
\ No newline at end of file

Modified: 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/util/PathUtil.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/util/PathUtil.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/util/PathUtil.java 
(original)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/util/PathUtil.java Wed 
Sep 30 17:53:31 2015
@@ -56,4 +56,15 @@ public class PathUtil {
         return path.substring(0, path.lastIndexOf('/'));
 
     }
+    
+    public static boolean isAncestor(String ancestor, String child) {
+        
+        while ( (child = getParent(child)) != null ) {
+            if ( child.equals(ancestor)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
 }

Modified: 
sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/Activator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/Activator.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/Activator.java
 (original)
+++ 
sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/Activator.java
 Wed Sep 30 17:53:31 2015
@@ -26,6 +26,8 @@ import org.apache.sling.ide.filter.Filte
 import org.apache.sling.ide.log.Logger;
 import org.apache.sling.ide.osgi.OsgiClientFactory;
 import org.apache.sling.ide.serialization.SerializationManager;
+import org.apache.sling.ide.transport.Batcher;
+import org.apache.sling.ide.transport.BatcherFactory;
 import org.apache.sling.ide.transport.CommandExecutionProperties;
 import org.apache.sling.ide.transport.RepositoryFactory;
 import org.eclipse.core.runtime.Plugin;
@@ -59,6 +61,7 @@ public class Activator extends Plugin {
     private ServiceTracker<OsgiClientFactory, OsgiClientFactory> 
osgiClientFactory;
     private ServiceTracker<EmbeddedArtifactLocator, EmbeddedArtifactLocator> 
artifactLocator;
     private ServiceTracker<?, ?> tracer;
+    private ServiceTracker<BatcherFactory, BatcherFactory> 
batcherFactoryLocator;
 
     private ServiceRegistration<?> tracerRegistration;
 
@@ -95,6 +98,9 @@ public class Activator extends Plugin {
         ServiceReference<Object> reference = (ServiceReference<Object>) 
tracerRegistration.getReference();
         tracer = new ServiceTracker<Object, Object>(context, reference, null);
         tracer.open();
+        
+        batcherFactoryLocator = new ServiceTracker<BatcherFactory, 
BatcherFactory>(context, BatcherFactory.class, null);
+        batcherFactoryLocator.open();
        }
 
        /*
@@ -111,6 +117,7 @@ public class Activator extends Plugin {
         osgiClientFactory.close();
         artifactLocator.close();
         tracer.close();
+        batcherFactoryLocator.close();
 
         plugin = null;
                super.stop(context);
@@ -151,6 +158,10 @@ public class Activator extends Plugin {
         return (Logger) ServiceUtil.getNotNull(tracer);
     }
     
+    public BatcherFactory getBatcherFactory() {
+        return (BatcherFactory) ServiceUtil.getNotNull(batcherFactoryLocator);
+    }
+    
     /**
      * @deprecated This should not be used directly to communicate with the 
client . There is no direct replacement
      */

Modified: 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ResourceChangeCommandFactoryTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ResourceChangeCommandFactoryTest.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ResourceChangeCommandFactoryTest.java
 (original)
+++ 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ResourceChangeCommandFactoryTest.java
 Wed Sep 30 17:53:31 2015
@@ -85,7 +85,7 @@ public class ResourceChangeCommandFactor
         assertThat("command.resource.properties", 
command.getResourceProxy().getProperties(),
                 equalTo(singletonMap("jcr:primaryType", (Object) 
"nt:folder")));
         assertThat("command.fileinfo", command.getFileInfo(), nullValue());
-        assertThat("command.kind", command.getKind(), 
equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
+        assertThat("command.kind", command.getSpyKind(), 
equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
     }
 
     @Test
@@ -107,7 +107,7 @@ public class ResourceChangeCommandFactor
         assertThat("command.resource.path", 
command.getResourceProxy().getPath(), equalTo("/content/test-root/nested"));
         assertThat("command.resource.properties", 
command.getResourceProxy().getProperties(), equalTo(props));
         assertThat("command.fileinfo", command.getFileInfo(), nullValue());
-        assertThat("command.kind", command.getKind(), 
equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
+        assertThat("command.kind", command.getSpyKind(), 
equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
     }
 
     @Test

Modified: 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
 (original)
+++ 
sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
 Wed Sep 30 17:53:31 2015
@@ -76,8 +76,13 @@ public class SpyCommand<T> implements Co
     public ResourceProxy getResourceProxy() {
         return resourceProxy;
     }
+    
+    @Override
+    public Command.Kind getKind() {
+        return null;
+    }
 
-    public SpyCommand.Kind getKind() {
+    public SpyCommand.Kind getSpyKind() {
         return kind;
     }
 }
\ No newline at end of file

Modified: 
sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
 (original)
+++ 
sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
 Wed Sep 30 17:53:31 2015
@@ -72,5 +72,10 @@ public abstract class AbstractCommand<T>
         // TODO - this is not supported
         return Collections.emptySet();
     }
+    
+    @Override
+    public Kind getKind() {
+        return null;
+    }
 
 }

Modified: sling/trunk/tooling/ide/impl-vlt-test/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt-test/pom.xml?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- sling/trunk/tooling/ide/impl-vlt-test/pom.xml (original)
+++ sling/trunk/tooling/ide/impl-vlt-test/pom.xml Wed Sep 30 17:53:31 2015
@@ -44,6 +44,12 @@
           </exclusions>
       </dependency>
       <dependency>
+          <groupId>org.easymock</groupId>
+          <artifactId>easymock</artifactId>
+          <version>3.2</version>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
           <groupId>org.hamcrest</groupId>
           <artifactId>hamcrest-all</artifactId>
           <version>1.3</version>

Added: 
sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/VltBatcherTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/VltBatcherTest.java?rev=1706096&view=auto
==============================================================================
--- 
sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/VltBatcherTest.java
 (added)
+++ 
sling/trunk/tooling/ide/impl-vlt-test/src/test/java/org/apache/sling/ide/impl/vlt/transport/VltBatcherTest.java
 Wed Sep 30 17:53:31 2015
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.vlt.transport;
+
+import static org.easymock.EasyMock.createMock;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+
+import org.apache.sling.ide.impl.vlt.DeleteNodeCommand;
+import org.apache.sling.ide.transport.Command;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+
+public class VltBatcherTest {
+
+    private Repository mockRepo;
+    private Credentials credentials;
+    private VltBatcher batcher;
+
+    @Before
+    public void prepare() {
+        mockRepo = createMock(Repository.class); 
+        credentials = createMock(Credentials.class);
+        batcher = new VltBatcher();
+    }
+    
+    @Test
+    public void moreComprehensiveDeletesAreCompacted() {
+
+        testMoreComprehensiveDeletesAreCompacted("/content", "/content", 
"/content/sub");
+    }
+
+    @Test
+    public void moreComprehensiveDeletesAreCompacted_reverseOrder() {
+        
+        testMoreComprehensiveDeletesAreCompacted("/content", "/content/sub", 
"/content");
+        
+    }
+    
+    private void testMoreComprehensiveDeletesAreCompacted(String expected, 
String firstPath, String... otherPaths) {
+
+        batcher.add(new DeleteNodeCommand(mockRepo, credentials, firstPath, 
null));
+        for ( String otherPath: otherPaths) {
+            batcher.add(new DeleteNodeCommand(mockRepo, credentials, 
otherPath, null));
+        }
+        
+        List<Command<?>> batched = batcher.get();
+        
+        assertThat(batched, hasSize(1));
+        Command<?> command = batched.get(0);
+        assertThat(command, instanceOf(DeleteNodeCommand.class));
+        assertThat(command.getPath(), equalTo(expected));
+    }
+
+    @Test
+    public void unrelatedDeletesAreNotCompacted() {
+        
+        DeleteNodeCommand first = new DeleteNodeCommand(mockRepo, credentials, 
"/content/branch", null);
+        DeleteNodeCommand second = new DeleteNodeCommand(mockRepo, 
credentials, "/content/sub", null);
+        
+        batcher.add(first);
+        batcher.add(second);
+        
+        List<Command<?>> batched = batcher.get();
+        
+        assertThat(batched, hasSize(2));
+        assertThat(batched.get(0), Matchers.<Command<?>> sameInstance(first));
+        assertThat(batched.get(1), Matchers.<Command<?>> sameInstance(second));
+    }
+    
+    @Test
+    public void dataIsClearedBetweenCalls() {
+        batcher.add(new DeleteNodeCommand(mockRepo, credentials, 
"/content/branch", null));
+        batcher.get();
+        assertThat(batcher.get(), hasSize(0));
+    }
+}

Added: sling/trunk/tooling/ide/impl-vlt/OSGI-INF/VltBatcherFactory.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/OSGI-INF/VltBatcherFactory.xml?rev=1706096&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-vlt/OSGI-INF/VltBatcherFactory.xml (added)
+++ sling/trunk/tooling/ide/impl-vlt/OSGI-INF/VltBatcherFactory.xml Wed Sep 30 
17:53:31 2015
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or
+    more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information regarding
+    copyright ownership. The ASF licenses this file to you under the
+    Apache License, Version 2.0 (the "License"); you may not use
+    this file except in compliance with the License. You may obtain
+    a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+    applicable law or agreed to in writing, software distributed
+    under the License is distributed on an "AS IS" BASIS, WITHOUT
+    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+-->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"; 
immediate="false">
+   <implementation 
class="org.apache.sling.ide.impl.vlt.transport.VltBatcherFactory"/>
+   <service>
+      <provide interface="org.apache.sling.ide.transport.BatcherFactory"/>
+   </service>
+</scr:component>

Modified: 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
 (original)
+++ 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
 Wed Sep 30 17:53:31 2015
@@ -41,4 +41,8 @@ public class DeleteNodeCommand extends J
         return null;
     }
 
+    @Override
+    public Kind getKind() {
+        return Kind.DELETE;
+    }
 }

Modified: 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/JcrCommand.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/JcrCommand.java?rev=1706096&r1=1706095&r2=1706096&view=diff
==============================================================================
--- 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/JcrCommand.java
 (original)
+++ 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/JcrCommand.java
 Wed Sep 30 17:53:31 2015
@@ -95,6 +95,11 @@ public abstract class JcrCommand<T> impl
     public Set<CommandExecutionFlag> getFlags() {
         return Collections.unmodifiableSet(flags);
     }
+    
+    @Override
+    public Kind getKind() {
+        return null;
+    }
 
     protected ResourceProxy nodeToResource(Node node) throws 
RepositoryException {
     

Added: 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcher.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcher.java?rev=1706096&view=auto
==============================================================================
--- 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcher.java
 (added)
+++ 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcher.java
 Wed Sep 30 17:53:31 2015
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.vlt.transport;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.ide.transport.Batcher;
+import org.apache.sling.ide.transport.Command;
+import org.apache.sling.ide.transport.Command.Kind;
+import org.apache.sling.ide.util.PathUtil;
+
+public class VltBatcher implements Batcher {
+    
+    private List<Command<?>> queue = new ArrayList<Command<?>>();
+    
+    @Override
+    public void add(Command<?> command) {
+        queue.add(command);
+    }
+    
+    @Override
+    public List<Command<?>> get() {
+
+        LinkedCommands deletes = new LinkedCommands();
+        List<Command<?>> result = new ArrayList<Command<?>>();
+        
+        for ( Command<?> cmd : queue) {
+            if ( cmd.getKind() == Kind.DELETE ) {
+                deletes.addLinked(cmd);        
+            } else {
+                result.add(cmd);
+            }
+        }
+        
+        result.addAll(0, deletes.getLinkHeads());
+        
+        queue.clear();
+        
+        return result;
+    }
+    
+    private static class LinkedCommands {
+        
+        private List<CommandWrapper> wrappers = new 
ArrayList<CommandWrapper>();
+        
+        public void addLinked(Command<?> cmd) {
+            
+            String path = cmd.getPath();
+            for ( CommandWrapper wrapper : wrappers ) {
+                if ( PathUtil.isAncestor(wrapper.main.getPath(), path ) ) {
+                    return;
+                }
+                
+                if ( PathUtil.isAncestor(path, wrapper.main.getPath())) {
+                    wrapper.main = cmd;
+                    return;
+                }
+            }
+            
+            wrappers.add(new CommandWrapper(cmd));
+        }
+        
+        public List<Command<?>> getLinkHeads() {
+            List<Command<?>> heads = new 
ArrayList<Command<?>>(wrappers.size());
+            for ( CommandWrapper wrapper : wrappers ) {
+                heads.add(wrapper.main);
+            }
+            
+            return heads;
+        }
+    }
+    
+    private static class CommandWrapper {
+        
+        public Command<?> main;
+        
+        private CommandWrapper(Command<?> main) {
+            this.main = main;
+        }
+    }
+}

Copied: 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcherFactory.java
 (from r1706046, 
sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java)
URL: 
http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcherFactory.java?p2=sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcherFactory.java&p1=sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java&r1=1706046&r2=1706096&rev=1706096&view=diff
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/Command.java 
(original)
+++ 
sling/trunk/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/transport/VltBatcherFactory.java
 Wed Sep 30 17:53:31 2015
@@ -14,17 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.ide.transport;
+package org.apache.sling.ide.impl.vlt.transport;
 
-import java.util.Set;
+import org.apache.sling.ide.transport.Batcher;
+import org.apache.sling.ide.transport.BatcherFactory;
 
-import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
+public class VltBatcherFactory implements BatcherFactory {
 
-public interface Command<T> {
+    @Override
+    public Batcher createBatcher() {
+        return new VltBatcher();
+    }
 
-       Result<T> execute();
-
-    String getPath();
-
-    Set<CommandExecutionFlag> getFlags();
 }


Reply via email to