You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2023/01/19 11:38:00 UTC

[jackrabbit-filevault] branch feature/support-checkout-on-case-insensitive-filesystems created (now 69e16b12)

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

kwin pushed a change to branch feature/support-checkout-on-case-insensitive-filesystems
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git


      at 69e16b12 JCRVLT-49 support node names only differing in casing on case insensitive file systems

This branch includes the following new commits:

     new 69e16b12 JCRVLT-49 support node names only differing in casing on case insensitive file systems

The 1 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.



[jackrabbit-filevault] 01/01: JCRVLT-49 support node names only differing in casing on case insensitive file systems

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

kwin pushed a commit to branch feature/support-checkout-on-case-insensitive-filesystems
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 69e16b123690d0edf1b0a3d6700f44bf8f2f342c
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Jan 19 12:37:53 2023 +0100

    JCRVLT-49 support node names only differing in casing on case
    insensitive file systems
    
    WIP
---
 .../jackrabbit/vault/util/PlatformNameFormat.java  | 10 ++-
 .../apache/jackrabbit/vault/util/package-info.java |  2 +-
 .../apache/jackrabbit/vault/vlt/VltDirectory.java  | 78 ++++++++++++++++++++++
 .../org/apache/jackrabbit/vault/vlt/VltFile.java   |  4 ++
 4 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java
index a5706907..33a3d9ac 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java
@@ -100,9 +100,7 @@ public class PlatformNameFormat {
                  case '/':
                  case'?':
                  case'%':
-                     buf.append('%');
-                     buf.append(Character.forDigit(c / 16, 16));
-                     buf.append(Character.forDigit(c % 16, 16));
+                     addEscapedCharacter(buf, c);
                      break;
                  default:
                      buf.append(c);
@@ -115,6 +113,12 @@ public class PlatformNameFormat {
         }
     }
 
+    public static void addEscapedCharacter(StringBuilder buf, char c) {
+        buf.append('%');
+        buf.append(Character.forDigit(c / 16, 16));
+        buf.append(Character.forDigit(c % 16, 16));
+    }
+
     /**
      * Returns the platform path for the given repository one.
      * @param repoPath the repository path
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
index 27fff62d..d387b718 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/util/package-info.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-@Version("2.10.0")
+@Version("2.11.0")
 package org.apache.jackrabbit.vault.util;
 
 import org.osgi.annotation.versioning.Version;
\ No newline at end of file
diff --git a/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltDirectory.java b/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltDirectory.java
index c5014e54..4412c267 100644
--- a/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltDirectory.java
+++ b/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltDirectory.java
@@ -18,11 +18,16 @@ package org.apache.jackrabbit.vault.vlt;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
+import java.util.function.Predicate;
 
 import javax.jcr.RepositoryException;
 
@@ -33,6 +38,7 @@ import org.apache.jackrabbit.vault.fs.api.VaultFsTransaction;
 import org.apache.jackrabbit.vault.util.Constants;
 import org.apache.jackrabbit.vault.util.FileInputSource;
 import org.apache.jackrabbit.vault.util.LineOutputStream;
+import org.apache.jackrabbit.vault.util.PlatformNameFormat;
 import org.apache.jackrabbit.vault.vlt.actions.Action;
 import org.apache.jackrabbit.vault.vlt.meta.MetaDirectory;
 import org.apache.jackrabbit.vault.vlt.meta.VltEntries;
@@ -76,6 +82,78 @@ public class VltDirectory {
         init();
     }
 
+    /** 
+     * Escapes the given name according to the file escaping rules in case a conflicting file name (e.g. just differ by case in case-ignoring filesystem) exists
+     * in the current directory.
+     * 
+     * @param name
+     * @return
+     */
+    String escapeToMakeUnique(String name) {
+        File newFile = new File(dir, name);
+        Predicate<VltFile> sameFilePredicate = f -> { 
+            try {
+                return Files.isSameFile(f.getFile().toPath(), newFile.toPath());
+            } catch (NoSuchFileException e) {
+                // ignore
+                return false;
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        };
+        Optional<VltFile> conflictingFile = getFiles().stream().filter(sameFilePredicate).findFirst();
+        if (conflictingFile.isPresent()) {
+            int firstDiffIndex = indexOfDifference(name, conflictingFile.get().getName());
+            StringBuilder newName = new StringBuilder(name.substring(0, firstDiffIndex));
+            PlatformNameFormat.addEscapedCharacter(newName, name.charAt(firstDiffIndex));
+            newName.append(name.substring(firstDiffIndex+1));
+            return newName.toString();
+        } else {
+            return name;
+        }
+    }
+
+    /**
+     * Compares two Strings, and returns the index at which the
+     * Strings begin to differ.
+     *
+     * For example,
+     * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code>
+     *
+     * <pre>
+     * StringUtils.indexOfDifference(null, null) = -1
+     * StringUtils.indexOfDifference("", "") = -1
+     * StringUtils.indexOfDifference("", "abc") = 0
+     * StringUtils.indexOfDifference("abc", "") = 0
+     * StringUtils.indexOfDifference("abc", "abc") = -1
+     * StringUtils.indexOfDifference("ab", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "xyz") = 0
+     * </pre>
+     *
+     * @param str1  the first String, may be null
+     * @param str2  the second String, may be null
+     * @return the index where str2 and str1 begin to differ; -1 if they are equal
+     */
+    private static int indexOfDifference(String str1, String str2) {
+        if (str1 == str2) {
+            return -1;
+        }
+        if (str1 == null || str2 == null) {
+            return 0;
+        }
+        int i;
+        for (i = 0; i < str1.length() && i < str2.length(); ++i) {
+            if (str1.charAt(i) != str2.charAt(i)) {
+                break;
+            }
+        }
+        if (i < str2.length() || i < str1.length()) {
+            return i;
+        }
+        return -1;
+    }
+
     public VltDirectory getParent() throws VltException {
         return new VltDirectory(ctx, dir.getParentFile());
     }
diff --git a/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltFile.java b/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltFile.java
index d7c970e5..68e07a03 100644
--- a/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltFile.java
+++ b/vault-vlt/src/main/java/org/apache/jackrabbit/vault/vlt/VltFile.java
@@ -95,6 +95,10 @@ public class VltFile implements DocumentSource {
     public VltFile(VltDirectory parent, String name, VltEntry entry)
             throws VltException {
         this.parent = parent;
+        if (entry == null) {
+            // potentially modify the name
+            name = parent.escapeToMakeUnique(name);
+        }
         this.name = name;
         this.entry = entry;
         this.file = new File(parent.getDirectory(), name);