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(); }