You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2025/05/22 13:43:36 UTC

(sling-ide-tooling) branch issue/SLING-7599 created (now a5153e84)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git


      at a5153e84 WIP on SLING-7599

This branch includes the following new commits:

     new 3e2cb905 WIP for SLING-7599
     new 076a079c Merge branch 'issue/SLING-7599' into issue/SLING-7599+12796
     new 68e64544 WIP for SLING-7599
     new 6b6c6597 Merge branch 'master' into issue/SLING-7599+12796
     new a5153e84 WIP on SLING-7599

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(sling-ide-tooling) 04/05: Merge branch 'master' into issue/SLING-7599+12796

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git

commit 6b6c6597f04cc2c60ea912476a597aef3de5a3f9
Merge: 68e64544 cd879e02
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 22 11:56:13 2025 +0200

    Merge branch 'master' into issue/SLING-7599+12796

 eclipse/eclipse-core/META-INF/MANIFEST.MF          |  9 ++++++++
 .../sling/ide/eclipse/core/debug/impl/Tracer.java  | 19 +++++++++++++++-
 .../sling/ide/eclipse/core/internal/Activator.java | 26 ++--------------------
 eclipse/eclipse-ui/META-INF/MANIFEST.MF            |  3 +--
 shared/parent/pom.xml                              | 15 +++++++++++++
 5 files changed, 45 insertions(+), 27 deletions(-)


(sling-ide-tooling) 03/05: WIP for SLING-7599

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git

commit 68e64544f79526b0b052c86072a00a8e3916d539
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 22 11:54:38 2025 +0200

    WIP for SLING-7599
---
 .../ide/eclipse/core/internal/SlingLaunchpadBehaviour.java    |  8 ++++----
 .../sling/ide/test/impl/DefaultCommandFactoryImplTest.java    |  3 +--
 .../org/apache/sling/ide/test/impl/helpers/SpyCommand.java    |  7 ++++---
 .../org/apache/sling/ide/test/impl/helpers/SpyRepository.java |  9 +++++----
 .../eclipse/ui/internal/ImportRepositoryContentAction.java    | 11 +++++++----
 5 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/eclipse/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java b/eclipse/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
index 0812f3db..f25794cb 100644
--- a/eclipse/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
+++ b/eclipse/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
@@ -42,6 +42,7 @@ import org.apache.sling.ide.transport.Batcher;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.Result;
 import org.eclipse.core.resources.IFile;
@@ -63,7 +64,6 @@ import org.eclipse.wst.server.core.IServer;
 import org.eclipse.wst.server.core.model.IModuleResource;
 import org.eclipse.wst.server.core.model.IModuleResourceDelta;
 import org.eclipse.wst.server.core.model.ServerBehaviourDelegate;
-import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
 public class SlingLaunchpadBehaviour extends ServerBehaviourDelegateWithModulePublishSupport {
@@ -128,7 +128,7 @@ public class SlingLaunchpadBehaviour extends ServerBehaviourDelegateWithModulePu
 	
 	            } else {
 	                
-	                Command<ResourceProxy> command = repository.newListChildrenNodeCommand("/");
+	                Command<ResourceProxy> command = repository.newListChildrenNodeCommand(new RepositoryPath("/"));
 	                result = command.execute();
 	                success = result.isSuccess();
 	                
@@ -592,9 +592,9 @@ public class SlingLaunchpadBehaviour extends ServerBehaviourDelegateWithModulePu
 
     private IResource getResource(IModuleResource resource) {
 
-        IResource file = (IFile) resource.getAdapter(IFile.class);
+        IResource file = resource.getAdapter(IFile.class);
         if (file == null) {
-            file = (IFolder) resource.getAdapter(IFolder.class);
+            file = resource.getAdapter(IFolder.class);
         }
 
         if (file == null) {
diff --git a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
index 7c7c89af..5f8b88ab 100644
--- a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
+++ b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
@@ -39,7 +39,6 @@ import org.apache.sling.ide.test.impl.helpers.SpyRepository;
 import org.apache.sling.ide.test.impl.helpers.TemporaryProject;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.ResourceProxy;
-import org.apache.sling.ide.util.PathUtil;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
@@ -207,6 +206,6 @@ public class DefaultCommandFactoryImplTest {
         List<ResourceProxy> children = command.getResourceProxy().getChildren();
 
         assertThat("command.resource.children.size", children.size(), equalTo(3));
-        assertThat("command.resource.children[2].name", PathUtil.getName(children.get(2).getPath()), equalTo("folder2"));
+        assertThat("command.resource.children[2].name", children.get(2).getPath().getName(), equalTo("folder2"));
     }
 }
diff --git a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
index 4917ab08..dd0ef3b6 100644
--- a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
+++ b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyCommand.java
@@ -23,6 +23,7 @@ import java.util.Set;
 import org.apache.sling.ide.sync.content.WorkspaceFile;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.Result;
 
@@ -41,11 +42,11 @@ public class SpyCommand<T> implements Command<T> {
 
     private final ResourceProxy resourceProxy;
     private final WorkspaceFile fileInfo;
-    private final String path;
+    private final RepositoryPath path;
     private final SpyCommand.Kind kind;
     private final EnumSet<CommandExecutionFlag> flags;
 
-    public SpyCommand(ResourceProxy resourceProxy, WorkspaceFile fileInfo, String path, SpyCommand.Kind kind,
+    public SpyCommand(ResourceProxy resourceProxy, WorkspaceFile fileInfo, RepositoryPath path, SpyCommand.Kind kind,
             CommandExecutionFlag... flags) {
         this.resourceProxy = resourceProxy;
         this.fileInfo = fileInfo;
@@ -61,7 +62,7 @@ public class SpyCommand<T> implements Command<T> {
     }
 
     @Override
-    public String getPath() {
+    public RepositoryPath getPath() {
         return path;
     }
 
diff --git a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyRepository.java b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyRepository.java
index ad02b714..1b78a361 100644
--- a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyRepository.java
+++ b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/helpers/SpyRepository.java
@@ -23,6 +23,7 @@ import org.apache.sling.ide.transport.FallbackNodeTypeRegistry;
 import org.apache.sling.ide.transport.NodeTypeRegistry;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 /**
@@ -50,22 +51,22 @@ public class SpyRepository implements Repository {
     }
 
     @Override
-    public Command<Void> newDeleteNodeCommand(String path) {
+    public Command<Void> newDeleteNodeCommand(RepositoryPath path) {
         return new SpyCommand<>(null, null, path, SpyCommand.Kind.DELETE);
     }
 
     @Override
-    public Command<ResourceProxy> newListChildrenNodeCommand(String path) {
+    public Command<ResourceProxy> newListChildrenNodeCommand(RepositoryPath path) {
         throw new UnsupportedOperationException("Not implemented");
     }
 
     @Override
-    public Command<ResourceProxy> newGetNodeContentCommand(String path) {
+    public Command<ResourceProxy> newGetNodeContentCommand(RepositoryPath path) {
         throw new UnsupportedOperationException("Not implemented");
     }
 
     @Override
-    public Command<byte[]> newGetNodeCommand(String path) {
+    public Command<byte[]> newGetNodeCommand(RepositoryPath path) {
         throw new UnsupportedOperationException("Not implemented");
     }
 
diff --git a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
index f67ed1f3..f69cf60b 100644
--- a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
+++ b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
@@ -44,6 +44,7 @@ import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.serialization.SerializationKindManager;
 import org.apache.sling.ide.serialization.SerializationManager;
 import org.apache.sling.ide.sync.content.SyncCommandFactory;
+import org.apache.sling.ide.sync.content.WorkspacePath;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryException;
@@ -256,8 +257,10 @@ public class ImportRepositoryContentAction {
             throws RepositoryException, CoreException, IOException, SerializationException {
 
         logger.trace("crawlChildrenAndImport({0},  {1}, {2}, {3}", repository, path, project, projectRelativePath);
+        
+        RepositoryPath repositoryPath = serializationManager.getRepositoryPath(new WorkspacePath(path));
 
-        ResourceProxy resource = executeCommand(repository.newListChildrenNodeCommand(path));
+        ResourceProxy resource = executeCommand(repository.newListChildrenNodeCommand(repositoryPath));
         
         SerializationData serializationData = builder.buildSerializationData(contentSyncRoot, resource);
         logger.trace("For resource at path {0} got serialization data {1}", resource.getPath(), serializationData);
@@ -270,7 +273,7 @@ public class ImportRepositoryContentAction {
 	
 	        switch (serializationData.getSerializationKind()) {
 	            case FILE: {
-	                byte[] contents = executeCommand(repository.newGetNodeCommand(path));
+	                byte[] contents = executeCommand(repository.newGetNodeCommand(repositoryPath));
                     createFile(project, getPathForPlainFileNode(resource, serializationFolderPath), contents);
 	
 	                if (serializationData.hasContents()) {
@@ -299,7 +302,7 @@ public class ImportRepositoryContentAction {
 
                                     // 2. recursively handle all resources
                                     for (ResourceProxy grandChild : reloadedChildResource.getChildren()) {
-                                        crawlChildrenAndImport(grandChild.getPath());
+                                        crawlChildrenAndImport(path + "/" + serializationManager.getLocalName(child.getPath().getName()) + "/" + serializationManager.getLocalName(grandChild.getPath().getName()));
                                     }
                                 }
 	                            
@@ -357,7 +360,7 @@ public class ImportRepositoryContentAction {
                 }
             }
 
-            crawlChildrenAndImport(child.getPath());
+            crawlChildrenAndImport(path + "/" + serializationManager.getLocalName(child.getPath().getName()));
         }
     }
 


(sling-ide-tooling) 02/05: Merge branch 'issue/SLING-7599' into issue/SLING-7599+12796

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git

commit 076a079c0ca6840a63026f5a1d5311529cf029a7
Merge: 0396dadf 3e2cb905
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed May 21 17:48:42 2025 +0200

    Merge branch 'issue/SLING-7599' into issue/SLING-7599+12796

 .../ui/internal/ImportRepositoryContentAction.java |   8 +-
 .../java/org/apache/sling/ide/filter/Filter.java   |   8 ++
 .../apache/sling/ide/filter/IgnoredResources.java  |   6 +-
 .../ide/serialization/SerializationManager.java    |   3 +-
 .../content/impl/DefaultSyncCommandFactory.java    |   8 +-
 .../org/apache/sling/ide/transport/Command.java    |   2 +-
 .../org/apache/sling/ide/transport/Repository.java |   8 +-
 .../apache/sling/ide/transport/RepositoryPath.java | 110 +++++++++++++++++++++
 .../apache/sling/ide/transport/ResourceProxy.java  |  50 +++-------
 .../sling/ide/transport/impl/DefaultBatcher.java   |  10 +-
 .../sling/ide/filter/IgnoredResourcesTest.java     |  17 ++--
 .../ide/serialization/NodeTypeResourceBuilder.java |   9 +-
 .../sling/ide/serialization/StubRepository.java    |   9 +-
 .../sling/ide/transport/ResourceProxyTest.java     |  36 +++----
 .../sling/ide/impl/vlt/AddOrUpdateNodeCommand.java |  24 ++---
 .../sling/ide/impl/vlt/DeleteNodeCommand.java      |   7 +-
 .../apache/sling/ide/impl/vlt/GetNodeCommand.java  |   5 +-
 .../sling/ide/impl/vlt/GetNodeContentCommand.java  |   5 +-
 .../org/apache/sling/ide/impl/vlt/JcrCommand.java  |  11 ++-
 .../sling/ide/impl/vlt/ListChildrenCommand.java    |   5 +-
 .../apache/sling/ide/impl/vlt/ListTreeCommand.java |   5 +-
 .../ide/impl/vlt/ReorderChildNodesCommand.java     |  15 ++-
 .../sling/ide/impl/vlt/VltNodeTypeFactory.java     |  12 +--
 .../apache/sling/ide/impl/vlt/VltRepository.java   |  11 ++-
 .../serialization/ResourceProxyParserHandler.java  |   5 +-
 .../serialization/VltSerializationDataBuilder.java |   6 +-
 .../vlt/serialization/VltSerializationManager.java |   9 +-
 .../ide/impl/vlt/AddOrUpdateNodeCommandIT.java     |   5 +-
 .../ide/impl/vlt/ReorderChildNodesCommandIT.java   |   3 +-
 .../ResourceProxyParserHandlerTest.java            |  17 ++--
 .../serialization/VltSerializationManagerTest.java |   9 +-
 .../ide/impl/vlt/transport/DefaultBatcherTest.java |  41 ++++----
 32 files changed, 298 insertions(+), 181 deletions(-)


(sling-ide-tooling) 05/05: WIP on SLING-7599

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git

commit a5153e8470c7d1f665610a250265acfcbf01e2e8
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 22 15:43:21 2025 +0200

    WIP on SLING-7599
---
 .../test/impl/DefaultCommandFactoryImplTest.java   |  8 ++++----
 .../ui/internal/ImportRepositoryContentAction.java | 23 +++++++++++-----------
 .../serialization/VltSerializationDataBuilder.java |  4 ++--
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
index 5f8b88ab..3d4dbf4d 100644
--- a/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
+++ b/eclipse/eclipse-test/src/org/apache/sling/ide/test/impl/DefaultCommandFactoryImplTest.java
@@ -105,14 +105,14 @@ public class DefaultCommandFactoryImplTest {
         SpyCommand<?> command = (SpyCommand<?>) factory.newCommandForAddedOrUpdatedResource(spyRepo,
                 EclipseResources.create(contentProject.findMember("jcr_root/content/test-root/nested/gitignore")));
         assertThat("command.path", command.getPath(), nullValue());
-        assertThat("command.resource.path", command.getResourceProxy().getPath(), equalTo("/content/test-root/nested/gitignore"));
+        assertThat("command.resource.path", command.getResourceProxy().getPath().asString(), equalTo("/content/test-root/nested/gitignore"));
         assertThat("command.resource.properties", command.getResourceProxy().getProperties(),
                 equalTo(singletonMap("jcr:primaryType", (Object) "nt:file")));
         assertThat("command.kind", command.getSpyKind(), equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
         
         command = (SpyCommand<?>) factory.newCommandForRemovedResource(spyRepo,
                 EclipseResources.create(contentProject.findMember("jcr_root/content/test-root/nested/gitignore")));
-        assertThat("command.path", command.getPath(), equalTo("/content/test-root/nested/gitignore"));
+        assertThat("command.path", command.getPath().asString(), equalTo("/content/test-root/nested/gitignore"));
         assertThat("command.kind", command.getSpyKind(), equalTo(SpyCommand.Kind.DELETE));
     }
 
@@ -128,7 +128,7 @@ public class DefaultCommandFactoryImplTest {
                 EclipseResources.create(contentProject.findMember("jcr_root/content/test-root")));
 
         assertThat("command.path", command.getPath(), nullValue());
-        assertThat("command.resource.path", command.getResourceProxy().getPath(), equalTo("/content/test-root"));
+        assertThat("command.resource.path", command.getResourceProxy().getPath().asString(), equalTo("/content/test-root"));
         assertThat("command.resource.properties", command.getResourceProxy().getProperties(),
                 equalTo(singletonMap("jcr:primaryType", (Object) "nt:folder")));
         assertThat("command.fileinfo", command.getFileInfo(), nullValue());
@@ -151,7 +151,7 @@ public class DefaultCommandFactoryImplTest {
         props.put("jcr:title", "Some Folder");
 
         assertThat("command.path", command.getPath(), nullValue());
-        assertThat("command.resource.path", command.getResourceProxy().getPath(), equalTo("/content/test-root/nested"));
+        assertThat("command.resource.path", command.getResourceProxy().getPath().asString(), equalTo("/content/test-root/nested"));
         assertThat("command.resource.properties", command.getResourceProxy().getProperties(), equalTo(props));
         assertThat("command.fileinfo", command.getFileInfo(), nullValue());
         assertThat("command.kind", command.getSpyKind(), equalTo(SpyCommand.Kind.ADD_OR_UPDATE));
diff --git a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
index f69cf60b..4b21f2b1 100644
--- a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
+++ b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
@@ -151,8 +151,10 @@ public class ImportRepositoryContentAction {
             recordNotIgnoredResources();
 
             ProgressUtils.advance(monitor, 1);
+            
+            RepositoryPath repositoryPath = serializationManager.getRepositoryPath(new WorkspacePath(repositoryImportRoot.toPortableString()));
 
-            crawlChildrenAndImport(repositoryImportRoot.toPortableString());
+            crawlChildrenAndImport(repositoryPath);
 
             removeNotIgnoredAndNotUpdatedResources(new NullProgressMonitor());
 
@@ -253,13 +255,10 @@ public class ImportRepositoryContentAction {
      * @throws IOException
      */
     // TODO: This probably should be pushed into the service layer
-    private void crawlChildrenAndImport(String path)
+    private void crawlChildrenAndImport(RepositoryPath repositoryPath)
             throws RepositoryException, CoreException, IOException, SerializationException {
 
-        logger.trace("crawlChildrenAndImport({0},  {1}, {2}, {3}", repository, path, project, projectRelativePath);
-        
-        RepositoryPath repositoryPath = serializationManager.getRepositoryPath(new WorkspacePath(path));
-
+        logger.trace("crawlChildrenAndImport({0},  {1}, {2}, {3}", repository, repositoryPath, project, projectRelativePath);
         ResourceProxy resource = executeCommand(repository.newListChildrenNodeCommand(repositoryPath));
         
         SerializationData serializationData = builder.buildSerializationData(contentSyncRoot, resource);
@@ -302,7 +301,7 @@ public class ImportRepositoryContentAction {
 
                                     // 2. recursively handle all resources
                                     for (ResourceProxy grandChild : reloadedChildResource.getChildren()) {
-                                        crawlChildrenAndImport(path + "/" + serializationManager.getLocalName(child.getPath().getName()) + "/" + serializationManager.getLocalName(grandChild.getPath().getName()));
+                                        crawlChildrenAndImport(grandChild.getPath());
                                     }
                                 }
 	                            
@@ -318,7 +317,7 @@ public class ImportRepositoryContentAction {
 
                     IFolder folder = createFolder(project, serializationFolderPath);
 
-                    parseIgnoreFiles(folder, path);
+                    parseIgnoreFiles(folder, repositoryPath.asString());
 
 	                if (serializationData.hasContents()) {
                         createFile(project, serializationFolderPath.append(serializationData.getFileName()),
@@ -360,7 +359,7 @@ public class ImportRepositoryContentAction {
                 }
             }
 
-            crawlChildrenAndImport(path + "/" + serializationManager.getLocalName(child.getPath().getName()));
+            crawlChildrenAndImport(child.getPath());
         }
     }
 
@@ -385,7 +384,7 @@ public class ImportRepositoryContentAction {
         return serializationFolderPath.removeLastSegments(1).append(name);
     }
 
-    private void parseIgnoreFiles(IFolder folder, String path) throws IOException, CoreException {
+    private void parseIgnoreFiles(IFolder folder, String repositoryPath) throws IOException, CoreException {
         // TODO - the parsing should be extracted
         IResource vltIgnore = folder.findMember(".vltignore");
         if (vltIgnore != null && vltIgnore instanceof IFile) {
@@ -396,8 +395,8 @@ public class ImportRepositoryContentAction {
             try (InputStream contents = ((IFile) vltIgnore).getContents()) {
                 List<String> ignoreLines = IOUtils.readLines(contents);
                 for (String ignoreLine : ignoreLines) {
-                    logger.trace("Registering ignore rule {0}:{1}", path, ignoreLine);
-                    ignoredResources.registerRegExpIgnoreRule(path, ignoreLine);
+                    logger.trace("Registering ignore rule {0}:{1}", repositoryPath, ignoreLine);
+                    ignoredResources.registerRegExpIgnoreRule(repositoryPath, ignoreLine);
                 }
             }
         }
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
index 91f5aaf8..52ec8f10 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
@@ -134,7 +134,7 @@ public class VltSerializationDataBuilder implements SerializationDataBuilder {
 
             SerializationKind serializationKind = getSerializationKind(aggregate);
 
-            if (resource.getPath().equals("/") || serializationKind == SerializationKind.METADATA_PARTIAL
+            if (resource.getPath().asString().equals("/") || serializationKind == SerializationKind.METADATA_PARTIAL
                     || serializationKind == SerializationKind.FILE || serializationKind == SerializationKind.FOLDER) {
                 nameHint = Constants.DOT_CONTENT_XML;
             } else if (serializationKind == SerializationKind.METADATA_FULL) {
@@ -335,7 +335,7 @@ public class VltSerializationDataBuilder implements SerializationDataBuilder {
         }
 
         for (Aggregate leaf : leaves) {
-            if (leaf.getPath().equals(resource.getPath())) {
+            if (leaf.getPath().equals(resource.getPath().asString())) {
                 chain.add(leaf);
                 return chain;
             } else if (Text.isDescendant(leaf.getPath(), resource.getPath().asString())) {


(sling-ide-tooling) 01/05: WIP for SLING-7599

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch issue/SLING-7599
in repository https://gitbox.apache.org/repos/asf/sling-ide-tooling.git

commit 3e2cb90507929d7cb6e4ddce2f4bf37802abd309
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed May 21 16:20:51 2025 +0200

    WIP for SLING-7599
---
 .../ui/internal/ImportRepositoryContentAction.java |   8 +-
 .../java/org/apache/sling/ide/filter/Filter.java   |   8 ++
 .../apache/sling/ide/filter/IgnoredResources.java  |   6 +-
 .../ide/serialization/SerializationManager.java    |   3 +-
 .../content/impl/DefaultSyncCommandFactory.java    |   8 +-
 .../org/apache/sling/ide/transport/Command.java    |   2 +-
 .../org/apache/sling/ide/transport/Repository.java |   8 +-
 .../apache/sling/ide/transport/RepositoryPath.java | 110 +++++++++++++++++++++
 .../apache/sling/ide/transport/ResourceProxy.java  |  50 +++-------
 .../sling/ide/transport/impl/DefaultBatcher.java   |  10 +-
 .../sling/ide/filter/IgnoredResourcesTest.java     |  17 ++--
 .../ide/serialization/NodeTypeResourceBuilder.java |   9 +-
 .../sling/ide/serialization/StubRepository.java    |   9 +-
 .../sling/ide/transport/ResourceProxyTest.java     |  36 +++----
 .../SimpleXmlSerializationManager.java             |  10 +-
 .../impl/resource/transport/AbstractCommand.java   |   1 -
 .../SimpleXmlSerializationManagerTest.java         |   3 +-
 .../sling/ide/impl/vlt/AddOrUpdateNodeCommand.java |  24 ++---
 .../sling/ide/impl/vlt/DeleteNodeCommand.java      |   7 +-
 .../apache/sling/ide/impl/vlt/GetNodeCommand.java  |   5 +-
 .../sling/ide/impl/vlt/GetNodeContentCommand.java  |   5 +-
 .../org/apache/sling/ide/impl/vlt/JcrCommand.java  |  11 ++-
 .../sling/ide/impl/vlt/ListChildrenCommand.java    |   5 +-
 .../apache/sling/ide/impl/vlt/ListTreeCommand.java |   5 +-
 .../ide/impl/vlt/ReorderChildNodesCommand.java     |  15 ++-
 .../sling/ide/impl/vlt/VltNodeTypeFactory.java     |  12 +--
 .../apache/sling/ide/impl/vlt/VltRepository.java   |  11 ++-
 .../serialization/ResourceProxyParserHandler.java  |   5 +-
 .../serialization/VltSerializationDataBuilder.java |   6 +-
 .../vlt/serialization/VltSerializationManager.java |   9 +-
 .../ide/impl/vlt/AddOrUpdateNodeCommandIT.java     |   5 +-
 .../ide/impl/vlt/ReorderChildNodesCommandIT.java   |   3 +-
 .../ResourceProxyParserHandlerTest.java            |  17 ++--
 .../serialization/VltSerializationManagerTest.java |   9 +-
 .../ide/impl/vlt/transport/DefaultBatcherTest.java |  41 ++++----
 shared/pom.xml                                     |   1 -
 36 files changed, 306 insertions(+), 188 deletions(-)

diff --git a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
index f7d1fa4f..f67ed1f3 100644
--- a/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
+++ b/eclipse/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ImportRepositoryContentAction.java
@@ -28,7 +28,6 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.util.Text;
 import org.apache.sling.ide.eclipse.core.EclipseResources;
 import org.apache.sling.ide.eclipse.core.ProjectUtil;
 import org.apache.sling.ide.eclipse.core.ResourceUtil;
@@ -48,6 +47,7 @@ import org.apache.sling.ide.sync.content.SyncCommandFactory;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceAndInfo;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.Result;
@@ -205,7 +205,7 @@ public class ImportRepositoryContentAction {
                         return true;
                     }
 
-                    String repositoryPath = rai.getResource().getPath();
+                    RepositoryPath repositoryPath = rai.getResource().getPath();
 
                     FilterResult filterResult = filter.filter(repositoryPath);
 
@@ -293,7 +293,7 @@ public class ImportRepositoryContentAction {
 
                                 if (reloadedChildResource.getChildren().size() != 0) {
 
-                                    String pathName = Text.getName(reloadedChildResource.getPath());
+                                    String pathName = reloadedChildResource.getPath().getName();
                                     pathName = serializationManager.getLocalName(pathName);
                                     createFolder(project, serializationFolderPath.append(pathName));
 
@@ -377,7 +377,7 @@ public class ImportRepositoryContentAction {
 
         // TODO - can we just use the serializationFolderPath ?
 
-        String name = serializationManager.getLocalName(Text.getName(resource.getPath()));
+        String name = serializationManager.getLocalName(resource.getPath().getName());
 
         return serializationFolderPath.removeLastSegments(1).append(name);
     }
diff --git a/shared/api/src/main/java/org/apache/sling/ide/filter/Filter.java b/shared/api/src/main/java/org/apache/sling/ide/filter/Filter.java
index 0dd41919..2a6d125e 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/filter/Filter.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/filter/Filter.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sling.ide.filter;
 
+import org.apache.sling.ide.transport.RepositoryPath;
+
 public interface Filter {
 
     /**
@@ -25,5 +27,11 @@ public interface Filter {
      * 
      * @return the filter result, never <code>null</code>
      */
+    // TODO - remove?
+    @Deprecated
     FilterResult filter(String repositoryPath);
+    
+    default FilterResult filter(RepositoryPath repositoryPath) {
+        return filter(repositoryPath.asString());
+    }
 }
diff --git a/shared/api/src/main/java/org/apache/sling/ide/filter/IgnoredResources.java b/shared/api/src/main/java/org/apache/sling/ide/filter/IgnoredResources.java
index 0ddf2ce1..e513a14a 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/filter/IgnoredResources.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/filter/IgnoredResources.java
@@ -20,6 +20,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 
+import org.apache.sling.ide.transport.RepositoryPath;
+
 /**
  * The <tt>IgnoredResources</tt> holds information about what resources are ignored in a local checkout
  */
@@ -55,9 +57,9 @@ public class IgnoredResources {
         patterns.add(Pattern.compile(reg.toString()));
     }
 
-    public boolean isIgnored(String repositoryPath) {
+    public boolean isIgnored(RepositoryPath repositoryPath) {
         for (Pattern pattern : patterns) {
-            if (pattern.matcher(repositoryPath).matches()) {
+            if (pattern.matcher(repositoryPath.asString()).matches()) {
                 return true;
             }
         }
diff --git a/shared/api/src/main/java/org/apache/sling/ide/serialization/SerializationManager.java b/shared/api/src/main/java/org/apache/sling/ide/serialization/SerializationManager.java
index 6fa32fd9..27865ba4 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/serialization/SerializationManager.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/serialization/SerializationManager.java
@@ -23,6 +23,7 @@ import org.apache.sling.ide.sync.content.WorkspaceFile;
 import org.apache.sling.ide.sync.content.WorkspacePath;
 import org.apache.sling.ide.sync.content.WorkspaceResource;
 import org.apache.sling.ide.transport.Repository;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public interface SerializationManager {
@@ -52,7 +53,7 @@ public interface SerializationManager {
      * @param localPath the local path
      * @return the repository path
      */
-    String getRepositoryPath(WorkspacePath localPath);
+    RepositoryPath getRepositoryPath(WorkspacePath localPath);
 
     /**
      * Maps a repository name to a local name.
diff --git a/shared/api/src/main/java/org/apache/sling/ide/sync/content/impl/DefaultSyncCommandFactory.java b/shared/api/src/main/java/org/apache/sling/ide/sync/content/impl/DefaultSyncCommandFactory.java
index 2f596e16..bafb2211 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/sync/content/impl/DefaultSyncCommandFactory.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/sync/content/impl/DefaultSyncCommandFactory.java
@@ -38,9 +38,9 @@ import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.CommandContext;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceAndInfo;
 import org.apache.sling.ide.transport.ResourceProxy;
-import org.apache.sling.ide.util.PathUtil;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -163,8 +163,8 @@ localFile);
                
                ResourceProxy serializationData = serializationManager.readSerializationData( possibleSerializationFile);
 
-               String repositoryPath = serializationManager.getRepositoryPath(resourceLocalPath);
-               String potentialPath = serializationData.getPath();
+               RepositoryPath repositoryPath = serializationManager.getRepositoryPath(resourceLocalPath);
+               RepositoryPath potentialPath = serializationData.getPath();
                boolean covered = serializationData.covers(repositoryPath);
 
                logger.trace(
@@ -360,7 +360,7 @@ localFile);
 
        while (childIterator.hasNext()) {
            ResourceProxy child = childIterator.next();
-           String childName = PathUtil.getName(child.getPath());
+           String childName = child.getPath().getName();
            String osChildName = serializationManager.getLocalName(childName);
 
            // covered children might have a FS representation, depending on their child nodes, so
diff --git a/shared/api/src/main/java/org/apache/sling/ide/transport/Command.java b/shared/api/src/main/java/org/apache/sling/ide/transport/Command.java
index 75671d5b..bb8634c5 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/transport/Command.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/transport/Command.java
@@ -32,7 +32,7 @@ public interface Command<T> {
 
 	Result<T> execute();
 
-    String getPath();
+	RepositoryPath getPath();
 
     Set<CommandExecutionFlag> getFlags();
     
diff --git a/shared/api/src/main/java/org/apache/sling/ide/transport/Repository.java b/shared/api/src/main/java/org/apache/sling/ide/transport/Repository.java
index 62aadba9..4765ee3c 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/transport/Repository.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/transport/Repository.java
@@ -106,7 +106,7 @@ public interface Repository {
      */
     Command<Void> newReorderChildNodesCommand(ResourceProxy resourceProxy);
 	
-    Command<Void> newDeleteNodeCommand(String path);
+    Command<Void> newDeleteNodeCommand(RepositoryPath path);
  
     /**
      * Retrieves information about the resource located at <tt>path</tt> and its direct descendants
@@ -114,7 +114,7 @@ public interface Repository {
      * @param path
      * @return a <tt>ResourceProxy</tt> rooted at <tt>path</tt> and its direct descendants
      */
-    Command<ResourceProxy> newListChildrenNodeCommand(String path);
+    Command<ResourceProxy> newListChildrenNodeCommand(RepositoryPath path);
  	
     /**
      * Retrieves all properties of a resource located at <tt>path</tt>
@@ -122,9 +122,9 @@ public interface Repository {
      * @param path
      * @return all properties for the resource located at <tt>path</tt>
      */
-    Command<ResourceProxy> newGetNodeContentCommand(String path);
+    Command<ResourceProxy> newGetNodeContentCommand(RepositoryPath path);
 
-	Command<byte[]> newGetNodeCommand(String path);
+	Command<byte[]> newGetNodeCommand(RepositoryPath path);
 	
 	/**
 	 * Returns the node type registry - when the underlying server is started -
diff --git a/shared/api/src/main/java/org/apache/sling/ide/transport/RepositoryPath.java b/shared/api/src/main/java/org/apache/sling/ide/transport/RepositoryPath.java
new file mode 100644
index 00000000..e2d8f8a5
--- /dev/null
+++ b/shared/api/src/main/java/org/apache/sling/ide/transport/RepositoryPath.java
@@ -0,0 +1,110 @@
+/*
+ * 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.Objects;
+
+import org.apache.sling.ide.util.PathUtil;
+
+public class RepositoryPath {
+    
+    private static boolean isParent(String parentPath, String childPath) {
+
+        if (!isDescendent(parentPath, childPath)) {
+            return false;
+        }
+
+        for (int i = parentPath.length() + 1; i < childPath.length(); i++) {
+            if (childPath.charAt(i) == '/') {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private static boolean isDescendent(String parentPath, String childPath) {
+        if (parentPath.equals("/")) {
+            return childPath.length() > 1;
+        }
+
+        return parentPath.length() < childPath.length() && childPath.charAt(parentPath.length()) == '/'
+                    && childPath.startsWith(parentPath);
+    }
+
+    private final String path;
+
+    public RepositoryPath(String path) {
+        // validate it is not null or empty and starts with a slash
+        if (path == null || path.isEmpty() || !path.startsWith("/"))
+            throw new IllegalArgumentException("Invalid repository path: " + path);
+        
+        this.path = path;
+    }
+    
+    public boolean isParent(RepositoryPath maybeChild) {
+     // TODO - should validate for direct parent
+        return isParent(asString(), maybeChild.asString());
+    }
+
+    public boolean isAncestor(RepositoryPath other) {
+        return PathUtil.isAncestor(asString(), other.asString());
+    }    
+    
+    public boolean isDescendent(RepositoryPath other) {
+        return isDescendent(asString(), other.asString());
+    }
+    
+    public String getName() {
+        return PathUtil.getName(path);
+    }
+    
+    public RepositoryPath getParent() {
+        return new RepositoryPath(PathUtil.getParent(asString()));
+    }
+    
+    public RepositoryPath addChild(String name) {
+        // TODO - validate name
+        return new RepositoryPath(path + "/" + name);
+    }
+    
+    public String asString() {
+        return path;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(path);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        RepositoryPath other = (RepositoryPath) obj;
+        return Objects.equals(path, other.path);
+    }
+
+    @Override
+    public String toString() {
+        return "RepositoryPath [path=" + path + "]";
+    }
+}
diff --git a/shared/api/src/main/java/org/apache/sling/ide/transport/ResourceProxy.java b/shared/api/src/main/java/org/apache/sling/ide/transport/ResourceProxy.java
index ccbd5a40..7c62eca0 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/transport/ResourceProxy.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/transport/ResourceProxy.java
@@ -42,25 +42,23 @@ import java.util.Map;
  */
 public class ResourceProxy {
 
-    private final String path;
+    private final RepositoryPath path;
     private final Map<String, Object> properties;
     private final List<ResourceProxy> children = new ArrayList<>();
     private final Map<Class<?>, Object> adapted = new HashMap<>(1);
 
-    // TODO - use a typed path object?
-    public ResourceProxy(String path) {
-        this(path, new HashMap<String, Object>());
+    public ResourceProxy(RepositoryPath path) {
+        this(path, new HashMap<>());
     }
 
-    public ResourceProxy(String path, Map<String, Object> properties) {
+    public ResourceProxy(RepositoryPath path, Map<String, Object> properties) {
         this.path = path;
         this.properties = properties;
     }
 
     public void addChild(ResourceProxy child) {
 
-        // TODO - should validate for direct parent
-        if (!isParent(path, child.getPath())) {
+        if ( !path.isParent(child.path) ) {
             throw new IllegalArgumentException("Resource at path " + child.getPath() + " is not a direct child of "
                     + path);
         }
@@ -73,7 +71,7 @@ public class ResourceProxy {
         this.properties.put(name, value);
     }
 
-    public String getPath() {
+    public RepositoryPath getPath() {
         return path;
     }
 
@@ -113,47 +111,29 @@ public class ResourceProxy {
         return coveredChildren;
     }
 
-    public boolean covers(String path) {
+    public boolean covers(RepositoryPath path) {
         for (ResourceProxy child : getCoveredChildren()) {
             if (child.getPath().equals(path)) {
                 return true;
-            } else if (isDescendent(child.getPath(), path)) {
+            } else if (child.getPath().isDescendent(path)) {
                 return child.covers(path);
             }
         }
 
         return false;
     }
-
-    private boolean isParent(String parentPath, String childPath) {
-
-        if (!isDescendent(parentPath, childPath)) {
-            return false;
-        }
-
-        for (int i = parentPath.length() + 1; i < childPath.length(); i++) {
-            if (childPath.charAt(i) == '/') {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private boolean isDescendent(String parentPath, String childPath) {
-        if (parentPath.equals("/")) {
-            return childPath.length() > 1;
-        }
-
-        return parentPath.length() < childPath.length() && childPath.charAt(parentPath.length()) == '/'
-                    && childPath.startsWith(parentPath);
+    
+    // TODO - remove?
+    @Deprecated
+    public boolean covers(String path) {
+        return covers(new RepositoryPath(path));
     }
 
-    public ResourceProxy getChild(String path) {
+    public ResourceProxy getChild(RepositoryPath path) {
         for (ResourceProxy child : getChildren()) {
             if (child.getPath().equals(path)) {
                 return child;
-            } else if (isDescendent(child.getPath(), path)) {
+            } else if ( child.getPath().isDescendent(path) ) {
                 return child.getChild(path);
             }
         }
diff --git a/shared/api/src/main/java/org/apache/sling/ide/transport/impl/DefaultBatcher.java b/shared/api/src/main/java/org/apache/sling/ide/transport/impl/DefaultBatcher.java
index 62348fa9..c466e913 100644
--- a/shared/api/src/main/java/org/apache/sling/ide/transport/impl/DefaultBatcher.java
+++ b/shared/api/src/main/java/org/apache/sling/ide/transport/impl/DefaultBatcher.java
@@ -22,7 +22,7 @@ import java.util.ListIterator;
 
 import org.apache.sling.ide.transport.Batcher;
 import org.apache.sling.ide.transport.Command;
-import org.apache.sling.ide.util.PathUtil;
+import org.apache.sling.ide.transport.RepositoryPath;
 
 public class DefaultBatcher implements Batcher {
     
@@ -93,17 +93,17 @@ public class DefaultBatcher implements Batcher {
         }
 
         private void processDelete(Command<?> newCmd) {
-            String path = newCmd.getPath();
+            RepositoryPath path = newCmd.getPath();
             for ( ListIterator<Command<?>> iterator = deletes.listIterator(); iterator.hasNext(); ) {
                 
                 // if we already have an ancestor deleted, skip this one
                 Command<?> oldCmd = iterator.next();
-                if ( PathUtil.isAncestor(oldCmd.getPath(), path ) ) {
+                if ( oldCmd.getPath().isAncestor(path) ) {
                     return;
                 }
                 
                 // if we are delete an ancestor of another resource which gets deleted, replace it
-                if ( PathUtil.isAncestor(path, oldCmd.getPath())) {
+                if ( path.isAncestor(oldCmd.getPath())) {
                     iterator.set(newCmd);
                     return;
                 }
@@ -114,7 +114,7 @@ public class DefaultBatcher implements Batcher {
         }
         
         private void processWithPathEqualityCheck(Command<?> newCmd, List<Command<?>> oldCmds) {
-            String path = newCmd.getPath();
+            RepositoryPath path = newCmd.getPath();
             for (Command<?> oldCmd : oldCmds) {
                 // if we already have an add-or-update for this path, skip it    
                 if ( path.equals(oldCmd.getPath()) ) {
diff --git a/shared/api/src/test/java/org/apache/sling/ide/filter/IgnoredResourcesTest.java b/shared/api/src/test/java/org/apache/sling/ide/filter/IgnoredResourcesTest.java
index a4f21ec1..d9f4a7a2 100644
--- a/shared/api/src/test/java/org/apache/sling/ide/filter/IgnoredResourcesTest.java
+++ b/shared/api/src/test/java/org/apache/sling/ide/filter/IgnoredResourcesTest.java
@@ -19,6 +19,7 @@ package org.apache.sling.ide.filter;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.junit.Assert.assertThat;
 
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.junit.Test;
 
 public class IgnoredResourcesTest {
@@ -29,7 +30,7 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/content", "en");
 
-        assertThat(r.isIgnored("/content/en"), equalTo(true));
+        assertThat(r.isIgnored(new RepositoryPath("/content/en")), equalTo(true));
     }
 
     @Test
@@ -38,8 +39,8 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/content", "*sync");
 
-        assertThat(r.isIgnored("/content/contentsync"), equalTo(true));
-        assertThat(r.isIgnored("/content/content"), equalTo(false));
+        assertThat(r.isIgnored(new RepositoryPath("/content/contentsync")), equalTo(true));
+        assertThat(r.isIgnored(new RepositoryPath("/content/content")), equalTo(false));
     }
 
     @Test
@@ -48,7 +49,7 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/content", "#en");
 
-        assertThat(r.isIgnored("/content/#en"), equalTo(false));
+        assertThat(r.isIgnored(new RepositoryPath("/content/#en")), equalTo(false));
     }
 
     @Test
@@ -57,8 +58,8 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/content", "en.html");
 
-        assertThat(r.isIgnored("/content/en.html"), equalTo(true));
-        assertThat(r.isIgnored("/content/en-html"), equalTo(false));
+        assertThat(r.isIgnored(new RepositoryPath("/content/en.html")), equalTo(true));
+        assertThat(r.isIgnored(new RepositoryPath("/content/en-html")), equalTo(false));
     }
 
     @Test
@@ -67,7 +68,7 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/content", "?en");
 
-        assertThat(r.isIgnored("/content/zen"), equalTo(true));
+        assertThat(r.isIgnored(new RepositoryPath("/content/zen")), equalTo(true));
     }
 
     @Test
@@ -76,7 +77,7 @@ public class IgnoredResourcesTest {
         IgnoredResources r = new IgnoredResources();
         r.registerRegExpIgnoreRule("/", "en");
 
-        assertThat(r.isIgnored("/en"), equalTo(true));
+        assertThat(r.isIgnored(new RepositoryPath("/en")), equalTo(true));
 
     }
 }
diff --git a/shared/api/src/test/java/org/apache/sling/ide/serialization/NodeTypeResourceBuilder.java b/shared/api/src/test/java/org/apache/sling/ide/serialization/NodeTypeResourceBuilder.java
index c39d4bb1..cd58a4c4 100644
--- a/shared/api/src/test/java/org/apache/sling/ide/serialization/NodeTypeResourceBuilder.java
+++ b/shared/api/src/test/java/org/apache/sling/ide/serialization/NodeTypeResourceBuilder.java
@@ -16,19 +16,14 @@
  */
 package org.apache.sling.ide.serialization;
 
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class NodeTypeResourceBuilder {
 
     public static NodeTypeResourceBuilder newBuilder(ResourceProxy parent, String name) {
 
-        String path;
-
-        if (parent.getPath().endsWith("/")) {
-            path = parent.getPath() + name;
-        } else {
-            path = parent.getPath() + "/" + name;
-        }
+        RepositoryPath path = parent.getPath().addChild(name);
 
         ResourceProxy resourceProxy = new ResourceProxy(path);
         // set defaults
diff --git a/shared/api/src/test/java/org/apache/sling/ide/serialization/StubRepository.java b/shared/api/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
index bd6ae3db..e51a93a5 100644
--- a/shared/api/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
+++ b/shared/api/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
@@ -23,27 +23,28 @@ import org.apache.sling.ide.transport.FallbackNodeTypeRegistry;
 import org.apache.sling.ide.transport.NodeTypeRegistry;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class StubRepository implements Repository {
 
     @Override
-    public Command<ResourceProxy> newListChildrenNodeCommand(final String path) {
+    public Command<ResourceProxy> newListChildrenNodeCommand(final RepositoryPath path) {
         return null;
     }
 
     @Override
-    public Command<ResourceProxy> newGetNodeContentCommand(String path) {
+    public Command<ResourceProxy> newGetNodeContentCommand(RepositoryPath path) {
         return null;
     }
 
     @Override
-    public Command<byte[]> newGetNodeCommand(String path) {
+    public Command<byte[]> newGetNodeCommand(RepositoryPath path) {
         return null;
     }
 
     @Override
-    public Command<Void> newDeleteNodeCommand(String path) {
+    public Command<Void> newDeleteNodeCommand(RepositoryPath path) {
         return null;
     }
 
diff --git a/shared/api/src/test/java/org/apache/sling/ide/transport/ResourceProxyTest.java b/shared/api/src/test/java/org/apache/sling/ide/transport/ResourceProxyTest.java
index 5e373c9e..c4800fce 100644
--- a/shared/api/src/test/java/org/apache/sling/ide/transport/ResourceProxyTest.java
+++ b/shared/api/src/test/java/org/apache/sling/ide/transport/ResourceProxyTest.java
@@ -23,11 +23,13 @@ import static org.junit.Assert.assertThat;
 import org.junit.Test;
 
 public class ResourceProxyTest {
+    
+    private static final RepositoryPath PATH_CONTENT = new RepositoryPath("/content"); 
 
     @Test
     public void coveredChildren_firstLevel() {
 
-        ResourceProxy r = new ResourceProxy("/content");
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
         r.addChild(newResource("/content/test", "nt:unstructured"));
 
         assertThat(r.covers("/content/test"), is(true));
@@ -36,7 +38,7 @@ public class ResourceProxyTest {
     @Test
     public void coveredChildren_secondLevel() {
 
-        ResourceProxy r = new ResourceProxy("/content");
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
         ResourceProxy child = newResource("/content/test", "nt:unstructured");
         r.addChild(child);
 
@@ -48,7 +50,7 @@ public class ResourceProxyTest {
     @Test
     public void coveredChildren_thirdLevel() {
 
-        ResourceProxy r = new ResourceProxy("/content");
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
 
         ResourceProxy child = newResource("/content/test", "nt:unstructured");
         r.addChild(child);
@@ -64,8 +66,8 @@ public class ResourceProxyTest {
     @Test
     public void coveredChildren_notCoveredFirstLevel() {
 
-        ResourceProxy r = new ResourceProxy("/content");
-        r.addChild(new ResourceProxy("/content/test"));
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
+        r.addChild(new ResourceProxy(PATH_CONTENT.addChild("test")));
 
         assertThat(r.covers("/content/test"), is(false));
     }
@@ -73,11 +75,11 @@ public class ResourceProxyTest {
     @Test
     public void coveredChildren_notCoveredSecondLevel() {
 
-        ResourceProxy r = new ResourceProxy("/content");
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
         ResourceProxy child = newResource("/content/test", "nt:unstructured");
         r.addChild(child);
 
-        child.addChild(new ResourceProxy("/content/test/en"));
+        child.addChild(new ResourceProxy(PATH_CONTENT.addChild("test").addChild("en")));
 
         assertThat(r.covers("/content/test/en"), is(false));
     }
@@ -85,7 +87,7 @@ public class ResourceProxyTest {
     @Test
     public void getChild() {
 
-        ResourceProxy r = new ResourceProxy("/content");
+        ResourceProxy r = new ResourceProxy(PATH_CONTENT);
         ResourceProxy child = newResource("/content/test", "nt:unstructured");
         r.addChild(child);
 
@@ -95,15 +97,15 @@ public class ResourceProxyTest {
         ResourceProxy grandGrandChild = newResource("/content/test/en/welcome", "nt:unstructured");
         grandChild.addChild(grandGrandChild);
 
-        assertThat(r.getChild("/content/test"), is(child));
-        assertThat(r.getChild("/content/test/en"), is(grandChild));
-        assertThat(r.getChild("/content/test/en/welcome"), is(grandGrandChild));
-        assertThat(r.getChild("/content/test/en2"), is(nullValue()));
+        assertThat(r.getChild(new RepositoryPath("/content/test")), is(child));
+        assertThat(r.getChild(new RepositoryPath("/content/test/en")), is(grandChild));
+        assertThat(r.getChild(new RepositoryPath("/content/test/en/welcome")), is(grandGrandChild));
+        assertThat(r.getChild(new RepositoryPath("/content/test/en2")), is(nullValue()));
     }
 
     private ResourceProxy newResource(String path, String primaryType) {
 
-        ResourceProxy child = new ResourceProxy(path);
+        ResourceProxy child = new ResourceProxy(new RepositoryPath(path));
         child.addProperty("jcr:primaryType", primaryType);
         return child;
     }
@@ -111,25 +113,25 @@ public class ResourceProxyTest {
     @Test(expected = IllegalArgumentException.class)
     public void addChild_IllegalChildRejected() {
 
-        new ResourceProxy("/content").addChild(new ResourceProxy("/var"));
+        new ResourceProxy(new RepositoryPath("/content")).addChild(new ResourceProxy(new RepositoryPath("/var")));  
     }
 
     @Test
     public void addChild_childOfRootNode() {
 
-        new ResourceProxy("/").addChild(new ResourceProxy("/var"));
+        new ResourceProxy(new RepositoryPath("/")).addChild(new ResourceProxy(new RepositoryPath("/var")));
     }
 
     @Test
     public void addChild_childOfRegularNode() {
 
-        new ResourceProxy("/content").addChild(new ResourceProxy("/content/test"));
+        new ResourceProxy(new RepositoryPath("/content")).addChild(new ResourceProxy(new RepositoryPath("/content/test")));
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void addChild_deeplyNested() {
 
-        new ResourceProxy("/content").addChild(new ResourceProxy("/content/test/en"));
+        new ResourceProxy(new RepositoryPath("/content")).addChild(new ResourceProxy(new RepositoryPath("/content/test/en")));
     }
 
 }
diff --git a/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java b/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
index da50fb69..8dcb90f1 100644
--- a/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
+++ b/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
@@ -47,6 +47,7 @@ import org.apache.sling.ide.sync.content.WorkspaceFile;
 import org.apache.sling.ide.sync.content.WorkspacePath;
 import org.apache.sling.ide.sync.content.WorkspaceResource;
 import org.apache.sling.ide.transport.Repository;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.osgi.service.component.annotations.Component;
 import org.xml.sax.Attributes;
@@ -87,7 +88,7 @@ public class SimpleXmlSerializationManager implements SerializationManager, Seri
                 saxParser.parse(new InputSource(source), h);
             }
 
-            return new ResourceProxy(file.getPathRelativeToSyncDir().asPortableString(), h.getResult());
+            return new ResourceProxy(new RepositoryPath(file.getPathRelativeToSyncDir().asPortableString()), h.getResult());
         } catch (ParserConfigurationException | SAXException e) {
             // TODO proper exception handling
             throw new RuntimeException(e);
@@ -149,7 +150,8 @@ public class SimpleXmlSerializationManager implements SerializationManager, Seri
             handler.endDocument();
 
             // TODO - also add the serialization type
-            return new SerializationData(resource.getPath(), CONTENT_XML, result.toByteArray(), null);
+            // TODO - resource path is probably incorrect here
+            return new SerializationData(resource.getPath().asString(), CONTENT_XML, result.toByteArray(), null);
         } catch (TransformerConfigurationException | TransformerFactoryConfigurationError | SAXException e) {
             // TODO proper exception handling
             throw new RuntimeException(e);
@@ -157,8 +159,8 @@ public class SimpleXmlSerializationManager implements SerializationManager, Seri
     }
 
     @Override
-    public String getRepositoryPath(WorkspacePath localPath) {
-        return localPath.asPortableString();
+    public RepositoryPath getRepositoryPath(WorkspacePath localPath) {
+        return new RepositoryPath(localPath.asPortableString());
     }
 
     @Override
diff --git a/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java b/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
index 90fb50b2..adaa3f40 100644
--- a/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
+++ b/shared/impl-resource/src/main/java/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
@@ -25,7 +25,6 @@ import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
 import org.apache.sling.ide.transport.RepositoryException;
 import org.apache.sling.ide.transport.RepositoryInfo;
 import org.apache.sling.ide.transport.Result;
-import org.apache.sling.ide.util.PathUtil;
 
 public abstract class AbstractCommand<T> implements Command<T> {
 
diff --git a/shared/impl-resource/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java b/shared/impl-resource/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
index a834564c..7ee22e1e 100644
--- a/shared/impl-resource/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
+++ b/shared/impl-resource/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
@@ -38,6 +38,7 @@ import org.apache.sling.ide.serialization.SerializationException;
 import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.sync.content.WorkspaceDirectory;
 import org.apache.sling.ide.sync.content.WorkspaceFile;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
@@ -70,7 +71,7 @@ public class SimpleXmlSerializationManagerTest {
     }
 
     private ResourceProxy newResourceWithProperties(Map<String, Object> properties) {
-        ResourceProxy resource = new ResourceProxy("/");
+        ResourceProxy resource = new ResourceProxy(new RepositoryPath("/"));
         for (Map.Entry<String, Object> entry : properties.entrySet()) {
             resource.addProperty(entry.getKey(), entry.getValue());
         }
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
index 803491c1..1c94f9a5 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
@@ -52,15 +52,14 @@ import javax.jcr.ValueFactory;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
 
-import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.vault.util.JcrConstants;
 import org.apache.sling.ide.filter.FilterResult;
 import org.apache.sling.ide.log.Logger;
 import org.apache.sling.ide.sync.content.WorkspaceFile;
 import org.apache.sling.ide.transport.CommandContext;
 import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
-import org.apache.sling.ide.util.PathUtil;
 
 public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
@@ -87,7 +86,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
     private void update(ResourceProxy resource, Session session) throws RepositoryException, IOException {
 
-        String path = resource.getPath();
+        String path = resource.getPath().asString();
         boolean nodeExists = session.nodeExists(path);
 
         Node node;
@@ -100,7 +99,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 	            node = createNode(resource, session);
 	            getLogger().trace("Created node at {0} with primaryType {1}", path, node.getPrimaryNodeType().getName());
         	} catch (RepositoryException e) {
-        		throw new RepositoryException("Could not create node at " + Text.getRelativeParent(resource.getPath(), 1) + " based on resource " + resource, e);
+        		throw new RepositoryException("Could not create node at " + resource.getPath().getParent().asString() + " based on resource " + resource, e);
         	}
         }
 
@@ -128,7 +127,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
             return;
         }
         
-        Map<String, ResourceProxy> resourceChildrenPaths = new HashMap<>(resourceChildren.size());
+        Map<RepositoryPath, ResourceProxy> resourceChildrenPaths = new HashMap<>(resourceChildren.size());
         for (ResourceProxy child : resourceChildren) {
             resourceChildrenPaths.put(child.getPath(), child);
         }
@@ -136,12 +135,13 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
         for (NodeIterator it = node.getNodes(); it.hasNext();) {
 
             Node child = it.nextNode();
-
-            if (resourceChildrenPaths.containsKey(child.getPath())) {
+            RepositoryPath childRepositoryPath = new RepositoryPath(child.getPath());
+            
+            if (resourceChildrenPaths.containsKey(childRepositoryPath)) {
                 // only descend for reordering when the child node is covered ; otherwise we
                 // don't have enough information
-                if (resource2.covers(child.getPath())) {
-                    processDeletedNodes(child, resourceChildrenPaths.get(child.getPath()));
+                if (resource2.covers(childRepositoryPath)) {
+                    processDeletedNodes(child, resourceChildrenPaths.get(childRepositoryPath));
                 }
                 continue;
             }
@@ -160,7 +160,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
     private Node createNode(ResourceProxy resource, Session session) throws RepositoryException, FileNotFoundException {
 
-        String parentLocation = Text.getRelativeParent(resource.getPath(), 1);
+        String parentLocation = resource.getPath().getParent().asString();
         if (parentLocation.isEmpty()) {
             parentLocation = "/";
         }
@@ -172,7 +172,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
         String primaryType = (String) resource.getProperties().get(JCR_PRIMARYTYPE);
         Node parent = session.getNode(parentLocation);
-        String childName = PathUtil.getName(resource.getPath());
+        String childName = resource.getPath().getName();
         if (primaryType == null) {
             return parent.addNode(childName);
         } else {
@@ -182,7 +182,7 @@ public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
     private void updateNode(Node node, ResourceProxy resource) throws RepositoryException, IOException {
 
-        if (node.getPath().equals(getPath()) && fileInfo != null) {
+        if (new RepositoryPath(node.getPath()).equals(getPath()) && fileInfo != null) {
             updateFileLikeNodeTypes(node);
         }
 
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
index f430fea6..4d4d44c2 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/DeleteNodeCommand.java
@@ -24,18 +24,19 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 
 public class DeleteNodeCommand extends JcrCommand<Void> {
 
-    public DeleteNodeCommand(Repository repository, Credentials credentials, String path, Logger logger) {
+    public DeleteNodeCommand(Repository repository, Credentials credentials, RepositoryPath path, Logger logger) {
         super(repository, credentials, path, logger);
     }
 
     @Override
     protected Void execute0(Session session) throws RepositoryException, IOException {
 
-        if (session.nodeExists(getPath())) {
-            session.getNode(getPath()).remove();
+        if (session.nodeExists(getPath().asString())) {
+            session.getNode(getPath().asString()).remove();
         }
 
         return null;
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeCommand.java
index d5878334..fe43b468 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeCommand.java
@@ -30,17 +30,18 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 
 public class GetNodeCommand extends JcrCommand<byte[]> {
     
-    public GetNodeCommand(Repository repository, Credentials credentials, String path, Logger logger) {
+    public GetNodeCommand(Repository repository, Credentials credentials, RepositoryPath path, Logger logger) {
         super(repository, credentials, path, logger);
     }
 
     @Override
     protected byte[] execute0(Session session) throws RepositoryException, IOException {
 
-        Node node = session.getNode(getPath());
+        Node node = session.getNode(getPath().asString());
 
         Property property;
         if (node.hasProperty("jcr:data")) {
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeContentCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeContentCommand.java
index b505822a..c591b124 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeContentCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/GetNodeContentCommand.java
@@ -23,18 +23,19 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class GetNodeContentCommand extends JcrCommand<ResourceProxy> {
 
-    public GetNodeContentCommand(Repository repository, Credentials credentials, String path, Logger logger) {
+    public GetNodeContentCommand(Repository repository, Credentials credentials, RepositoryPath path, Logger logger) {
         super(repository, credentials, path, logger);
     }
 
     @Override
     protected ResourceProxy execute0(Session session) throws RepositoryException {
 
-        Node node = session.getNode(getPath());
+        Node node = session.getNode(getPath().asString());
 
         return nodeToResource(node);
     }
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/JcrCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/JcrCommand.java
index 9b0ecf83..04b9a7dc 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/JcrCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/JcrCommand.java
@@ -36,6 +36,7 @@ import javax.jcr.Session;
 import org.apache.sling.ide.log.Logger;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.Repository.CommandExecutionFlag;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.Result;
 
@@ -43,11 +44,11 @@ public abstract class JcrCommand<T> implements Command<T> {
 
     private final Credentials credentials;
     private final Repository repository;
-    private final String path;
+    private final RepositoryPath path;
     private final Logger logger;
     private final EnumSet<CommandExecutionFlag> flags;
 
-    public JcrCommand(Repository repository, Credentials credentials, String path, Logger logger,
+    public JcrCommand(Repository repository, Credentials credentials, RepositoryPath path, Logger logger,
             CommandExecutionFlag... flags) {
 
         this.repository = repository;
@@ -84,7 +85,8 @@ public abstract class JcrCommand<T> implements Command<T> {
 
     protected abstract T execute0(Session session) throws RepositoryException, IOException;
 
-    public String getPath() {
+    @Override
+    public RepositoryPath getPath() {
         return path;
     }
 
@@ -92,6 +94,7 @@ public abstract class JcrCommand<T> implements Command<T> {
         return logger;
     }
 
+    @Override
     public Set<CommandExecutionFlag> getFlags() {
         return Collections.unmodifiableSet(flags);
     }
@@ -103,7 +106,7 @@ public abstract class JcrCommand<T> implements Command<T> {
 
     protected ResourceProxy nodeToResource(Node node) throws RepositoryException {
     
-        ResourceProxy resource = new ResourceProxy(node.getPath());
+        ResourceProxy resource = new ResourceProxy(new RepositoryPath(node.getPath()));
         resource.addAdapted(Node.class, node);
 
         PropertyIterator properties = node.getProperties();
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListChildrenCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListChildrenCommand.java
index 1a87cea2..7635d914 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListChildrenCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListChildrenCommand.java
@@ -24,18 +24,19 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class ListChildrenCommand extends JcrCommand<ResourceProxy> {
 
-    public ListChildrenCommand(Repository repository, Credentials credentials, String path, Logger logger) {
+    public ListChildrenCommand(Repository repository, Credentials credentials, RepositoryPath path, Logger logger) {
         super(repository, credentials, path, logger);
     }
 
     @Override
     protected ResourceProxy execute0(Session session) throws RepositoryException {
 
-        Node node = session.getNode(getPath());
+        Node node = session.getNode(getPath().asString());
         NodeIterator nodes = node.getNodes();
 
         ResourceProxy parent = nodeToResource(node);
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListTreeCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListTreeCommand.java
index 16549073..dc2b016c 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListTreeCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ListTreeCommand.java
@@ -24,13 +24,14 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class ListTreeCommand extends JcrCommand<ResourceProxy> {
 
     private final int levels;
 
-    public ListTreeCommand(Repository repository, Credentials credentials, String path, int levels, Logger logger) {
+    public ListTreeCommand(Repository repository, Credentials credentials, RepositoryPath path, int levels, Logger logger) {
         super(repository, credentials, path, logger);
         this.levels = Math.max(1,levels);
     }
@@ -38,7 +39,7 @@ public class ListTreeCommand extends JcrCommand<ResourceProxy> {
     @Override
     protected ResourceProxy execute0(Session session) throws RepositoryException {
 
-        Node node = session.getNode(getPath());
+        Node node = session.getNode(getPath().asString());
 
         ResourceProxy parent = nodeToResource(node);
 
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommand.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommand.java
index 48460f6e..a2c8dd6a 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommand.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommand.java
@@ -31,7 +31,6 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 
-import org.apache.jackrabbit.util.Text;
 import org.apache.sling.ide.log.Logger;
 import org.apache.sling.ide.transport.ResourceProxy;
 
@@ -53,12 +52,12 @@ public class ReorderChildNodesCommand extends JcrCommand<Void> {
     @Override
     protected Void execute0(Session session) throws RepositoryException, IOException {
 
-        boolean nodeExists = session.nodeExists(getPath());
+        boolean nodeExists = session.nodeExists(getPath().asString());
         if (!nodeExists) {
             return null;
         }
 
-        Node node = session.getNode(getPath());
+        Node node = session.getNode(getPath().asString());
 
         NodeType primaryNodeType = node.getPrimaryNodeType();
 
@@ -93,7 +92,7 @@ public class ReorderChildNodesCommand extends JcrCommand<Void> {
         }
 
         for (ResourceProxy childResources : children) {
-            resourceChildNames.add(Text.getName(childResources.getPath()));
+            resourceChildNames.add(childResources.getPath().getName());
         }
         ListIterator<Node> nodeChildrenListIt = nodeChildren.listIterator();
 
@@ -116,7 +115,7 @@ public class ReorderChildNodesCommand extends JcrCommand<Void> {
             Node childNode = nodeChildrenListIt.next();
 
             // order is as expected, skip reordering
-            if (Text.getName(childResource.getPath()).equals(childNode.getName())) {
+            if (childResource.getPath().getName().equals(childNode.getName())) {
                 // descend into covered child resources once they are properly arranged and perform reordering
                 if (resourceToReorder.covers(childResource.getPath())) {
                     reorderChildNodes(childNode, childResource);
@@ -133,16 +132,16 @@ public class ReorderChildNodesCommand extends JcrCommand<Void> {
 
             String expectedParentName;
             if (childrenIterator.hasNext()) {
-                expectedParentName = Text.getName(childrenIterator.next().getPath());
+                expectedParentName = childrenIterator.next().getPath().getName();
                 childrenIterator.previous(); // move back
             } else {
                 expectedParentName = null;
             }
 
             getLogger().trace("For node at {0} ordering {1} before {2}", nodeToReorder.getPath(),
-                    Text.getName(childResource.getPath()), expectedParentName);
+                    childResource.getPath().getName(), expectedParentName);
 
-            nodeToReorder.orderBefore(Text.getName(childResource.getPath()), expectedParentName);
+            nodeToReorder.orderBefore(childResource.getPath().getName(), expectedParentName);
         }
     }
 
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltNodeTypeFactory.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltNodeTypeFactory.java
index fc7d5163..3c95d9cd 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltNodeTypeFactory.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltNodeTypeFactory.java
@@ -28,9 +28,9 @@ import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
 
 import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.Result;
-import org.apache.sling.ide.util.PathUtil;
 
 public class VltNodeTypeFactory {
 
@@ -45,7 +45,7 @@ public class VltNodeTypeFactory {
     }
 
     void init(VltRepository repository) throws RepositoryException {
-        Result<ResourceProxy> jcrSystem = repository.newListTreeNodeCommand("/jcr:system/jcr:nodeTypes", 3).execute();
+        Result<ResourceProxy> jcrSystem = repository.newListTreeNodeCommand(new RepositoryPath("/jcr:system/jcr:nodeTypes"), 3).execute();
         // phase 1: create all node types
         for (ResourceProxy child : jcrSystem.get().getChildren()) {
             
@@ -95,7 +95,7 @@ public class VltNodeTypeFactory {
 
         Set<VltNodeDefinition> nds = new HashSet<>();
         for (ResourceProxy ntChild : child.getChildren()) {
-            String ntChildName = PathUtil.getName(ntChild.getPath());
+            String ntChildName = ntChild.getPath().getName();
             if (ntChildName.startsWith("jcr:childNodeDefinition")) {
                 VltNodeDefinition nd = handleChildNodeDefinition(ntChild);
                 nds.add(nd);
@@ -112,7 +112,7 @@ public class VltNodeTypeFactory {
 
     private VltNodeType createNodeType(ResourceProxy child) {
         final VltNodeType nt = new VltNodeType(child);
-        final String name = PathUtil.getName(child.getPath());
+        final String name = child.getPath().getName();
         nt.setName(name);
         return nt;
     }
@@ -122,7 +122,7 @@ public class VltNodeTypeFactory {
         
         // load propertyDefinition children
         for (ResourceProxy aChild : child.getChildren()) {
-            String childName = PathUtil.getName(aChild.getPath());
+            String childName = aChild.getPath().getName();
             if (childName.startsWith("jcr:propertyDefinition")) {
                 String jcrName = (String)aChild.getProperties().get("jcr:name");
                 if (jcrName!=null) {
@@ -305,7 +305,7 @@ public class VltNodeTypeFactory {
             VltNodeType superType = (VltNodeType) declaredSupertypes[i];
             allSuperTypes.add(superType);
             nt.addSuperType(superType);
-            initSuperTypes(allSuperTypes, (VltNodeType) superType);
+            initSuperTypes(allSuperTypes, superType);
         }
     }
 
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltRepository.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltRepository.java
index 817c5b3d..7ed83a57 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltRepository.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/VltRepository.java
@@ -27,6 +27,7 @@ import org.apache.sling.ide.transport.CommandContext;
 import org.apache.sling.ide.transport.NodeTypeRegistry;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 /**
@@ -93,26 +94,26 @@ public class VltRepository implements Repository {
     }
 
     @Override
-    public Command<Void> newDeleteNodeCommand(String path) {
+    public Command<Void> newDeleteNodeCommand(RepositoryPath path) {
         return new DeleteNodeCommand(jcrRepo, credentials, path, logger);
     }
 
     @Override
-    public Command<ResourceProxy> newListChildrenNodeCommand(String path) {
+    public Command<ResourceProxy> newListChildrenNodeCommand(RepositoryPath path) {
         return new ListChildrenCommand(jcrRepo, credentials, path, logger);
     }
 
     @Override
-    public Command<ResourceProxy> newGetNodeContentCommand(String path) {
+    public Command<ResourceProxy> newGetNodeContentCommand(RepositoryPath path) {
         return new GetNodeContentCommand(jcrRepo, credentials, path, logger);
     }
 
     @Override
-    public Command<byte[]> newGetNodeCommand(String path) {
+    public Command<byte[]> newGetNodeCommand(RepositoryPath path) {
     	return new GetNodeCommand(jcrRepo, credentials, path, logger);
     }
 
-    Command<ResourceProxy> newListTreeNodeCommand(String path, int levels) {
+    Command<ResourceProxy> newListTreeNodeCommand(RepositoryPath path, int levels) {
         return new ListTreeCommand(jcrRepo, credentials, path, levels, logger);
     }
     
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandler.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandler.java
index 79c25f95..ab1ad71c 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandler.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandler.java
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.util.ISO8601;
 import org.apache.jackrabbit.vault.fs.io.DocViewParserHandler;
 import org.apache.jackrabbit.vault.util.DocViewNode2;
 import org.apache.jackrabbit.vault.util.DocViewProperty2;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 
 public class ResourceProxyParserHandler implements DocViewParserHandler {
@@ -73,7 +74,7 @@ public class ResourceProxyParserHandler implements DocViewParserHandler {
 	public void startDocViewNode(String nodePath, DocViewNode2 docViewNode, Optional<DocViewNode2> parentDocViewNode,
 			int line, int column) throws IOException, RepositoryException {
 		
-		ResourceProxy currentResource = new ResourceProxy(nodePath);
+		ResourceProxy currentResource = new ResourceProxy(new RepositoryPath(nodePath));
 		for (DocViewProperty2 property: docViewNode.getProperties()) {
 			Object value = TypeHint.convertDocViewPropertyToTypedValue(property);
 			if (value != null) {
@@ -102,11 +103,13 @@ public class ResourceProxyParserHandler implements DocViewParserHandler {
      */
     static enum TypeHint {
         UNDEFINED(PropertyType.UNDEFINED) {
+            @Override
             Object parseValues(String[] values, boolean explicitMultiValue) {
                 return STRING.parseValues(values, explicitMultiValue);
             }
         },
         STRING(PropertyType.STRING) {
+            @Override
             Object parseValues(String[] values, boolean explicitMultiValue) {
                 if (values.length == 1 && !explicitMultiValue) {
                     return values[0];
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
index a00e9f00..91f5aaf8 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationDataBuilder.java
@@ -277,13 +277,13 @@ public class VltSerializationDataBuilder implements SerializationDataBuilder {
      */
     private List<Aggregate> findAggregateChain(ResourceProxy resource) throws IOException, RepositoryException {
 
-        VaultFile vaultFile = fs.getFile(PlatformNameFormat.getPlatformPath(resource.getPath()));
+        VaultFile vaultFile = fs.getFile(PlatformNameFormat.getPlatformPath(resource.getPath().asString()));
 
         if (vaultFile == null || vaultFile.getAggregate() == null) {
                 // this file might be a leaf aggregate of a vaultfile higher in the resource path ; so look for a
                 // parent higher
 
-            String parentPath = Text.getRelativeParent(resource.getPath(), 1);
+            String parentPath = resource.getPath().getParent().asString();
             while (!parentPath.equals("/")) {
                 VaultFile parentFile = fs.getFile(PlatformNameFormat.getPlatformPath(parentPath));
 
@@ -338,7 +338,7 @@ public class VltSerializationDataBuilder implements SerializationDataBuilder {
             if (leaf.getPath().equals(resource.getPath())) {
                 chain.add(leaf);
                 return chain;
-            } else if (Text.isDescendant(leaf.getPath(), resource.getPath())) {
+            } else if (Text.isDescendant(leaf.getPath(), resource.getPath().asString())) {
                 chain.add(leaf);
                 return lookForAggregateInLeaves(resource, leaf, chain);
             }
diff --git a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
index d3c0973c..8ebc8a35 100644
--- a/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
+++ b/shared/impl-vlt/src/main/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
@@ -47,6 +47,7 @@ import org.apache.sling.ide.sync.content.WorkspaceFile;
 import org.apache.sling.ide.sync.content.WorkspacePath;
 import org.apache.sling.ide.sync.content.WorkspaceProject;
 import org.apache.sling.ide.sync.content.WorkspaceResource;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -153,7 +154,7 @@ public class VltSerializationManager implements SerializationManager {
     }
 
     @Override
-    public String getRepositoryPath(WorkspacePath localPath) {
+    public RepositoryPath getRepositoryPath(WorkspacePath localPath) {
 
         String osPath = localPath.asPortableString();
         String repositoryPath;
@@ -182,7 +183,7 @@ public class VltSerializationManager implements SerializationManager {
             repositoryPath = "/";
         }
 
-        return repositoryPath;
+        return new RepositoryPath(repositoryPath);
     }
 
     @Override
@@ -207,12 +208,12 @@ public class VltSerializationManager implements SerializationManager {
         if (file == null || ! file.exists() )
             return null;
 
-        String repositoryPath = getRepositoryPath(file.getPathRelativeToSyncDir());
+        RepositoryPath repositoryPath = getRepositoryPath(file.getPathRelativeToSyncDir());
 
         try (InputStream source = file.getContents()) {
         	DocViewParser parser = new DocViewParser();
         	ResourceProxyParserHandler handler = new ResourceProxyParserHandler();
-        	parser.parse(repositoryPath, new InputSource(source), handler);
+        	parser.parse(repositoryPath.asString(), new InputSource(source), handler);
             return handler.getRoot();
         } catch (XmlParseException e) {
             // TODO proper error handling
diff --git a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandIT.java b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandIT.java
index 4e6e0015..13d86051 100644
--- a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandIT.java
+++ b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommandIT.java
@@ -30,6 +30,7 @@ import org.apache.sling.ide.filter.Filter;
 import org.apache.sling.ide.filter.FilterResult;
 import org.apache.sling.ide.log.Logger;
 import org.apache.sling.ide.transport.CommandContext;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.hamcrest.Matchers;
 import org.junit.Ignore;
@@ -60,7 +61,7 @@ public class AddOrUpdateNodeCommandIT {
 
 	private ResourceProxy newResource(String path, String primaryType) {
 
-		ResourceProxy resource = new ResourceProxy(path);
+		ResourceProxy resource = new ResourceProxy(new RepositoryPath(path));
 		resource.addProperty("jcr:primaryType", primaryType);
 		return resource;
 	}
@@ -281,7 +282,7 @@ public class AddOrUpdateNodeCommandIT {
 	public void createIfRequiredFlagCreatesNeededResourcesEvenWhenPrimaryTypeIsMissing() throws Exception {
 
 		Session session = repositoryManager.getAdminSession();
-		ResourceProxy resource = new ResourceProxy("/content");
+		ResourceProxy resource = new ResourceProxy(new RepositoryPath("/content"));
 
 		AddOrUpdateNodeCommand cmd = new AddOrUpdateNodeCommand(repositoryManager.getRepository(), repositoryManager.getAdminCredentials(), DEFAULT_CONTEXT, null,
 				resource, logger, CREATE_ONLY_WHEN_MISSING);
diff --git a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommandIT.java b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommandIT.java
index 25a7e26f..d8946b43 100644
--- a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommandIT.java
+++ b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/ReorderChildNodesCommandIT.java
@@ -28,6 +28,7 @@ import javax.jcr.NodeIterator;
 import javax.jcr.Session;
 
 import org.apache.sling.ide.log.Logger;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.junit.Rule;
 import org.junit.Test;
@@ -115,7 +116,7 @@ public class ReorderChildNodesCommandIT {
 
     private ResourceProxy newResource(String path, String primaryType) {
 
-        ResourceProxy resource = new ResourceProxy(path);
+        ResourceProxy resource = new ResourceProxy(new RepositoryPath(path));
         resource.addProperty("jcr:primaryType", primaryType);
         return resource;
     }
diff --git a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandlerTest.java b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandlerTest.java
index 8f4dfc5f..5a4c8a53 100644
--- a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandlerTest.java
+++ b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/ResourceProxyParserHandlerTest.java
@@ -28,13 +28,9 @@ import java.math.BigDecimal;
 import java.util.Calendar;
 import java.util.Map;
 
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
 import org.apache.jackrabbit.vault.fs.io.DocViewParser;
 import org.apache.jackrabbit.vault.fs.io.DocViewParser.XmlParseException;
-import org.apache.sling.ide.impl.vlt.Slf4jLogger;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
@@ -42,7 +38,6 @@ import org.hamcrest.Matchers;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 
 public class ResourceProxyParserHandlerTest {
 
@@ -127,20 +122,20 @@ public class ResourceProxyParserHandlerTest {
 
         ResourceProxy root = parseContentXmlFile("full-coverage.xml", "/apps/full-coverage");
 
-        assertThat("full-coverage path", root.getPath(), is("/apps/full-coverage"));
+        assertThat("full-coverage path", root.getPath(), is(new RepositoryPath("/apps/full-coverage")));
         assertThat("full-coverage properties.size", root.getProperties().size(), is(3));
         assertThat("full-coverage properties[jcr:title]", root.getProperties(),
                 hasEntry("jcr:title", (Object) "Full coverage parent"));
         assertThat("full-coverage children.size", root.getChildren().size(), is(2));
 
         ResourceProxy parent1 = root.getChildren().get(0);
-        assertThat("parent-1 path", parent1.getPath(), is("/apps/full-coverage/parent-1"));
+        assertThat("parent-1 path", parent1.getPath(), is(new RepositoryPath("/apps/full-coverage/parent-1")));
         assertThat("parent-1 properties[jcr:title]", parent1.getProperties(),
                 hasEntry("jcr:title", (Object) "Parent 1"));
         assertThat("parent-1 children.size", parent1.getChildren().size(), is(2));
 
         ResourceProxy child11 = parent1.getChildren().get(0);
-        assertThat("child-1-1 path", child11.getPath(), is("/apps/full-coverage/parent-1/child-1-1"));
+        assertThat("child-1-1 path", child11.getPath(), is(new RepositoryPath("/apps/full-coverage/parent-1/child-1-1")));
         assertThat("child-1-1 properties[jcr:title]", child11.getProperties(),
                 hasEntry("jcr:title", (Object) "Child 1-1"));
 
@@ -246,11 +241,11 @@ public class ResourceProxyParserHandlerTest {
 
     static class ResourceChildPathMatcher extends TypeSafeMatcher<Iterable<? extends ResourceProxy>> {
 
-        private final String resourcePath;
+        private final RepositoryPath resourcePath;
 
         private ResourceChildPathMatcher(String resourcePath) {
 
-            this.resourcePath = resourcePath;
+            this.resourcePath = new RepositoryPath(resourcePath);
         }
 
         @Override
diff --git a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManagerTest.java b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManagerTest.java
index 9375215b..9f414441 100644
--- a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManagerTest.java
+++ b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManagerTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertThat;
 
 import org.apache.sling.ide.impl.vlt.Slf4jLogger;
 import org.apache.sling.ide.sync.content.WorkspacePath;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -60,18 +61,20 @@ public class VltSerializationManagerTest {
 
     @Test
     public void getRepositoryPath_CleanName() {
-        assertThat(serializationManager.getRepositoryPath(new WorkspacePath("/content/test")), is("/content/test"));
+        assertThat(serializationManager.getRepositoryPath(new WorkspacePath("/content/test")), 
+                is(new RepositoryPath("/content/test")));
     }
 
     @Test
     public void getRepositoryPath_MangledName() {
         assertThat(serializationManager.getRepositoryPath(new WorkspacePath("/content/test/_jcr_content")),
-                is("/content/test/jcr:content"));
+                is(new RepositoryPath("/content/test/jcr:content")));
     }
 
     @Test
     public void getRepositoryPath_SerializationDir() {
-        assertThat(serializationManager.getRepositoryPath(new WorkspacePath("/content/test.dir/file")), is("/content/test/file"));
+        assertThat(serializationManager.getRepositoryPath(new WorkspacePath("/content/test.dir/file")), 
+                is(new RepositoryPath("/content/test/file")));
     }
 
 }
diff --git a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/transport/DefaultBatcherTest.java b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/transport/DefaultBatcherTest.java
index 4e705295..11d642bf 100644
--- a/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/transport/DefaultBatcherTest.java
+++ b/shared/impl-vlt/src/test/java/org/apache/sling/ide/impl/vlt/transport/DefaultBatcherTest.java
@@ -32,6 +32,7 @@ import org.apache.sling.ide.impl.vlt.DeleteNodeCommand;
 import org.apache.sling.ide.impl.vlt.GetNodeContentCommand;
 import org.apache.sling.ide.impl.vlt.ReorderChildNodesCommand;
 import org.apache.sling.ide.transport.Command;
+import org.apache.sling.ide.transport.RepositoryPath;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.apache.sling.ide.transport.impl.DefaultBatcher;
 import org.hamcrest.Matchers;
@@ -69,9 +70,9 @@ public class DefaultBatcherTest {
     
     private void testMoreComprehensiveDeletesAreCompacted(String expected, String firstPath, String... otherPaths) {
 
-        batcher.add(new DeleteNodeCommand(mockRepo, credentials, firstPath, null));
+        batcher.add(new DeleteNodeCommand(mockRepo, credentials, new RepositoryPath(firstPath), null));
         for ( String otherPath: otherPaths) {
-            batcher.add(new DeleteNodeCommand(mockRepo, credentials, otherPath, null));
+            batcher.add(new DeleteNodeCommand(mockRepo, credentials, new RepositoryPath(otherPath), null));
         }
         
         List<Command<?>> batched = batcher.get();
@@ -79,14 +80,14 @@ public class DefaultBatcherTest {
         assertThat(batched, hasSize(1));
         Command<?> command = batched.get(0);
         assertThat(command, instanceOf(DeleteNodeCommand.class));
-        assertThat(command.getPath(), equalTo(expected));
+        assertThat(command.getPath().asString(), equalTo(expected));
     }
 
     @Test
     public void unrelatedDeletesAreNotCompacted() {
         
-        assertCommandsAreNotCompacted(new DeleteNodeCommand(mockRepo, credentials, "/content/branch", null), 
-                new DeleteNodeCommand(mockRepo, credentials, "/content/sub", null));
+        assertCommandsAreNotCompacted(new DeleteNodeCommand(mockRepo, credentials, new RepositoryPath("/content/branch"), null), 
+                new DeleteNodeCommand(mockRepo, credentials, new RepositoryPath("/content/sub"), null));
     }
     
     public void assertCommandsAreNotCompacted(Command<?> first, Command<?> second) {
@@ -104,7 +105,7 @@ public class DefaultBatcherTest {
     
     @Test
     public void dataIsClearedBetweenCalls() {
-        batcher.add(new DeleteNodeCommand(mockRepo, credentials, "/content/branch", null));
+        batcher.add(new DeleteNodeCommand(mockRepo, credentials, new RepositoryPath("/content/branch"), null));
         batcher.get();
         assertThat(batcher.get(), hasSize(0));
     }
@@ -112,8 +113,8 @@ public class DefaultBatcherTest {
     @Test
     public void identicalAddOrUpdatesAreCompacted() {
         
-        AddOrUpdateNodeCommand first = new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, new ResourceProxy("/content"), null);
-        AddOrUpdateNodeCommand second = new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, new ResourceProxy("/content"), null);
+        AddOrUpdateNodeCommand first = new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, newResource("/content"), null);
+        AddOrUpdateNodeCommand second = new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, newResource("/content"), null);
         
         batcher.add(first);
         batcher.add(second);
@@ -123,22 +124,22 @@ public class DefaultBatcherTest {
         assertThat(batched, hasSize(1));
         Command<?> command = batched.get(0);
         assertThat(command, instanceOf(AddOrUpdateNodeCommand.class));
-        assertThat(command.getPath(), equalTo("/content"));
+        assertThat(command.getPath().asString(), equalTo("/content"));
         
     }
 
     @Test
     public void unrelatedAddOrUpdatesAreNotCompacted() {
         
-        assertCommandsAreNotCompacted(new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, new ResourceProxy("/content/a"), null), 
-                new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, new ResourceProxy("/content/b"), null));
+        assertCommandsAreNotCompacted(new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, newResource("/content/a"), null), 
+                new AddOrUpdateNodeCommand(mockRepo, credentials, null, null, newResource("/content/b"), null));
     }
 
     @Test
     public void identicalsReorderingsAreCompacted() {
         
-        ReorderChildNodesCommand first = new ReorderChildNodesCommand(mockRepo, credentials, new ResourceProxy("/content"), null);
-        ReorderChildNodesCommand second = new ReorderChildNodesCommand(mockRepo, credentials,new ResourceProxy("/content"), null);
+        ReorderChildNodesCommand first = new ReorderChildNodesCommand(mockRepo, credentials, newResource("/content"), null);
+        ReorderChildNodesCommand second = new ReorderChildNodesCommand(mockRepo, credentials,newResource("/content"), null);
         
         batcher.add(first);
         batcher.add(second);
@@ -148,20 +149,24 @@ public class DefaultBatcherTest {
         assertThat(batched, hasSize(1));
         Command<?> command = batched.get(0);
         assertThat(command, instanceOf(ReorderChildNodesCommand.class));
-        assertThat(command.getPath(), equalTo("/content"));
+        assertThat(command.getPath().asString(), equalTo("/content"));
     }
     
     @Test
     public void unrelatedReorderingsAreNotCompacted() {
         
-        assertCommandsAreNotCompacted(new ReorderChildNodesCommand(mockRepo, credentials, new ResourceProxy("/content/a"), null), 
-                new ReorderChildNodesCommand(mockRepo, credentials,new ResourceProxy("/content/b"), null));
+        assertCommandsAreNotCompacted(new ReorderChildNodesCommand(mockRepo, credentials, newResource("/content/a"), null), 
+                new ReorderChildNodesCommand(mockRepo, credentials,newResource("/content/b"), null));
     }
     
     @Test
     public void unhandledCommandIsReturnedAsIs() {
         
-        assertCommandsAreNotCompacted(new GetNodeContentCommand(mockRepo, credentials, "/content", null), 
-                new GetNodeContentCommand(mockRepo, credentials, "/content", null));
+        assertCommandsAreNotCompacted(new GetNodeContentCommand(mockRepo, credentials, new RepositoryPath("/content"), null), 
+                new GetNodeContentCommand(mockRepo, credentials, new RepositoryPath("/content"), null));
+    }
+    
+    private ResourceProxy newResource(String path) {
+        return new ResourceProxy(new RepositoryPath(path));
     }
 }
diff --git a/shared/pom.xml b/shared/pom.xml
index cd49152b..ab016b6b 100644
--- a/shared/pom.xml
+++ b/shared/pom.xml
@@ -34,7 +34,6 @@
     <modules>
         <module>parent</module>
         <module>api</module>
-        <module>impl-resource</module>
         <module>impl-vlt</module>
         <module>artifacts</module>
         <module>sync-fs</module>