This is an automated email from the ASF dual-hosted git repository. claude pushed a commit to branch RAT-524_Fix_DocumentName.isCaseSensitive_detection_time in repository https://gitbox.apache.org/repos/asf/creadur-rat.git
commit 6f7d15b8c3ef8147b43e4da0afc5403eddf67334 Author: Claude Warren <[email protected]> AuthorDate: Sat Dec 6 16:56:55 2025 +0000 Moved FSInfo data into separate object and cached it in a REGISTRY map --- .../java/org/apache/rat/document/DocumentName.java | 113 ++++++++++++++------- 1 file changed, 77 insertions(+), 36 deletions(-) diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/DocumentName.java b/apache-rat-core/src/main/java/org/apache/rat/document/DocumentName.java index dfe6d057..c2c0510e 100644 --- a/apache-rat-core/src/main/java/org/apache/rat/document/DocumentName.java +++ b/apache-rat-core/src/main/java/org/apache/rat/document/DocumentName.java @@ -28,8 +28,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -298,43 +300,36 @@ public class DocumentName implements Comparable<DocumentName> { return HashCodeBuilder.reflectionHashCode(this); } - /** - * The file system information needed to process document names. - */ - public static class FSInfo implements Comparable<FSInfo> { - /** The common name for the file system this Info represents. */ - private final String name; - /** The separator between directory names. */ - private final String separator; - /** The case-sensitivity flag. */ + private static final class FSInfoData { + /** The case sensitivity flag */ private final boolean isCaseSensitive; /** The list of roots for the file system. */ private final List<String> roots; + /** The separator between directory names. */ + private final String separator; - public static FSInfo getDefault() { - FSInfo result = (FSInfo) System.getProperties().get("FSInfo"); - return result == null ? - new FSInfo("default", FileSystems.getDefault()) - : result; - } /** - * Constructor. Extracts the necessary data from the file system. - * @param fileSystem the file system to extract data from. + * Constructor for known properties. + * @param separator the directory separator character(s). + * @param isCaseSensitive {@code true} if the file system is cases sensitive. + * @param roots THe list of roots for the file system. */ - public FSInfo(final FileSystem fileSystem) { - this("anon", fileSystem); + FSInfoData(final String separator, final boolean isCaseSensitive, final List<String> roots) { + this.isCaseSensitive = isCaseSensitive; + this.roots = roots; + this.separator = separator; } /** - * Constructor. Extracts the necessary data from the file system. - * @param fileSystem the file system to extract data from. + * Constructor for an arbitrary file system. + * This constructor can be processor intensive as it has to check the file system for case sensitivity. + * @param fileSystem the file system. */ - public FSInfo(final String name, final FileSystem fileSystem) { - this.name = name; - this.separator = fileSystem.getSeparator(); - this.isCaseSensitive = isCaseSensitive(fileSystem); + FSInfoData(final FileSystem fileSystem) { + isCaseSensitive = isCaseSensitive(fileSystem); roots = new ArrayList<>(); fileSystem.getRootDirectories().forEach(r -> roots.add(r.toString())); + separator = fileSystem.getSeparator(); } /** @@ -375,26 +370,72 @@ public class DocumentName implements Comparable<DocumentName> { return isCaseSensitive; } + } + /** + * The file system information needed to process document names. + */ + public static final class FSInfo implements Comparable<FSInfo> { /** - * Gets the common name for the underlying file system. - * @return the common file system name. + * The map of FileSystem to FSInfoData used to avoid expensive FileSystem processing. */ - @Override - public String toString() { - return name; + private static final Map<FileSystem, FSInfoData> REGISTRY = new ConcurrentHashMap<>(); + + /** The case-sensitivity flag. */ + private final FSInfoData data; + + /** The common name for the file system */ + private final String name; + + /** + * Gets the FSInfo for the default file system. + * If the System property {@code FSInfo} is set, the {@code FSInfo} stored there is used, otherwise + * the {@link FileSystem} returned from {@link FileSystems#getDefault()} is used. + * @return the FSInfo for the default file system. + */ + public static FSInfo getDefault() { + FSInfo result = (FSInfo) System.getProperties().get("FSInfo"); + return result == null ? + new FSInfo(FileSystems.getDefault()) + : result; + } + + /** + * Constructor. Extracts the necessary data from the file system. + * @param fileSystem the file system to extract data from. + */ + public FSInfo(final FileSystem fileSystem) { + this("anon", fileSystem); + } + + /** + * Constructor. Extracts the necessary data from the file system. + * @param name the common name for the file system. + * @param fileSystem the file system to extract data from. + */ + FSInfo(final String name, final FileSystem fileSystem) { + this.data = REGISTRY.computeIfAbsent(fileSystem, k -> new FSInfoData(fileSystem)); + this.name = name; } /** * Constructor for virtual/abstract file systems for example the entry names within an archive. + * @param name the common name for the file system. * @param separator the separator string to use. * @param isCaseSensitive the case-sensitivity flag. * @param roots the roots for the file system. */ FSInfo(final String name, final String separator, final boolean isCaseSensitive, final List<String> roots) { + data = new FSInfoData(separator, isCaseSensitive, roots); this.name = name; - this.separator = separator; - this.isCaseSensitive = isCaseSensitive; - this.roots = new ArrayList<>(roots); + } + + /** + * Gets the common name for the underlying file system. + * @return the common file system name. + */ + @Override + public String toString() { + return name; } /** @@ -402,7 +443,7 @@ public class DocumentName implements Comparable<DocumentName> { * @return The directory separator. */ public String dirSeparator() { - return separator; + return data.separator; } /** @@ -410,7 +451,7 @@ public class DocumentName implements Comparable<DocumentName> { * @return the case-sensitivity flag. */ public boolean isCaseSensitive() { - return isCaseSensitive; + return data.isCaseSensitive; } /** @@ -419,7 +460,7 @@ public class DocumentName implements Comparable<DocumentName> { * @return an optional containing the root or empty. */ public Optional<String> rootFor(final String name) { - for (String sysRoot : roots) { + for (String sysRoot : data.roots) { if (name.startsWith(sysRoot)) { return Optional.of(sysRoot); }
