You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2020/11/10 12:53:17 UTC

[sling-org-apache-sling-feature-cpconverter] branch master updated: Replace java.nio.Path with new RepoPath class.

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

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c2ef99  Replace java.nio.Path with new RepoPath class.
     new 01af877  Merge pull request #33 from bosschaert/SLING-9891
6c2ef99 is described below

commit 6c2ef9929c3e12acf4b7b104871816a6e3e15f4e
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Tue Nov 10 11:16:45 2020 +0000

    Replace java.nio.Path with new RepoPath class.
    
    Also in this commit, use platform independent line separators in test
    result comparisons.
---
 .../apache/sling/feature/cpconverter/acl/Acl.java  |  13 +-
 .../feature/cpconverter/acl/DefaultAclManager.java |  35 +++---
 .../sling/feature/cpconverter/acl/SystemUser.java  |   9 +-
 .../handlers/RepPolicyEntryHandler.java            |  36 +++---
 .../handlers/SystemUsersEntryHandler.java          |  16 +--
 .../sling/feature/cpconverter/shared/RepoPath.java | 131 +++++++++++++++++++++
 .../ContentPackage2FeatureModelConverterTest.java  |  31 ++---
 .../feature/cpconverter/acl/AclManagerTest.java    |  76 ++++++------
 .../handlers/PrivilegesHandlerTest.java            |   2 +-
 .../handlers/RepPolicyEntryHandlerTest.java        | 108 ++++++++---------
 .../handlers/SystemUsersEntryHandlerTest.java      |   4 +-
 .../feature/cpconverter/shared/RepoPathTest.java   |  81 +++++++++++++
 .../vltpkg/PackagesEventsEmitterTest.java          |  11 +-
 13 files changed, 382 insertions(+), 171 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java
index b195441..c9b2124 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java
@@ -16,7 +16,8 @@
  */
 package org.apache.sling.feature.cpconverter.acl;
 
-import java.nio.file.Path;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -29,13 +30,13 @@ public final class Acl {
 
     private final String privileges;
 
-    private final Path path;
+    private final RepoPath path;
 
-    private final Path repositoryPath;
+    private final RepoPath repositoryPath;
 
     private final List<String> restrictions = new LinkedList<>();
 
-    public Acl(String operation, String privileges, Path path, Path repositoryPath) {
+    public Acl(String operation, String privileges, RepoPath path, RepoPath repositoryPath) {
         this.operation = operation;
         this.privileges = privileges;
         this.path = path;
@@ -56,11 +57,11 @@ public final class Acl {
         return privileges;
     }
 
-    public Path getPath() {
+    public RepoPath getPath() {
         return path;
     }
 
-    public Path getRepositoryPath() {
+    public RepoPath getRepositoryPath() {
         return repositoryPath;
     }
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
index cb6e8e9..d4460bd 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
@@ -16,10 +16,13 @@
  */
 package org.apache.sling.feature.cpconverter.acl;
 
+import org.apache.jackrabbit.vault.util.PlatformNameFormat;
+import org.apache.sling.feature.cpconverter.features.FeaturesManager;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
+import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
+
 import java.io.File;
 import java.io.FileInputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Formatter;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -34,13 +37,6 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
-import org.apache.jackrabbit.vault.util.PlatformNameFormat;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.cpconverter.features.FeaturesManager;
-import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
-
 public final class DefaultAclManager implements AclManager {
 
     private static final String CONTENT_XML_FILE_NAME = ".content.xml";
@@ -49,9 +45,9 @@ public final class DefaultAclManager implements AclManager {
 
     private final Set<SystemUser> preProvidedSystemUsers = new LinkedHashSet<>();
 
-    private final Set<Path> preProvidedSystemPaths = new HashSet<>();
+    private final Set<RepoPath> preProvidedSystemPaths = new HashSet<>();
 
-    private final Set<Path> preProvidedPaths = new HashSet<>();
+    private final Set<RepoPath> preProvidedPaths = new HashSet<>();
 
     private final Set<SystemUser> systemUsers = new LinkedHashSet<>();
 
@@ -76,13 +72,13 @@ public final class DefaultAclManager implements AclManager {
         return false;
     }
 
-    private void addPath(Path path, Set<Path> paths) {
+    private void addPath(RepoPath path, Set<RepoPath> paths) {
         if (preProvidedPaths.add(path)) {
             paths.add(path);
         }
 
-        Path parent = path.getParent();
-        if (parent != null && parent.getNameCount() > 0) {
+        RepoPath parent = path.getParent();
+        if (parent != null && parent.getSegmentCount() > 0) {
             addPath(parent, paths);
         }
     }
@@ -177,7 +173,7 @@ public final class DefaultAclManager implements AclManager {
         return Optional.empty();
     }
 
-    private final void addSystemUserPath(Formatter formatter, Path path) {
+    private final void addSystemUserPath(Formatter formatter, RepoPath path) {
         if (preProvidedSystemPaths.add(path)) {
             formatter.format("create path (rep:AuthorizableFolder) %s%n", path);
         }
@@ -207,20 +203,20 @@ public final class DefaultAclManager implements AclManager {
             return;
         }
 
-        Set<Path> paths = new TreeSet<>();
+        Set<RepoPath> paths = new TreeSet<>();
         for (Acl authorization : authorizations) {
             addPath(authorization.getRepositoryPath(), paths);
         }
 
-        for (Path path : paths) {
+        for (RepoPath path : paths) {
             String type = computePathType(path, packageAssemblers);
 
             formatter.format("create path (%s) %s%n", type, path);
         }
     }
 
-    private static String computePathType(Path path, List<VaultPackageAssembler> packageAssemblers) {
-        path = Paths.get(PlatformNameFormat.getPlatformPath(path.toString()));
+	private static String computePathType(RepoPath path, List<VaultPackageAssembler> packageAssemblers) {
+        path = new RepoPath(PlatformNameFormat.getPlatformPath(path.toString()));
 
         for (VaultPackageAssembler packageAssembler: packageAssemblers) {
             File currentDir = packageAssembler.getEntry(path.toString());
@@ -270,5 +266,4 @@ public final class DefaultAclManager implements AclManager {
     private static boolean areEmpty(List<Acl> authorizations) {
         return authorizations == null || authorizations.isEmpty();
     }
-
 }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
index 097fad7..019b8dc 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
@@ -16,16 +16,17 @@
  */
 package org.apache.sling.feature.cpconverter.acl;
 
-import java.nio.file.Path;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
+
 import java.util.Objects;
 
 public class SystemUser {
 
     private final String id;
 
-    private final Path path;
+    private final RepoPath path;
 
-    public SystemUser(String id, Path path) {
+    public SystemUser(String id, RepoPath path) {
         this.id = id;
         this.path = path;
     }
@@ -34,7 +35,7 @@ public class SystemUser {
         return id;
     }
 
-    public Path getPath() {
+    public RepoPath getPath() {
         return path;
     }
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
index 59832c7..844a407 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
@@ -16,15 +16,24 @@
  */
 package org.apache.sling.feature.cpconverter.handlers;
 
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
+import org.apache.jackrabbit.vault.util.PlatformNameFormat;
+import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.apache.sling.feature.cpconverter.acl.Acl;
+import org.apache.sling.feature.cpconverter.acl.AclManager;
+import org.apache.sling.feature.cpconverter.shared.AbstractJcrNodeParser;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
 
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
@@ -37,16 +46,7 @@ import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.vault.fs.io.Archive;
-import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
-import org.apache.jackrabbit.vault.util.PlatformNameFormat;
-import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
-import org.apache.sling.feature.cpconverter.acl.Acl;
-import org.apache.sling.feature.cpconverter.acl.AclManager;
-import org.apache.sling.feature.cpconverter.shared.AbstractJcrNodeParser;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 
 public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
 
@@ -79,8 +79,8 @@ public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
         StringWriter stringWriter = new StringWriter();
         handler.setResult(new StreamResult(stringWriter));
 
-        RepPolicyParser systemUserParser = new RepPolicyParser(Paths.get(resourcePath),
-                                                               Paths.get(PlatformNameFormat.getRepositoryPath(resourcePath)),
+        RepPolicyParser systemUserParser = new RepPolicyParser(new RepoPath(resourcePath),
+                                                               new RepoPath(PlatformNameFormat.getRepositoryPath(resourcePath)),
                                                                converter.getAclManager(),
                                                                handler);
         boolean hasRejectedAcls;
@@ -124,9 +124,9 @@ public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
 
         private final Stack<Acl> acls = new Stack<>();
 
-        private final Path path;
+        private final RepoPath path;
 
-        private final Path repositoryPath;
+        private final RepoPath repositoryPath;
 
         private final AclManager aclManager;
 
@@ -140,7 +140,7 @@ public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
         // just internal pointer for every iteration
         private boolean processCurrentAcl = false;
 
-        public RepPolicyParser(Path path, Path repositoryPath, AclManager aclManager, TransformerHandler handler) {
+        public RepPolicyParser(RepoPath path, RepoPath repositoryPath, AclManager aclManager, TransformerHandler handler) {
             super(REP_ACL);
             this.path = path;
             this.repositoryPath = repositoryPath;
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
index f5f0dc0..72e7fbd 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
@@ -16,17 +16,17 @@
  */
 package org.apache.sling.feature.cpconverter.handlers;
 
-import java.io.InputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.regex.Matcher;
+import org.xml.sax.Attributes;
 
 import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
 import org.apache.sling.feature.cpconverter.acl.SystemUser;
 import org.apache.sling.feature.cpconverter.shared.AbstractJcrNodeParser;
-import org.xml.sax.Attributes;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
+
+import java.io.InputStream;
+import java.util.regex.Matcher;
 
 public final class SystemUsersEntryHandler extends AbstractRegexEntryHandler {
 
@@ -42,7 +42,7 @@ public final class SystemUsersEntryHandler extends AbstractRegexEntryHandler {
             path = matcher.group(1);
         }
 
-        Path currentPath = Paths.get(path).getParent();
+        RepoPath currentPath = new RepoPath(path).getParent();
 
         SystemUserParser systemUserParser = new SystemUserParser(converter, currentPath);
         try (InputStream input = archive.openInputStream(entry)) {
@@ -58,9 +58,9 @@ public final class SystemUsersEntryHandler extends AbstractRegexEntryHandler {
 
         private final ContentPackage2FeatureModelConverter converter;
 
-        private final Path path;
+        private final RepoPath path;
 
-        public SystemUserParser(ContentPackage2FeatureModelConverter converter, Path path) {
+        public SystemUserParser(ContentPackage2FeatureModelConverter converter, RepoPath path) {
             super(REP_SYSTEM_USER);
             this.converter = converter;
             this.path = path;
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/shared/RepoPath.java b/src/main/java/org/apache/sling/feature/cpconverter/shared/RepoPath.java
new file mode 100644
index 0000000..6253de3
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/shared/RepoPath.java
@@ -0,0 +1,131 @@
+/*
+ * 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.feature.cpconverter.shared;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/** A Repo Path represents a path in the repository, for example when used in
+ * a repoinit section.
+ *
+ * @see
+ * <a href="https://github.com/apache/sling-org-apache-sling-repoinit-parser/blob/master/src/main/javacc/RepoInitGrammar.jjt">Repoinit Grammar</a>
+ *
+ */
+public class RepoPath implements Comparable<RepoPath>{
+    private final List<String> path;
+
+    /**
+     * Construct a Repo Path from a string. The string should separate the path
+     * segments with forward slashes, e.g. {@code /my/repo/path}.
+     *
+     * @param path The string representation of the path. If the initial leading forward
+     * slash is missing it will be assumed to be there.
+     */
+    public RepoPath(String path) {
+        path = path.trim();
+        if (path.startsWith("/"))
+            path = path.substring(1);
+
+        this.path = Arrays.asList(path.split("/"));
+    }
+
+    /**
+     * Construct a Repo Path from a List.
+     *
+     * @param list The list to create the repo path from. The list should not have
+     * any separators.
+     */
+    public RepoPath(List<String> list) {
+        this.path = new ArrayList<>(list);
+    }
+
+    @Override
+    public int compareTo(RepoPath o) {
+        String me = toString();
+        String them = o.toString();
+        return me.compareTo(them);
+    }
+
+    /**
+     * Get the parent path of the current path.
+     *
+     * @return The parent path, or {@code null} if we are at the root and there is no
+     * further parent.
+     */
+    public RepoPath getParent() {
+        if (path.isEmpty())
+            return null;
+
+        ArrayList<String> parentPath = new ArrayList<>(path.subList(0, path.size() - 1));
+        if (parentPath.isEmpty())
+            return null;
+
+        return new RepoPath(parentPath);
+    }
+
+    /**
+     * Get the nubmer of segments in this path.
+     *
+     * @return The number of segments.
+     */
+    public int getSegmentCount() {
+        return path.size();
+    }
+
+    /**
+     * Check is this path starts with the other path.
+     *
+     * @param otherPath The other path to check against.
+     * @return If it starts with the other path or not.
+     */
+    public boolean startsWith(RepoPath otherPath) {
+        if (otherPath == null)
+            return true; // Every path starts with the root path
+
+        if (path.size() < otherPath.path.size())
+            return false;
+
+        List<String> l = new ArrayList<>(path.subList(0, otherPath.path.size()));
+        return l.equals(otherPath.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;
+        RepoPath other = (RepoPath) obj;
+        return Objects.equals(path, other.path);
+    }
+
+    @Override
+    public String toString() {
+        return "/" + path.stream().collect(Collectors.joining("/"));
+    }
+}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
index e99cd46..3b6693a 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverterTest.java
@@ -575,21 +575,22 @@ public class ContentPackage2FeatureModelConverterTest {
             Extension repoinitExtension = feature.getExtensions().getByName("repoinit");
             assertNotNull(repoinitExtension);
 
-            String expected = "register nodetypes\n" +
-                    "<<===\n" +
-                    "<< <'sling'='http://sling.apache.org/jcr/sling/1.0'>\n" +
-                    "<< <'nt'='http://www.jcp.org/jcr/nt/1.0'>\n" +
-                    "<< <'rep'='internal'>\n" +
-                    "\n" +
-                    "<< [sling:Folder] > nt:folder\n" +
-                    "<<   - * (undefined) multiple\n" +
-                    "<<   - * (undefined)\n" +
-                    "<<   + * (nt:base) = sling:Folder version\n" +
-                    "\n" +
-                    "<< [rep:RepoAccessControllable]\n" +
-                    "<<   mixin\n" +
-                    "<<   + rep:repoPolicy (rep:Policy) protected ignore\n" +
-                    "\n===>>\n";
+            String expected = "register nodetypes" + System.lineSeparator() +
+                    "<<===" + System.lineSeparator() +
+                    "<< <'sling'='http://sling.apache.org/jcr/sling/1.0'>" + System.lineSeparator() +
+                    "<< <'nt'='http://www.jcp.org/jcr/nt/1.0'>" + System.lineSeparator() +
+                    "<< <'rep'='internal'>" + System.lineSeparator() +
+                    "" + System.lineSeparator() +
+                    "<< [sling:Folder] > nt:folder" + System.lineSeparator() +
+                    "<<   - * (undefined) multiple" + System.lineSeparator() +
+                    "<<   - * (undefined)" + System.lineSeparator() +
+                    "<<   + * (nt:base) = sling:Folder version" + System.lineSeparator() +
+                    System.lineSeparator() +
+                    "<< [rep:RepoAccessControllable]" + System.lineSeparator() +
+                    "<<   mixin" + System.lineSeparator() +
+                    "<<   + rep:repoPolicy (rep:Policy) protected ignore" + System.lineSeparator() +
+                    System.lineSeparator() +
+                    "===>>" + System.lineSeparator();
             String actual = repoinitExtension.getText();
             assertEquals(expected, actual);
         }
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/acl/AclManagerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/acl/AclManagerTest.java
index 3deee3e..15978fc 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/acl/AclManagerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/acl/AclManagerTest.java
@@ -16,28 +16,13 @@
  */
 package org.apache.sling.feature.cpconverter.acl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.File;
-import java.io.StringReader;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
 import org.apache.jackrabbit.vault.util.PlatformNameFormat;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
 import org.apache.sling.feature.cpconverter.features.FeaturesManager;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
 import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
 import org.apache.sling.repoinit.parser.RepoInitParser;
 import org.apache.sling.repoinit.parser.RepoInitParsingException;
@@ -48,6 +33,21 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import java.io.File;
+import java.io.StringReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 public class AclManagerTest {
     private AclManager aclManager;
     private Path tempDir;
@@ -71,12 +71,12 @@ public class AclManagerTest {
 
     @Test
     public void makeSureAclsAreCreatedOnlyoutsideSytemUsersPaths() throws Exception {
-        aclManager.addSystemUser(new SystemUser("acs-commons-ensure-oak-index-service", Paths.get("/asd/public")));
+        aclManager.addSystemUser(new SystemUser("acs-commons-ensure-oak-index-service", new RepoPath("/asd/public")));
 
         // emulate a second iteration of conversion
         aclManager.reset();
 
-        aclManager.addSystemUser(new SystemUser("acs-commons-package-replication-status-event-service", Paths.get("/asd/public")));
+        aclManager.addSystemUser(new SystemUser("acs-commons-package-replication-status-event-service", new RepoPath("/asd/public")));
 
         aclManager.addAcl("acs-commons-ensure-oak-index-service", newAcl("allow", "jcr:read,rep:write,rep:indexDefinitionManagement", "/asd/not/system/user/path"));
         aclManager.addAcl("acs-commons-package-replication-status-event-service", newAcl("allow", "jcr:read,crx:replicate,jcr:removeNode", "/asd/public"));
@@ -98,20 +98,20 @@ public class AclManagerTest {
         assertNotNull(repoinitExtension);
 
         // acs-commons-on-deploy-scripts-service will be missed
-        String expected = "create path (rep:AuthorizableFolder) /asd/public\n" + // SLING-8586
-                "create service user acs-commons-package-replication-status-event-service with path /asd/public\n" +
-                "create path (sling:Folder) /asd\n" +
-                "create path (sling:Folder) /asd/not\n" +
-                "create path (sling:Folder) /asd/not/system\n" +
-                "create path (sling:Folder) /asd/not/system/user\n" +
-                "create path (sling:Folder) /asd/not/system/user/path\n" +
+        String expected = "create path (rep:AuthorizableFolder) /asd/public" + System.lineSeparator() + // SLING-8586
+                "create service user acs-commons-package-replication-status-event-service with path /asd/public" + System.lineSeparator() +
+                "create path (sling:Folder) /asd" + System.lineSeparator() +
+                "create path (sling:Folder) /asd/not" + System.lineSeparator() +
+                "create path (sling:Folder) /asd/not/system" + System.lineSeparator() +
+                "create path (sling:Folder) /asd/not/system/user" + System.lineSeparator() +
+                "create path (sling:Folder) /asd/not/system/user/path" + System.lineSeparator() +
                 // see SLING-8561
                 // "set ACL for acs-commons-package-replication-status-event-service\n" +
                 // "allow jcr:read,crx:replicate,jcr:removeNode on /asd/public\n" +
                 // "end\n" +
-                "set ACL for acs-commons-ensure-oak-index-service\n" +
-                "allow jcr:read,rep:write,rep:indexDefinitionManagement on /asd/not/system/user/path\n" +
-                "end\n";
+                "set ACL for acs-commons-ensure-oak-index-service" + System.lineSeparator() +
+                "allow jcr:read,rep:write,rep:indexDefinitionManagement on /asd/not/system/user/path" + System.lineSeparator() +
+                "end" + System.lineSeparator();
         String actual = repoinitExtension.getText();
         assertEquals(expected, actual);
 
@@ -122,7 +122,7 @@ public class AclManagerTest {
 
     @Test
     public void pathWithSpecialCharactersTest() throws RepoInitParsingException {
-        aclManager.addSystemUser(new SystemUser("sys-usr", Paths.get("/home/users/system")));
+        aclManager.addSystemUser(new SystemUser("sys-usr", new RepoPath("/home/users/system")));
         aclManager.addAcl("sys-usr", newAcl("allow", "jcr:read", "/content/_cq_tags"));
         aclManager.addAcl("sys-usr", newAcl("allow", "jcr:write", "/content/cq:tags"));
         VaultPackageAssembler assembler = mock(VaultPackageAssembler.class);
@@ -137,14 +137,14 @@ public class AclManagerTest {
         Extension repoinitExtension = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
         assertNotNull(repoinitExtension);
 
-        String expected = "create path (rep:AuthorizableFolder) /home/users/system\n" + // SLING-8586
-                "create service user sys-usr with path /home/users/system\n" +
-                "create path (sling:Folder) /content\n" +
-                "create path (sling:Folder) /content/cq:tags\n" +
-                "set ACL for sys-usr\n" +
-                "allow jcr:read on /content/cq:tags\n" +
-                "allow jcr:write on /content/cq:tags\n" +
-                "end\n";
+        String expected = "create path (rep:AuthorizableFolder) /home/users/system" + System.lineSeparator() + // SLING-8586
+                "create service user sys-usr with path /home/users/system" + System.lineSeparator() +
+                "create path (sling:Folder) /content" + System.lineSeparator() +
+                "create path (sling:Folder) /content/cq:tags" + System.lineSeparator() +
+                "set ACL for sys-usr" + System.lineSeparator() +
+                "allow jcr:read on /content/cq:tags" + System.lineSeparator() +
+                "allow jcr:write on /content/cq:tags" + System.lineSeparator() +
+                "end" + System.lineSeparator();
 
         String actual = repoinitExtension.getText();
         assertEquals(expected, actual);
@@ -155,7 +155,7 @@ public class AclManagerTest {
     }
 
     private static Acl newAcl(String operation, String privileges, String path) {
-        return new Acl(operation, privileges, Paths.get(path), Paths.get(PlatformNameFormat.getRepositoryPath(path)));
+        return new Acl(operation, privileges, new RepoPath(path), new RepoPath(PlatformNameFormat.getRepositoryPath(path)));
     }
 
 }
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java
index b6d9ac1..0636e5c 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java
@@ -86,7 +86,7 @@ public class PrivilegesHandlerTest {
 
         Extension repoinitExtension = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
         assertNotNull(repoinitExtension);
-        assertTrue(repoinitExtension.getText().contains("register privilege rx:replicate\n"));
+        assertTrue(repoinitExtension.getText().contains("register privilege rx:replicate" + System.lineSeparator()));
     }
 
 }
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
index 28efe71..f540479 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
@@ -16,24 +16,6 @@
  */
 package org.apache.sling.feature.cpconverter.handlers;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.StringReader;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
-
 import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
 import org.apache.sling.feature.ArtifactId;
@@ -45,6 +27,7 @@ import org.apache.sling.feature.cpconverter.acl.DefaultAclManager;
 import org.apache.sling.feature.cpconverter.acl.SystemUser;
 import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
 import org.apache.sling.feature.cpconverter.features.FeaturesManager;
+import org.apache.sling.feature.cpconverter.shared.RepoPath;
 import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
 import org.apache.sling.repoinit.parser.RepoInitParser;
 import org.apache.sling.repoinit.parser.impl.RepoInitParserService;
@@ -53,6 +36,22 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 public final class RepPolicyEntryHandlerTest {
 
     private RepPolicyEntryHandler handler;
@@ -95,30 +94,30 @@ public final class RepPolicyEntryHandlerTest {
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
         // commented ACLs are due SLING-8561
-        String expected = "create path (rep:AuthorizableFolder) /asd/public\n" + // SLING-8586
-                "create service user acs-commons-ensure-oak-index-service with path /asd/public\n" +
+        String expected = "create path (rep:AuthorizableFolder) /asd/public" + System.lineSeparator() + // SLING-8586
+                "create service user acs-commons-ensure-oak-index-service with path /asd/public" + System.lineSeparator() +
                 // "create path (sling:Folder) /asd\n" +
                 // "create path (sling:Folder) /asd/public\n" +
                 // "set ACL for acs-commons-ensure-oak-index-service\n" +
                 // "allow jcr:read,rep:write,rep:indexDefinitionManagement on /asd/public restriction(rep:glob,*/oak:index/*)\n" +
                 // "end\n" +
-                "create service user acs-commons-dispatcher-flush-service with path /asd/public\n" +
+                "create service user acs-commons-dispatcher-flush-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-dispatcher-flush-service\n" +
                 // "allow jcr:read,crx:replicate,jcr:removeNode on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-package-replication-status-event-service with path /asd/public\n" +
+                "create service user acs-commons-package-replication-status-event-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-package-replication-status-event-service\n" +
                 // "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-ensure-service-user-service with path /asd/public\n" +
+                "create service user acs-commons-ensure-service-user-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-ensure-service-user-service\n" +
                 // "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-automatic-package-replicator-service with path /asd/public\n" +
+                "create service user acs-commons-automatic-package-replicator-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-automatic-package-replicator-service\n" +
                 // "allow jcr:read on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-on-deploy-scripts-service with path /asd/public\n";
+                "create service user acs-commons-on-deploy-scripts-service with path /asd/public" + System.lineSeparator();
                 // "set ACL for acs-commons-on-deploy-scripts-service\n" +
                 // "allow jcr:read on /asd/public\n" +
                 // "end\n";
@@ -142,22 +141,22 @@ public final class RepPolicyEntryHandlerTest {
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
         // commented ACLs are due SLING-8561
-        String expected = "create path (rep:AuthorizableFolder) /asd/public\n" + // SLING-8586
-                "create service user acs-commons-package-replication-status-event-service with path /asd/public\n" +
+        String expected = "create path (rep:AuthorizableFolder) /asd/public" + System.lineSeparator() + // SLING-8586
+                "create service user acs-commons-package-replication-status-event-service with path /asd/public" + System.lineSeparator() +
                 // "create path (sling:Folder) /asd\n" +
                 // "create path (sling:Folder) /asd/public\n" +
                 // "set ACL for acs-commons-package-replication-status-event-service\n" +
                 // "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-ensure-service-user-service with path /asd/public\n" +
+                "create service user acs-commons-ensure-service-user-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-ensure-service-user-service\n" +
                 // "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-automatic-package-replicator-service with path /asd/public\n" +
+                "create service user acs-commons-automatic-package-replicator-service with path /asd/public" + System.lineSeparator() +
                 // "set ACL for acs-commons-automatic-package-replicator-service\n" +
                 // "allow jcr:read on /asd/public\n" +
                 // "end\n" +
-                "create service user acs-commons-on-deploy-scripts-service with path /asd/public\n";
+                "create service user acs-commons-on-deploy-scripts-service with path /asd/public" + System.lineSeparator();
                 //"set ACL for acs-commons-on-deploy-scripts-service\n" +
                 //"allow jcr:read on /asd/public\n" +
                 //"end\n";
@@ -169,32 +168,33 @@ public final class RepPolicyEntryHandlerTest {
         assertFalse(operations.isEmpty());
 
         // acs-commons-ensure-oak-index-service and acs-commons-dispatcher-flush-service not recognized as system users
-        expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">\n"
+        expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">" + System.lineSeparator()
                 +
-                "    <allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">\n"
-                + "        <rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>\n"
-                + "    </allow0>\n"
-                + "    <allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>\n"
+                "    <allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">" + System.lineSeparator()
+                + "        <rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>" + System.lineSeparator()
+                + "    </allow0>" + System.lineSeparator()
+                + "    <allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>" + System.lineSeparator()
                 +
-                "</jcr:root>\n";
+                "</jcr:root>" + System.lineSeparator();
         actual = result.getExcludedAcls();
         assertEquals(expected, actual);
     }
 
     @Test
     public void systemUserAclSetNotForUserPath() throws Exception {
-        ParseResult result = parseAndSetRepoinit(new SystemUser("acs-commons-package-replication-status-event-service", Paths.get("/this/is/a/completely/different/path")));
+        ParseResult result = parseAndSetRepoinit(new SystemUser("acs-commons-package-replication-status-event-service",
+                new RepoPath("/this/is/a/completely/different/path")));
         Extension repoinitExtension = result.getRepoinitExtension();
         assertNotNull(repoinitExtension);
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
-        String expected = "create path (rep:AuthorizableFolder) /this/is/a/completely/different/path\n" + // SLING-8586
-                "create service user acs-commons-package-replication-status-event-service with path /this/is/a/completely/different/path\n" +
-                "create path (sling:Folder) /asd\n" +
-                "create path (sling:Folder) /asd/public\n" +
-                "set ACL for acs-commons-package-replication-status-event-service\n" +
-                "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
-                "end\n";
+        String expected = "create path (rep:AuthorizableFolder) /this/is/a/completely/different/path" + System.lineSeparator() + // SLING-8586
+                "create service user acs-commons-package-replication-status-event-service with path /this/is/a/completely/different/path" + System.lineSeparator() +
+                "create path (sling:Folder) /asd" + System.lineSeparator() +
+                "create path (sling:Folder) /asd/public" + System.lineSeparator() +
+                "set ACL for acs-commons-package-replication-status-event-service" + System.lineSeparator() +
+                "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public" + System.lineSeparator() +
+                "end" + System.lineSeparator();
         String actual = repoinitExtension.getText();
         assertEquals(expected, actual);
 
@@ -203,17 +203,17 @@ public final class RepPolicyEntryHandlerTest {
         assertFalse(operations.isEmpty());
 
         // acs-commons-package-replication-status-event-service only recognised as system user - ACLs in allow2
-        expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">\n"
+        expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">" + System.lineSeparator()
                 +
-                "    <allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">\n"
-                + "        <rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>\n"
-                + "    </allow0>\n"
-                + "    <allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>\n"
-                + "    <allow3 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-service-user-service\" rep:privileges=\"{Name}[jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl]\"/>\n"
-                + "    <allow4 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-automatic-package-replicator-service\" rep:privileges=\"{Name}[jcr:read]\"/>\n"
-                + "    <allow5 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-on-deploy-scripts-service\" rep:privileges=\"{Name}[jcr:read]\"/>\n"
+                "    <allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">" + System.lineSeparator()
+                + "        <rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>" + System.lineSeparator()
+                + "    </allow0>" + System.lineSeparator()
+                + "    <allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>" + System.lineSeparator()
+                + "    <allow3 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-service-user-service\" rep:privileges=\"{Name}[jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl]\"/>" + System.lineSeparator()
+                + "    <allow4 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-automatic-package-replicator-service\" rep:privileges=\"{Name}[jcr:read]\"/>" + System.lineSeparator()
+                + "    <allow5 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-on-deploy-scripts-service\" rep:privileges=\"{Name}[jcr:read]\"/>" + System.lineSeparator()
                 +
-                "</jcr:root>\n";
+                "</jcr:root>" + System.lineSeparator();
         actual = result.getExcludedAcls();
         assertEquals(expected, actual);
     }
@@ -225,7 +225,7 @@ public final class RepPolicyEntryHandlerTest {
     }
 
     private ParseResult parseAndSetRepoinit(String...systemUsersNames) throws Exception {
-        Path alwaysTheSamePath = Paths.get("/asd/public");
+        RepoPath alwaysTheSamePath = new RepoPath("/asd/public");
 
         SystemUser[] systemUsers = new SystemUser[systemUsersNames.length];
         for (int i = 0; i < systemUsersNames.length; i++) {
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
index 3932136..c2cd532 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
@@ -81,8 +81,8 @@ public class SystemUsersEntryHandlerTest {
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
         assertTrue(repoinitExtension.isRequired());
 
-        String expected = "create path (rep:AuthorizableFolder) /home/users/system/asd-share-commons\n" + // SLING-8586
-                "create service user asd-share-commons-asd-index-definition-reader-service with path /home/users/system/asd-share-commons\n";
+        String expected = "create path (rep:AuthorizableFolder) /home/users/system/asd-share-commons" + System.lineSeparator() + // SLING-8586
+                "create service user asd-share-commons-asd-index-definition-reader-service with path /home/users/system/asd-share-commons" + System.lineSeparator();
         String actual = repoinitExtension.getText();
         assertEquals(expected, actual);
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/shared/RepoPathTest.java b/src/test/java/org/apache/sling/feature/cpconverter/shared/RepoPathTest.java
new file mode 100644
index 0000000..53b3a15
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/cpconverter/shared/RepoPathTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.feature.cpconverter.shared;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class RepoPathTest {
+    @Test
+    public void testCtors() {
+        RepoPath r1 = new RepoPath("/a/b/c");
+        RepoPath r2 = new RepoPath(Arrays.asList("a", "b", "c"));
+
+        assertEquals(r1, r2);
+        assertEquals("/a/b/c", r2.toString());
+    }
+
+    @Test
+    public void testCompareTo() {
+        RepoPath r1 = new RepoPath("/a/b/c");
+        RepoPath r2 = new RepoPath(Arrays.asList("a", "b", "c"));
+
+        assertEquals(0, r1.compareTo(r2));
+
+        r2 = new RepoPath("/a/b");
+        assertTrue(r1.compareTo(r2) > 0);
+        assertTrue(r2.compareTo(r1) < 0);
+    }
+
+    @Test
+    public void testGetParent() {
+        RepoPath r1 = new RepoPath("/foo/bar");
+        RepoPath r2 = new RepoPath("foo");
+
+        assertEquals(r2, r1.getParent());
+
+        assertNull(r2.getParent());
+        assertNull(new RepoPath(Collections.emptyList()).getParent());
+    }
+
+    @Test
+    public void testGetSegmentCount() {
+        assertEquals(2, new RepoPath("/foo/bar").getSegmentCount());
+    }
+
+    @Test
+    public void testStartsWith() {
+        RepoPath r1 = new RepoPath("/foo/bar");
+        RepoPath r2 = new RepoPath("foo");
+
+        assertTrue(r1.startsWith(r2));
+        assertFalse(r2.startsWith(r1));
+        assertTrue(r1.startsWith(r1));
+        assertTrue(r2.startsWith(r2));
+        assertFalse(r2.startsWith(new RepoPath(Collections.singletonList("fo"))));
+
+        assertTrue(r1.startsWith(r1.getParent()));
+        assertTrue(r2.startsWith(r2.getParent()));
+    }
+}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java
index bfa3887..1dce955 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/PackagesEventsEmitterTest.java
@@ -55,7 +55,8 @@ public class PackagesEventsEmitterTest {
         VaultPackage parent = mock(VaultPackage.class);
         when(parent.getPackageType()).thenReturn(PackageType.MIXED);
         when(parent.getId()).thenReturn(ID_PARENT);
-        when(parent.getFile()).thenReturn(new File("/org/apache/sling/content-package.zip"));
+        File cpFile = new File("/org/apache/sling/content-package.zip").getAbsoluteFile();
+		when(parent.getFile()).thenReturn(cpFile);
         when(parent.getDependencies()).thenReturn(new Dependency[0]);
 
         StringWriter stringWriter = new StringWriter();
@@ -91,10 +92,10 @@ public class PackagesEventsEmitterTest {
 
         String actual = stringWriter.toString();
 
-        String expected = "/org/apache/sling/content-package.zip,apache/sling:parent:1.0.0,MIXED,,,\n" + 
-                "/org/apache/sling/content-package.zip,apache/sling:application-child:1.0.0,APPLICATION,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip\n" + 
-                "/org/apache/sling/content-package.zip,apache/sling:content-child:1.0.0,CONTENT,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip\n" + 
-                "/org/apache/sling/content-package.zip,apache/sling:nested-child:1.0.0,CONTAINER,apache/sling:application-child:1.0.0,/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip,/org/apache/sling/content-package.zip!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip!/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip\n";
+        String expected = cpFile + ",apache/sling:parent:1.0.0,MIXED,,," + System.lineSeparator() + 
+        		cpFile + ",apache/sling:application-child:1.0.0,APPLICATION,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip," + cpFile + "!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip" + System.lineSeparator() + 
+        		cpFile + ",apache/sling:content-child:1.0.0,CONTENT,apache/sling:parent:1.0.0,/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip," + cpFile + "!/jcr_root/etc/packages/org/apache/sling/content-child-1.0.zip" + System.lineSeparator() + 
+        		cpFile + ",apache/sling:nested-child:1.0.0,CONTAINER,apache/sling:application-child:1.0.0,/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip," + cpFile + "!/jcr_root/etc/packages/org/apache/sling/application-child-1.0.zip!/jcr_root/etc/packages/org/apache/sling/nested-child-1.0.zip" + System.lineSeparator();
         assertTrue(actual.endsWith(expected));
     }