From 9f82d3d5db8fd1640cbbf991c32077c3f396c9a6 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Sun, 12 Jan 2025 16:01:43 +0000
Subject: [PATCH 01/17] Added FSInfo to handle file system differences
---
apache-rat-core/pom.xml | 5 +
.../it/java/org/apache/rat/ReportTest.java | 2 +-
.../rat/config/exclusion/ExclusionUtils.java | 14 +
.../apache/rat/document/ArchiveEntryName.java | 74 +++
.../org/apache/rat/document/DocumentName.java | 553 ++++++++++++------
.../org/apache/rat/walker/ArchiveWalker.java | 15 +-
.../org/apache/rat/OptionCollectionTest.java | 12 +-
.../rat/analysis/AnalyserFactoryTest.java | 4 +-
.../config/exclusion/FileProcessorTest.java | 3 +-
.../apache/rat/document/DocumentNameTest.java | 325 +++++++---
.../org/apache/rat/document/FSInfoTest.java | 60 ++
.../rat/document/guesser/NoteGuesserTest.java | 7 +-
.../rat/testhelpers/TestingDocument.java | 4 +-
pom.xml | 10 +-
14 files changed, 798 insertions(+), 290 deletions(-)
create mode 100644 apache-rat-core/src/main/java/org/apache/rat/document/ArchiveEntryName.java
create mode 100644 apache-rat-core/src/test/java/org/apache/rat/document/FSInfoTest.java
diff --git a/apache-rat-core/pom.xml b/apache-rat-core/pom.xml
index 8ac00d1e3..844a7efc5 100644
--- a/apache-rat-core/pom.xml
+++ b/apache-rat-core/pom.xml
@@ -281,5 +281,10 @@
groovy-all
test
+
+ com.google.jimfs
+ jimfs
+ test
+
diff --git a/apache-rat-core/src/it/java/org/apache/rat/ReportTest.java b/apache-rat-core/src/it/java/org/apache/rat/ReportTest.java
index b58c6732b..16bc908bc 100644
--- a/apache-rat-core/src/it/java/org/apache/rat/ReportTest.java
+++ b/apache-rat-core/src/it/java/org/apache/rat/ReportTest.java
@@ -163,7 +163,7 @@ public static Stream args() throws RatException {
@Override
public void report(Document document) {
if (!document.isIgnored()) {
- String[] tokens = document.getName().tokenize(document.getName().localized());
+ String[] tokens = DocumentName.FSInfo.getDefault().tokenize(document.getName().localized());
results.add(Arguments.of(tokens[1], document));
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionUtils.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionUtils.java
index 339ce0978..3f082336a 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionUtils.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionUtils.java
@@ -185,4 +185,18 @@ private static void verifyFile(final File file) {
throw new ConfigurationException(format("%s is not a valid file.", file));
}
}
+
+ /**
+ * Tokenizes the string based on the directory separator.
+ * @param source the source to tokenize
+ * @param from the directory separator for the source.
+ * @param to the directory separator for the result.
+ * @return the source string with the separators converted.
+ */
+ public static String convertSeparator(final String source, final String from, final String to) {
+ if (StringUtils.isEmpty(source) || from.equals(to)) {
+ return source;
+ }
+ return String.join(to, source.split("\\Q" + from + "\\E"));
+ }
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/ArchiveEntryName.java b/apache-rat-core/src/main/java/org/apache/rat/document/ArchiveEntryName.java
new file mode 100644
index 000000000..889a7b165
--- /dev/null
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/ArchiveEntryName.java
@@ -0,0 +1,74 @@
+/*
+ * 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.rat.document;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+
+public class ArchiveEntryName extends DocumentName {
+ /** Then name of the document that contains this entry */
+ private final DocumentName archiveFileName;
+
+ private static DocumentName.Builder prepareBuilder(final DocumentName archiveFileName, final String archiveEntryName) {
+ String root = archiveFileName.getName() + "#";
+ FSInfo fsInfo = new FSInfo("archiveEntry", "/", true, Collections.singletonList(root));
+ return DocumentName.builder(fsInfo)
+ .setRoot(root)
+ .setBaseName(root + "/")
+ .setName(archiveEntryName);
+ }
+ public ArchiveEntryName(final DocumentName archiveFileName, final String archiveEntryName) {
+ super(prepareBuilder(archiveFileName, archiveEntryName));
+ this.archiveFileName = archiveFileName;
+ }
+
+ @Override
+ public File asFile() {
+ return archiveFileName.asFile();
+ }
+
+ @Override
+ public Path asPath() {
+ return Paths.get(archiveFileName.asPath().toString(), "#", super.asPath().toString());
+ }
+
+ @Override
+ public DocumentName resolve(final String child) {
+ return new ArchiveEntryName(this.archiveFileName, super.resolve(child).localized());
+ }
+
+ @Override
+ public String getBaseName() {
+ return archiveFileName.getName() + "#";
+ }
+
+ @Override
+ boolean startsWithRootOrSeparator(final String candidate, final String root, final String separator) {
+ return super.startsWithRootOrSeparator(candidate, root, separator);
+ }
+
+ @Override
+ public String localized(final String dirSeparator) {
+ String superLocal = super.localized(dirSeparator);
+ superLocal = superLocal.substring(superLocal.lastIndexOf("#") + 1);
+ return archiveFileName.localized(dirSeparator) + "#" + superLocal;
+ }
+}
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 e71bed85b..9b0c6a0d9 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
@@ -20,19 +20,24 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
+import java.util.Optional;
+import java.util.stream.Collectors;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.CompareToBuilder;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
-import org.apache.rat.utils.DefaultLog;
/**
* The name for a document. The {@code DocumentName} is an immutable structure that handles all the intricacies of file
@@ -51,66 +56,85 @@
* within an archive. When representing a file in an archive the baseName is the name of the enclosing archive document.
*
*/
-public final class DocumentName implements Comparable {
- /** The list of all roots on the file system. */
- static final Set ROOTS = new HashSet<>();
- /** {@code True} if the file system on which we are operating is case-sensitive. */
- public static final boolean FS_IS_CASE_SENSITIVE;
+public class DocumentName implements Comparable {
/** The full name for the document. */
private final String name;
/** The name of the base directory for the document. */
- private final String baseName;
- /** The directory separator for this document. */
- private final String dirSeparator;
- /** The case-sensitive flag */
- private final boolean isCaseSensitive;
+ //private final String baseName;
+ private final DocumentName baseName;
+ /** The file system info for this document. */
+ private final FSInfo fsInfo;
/** The root for the DocumentName. May be empty but not null. */
private final String root;
- // determine the case sensitivity of the file system we are operating on.
- static {
- boolean fsSensitive = true;
- File f = null;
+ /**
+ * Determines if the file system is case-sensitive.
+ * @param fileSystem the file system to check
+ * @return {@code true} if the file system is case-sensitive.
+ */
+ private static boolean isCaseSensitive(final FileSystem fileSystem) {
+ boolean isCaseSensitive = false;
+ Path nameSet = null;
+ Path filea = null;
+ Path fileA = null;
try {
- Path p = Files.createTempDirectory("NameSet");
- f = p.toFile();
- fsSensitive = !new File(f, "a").equals(new File(f, "A"));
- } catch (IOException e) {
- fsSensitive = true;
- } finally {
- if (f != null) {
- try {
- FileUtils.deleteDirectory(f);
- } catch (IOException e) {
- DefaultLog.getInstance().warn("Unable to delete temporary directory: " + f, e);
+ try {
+ Path root = fileSystem.getPath("");
+ nameSet = Files.createTempDirectory(root, "NameSet");
+ filea = nameSet.resolve("a");
+ fileA = nameSet.resolve("A");
+ Files.createFile(filea);
+ Files.createFile(fileA);
+ isCaseSensitive = true;
+ } catch (IOException e) {
+ // do nothing
+ } finally {
+ if (filea != null) {
+ Files.deleteIfExists(filea);
+ }
+ if (fileA != null) {
+ Files.deleteIfExists(fileA);
+ }
+ if (nameSet != null) {
+ Files.deleteIfExists(nameSet);
}
}
+ } catch (IOException e) {
+ // do nothing.
}
- FS_IS_CASE_SENSITIVE = fsSensitive;
-
- // determine all the roots on the file system(s).
- File[] roots = File.listRoots();
- if (roots != null) {
- for (File root : roots) {
- String name = root.getPath();
- ROOTS.add(name);
- }
- }
-
+ return isCaseSensitive;
}
/**
- * Creates a Builder with directory separator and case sensitivity based on the local file system.
+ * Creates a Builder with the default File system info.
* @return the Builder.
+ * @see FSInfo
*/
public static Builder builder() {
- return new Builder();
+ return new Builder(FSInfo.getDefault());
+ }
+
+ /**
+ * Creates a builder with the specified FSInfo instance.
+ * @param fsInfo the FSInfo to use for the builder.
+ * @return a new builder.
+ */
+ public static Builder builder(final FSInfo fsInfo) {
+ return new Builder(fsInfo);
+ }
+
+ /**
+ * Creates a builder for the specified file system.
+ * @param fileSystem the file system to create ethe builder on.
+ * @return a new builder.
+ */
+ public static Builder builder(final FileSystem fileSystem) {
+ return new Builder(fileSystem);
}
/**
* Creates a builder from a File. The {@link #baseName} is set to the file name if it is a directory otherwise
- * it is set to the directory containing the file. The {@link #dirSeparator} is set from the file and
- * case sensitivity based on the local file system.
+ * it is set to the directory containing the file.
* @param file The file to set defaults from.
* @return the Builder.
*/
@@ -131,26 +155,49 @@ public static Builder builder(final DocumentName documentName) {
* Builds the DocumentName from the builder.
* @param builder the builder to provide the values.
*/
- private DocumentName(final Builder builder) {
+ DocumentName(final Builder builder) {
this.name = builder.name;
- this.baseName = builder.baseName;
- this.dirSeparator = builder.dirSeparator;
- this.isCaseSensitive = builder.isCaseSensitive;
+ this.fsInfo = builder.fsInfo;
this.root = builder.root;
+ this.baseName = builder.sameNameFlag ? this : builder.baseName;
+ }
+
+ /**
+ * Creates a file from the document name.
+ * @return a new File object.
+ */
+ public File asFile() {
+ return new File(getName());
+ }
+
+ /**
+ * Creates a path from the document name.
+ * @return an new Path object.
+ */
+ public Path asPath() {
+ return Paths.get(name);
}
/**
- * Creates a new DocumentName by adding the child to the current name.
+ * Creates a new DocumentName by adding the child to the current name. Resulting documentName will
+ * have the same base name.
* @param child the child to add (must use directory separator from this document name).
- * @return the new document name with the same {@link #baseName}, {@link #dirSeparator} and case sensitivity as
+ * @return the new document name with the same {@link #baseName}, directory sensitivity and case sensitivity as
* this one.
*/
public DocumentName resolve(final String child) {
- List parts = new ArrayList<>();
- parts.addAll(Arrays.asList(tokenize(name)));
- parts.addAll(Arrays.asList(tokenize(child)));
- String newName = String.join(dirSeparator, parts);
- return new Builder(this).setName(newName).build();
+ if (StringUtils.isBlank(child)) {
+ return this;
+ }
+ String separator = fsInfo.dirSeparator();
+ String pattern = separator.equals("/") ? child.replace('\\', '/') :
+ child.replace('/', '\\');
+
+ if (!pattern.startsWith(separator)) {
+ pattern = name + separator + pattern;
+ }
+
+ return new Builder(this).setName(pattern).build();
}
/**
@@ -158,7 +205,7 @@ public DocumentName resolve(final String child) {
* @return the fully qualified name of the document.
*/
public String getName() {
- return root + dirSeparator + name;
+ return root + fsInfo.dirSeparator() + name;
}
/**
@@ -166,7 +213,7 @@ public String getName() {
* @return the fully qualified basename of the document.
*/
public String getBaseName() {
- return root + dirSeparator + baseName;
+ return baseName.getName();
}
/**
@@ -182,7 +229,7 @@ public String getRoot() {
* @return the DocumentName for the basename of this document name.
*/
public DocumentName getBaseDocumentName() {
- return name.equals(baseName) ? this : builder(this).setName(baseName).build();
+ return baseName;
}
/**
@@ -190,7 +237,25 @@ public DocumentName getBaseDocumentName() {
* @return the directory separator.
*/
public String getDirectorySeparator() {
- return dirSeparator;
+ return fsInfo.dirSeparator();
+ }
+
+ /**
+ * Determines if the candidate starts with the root or separator strings.
+ * @param candidate the candidate ot check. If blank method will return false.
+ * @param root the root to check. If blank the root check is skipped.
+ * @param separator the separator to check. If blank the check is skipped.
+ * @return true if either the root or separator check returned true.
+ */
+ boolean startsWithRootOrSeparator(final String candidate, final String root, final String separator) {
+ if (StringUtils.isBlank(candidate)) {
+ return false;
+ }
+ boolean result = !StringUtils.isBlank(root) && candidate.startsWith(root);
+ if (!result) {
+ result = !StringUtils.isBlank(separator) && candidate.startsWith(separator);
+ }
+ return result;
}
/**
@@ -199,12 +264,13 @@ public String getDirectorySeparator() {
* @return the portion of the name that is not part of the base name.
*/
public String localized() {
- String result = name;
- if (result.startsWith(baseName)) {
- result = result.substring(baseName.length());
+ String result = getName();
+ String baseNameStr = baseName.getName();
+ if (result.startsWith(baseNameStr)) {
+ result = result.substring(baseNameStr.length());
}
- if (!result.startsWith(dirSeparator)) {
- result = dirSeparator + result;
+ if (!startsWithRootOrSeparator(result, getRoot(), fsInfo.dirSeparator())) {
+ result = fsInfo.dirSeparator() + result;
}
return result;
}
@@ -216,24 +282,26 @@ public String localized() {
* @return the portion of the name that is not part of the base name.
*/
public String localized(final String dirSeparator) {
- return String.join(dirSeparator, tokenize(localized()));
- }
+ String[] tokens = fsInfo.tokenize(localized());
+ if (tokens.length == 0) {
+ return dirSeparator;
+ }
+ if (tokens.length == 1) {
+ return dirSeparator + tokens[0];
+ }
- /**
- * Tokenizes the string based on the {@link #dirSeparator} of this DocumentName.
- * @param source the source to tokenize
- * @return the array of tokenized strings.
- */
- public String[] tokenize(final String source) {
- return source.split("\\Q" + dirSeparator + "\\E");
+ String modifiedRoot = dirSeparator.equals("/") ? root.replace('\\', '/') :
+ root.replace('/', '\\');
+ String result = String.join(dirSeparator, tokens);
+ return startsWithRootOrSeparator(result, modifiedRoot, dirSeparator) ? result : dirSeparator + result;
}
/**
- * Gets the last segment of the name. This is the part after the last {@link #dirSeparator}..
+ * Gets the last segment of the name. This is the part after the last directory separator.
* @return the last segment of the name.
*/
public String getShortName() {
- int pos = name.lastIndexOf(dirSeparator);
+ int pos = name.lastIndexOf(fsInfo.dirSeparator());
return pos == -1 ? name : name.substring(pos + 1);
}
@@ -242,7 +310,7 @@ public String getShortName() {
* @return {@code true} if the name is case-sensitive.
*/
public boolean isCaseSensitive() {
- return isCaseSensitive;
+ return fsInfo.isCaseSensitive();
}
/**
@@ -255,28 +323,158 @@ public String toString() {
}
@Override
- public int compareTo(final DocumentName o) {
- return FS_IS_CASE_SENSITIVE ? name.compareTo(o.name) : name.compareToIgnoreCase(o.name);
+ public int compareTo(final DocumentName other) {
+ return CompareToBuilder.reflectionCompare(this, other);
}
@Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- DocumentName that = (DocumentName) o;
- if (isCaseSensitive() == that.isCaseSensitive() && Objects.equals(dirSeparator, that.dirSeparator)) {
- return isCaseSensitive ? name.equalsIgnoreCase(that.name) : name.equals(that.name);
- }
- return false;
+ public boolean equals(final Object other) {
+ return EqualsBuilder.reflectionEquals(this, other);
}
@Override
public int hashCode() {
- return Objects.hash(name, dirSeparator, isCaseSensitive());
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ /**
+ * The File system information needed to process document names.
+ */
+ public static class FSInfo implements Comparable {
+ /** 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 final boolean isCaseSensitive;
+ /** The list of roots for the file system */
+ private final List roots;
+
+ 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.
+ */
+ public FSInfo(final FileSystem fileSystem) {
+ this("anon", fileSystem);
+ }
+
+ /**
+ * Constructor. Extracts the necessary data from the file system.
+ * @param fileSystem the file system to extract data from.
+ */
+ public FSInfo(final String name, final FileSystem fileSystem) {
+ this.name = name;
+ this.separator = fileSystem.getSeparator();
+ this.isCaseSensitive = DocumentName.isCaseSensitive(fileSystem);
+ roots = new ArrayList<>();
+ fileSystem.getRootDirectories().forEach(r -> roots.add(r.toString()));
+ }
+
+ /**
+ * Gets the common name for the underlying file system.
+ * @return the common file system name.
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+ /**
+ * Constructor for virtual/abstract file systems for example the entry names within an an archive.
+ * @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 roots) {
+ this.name = name;
+ this.separator = separator;
+ this.isCaseSensitive = isCaseSensitive;
+ this.roots = new ArrayList<>(roots);
+ }
+
+ /**
+ * Gets the directory separator.
+ * @return The directory separator.
+ */
+ public String dirSeparator() {
+ return separator;
+ }
+
+ /**
+ * Gets the case-sensitivity flag.
+ * @return the case-sensitivity flag.
+ */
+ public boolean isCaseSensitive() {
+ return isCaseSensitive;
+ }
+
+ /**
+ * Retrieves the root extracted from the name.
+ * @param name the name to extract the root from
+ * @return an optional containing the root or empty.
+ */
+ public Optional rootFor(final String name) {
+ for (String sysRoot : roots) {
+ if (name.startsWith(sysRoot)) {
+ return Optional.of(sysRoot);
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Tokenizes the string based on the directory separator of this DocumentName.
+ * @param source the source to tokenize
+ * @return the array of tokenized strings.
+ */
+ public String[] tokenize(final String source) {
+ return source.split("\\Q" + dirSeparator() + "\\E");
+ }
+
+ /**
+ * Removes "." and ".." from filenames names.
+ * @param pattern the file name pattern
+ * @return the normalized file name.
+ */
+ public String normalize(final String pattern) {
+ if (StringUtils.isBlank(pattern)) {
+ return "";
+ }
+ List parts = new ArrayList<>(Arrays.asList(tokenize(pattern)));
+ for (int i = 0; i < parts.size(); i++) {
+ String part = parts.get(i);
+ if (part.equals("..")) {
+ if (i == 0) {
+ throw new IllegalStateException("can not creat path before root");
+ }
+ parts.set(i - 1, null);
+ parts.set(i, null);
+ } else if (part.equals(".")) {
+ parts.set(i, null);
+ }
+ }
+ return parts.stream().filter(Objects::nonNull).collect(Collectors.joining(dirSeparator()));
+ }
+
+ @Override
+ public int compareTo(final FSInfo other) {
+ return CompareToBuilder.reflectionCompare(this, other);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ return EqualsBuilder.reflectionEquals(this, other);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
}
/**
@@ -286,44 +484,65 @@ public static final class Builder {
/** The name for the document */
private String name;
/** The base name for the document */
- private String baseName;
- /** The directory separator */
- private String dirSeparator;
- /** The case sensitivity flag */
- private boolean isCaseSensitive;
+ private DocumentName baseName;
+ /** The file system info */
+ private final FSInfo fsInfo;
/** The file system root */
private String root;
+ /** A flag for baseName same as this */
+ private boolean sameNameFlag;
/**
* Create with default settings.
*/
- private Builder() {
- isCaseSensitive = FS_IS_CASE_SENSITIVE;
- dirSeparator = File.separator;
+ private Builder(final FSInfo fsInfo) {
+ this.fsInfo = fsInfo;
root = "";
}
+ /**
+ * Create with default settings.
+ */
+ private Builder(final FileSystem fileSystem) {
+ this(new FSInfo(fileSystem));
+ }
+
/**
* Create based on the file provided.
* @param file the file to base the builder on.
*/
private Builder(final File file) {
- this();
+ this(FSInfo.getDefault());
+ setName(file);
+ }
+
+ /**
+ * Used in testing
+ * @param fsInfo the FSInfo for the file.
+ * @param file the file to process
+ */
+ Builder(final FSInfo fsInfo, final File file) {
+ this(fsInfo);
setName(file);
- isCaseSensitive = FS_IS_CASE_SENSITIVE;
- dirSeparator = File.separator;
}
/**
* Create a Builder that clones the specified DocumentName.
* @param documentName the DocumentName to clone.
*/
- private Builder(final DocumentName documentName) {
+ Builder(final DocumentName documentName) {
this.root = documentName.root;
this.name = documentName.name;
this.baseName = documentName.baseName;
- this.isCaseSensitive = documentName.isCaseSensitive;
- this.dirSeparator = documentName.dirSeparator;
+ this.fsInfo = documentName.fsInfo;
+ }
+
+ /**
+ * Get the directory separator for this builder.
+ * @return the directory separator fo this builder.
+ */
+ public String directorySeparator() {
+ return fsInfo.dirSeparator();
}
/**
@@ -331,12 +550,11 @@ private Builder(final DocumentName documentName) {
*/
private void verify() {
Objects.requireNonNull(name, "Name cannot be null");
- Objects.requireNonNull(baseName, "Basename cannot be null");
- if (name.startsWith(dirSeparator)) {
- name = name.substring(dirSeparator.length());
+ if (name.startsWith(fsInfo.dirSeparator())) {
+ name = name.substring(fsInfo.dirSeparator().length());
}
- if (baseName.startsWith(dirSeparator)) {
- baseName = baseName.substring(dirSeparator.length());
+ if (!sameNameFlag) {
+ Objects.requireNonNull(baseName, "Basename cannot be null");
}
}
@@ -346,58 +564,54 @@ private void verify() {
* @return this.
*/
public Builder setRoot(final String root) {
- this.root = root;
+ this.root = StringUtils.defaultIfBlank(root, "");
return this;
}
/**
- * Sets the name for this DocumentName. Will reset the root to the empty string.
+ * Sets the name for this DocumentName relative to the baseName. If the {@code name} is null
+ * an empty string is used.
*
- * To correctly parse the string it must either be the directory separator specified by
- * {@link File#separator} or must have been explicitly set by calling {@link #setDirSeparator(String)}
- * before making this call.
+ * To correctly parse the string it must use the directory separator specified by
+ * this Document.
*
- * @param name the name for this Document name.
+ * @param name the name for this Document name. Will be made relative to the baseName
* @return this
*/
public Builder setName(final String name) {
- Pair pair = splitRoot(name, dirSeparator);
+ Pair pair = splitRoot(StringUtils.defaultIfBlank(name, ""));
if (this.root.isEmpty()) {
this.root = pair.getLeft();
}
- this.name = pair.getRight();
+ this.name = fsInfo.normalize(pair.getRight());
+ if (this.baseName != null && !baseName.name.isEmpty()) {
+ if (!this.name.startsWith(baseName.name)) {
+ this.name = this.name.isEmpty() ? baseName.name :
+ baseName.name + fsInfo.dirSeparator() + this.name;
+ }
+ }
return this;
}
- /**
- * Extracts the root/name pair from a file.
- * @param file the file to extract the root/name pair from.
- * @return the root/name pair.
- */
- static Pair splitRoot(final File file) {
- return splitRoot(file.getAbsolutePath(), File.separator);
- }
-
/**
* Extracts the root/name pair from a name string.
*
* Package private for testing.
*
* @param name the name to extract the root/name pair from.
- * @param dirSeparator the directory separator.
* @return the root/name pair.
*/
- static Pair splitRoot(final String name, final String dirSeparator) {
+ Pair splitRoot(final String name) {
String workingName = name;
- String root = "";
- for (String sysRoot : ROOTS) {
- if (workingName.startsWith(sysRoot)) {
- workingName = workingName.substring(sysRoot.length());
- if (!workingName.startsWith(dirSeparator)) {
- if (sysRoot.endsWith(dirSeparator)) {
- root = sysRoot.substring(0, sysRoot.length() - dirSeparator.length());
+ Optional maybeRoot = fsInfo.rootFor(name);
+ String root = maybeRoot.orElse("");
+ if (!root.isEmpty()) {
+ if (workingName.startsWith(root)) {
+ workingName = workingName.substring(root.length());
+ if (!workingName.startsWith(fsInfo.dirSeparator())) {
+ if (root.endsWith(fsInfo.dirSeparator())) {
+ root = root.substring(0, root.length() - fsInfo.dirSeparator().length());
}
- return ImmutablePair.of(root, workingName);
}
}
}
@@ -415,21 +629,24 @@ private void setEmptyRoot(final String root) {
}
/**
- * Sets the properties from the file. This method sets the {@link #root} if it is empty, and resets {@link #name},
- * {@link #dirSeparator} and {@link #baseName}.
+ * Sets the properties from the file. Will reset the baseName appropraitly.
* @param file the file to set the properties from.
* @return this.
*/
public Builder setName(final File file) {
- Pair pair = splitRoot(file);
+ Pair pair = splitRoot(file.getAbsolutePath());
setEmptyRoot(pair.getLeft());
- this.name = pair.getRight();
- this.dirSeparator = File.separator;
- this.baseName = name;
- if (!file.isDirectory()) {
+ this.name = fsInfo.normalize(pair.getRight());
+ if (file.isDirectory()) {
+ sameNameFlag = true;
+ } else {
File p = file.getParentFile();
if (p != null) {
setBaseName(p);
+ } else {
+ Builder baseBuilder = new Builder(this.fsInfo).setName(this.directorySeparator());
+ baseBuilder.sameNameFlag = true;
+ setBaseName(baseBuilder.build());
}
}
return this;
@@ -439,17 +656,15 @@ public Builder setName(final File file) {
* Sets the baseName.
* Will set the root if it is not set.
*
- * To correctly parse the string it must either be the directory separator specified by
- * {@link File#separator} or must have been explicitly set by calling {@link #setDirSeparator(String)}
- * before making this call.
+ * To correctly parse the string it must use the directory separator specified by this builder.
*
* @param baseName the basename to use.
* @return this.
*/
public Builder setBaseName(final String baseName) {
- Pair pair = splitRoot(baseName, dirSeparator);
- setEmptyRoot(pair.getLeft());
- this.baseName = pair.getRight();
+ DocumentName.Builder builder = DocumentName.builder(fsInfo).setName(baseName);
+ builder.sameNameFlag = true;
+ setBaseName(builder);
return this;
}
@@ -460,7 +675,7 @@ public Builder setBaseName(final String baseName) {
* @return this.
*/
public Builder setBaseName(final DocumentName baseName) {
- this.baseName = baseName.getName();
+ this.baseName = baseName;
if (!baseName.getRoot().isEmpty()) {
this.root = baseName.getRoot();
}
@@ -468,36 +683,24 @@ public Builder setBaseName(final DocumentName baseName) {
}
/**
- * Sets the basename from a File. Sets {@link #root} and the {@link #baseName}
- * Will set the root.
- * @param file the file to set the base name from.
- * @return this.
+ * Executes the builder, sets the base name and clears the sameName flag.
+ * @param builder the builder for the base name.
*/
- public Builder setBaseName(final File file) {
- Pair pair = splitRoot(file);
- this.root = pair.getLeft();
- this.baseName = pair.getRight();
- return this;
+ private void setBaseName(final DocumentName.Builder builder) {
+ this.baseName = builder.build();
+ this.sameNameFlag = false;
}
/**
- * Sets the directory separator.
- * @param dirSeparator the directory separator to use.
- * @return this.
- */
- public Builder setDirSeparator(final String dirSeparator) {
- Objects.requireNonNull(dirSeparator, "Directory separator cannot be null");
- this.dirSeparator = dirSeparator;
- return this;
- }
-
- /**
- * Sets the {@link #isCaseSensitive} flag.
- * @param isCaseSensitive the expected state of the flag.
+ * Sets the basename from a File. Sets {@link #root} and the {@link #baseName}
+ * Will set the root.
+ * @param file the file to set the base name from.
* @return this.
*/
- public Builder setCaseSensitive(final boolean isCaseSensitive) {
- this.isCaseSensitive = isCaseSensitive;
+ public Builder setBaseName(final File file) {
+ DocumentName.Builder builder = DocumentName.builder(fsInfo).setName(file);
+ builder.sameNameFlag = true;
+ setBaseName(builder);
return this;
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
index d9148701e..e2cc470e6 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
@@ -35,6 +35,7 @@
import org.apache.rat.api.Document;
import org.apache.rat.api.RatException;
import org.apache.rat.document.ArchiveEntryDocument;
+import org.apache.rat.document.ArchiveEntryName;
import org.apache.rat.document.DocumentName;
import org.apache.rat.report.RatReport;
import org.apache.rat.utils.DefaultLog;
@@ -82,20 +83,18 @@ private InputStream createInputStream() throws IOException {
*/
public Collection getDocuments() throws RatException {
List result = new ArrayList<>();
+ //DocumentName.FSInfo archiveInfo = new DocumentName.FSInfo(true, Arrays.asList("/"), "/");
try (ArchiveInputStream extends ArchiveEntry> input = new ArchiveStreamFactory().createArchiveInputStream(createInputStream())) {
- ArchiveEntry entry = null;
+ ArchiveEntry entry;
while ((entry = input.getNextEntry()) != null) {
if (!entry.isDirectory() && input.canReadEntryData(entry)) {
- DocumentName innerName = DocumentName.builder().setDirSeparator("/").setName(entry.getName())
- .setBaseName(".").setCaseSensitive(true).build();
+ DocumentName innerName = DocumentName.builder().setName(entry.getName())
+ .setBaseName(".").build();
if (this.getDocument().getNameExcluder().matches(innerName)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(input, baos);
- DocumentName archiveName = getDocument().getName();
- String outerNameStr = format("%s#%s", archiveName.getName(), entry.getName());
- DocumentName outerName = DocumentName.builder(archiveName).setName(outerNameStr)
- .setCaseSensitive(true).build();
- result.add(new ArchiveEntryDocument(outerName, baos.toByteArray(), getDocument().getNameExcluder()));
+ ArchiveEntryName entryName = new ArchiveEntryName(getDocument().getName(), entry.getName());
+ result.add(new ArchiveEntryDocument(entryName, baos.toByteArray(), getDocument().getNameExcluder()));
}
}
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/OptionCollectionTest.java b/apache-rat-core/src/test/java/org/apache/rat/OptionCollectionTest.java
index ab1ce763a..38712c9bf 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/OptionCollectionTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/OptionCollectionTest.java
@@ -18,11 +18,13 @@
*/
package org.apache.rat;
+import java.nio.file.Path;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.rat.document.DocumentName;
import org.apache.rat.license.LicenseSetFactory;
import org.apache.rat.report.IReportable;
import org.apache.rat.test.AbstractOptionsProvider;
@@ -46,6 +48,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import static java.lang.String.format;
+
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -148,11 +151,12 @@ public void testDefaultConfiguration() throws ParseException {
@ParameterizedTest
@ValueSource(strings = { ".", "./", "target", "./target" })
public void getReportableTest(String fName) throws IOException {
- File expected = new File(fName);
+ File base = new File(fName);
+ String expected = DocumentName.FSInfo.getDefault().normalize(base.getAbsolutePath());
ReportConfiguration config = OptionCollection.parseCommands(new String[]{fName}, o -> fail("Help called"), false);
- IReportable reportable = OptionCollection.getReportable(expected, config);
- assertNotNull(reportable, () -> format("'%s' returned null", fName));
- assertThat(reportable.getName().getName()).isEqualTo(expected.getAbsolutePath());
+ IReportable reportable = OptionCollection.getReportable(base, config);
+ assertThat(reportable).as(() -> format("'%s' returned null", fName)).isNotNull();
+ assertThat(reportable.getName().getName()).isEqualTo(expected);
}
/**
diff --git a/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java b/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java
index 4e2461ce6..72ebff4be 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/analysis/AnalyserFactoryTest.java
@@ -114,8 +114,8 @@ public void archiveTypeAnalyserTest() throws Exception {
private static Stream archiveProcessingTestData() {
List lst = new ArrayList<>();
lst.add(Arguments.of(ReportConfiguration.Processing.NOTIFICATION, 0));
- lst.add(Arguments.of(ReportConfiguration.Processing.PRESENCE, 2));
- lst.add(Arguments.of(ReportConfiguration.Processing.ABSENCE, 3));
+ lst.add(Arguments.of(ReportConfiguration.Processing.PRESENCE, 1));
+ lst.add(Arguments.of(ReportConfiguration.Processing.ABSENCE, 2));
return lst.stream();
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/FileProcessorTest.java b/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/FileProcessorTest.java
index 0519cee82..922912674 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/FileProcessorTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/FileProcessorTest.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.stream.Stream;
import org.apache.rat.document.DocumentName;
+import org.apache.rat.document.FSInfoTest;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -40,7 +41,7 @@ void localizePatternTest(DocumentName baseName, String pattern, String expectedS
public static Stream localizePatternData() {
List lst = new ArrayList<>();
- DocumentName baseName = DocumentName.builder().setName("fileBeingRead").setBaseName("baseDir").setDirSeparator("/").build();
+ DocumentName baseName = DocumentName.builder(FSInfoTest.UNIX).setName("fileBeingRead").setBaseName("baseDir").build();
lst.add(Arguments.of(baseName, "file", "/baseDir/file"));
lst.add(Arguments.of(baseName, "!file", "!/baseDir/file"));
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/DocumentNameTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/DocumentNameTest.java
index def6ec447..31693e030 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/DocumentNameTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/DocumentNameTest.java
@@ -18,43 +18,217 @@
*/
package org.apache.rat.document;
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.rat.config.exclusion.ExclusionUtils;
+import org.apache.rat.document.DocumentName.FSInfo;
+
import org.assertj.core.util.Files;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.Mockito;
-import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.apache.rat.document.FSInfoTest.OSX;
+import static org.apache.rat.document.FSInfoTest.UNIX;
+import static org.apache.rat.document.FSInfoTest.WINDOWS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.any;
public class DocumentNameTest {
+ public static DocumentName mkName(Path tempDir, FSInfo fsInfo) throws IOException {
+ File docFile = mkFile(tempDir.toFile(), fsInfo);
+ DocumentName result = DocumentName.builder(fsInfo).setName(docFile).build();
+ DocumentName mocked = Mockito.spy(result);
+
+ String fn = result.localized(FileSystems.getDefault().getSeparator());
+ File file = tempDir.resolve(fn.substring(1)).toFile();
+ File mockedFile = mkFile(file, fsInfo);
+ when(mocked.asFile()).thenReturn(mockedFile);
+
+ assertThat(mocked.asFile()).isEqualTo(mockedFile);
+ return mocked;
+ }
+
+ private static File[] listFiles(File file, FSInfo fsInfo) {
+ File[] fileList = file.listFiles();
+ if (fileList == null) {
+ return fileList;
+ }
+ return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).toArray(File[]::new);
+ }
+
+ private static File[] listFiles(File file, FSInfo fsInfo, FileFilter filter) {
+ File[] fileList = file.listFiles();
+ if (fileList == null) {
+ return fileList;
+ }
+ return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).filter(filter::accept).toArray(File[]::new);
+ }
+
+ private static File[] listFiles(File file, FSInfo fsInfo, FilenameFilter filter) {
+ File[] fileList = file.listFiles();
+ if (fileList == null) {
+ return fileList;
+ }
+ return Arrays.stream(fileList).map(f -> mkFile(f, fsInfo)).filter(x -> filter.accept(x, x.getName())).toArray(File[]::new);
+ }
+
+ public static File mkFile(final File file, final FSInfo fsInfo) {
+ File mockedFile = mock(File.class);
+ when(mockedFile.listFiles()).thenAnswer( env -> listFiles(file, fsInfo));
+ when(mockedFile.listFiles(any(FilenameFilter.class))).thenAnswer( env -> listFiles(file, fsInfo, env.getArgument(0, FilenameFilter.class)));
+ when(mockedFile.listFiles(any(FileFilter.class))).thenAnswer(env -> listFiles(file, fsInfo, env.getArgument(0, FileFilter.class)));
+ when(mockedFile.getName()).thenReturn(ExclusionUtils.convertSeparator(file.getName(), FSInfoTest.DEFAULT.dirSeparator(), fsInfo.dirSeparator()));
+ when(mockedFile.getAbsolutePath()).thenReturn(ExclusionUtils.convertSeparator(file.getAbsolutePath(), FSInfoTest.DEFAULT.dirSeparator(), fsInfo.dirSeparator()));
+ when(mockedFile.isFile()).thenAnswer(env -> file.isFile());
+ when(mockedFile.exists()).thenAnswer(emv -> file.exists());
+ when(mockedFile.isDirectory()).thenAnswer(env -> file.isDirectory());
+
+ return mockedFile;
+ }
+
+ public static DocumentName mkName(Path tempDir, DocumentName baseDir, String pth) throws IOException {
+ DocumentName result = baseDir.resolve(ExclusionUtils.convertSeparator(pth, "/", baseDir.getDirectorySeparator()));
+ DocumentName mocked = Mockito.spy(result);
+
+ String fn = result.localized(FileSystems.getDefault().getSeparator());
+ File file = tempDir.resolve(fn.substring(1)).toFile();
+ File parent = file.getParentFile();
+ if (parent.exists() && !parent.isDirectory()) {
+ parent.delete();
+ }
+ parent.mkdirs();
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ FileUtils.deleteDirectory(file);
+ } else {
+ FileUtils.delete(file);
+ }
+ }
+ file.createNewFile();
+ when(mocked.asFile()).thenReturn(file);
+ return mocked;
+ }
+
+
+ @ParameterizedTest(name = "{index} {0} {2}")
+ @MethodSource("resolveTestData")
+ void resolveTest(String testName, DocumentName base, String toResolve, DocumentName expected) {
+ DocumentName actual = base.resolve(toResolve);
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ private static Stream resolveTestData() {
+ List lst = new ArrayList<>();
+
+ DocumentName base = DocumentName.builder(UNIX).setName("/dir/unix").setBaseName("/").build();
+
+ DocumentName expected = DocumentName.builder(UNIX).setName("/dir/unix/relative").setBaseName("/").build();
+ lst.add(Arguments.of("unix", base, "relative", expected));
+
+ expected = DocumentName.builder(UNIX).setName("/from/root").setBaseName("/").build();
+ lst.add(Arguments.of("unix", base, "/from/root", expected));
+
+ expected = DocumentName.builder(UNIX).setName("dir/up/and/down").setBaseName("/").build();
+ lst.add(Arguments.of("unix", base, "../up/and/down", expected));
+
+ expected = DocumentName.builder(UNIX).setName("/from/root").setBaseName("/").build();
+ lst.add(Arguments.of("unix", base, "\\from\\root", expected));
+
+ expected = DocumentName.builder(UNIX).setName("dir/up/and/down").setBaseName("/").build();
+ lst.add(Arguments.of("unix", base, "..\\up\\and\\down", expected));
+
+ // WINDOWS
+ base = DocumentName.builder(WINDOWS).setName("\\dir\\windows").setBaseName("C:\\").build();
+
+ expected = DocumentName.builder(WINDOWS).setName("\\dir\\windows\\relative").setBaseName("C:\\").build();
+ lst.add(Arguments.of("windows", base, "relative", expected));
+
+ expected = DocumentName.builder(WINDOWS).setName("\\from\\root").setBaseName("C:\\").build();
+ lst.add(Arguments.of("windows", base, "/from/root", expected));
+
+ expected = DocumentName.builder(WINDOWS).setName("dir\\up\\and\\down").setBaseName("C:\\").build();
+ lst.add(Arguments.of("windows", base, "../up/and/down", expected));
+
+ expected = DocumentName.builder(WINDOWS).setName("\\from\\root").setBaseName("C:\\").build();
+ lst.add(Arguments.of("windows", base, "\\from\\root", expected));
+
+ expected = DocumentName.builder(WINDOWS).setName("dir\\up\\and\\down").setBaseName("C:\\").build();
+ lst.add(Arguments.of("windows", base, "..\\up\\and\\down", expected));
+
+ // OSX
+ base = DocumentName.builder(OSX).setName("/dir/osx").setBaseName("/").build();
+
+ expected = DocumentName.builder(OSX).setName("/dir/osx/relative").setBaseName("/").build();
+ lst.add(Arguments.of("osx", base, "relative", expected));
+
+ expected = DocumentName.builder(OSX).setName("/from/root").setBaseName("/").build();
+ lst.add(Arguments.of("osx", base, "/from/root", expected));
+
+ expected = DocumentName.builder(OSX).setName("dir/up/and/down").setBaseName("/").build();
+ lst.add(Arguments.of("osx", base, "../up/and/down", expected));
+
+ expected = DocumentName.builder(OSX).setName("/from/root").setBaseName("/").build();
+ lst.add(Arguments.of("osx", base, "\\from\\root", expected));
+
+ expected = DocumentName.builder(OSX).setName("dir/up/and/down").setBaseName("/").build();
+ lst.add(Arguments.of("osx", base, "..\\up\\and\\down", expected));
+
+ return lst.stream();
+
+ }
+
@Test
- public void localizeTest() {
- DocumentName documentName = DocumentName.builder().setName("/a/b/c")
- .setBaseName("/a").setDirSeparator("/").setCaseSensitive(false).build();
+ void localizeTest() {
+ DocumentName documentName = DocumentName.builder(UNIX).setName("/a/b/c")
+ .setBaseName("/a").build();
+ assertThat(documentName.localized()).isEqualTo("/b/c");
+ assertThat(documentName.localized("-")).isEqualTo("-b-c");
+
+ documentName = DocumentName.builder(WINDOWS).setName("\\a\\b\\c")
+ .setBaseName("\\a").build();
+ assertThat(documentName.localized()).isEqualTo("\\b\\c");
+ assertThat(documentName.localized("-")).isEqualTo("-b-c");
+
+ documentName = DocumentName.builder(OSX).setName("/a/b/c")
+ .setBaseName("/a").build();
assertThat(documentName.localized()).isEqualTo("/b/c");
assertThat(documentName.localized("-")).isEqualTo("-b-c");
+
}
- @ParameterizedTest(name ="{index} {0}")
+ @ParameterizedTest(name = "{index} {0}")
@MethodSource("validBuilderData")
void validBuilderTest(String testName, DocumentName.Builder builder, String root, String name, String baseName, String dirSeparator) {
DocumentName underTest = builder.build();
assertThat(underTest.getRoot()).as(testName).isEqualTo(root);
assertThat(underTest.getDirectorySeparator()).as(testName).isEqualTo(dirSeparator);
- assertThat(underTest.getName()).as(testName).isEqualTo(root+dirSeparator+name);
- assertThat(underTest.getBaseName()).as(testName).isEqualTo(root+dirSeparator+baseName);
+ assertThat(underTest.getName()).as(testName).isEqualTo(root + dirSeparator + name);
+ assertThat(underTest.getBaseName()).as(testName).isEqualTo(root + dirSeparator + baseName);
}
- private static Stream validBuilderData() {
+ private static Stream validBuilderData() throws IOException {
List lst = new ArrayList<>();
File f = Files.newTemporaryFile();
@@ -94,98 +268,67 @@ private static Stream validBuilderData() {
lst.add(Arguments.of("setName(root)", DocumentName.builder().setName(r), root, "", "", File.separator));
lst.add(Arguments.of("Builder(root)", DocumentName.builder(r), root, "", "", File.separator));
- lst.add(Arguments.of("foo/bar foo", DocumentName.builder().setDirSeparator("/")
+
+ lst.add(Arguments.of("foo/bar foo", DocumentName.builder(UNIX)
.setName("/foo/bar").setBaseName("foo"), "", "foo/bar", "foo", "/"));
- DocumentName.Builder builder = DocumentName.builder().setDirSeparator("\\").setName("\\foo\\bar").setBaseName("foo")
+
+ DocumentName.Builder builder = DocumentName.builder(WINDOWS).setName("\\foo\\bar").setBaseName("C:\\foo")
.setRoot("C:");
- lst.add(Arguments.of("C:\\foo\\bar foo", builder, "C:", "foo\\bar", "foo", "\\"));
+ lst.add(Arguments.of("\\foo\\bar foo", builder, "C:", "foo\\bar", "foo", "\\"));
+
+ lst.add(Arguments.of("foo/bar foo", DocumentName.builder(OSX)
+ .setName("/foo/bar").setBaseName("foo"), "", "foo/bar", "foo", "/"));
return lst.stream();
}
@Test
- public void splitRootsTest() {
- Set preserve = new HashSet<>(DocumentName.ROOTS);
- try {
- DocumentName.ROOTS.clear();
- DocumentName.ROOTS.add("C:\\");
- Pair result = DocumentName.Builder.splitRoot("C:\\My\\path\\to\\a\\file.txt", "\\");
- assertThat(result.getLeft()).isEqualTo("C:");
- assertThat(result.getRight()).isEqualTo("My\\path\\to\\a\\file.txt");
-
-
- DocumentName.ROOTS.clear();
- DocumentName.ROOTS.add("/");
- result = DocumentName.Builder.splitRoot("/My/path/to/a/file.txt", "/");
- assertThat(result.getLeft()).isEqualTo("");
- assertThat(result.getRight()).isEqualTo("My/path/to/a/file.txt");
-
- } finally {
- DocumentName.ROOTS.clear();
- DocumentName.ROOTS.addAll(preserve);
- }
+ void splitRootsTest() throws IOException {
+ Pair result = DocumentName.builder(WINDOWS).splitRoot("C:\\My\\path\\to\\a\\file.txt");
+ assertThat(result.getLeft()).isEqualTo("C:");
+ assertThat(result.getRight()).isEqualTo("My\\path\\to\\a\\file.txt");
+
+ result = DocumentName.builder(UNIX).splitRoot("/My/path/to/a/file.txt");
+ assertThat(result.getLeft()).isEqualTo("");
+ assertThat(result.getRight()).isEqualTo("My/path/to/a/file.txt");
+
+ result = DocumentName.builder(OSX).splitRoot("/My/path/to/a/file.txt");
+ assertThat(result.getLeft()).isEqualTo("");
+ assertThat(result.getRight()).isEqualTo("My/path/to/a/file.txt");
+
}
@Test
- public void archiveEntryNameTest() {
- Set preserve = new HashSet<>(DocumentName.ROOTS);
- try {
- DocumentName.ROOTS.clear();
- DocumentName.ROOTS.add("C:\\");
-
- DocumentName archiveName = DocumentName.builder().setDirSeparator("\\")
- .setName("C:\\archives\\anArchive.zip").setBaseName("archives").build();
- assertThat(archiveName.getRoot()).isEqualTo("C:");
- assertThat(archiveName.getDirectorySeparator()).isEqualTo("\\");
- assertThat(archiveName.getBaseName()).isEqualTo("C:\\archives");
- assertThat(archiveName.getName()).isEqualTo("C:\\archives\\anArchive.zip");
- assertThat(archiveName.localized()).isEqualTo("\\anArchive.zip");
-
- String entryName = "./anArchiveEntry.txt";
- DocumentName innerName = DocumentName.builder()
- .setDirSeparator("/").setName(entryName)
- .setBaseName(".").setCaseSensitive(true).build();
- assertThat(innerName.getRoot()).isEqualTo("");
- assertThat(innerName.getDirectorySeparator()).isEqualTo("/");
- assertThat(innerName.getBaseName()).isEqualTo("/.");
- assertThat(innerName.getName()).isEqualTo("/" + entryName);
- assertThat(innerName.localized()).isEqualTo("/anArchiveEntry.txt");
-
- String outerNameStr = format("%s#%s", archiveName.getName(), entryName);
- DocumentName outerName = DocumentName.builder(archiveName).setName(outerNameStr)
- .setCaseSensitive(innerName.isCaseSensitive()).build();
-
- assertThat(outerName.getRoot()).isEqualTo("C:");
- assertThat(outerName.getDirectorySeparator()).isEqualTo("\\");
- assertThat(outerName.getBaseName()).isEqualTo("C:\\archives");
- assertThat(outerName.getName()).isEqualTo("C:\\archives\\anArchive.zip#./anArchiveEntry.txt");
- assertThat(outerName.localized()).isEqualTo("\\anArchive.zip#./anArchiveEntry.txt");
- assertThat(outerName.localized("/")).isEqualTo("/anArchive.zip#./anArchiveEntry.txt");
-
- // test with directory
- entryName = "./someDir/anArchiveEntry.txt";
- innerName = DocumentName.builder()
- .setDirSeparator("/").setName(entryName)
- .setBaseName(".").setCaseSensitive(true).build();
- assertThat(innerName.getRoot()).isEqualTo("");
- assertThat(innerName.getDirectorySeparator()).isEqualTo("/");
- assertThat(innerName.getBaseName()).isEqualTo("/.");
- assertThat(innerName.getName()).isEqualTo("/" + entryName);
- assertThat(innerName.localized()).isEqualTo("/someDir/anArchiveEntry.txt");
-
- outerNameStr = format("%s#%s", archiveName.getName(), entryName);
- outerName = DocumentName.builder(archiveName).setName(outerNameStr)
- .setCaseSensitive(innerName.isCaseSensitive()).build();
-
- assertThat(outerName.getRoot()).isEqualTo("C:");
- assertThat(outerName.getDirectorySeparator()).isEqualTo("\\");
- assertThat(outerName.getBaseName()).isEqualTo("C:\\archives");
- assertThat(outerName.getName()).isEqualTo("C:\\archives\\anArchive.zip#./someDir/anArchiveEntry.txt");
- assertThat(outerName.localized()).isEqualTo("\\anArchive.zip#./someDir/anArchiveEntry.txt");
- assertThat(outerName.localized("/")).isEqualTo("/anArchive.zip#./someDir/anArchiveEntry.txt");
- } finally {
- DocumentName.ROOTS.clear();
- DocumentName.ROOTS.addAll(preserve);
- }
+ void archiveEntryNameTest() throws IOException {
+ String entryName = "./anArchiveEntry.txt";
+ DocumentName archiveName = DocumentName.builder(WINDOWS)
+ .setName("C:\\archives\\anArchive.zip").setBaseName("C:\\archives").build();
+
+ assertThat(archiveName.getRoot()).isEqualTo("C:");
+ assertThat(archiveName.getDirectorySeparator()).isEqualTo("\\");
+ assertThat(archiveName.getBaseName()).isEqualTo("C:\\archives");
+ assertThat(archiveName.getName()).isEqualTo("C:\\archives\\anArchive.zip");
+ assertThat(archiveName.localized()).isEqualTo("\\anArchive.zip");
+
+
+ ArchiveEntryName archiveEntryName = new ArchiveEntryName(archiveName, entryName);
+
+ assertThat(archiveEntryName.getRoot()).isEqualTo(archiveName.getName()+"#");
+ assertThat(archiveEntryName.getDirectorySeparator()).isEqualTo("/");
+ assertThat(archiveEntryName.getBaseName()).isEqualTo("C:\\archives\\anArchive.zip#");
+ assertThat(archiveEntryName.getName()).isEqualTo("C:\\archives\\anArchive.zip#/anArchiveEntry.txt");
+ assertThat(archiveEntryName.localized()).isEqualTo("/anArchiveEntry.txt");
+ assertThat(archiveEntryName.localized("/")).isEqualTo("/anArchive.zip#/anArchiveEntry.txt");
+
+ // test with directory
+ entryName = "./someDir/anArchiveEntry.txt";
+ archiveEntryName = new ArchiveEntryName(archiveName, entryName);
+
+ assertThat(archiveEntryName.getRoot()).isEqualTo(archiveName.getName()+"#");
+ assertThat(archiveEntryName.getDirectorySeparator()).isEqualTo("/");
+ assertThat(archiveEntryName.getBaseName()).isEqualTo("C:\\archives\\anArchive.zip#");
+ assertThat(archiveEntryName.getName()).isEqualTo("C:\\archives\\anArchive.zip#/someDir/anArchiveEntry.txt");
+ assertThat(archiveEntryName.localized()).isEqualTo("/someDir/anArchiveEntry.txt");
+ assertThat(archiveEntryName.localized("/")).isEqualTo("/anArchive.zip#/someDir/anArchiveEntry.txt");
}
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/FSInfoTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/FSInfoTest.java
new file mode 100644
index 000000000..db2f91ea2
--- /dev/null
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/FSInfoTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.rat.document;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.provider.Arguments;
+
+public class FSInfoTest {
+ public static final DocumentName.FSInfo DEFAULT;
+ public static final DocumentName.FSInfo OSX;
+ public static final DocumentName.FSInfo UNIX;
+ public static final DocumentName.FSInfo WINDOWS;
+
+ static {
+ try (FileSystem osx = Jimfs.newFileSystem(Configuration.osX());
+ FileSystem unix = Jimfs.newFileSystem(Configuration.unix());
+ FileSystem windows = Jimfs.newFileSystem(Configuration.windows())) {
+ OSX = new DocumentName.FSInfo("osx", osx);
+ UNIX = new DocumentName.FSInfo("unix", unix);
+ WINDOWS = new DocumentName.FSInfo("windows", windows);
+ DEFAULT = new DocumentName.FSInfo("default", FileSystems.getDefault());
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to creat FSInfo objects: " + e.getMessage(), e);
+ }
+ }
+
+ public static final DocumentName.FSInfo[] TEST_SUITE = {UNIX, WINDOWS, OSX};
+
+ /**
+ * Provided arguments for parameterized tests that only require the fsInfo.
+ * @return a stream of TEST_SUITE based Arguments.
+ */
+ public static Stream fsInfoArgs() {
+ return Arrays.stream(TEST_SUITE).map(Arguments::of);
+ }
+}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/document/guesser/NoteGuesserTest.java b/apache-rat-core/src/test/java/org/apache/rat/document/guesser/NoteGuesserTest.java
index 2abf19340..87d157a0e 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/document/guesser/NoteGuesserTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/document/guesser/NoteGuesserTest.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.stream.Stream;
import org.apache.rat.document.DocumentName;
+import org.apache.rat.document.FSInfoTest;
import org.apache.rat.testhelpers.TestingDocument;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -41,10 +42,8 @@ public void testMatches(DocumentName testingName, boolean expected) {
private static Stream nameData() {
List lst = new ArrayList<>();
- final DocumentName linuxBaseName = DocumentName.builder().setName("/").setBaseName("/").setDirSeparator("/")
- .setCaseSensitive(true).build();
- final DocumentName windowsBaseName = DocumentName.builder().setName("\\").setBaseName("\\")
- .setDirSeparator("\\").setCaseSensitive(false).build();
+ final DocumentName linuxBaseName = DocumentName.builder(FSInfoTest.UNIX).setName("/").setBaseName("/").build();
+ final DocumentName windowsBaseName = DocumentName.builder(FSInfoTest.WINDOWS).setName("\\").setBaseName("\\").build();
lst.add(Arguments.of(linuxBaseName.resolve("DEPENDENCIES"), true));
lst.add(Arguments.of(linuxBaseName.resolve("LICENSE"), true));
diff --git a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
index c1e756687..532182b8e 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
@@ -50,13 +50,13 @@ public TestingDocument(DocumentName documentName) {
}
public TestingDocument(String name, DocumentNameMatcher matcher) {
- super(DocumentName.builder().setName(name).setBaseName("").setDirSeparator("/").setCaseSensitive(true).build(), matcher);
+ super(DocumentName.builder().setName(name).setBaseName("").build(), matcher);
this.reader = null;
this.input = null;
}
public TestingDocument(Reader reader, String name) {
- super(DocumentName.builder().setName(name).setBaseName("").setDirSeparator("/").setCaseSensitive(true).build(), DocumentNameMatcher.MATCHES_ALL);
+ super(DocumentName.builder().setName(name).setBaseName("").build(), DocumentNameMatcher.MATCHES_ALL);
this.reader = reader;
this.input = null;
}
diff --git a/pom.xml b/pom.xml
index b181a2056..531a403e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -198,7 +198,7 @@ agnostic home for software distribution comprehension and audit tools.
org.assertj
assertj-core
- 3.27.2
+ 3.27.1
test
@@ -217,6 +217,12 @@ agnostic home for software distribution comprehension and audit tools.
2.4.21
test
+
+ com.google.jimfs
+ jimfs
+ 1.3.0
+ test
+
@@ -489,7 +495,7 @@ agnostic home for software distribution comprehension and audit tools.
org.apache.maven.plugins
maven-remote-resources-plugin
- 3.3.0
+ 3.2.0
org.apache.maven.plugins
From f9a46f61127c8cdfab0bdf5c46cb7500976ae2b2 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Sun, 12 Jan 2025 16:18:06 +0000
Subject: [PATCH 02/17] updated spotbugs
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 531a403e2..890ec493a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -386,7 +386,7 @@ agnostic home for software distribution comprehension and audit tools.
4.8.6.6
- 94
+ 98
true
org.apache.rat.-
From cefaff7e2329caee6e00029dda7bc98c10ba977f Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Sun, 12 Jan 2025 17:34:34 +0000
Subject: [PATCH 03/17] attempt to fix windows error
---
.../org/apache/rat/walker/FileListWalkerTest.java | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java b/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
index 14ac1478b..9bc554029 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
@@ -33,8 +33,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
public class FileListWalkerTest {
@@ -117,15 +116,13 @@ public static void setUp() throws Exception {
@Test
public void readFilesTest() throws RatException {
- FileListWalker walker = new FileListWalker(new FileDocument(source, DocumentNameMatcher.MATCHES_ALL));
+ FileDocument fileDocument = new FileDocument(source, DocumentNameMatcher.MATCHES_ALL);
+ FileListWalker walker = new FileListWalker(fileDocument);
List scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {regularName.localized("/"), hiddenName.localized("/"),
anotherName.localized("/")};
- assertEquals(3, scanned.size());
- for (String ex : expected) {
- assertTrue(scanned.contains(ex), ()-> String.format("Missing %s from %s", ex, String.join(", ", scanned)));
- }
+ assertThat(scanned).containsExactly(expected);
}
static class TestRatReport implements RatReport {
From a46a244676557e0a65a5dd9e4c00808c39b85233 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Sun, 12 Jan 2025 18:00:11 +0000
Subject: [PATCH 04/17] fixed merge error
---
.../test/java/org/apache/rat/testhelpers/TestingDocument.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
index 532182b8e..1bd66377b 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/testhelpers/TestingDocument.java
@@ -29,6 +29,7 @@
import org.apache.rat.api.Document;
import org.apache.rat.document.DocumentNameMatcher;
import org.apache.rat.document.DocumentName;
+import org.apache.rat.document.FSInfoTest;
public class TestingDocument extends Document {
@@ -62,7 +63,7 @@ public TestingDocument(Reader reader, String name) {
}
public TestingDocument(IOSupplier inputStream, String name) {
- super(DocumentName.builder().setName(name).setBaseName("").setDirSeparator("/").setCaseSensitive(true).build(), DocumentNameMatcher.MATCHES_ALL);
+ super(DocumentName.builder(FSInfoTest.UNIX).setName(name).setBaseName("").build(), DocumentNameMatcher.MATCHES_ALL);
this.input = inputStream;
this.reader = null;
}
From 103d9dbbf48c26c3c22a665da6c9fd38a239e58d Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Mon, 13 Jan 2025 23:43:39 +0000
Subject: [PATCH 05/17] fixed pattern match
---
.../config/exclusion/ExclusionProcessor.java | 4 +-
.../config/exclusion/plexus/MatchPattern.java | 2 +-
.../exclusion/plexus/MatchPatterns.java | 40 +-
.../rat/document/DocumentNameMatcher.java | 390 ++++++++++++++++--
4 files changed, 370 insertions(+), 66 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
index e21432e03..105312930 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
@@ -255,10 +255,10 @@ public DocumentNameMatcher getNameMatcher(final DocumentName basedir) {
.addTo(new ArrayList<>());
if (!incl.isEmpty()) {
- inclMatchers.add(new DocumentNameMatcher("included patterns", MatchPatterns.from(incl), basedir));
+ inclMatchers.add(new DocumentNameMatcher("included patterns", MatchPatterns.from("/", incl), basedir));
}
if (!excl.isEmpty()) {
- exclMatchers.add(new DocumentNameMatcher("excluded patterns", MatchPatterns.from(excl), basedir));
+ exclMatchers.add(new DocumentNameMatcher("excluded patterns", MatchPatterns.from("/", excl), basedir));
}
if (!includedPaths.isEmpty()) {
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index c43836ecd..c2c3ae7c9 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -49,7 +49,7 @@ public final class MatchPattern {
private final char[][] tokenizedChar;
- private MatchPattern(final String source, final String separator) {
+ MatchPattern(final String source, final String separator) {
regexPattern = SelectorUtils.isRegexPrefixedPattern(source)
? source.substring(
SelectorUtils.REGEX_HANDLER_PREFIX.length(),
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
index 454ba304e..9a6d443e4 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
@@ -22,8 +22,9 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
-import java.util.function.Predicate;
+import java.util.stream.Collectors;
@SuppressWarnings({"checkstyle:RegexpSingleLine", "checkstyle:JavadocVariable"})
/**
@@ -41,15 +42,15 @@ private MatchPatterns(final MatchPattern[] patterns) {
@Override
public String toString() {
- return source();
+ return Arrays.stream(patterns).map(MatchPattern::toString).collect(Collectors.toList()).toString();
}
public String source() {
- List sources = new ArrayList<>();
- for (MatchPattern pattern : patterns) {
- sources.add(pattern.source());
- }
- return "[" + String.join(", ", sources) + "]";
+ return Arrays.stream(patterns).map(MatchPattern::source).collect(Collectors.toList()).toString();
+ }
+
+ public Iterable patterns() {
+ return Arrays.asList(patterns);
}
/**
@@ -83,36 +84,23 @@ public boolean matches(final String name, final char[][] tokenizedNameChar, fina
return false;
}
- public Predicate asPredicate(final boolean isCaseSensitive) {
- return name -> matches(name, isCaseSensitive);
- }
-
- public boolean matchesPatternStart(final String name, final boolean isCaseSensitive) {
- for (MatchPattern includesPattern : patterns) {
- if (includesPattern.matchPatternStart(name, isCaseSensitive)) {
- return true;
- }
- }
- return false;
- }
-
- public static MatchPatterns from(final String... sources) {
+ public static MatchPatterns from(final String separator, final String... sources) {
final int length = sources.length;
MatchPattern[] result = new MatchPattern[length];
for (int i = 0; i < length; i++) {
- result[i] = MatchPattern.fromString(sources[i]);
+ result[i] = new MatchPattern(sources[i], separator);
}
return new MatchPatterns(result);
}
- public static MatchPatterns from(final Iterable strings) {
- return new MatchPatterns(getMatchPatterns(strings));
+ public static MatchPatterns from(final String separator, final Iterable strings) {
+ return new MatchPatterns(getMatchPatterns(separator, strings));
}
- private static MatchPattern[] getMatchPatterns(final Iterable items) {
+ private static MatchPattern[] getMatchPatterns(final String separator, final Iterable items) {
List result = new ArrayList<>();
for (String string : items) {
- result.add(MatchPattern.fromString(string));
+ result.add(new MatchPattern(string, separator));
}
return result.toArray(new MatchPattern[0]);
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/DocumentNameMatcher.java b/apache-rat-core/src/main/java/org/apache/rat/document/DocumentNameMatcher.java
index 30bbbbede..0e66b19f7 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/DocumentNameMatcher.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/DocumentNameMatcher.java
@@ -23,9 +23,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Optional;
+import java.util.Set;
import java.util.function.Predicate;
+import org.apache.rat.ConfigurationException;
import org.apache.rat.config.exclusion.plexus.MatchPattern;
import org.apache.rat.config.exclusion.plexus.MatchPatterns;
@@ -40,6 +45,8 @@ public final class DocumentNameMatcher {
private final Predicate predicate;
/** The name of this matcher. */
private final String name;
+ /** {@code true} this this matcher is a collection of matchers */
+ private final boolean isCollection;
/**
* A matcher that matches all documents.
@@ -59,6 +66,7 @@ public final class DocumentNameMatcher {
public DocumentNameMatcher(final String name, final Predicate predicate) {
this.name = name;
this.predicate = predicate;
+ this.isCollection = predicate instanceof CollectionPredicateImpl;
}
/**
@@ -77,9 +85,22 @@ public DocumentNameMatcher(final String name, final DocumentNameMatcher delegate
* @param basedir the base directory for the scanning.
*/
public DocumentNameMatcher(final String name, final MatchPatterns patterns, final DocumentName basedir) {
- this(name, (Predicate) documentName -> patterns.matches(documentName.getName(),
- MatchPattern.tokenizePathToString(documentName.getName(), basedir.getDirectorySeparator()),
- basedir.isCaseSensitive()));
+ this(name, new MatchPatternsPredicate(basedir, patterns));
+ }
+
+ /**
+ * Tokenizes name for faster Matcher processing.
+ * @param name the name to tokenize
+ * @param dirSeparator the directory separator
+ * @return the tokenized name.
+ */
+ private static char[][] tokenize(final String name, final String dirSeparator) {
+ String[] tokenizedName = MatchPattern.tokenizePathToString(name, dirSeparator);
+ char[][] tokenizedNameChar = new char[tokenizedName.length][];
+ for (int i = 0; i < tokenizedName.length; i++) {
+ tokenizedNameChar[i] = tokenizedName[i].toCharArray();
+ }
+ return tokenizedNameChar;
}
/**
@@ -88,7 +109,20 @@ public DocumentNameMatcher(final String name, final MatchPatterns patterns, fina
* @param matchers fully specified matchers.
*/
public DocumentNameMatcher(final String name, final MatchPatterns matchers) {
- this(name, (Predicate) documentName -> matchers.matches(documentName.getName(), documentName.isCaseSensitive()));
+ this(name, new CollectionPredicate() {
+ @Override
+ public Iterable getMatchers() {
+ final List result = new ArrayList<>();
+ matchers.patterns().forEach(p -> result.add(new DocumentNameMatcher(p.source(),
+ (Predicate) x -> MatchPatterns.from("/", p.source()).matches(x.getName(), x.isCaseSensitive()))));
+ return result;
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ return matchers.matches(documentName.getName(), documentName.isCaseSensitive());
+ }
+ });
}
/**
@@ -97,7 +131,7 @@ public DocumentNameMatcher(final String name, final MatchPatterns matchers) {
* @param fileFilter the file filter to execute.
*/
public DocumentNameMatcher(final String name, final FileFilter fileFilter) {
- this(name, (Predicate) documentName -> fileFilter.accept(new File(documentName.getName())));
+ this(name, new FileFilterPredicate(fileFilter));
}
/**
@@ -108,11 +142,39 @@ public DocumentNameMatcher(final FileFilter fileFilter) {
this(fileFilter.toString(), fileFilter);
}
+ public boolean isCollection() {
+ return isCollection;
+ }
+
+ /**
+ * Returns the predicate that this DocumentNameMatcher is using.
+ * @return The predicate that this DocumentNameMatcher is using.
+ */
+ public Predicate getPredicate() {
+ return predicate;
+ }
+
@Override
public String toString() {
return name;
}
+ /**
+ * Decomposes the matcher execution against the candidate.
+ * @param candidate the candiate to check.
+ * @return a list of {@link DecomposeData} for each evaluation in the matcher.
+ */
+ public List decompose(final DocumentName candidate) {
+ final List result = new ArrayList<>();
+ decompose(0, this, candidate, result);
+ return result;
+ }
+
+ private void decompose(final int level, final DocumentNameMatcher matcher, final DocumentName candidate, final List result) {
+ final Predicate pred = matcher.getPredicate();
+ result.add(new DecomposeData(level, matcher, candidate, pred.test(candidate)));
+ }
+
/**
* Performs the match against the DocumentName.
* @param documentName the document name to check.
@@ -135,8 +197,7 @@ public static DocumentNameMatcher not(final DocumentNameMatcher nameMatcher) {
return MATCHES_ALL;
}
- return new DocumentNameMatcher(format("not(%s)", nameMatcher),
- (Predicate) documentName -> !nameMatcher.matches(documentName));
+ return new DocumentNameMatcher(format("not(%s)", nameMatcher), new NotPredicate(nameMatcher));
}
/**
@@ -150,30 +211,43 @@ private static String join(final Collection matchers) {
return String.join(", ", children);
}
+ private static Optional standardCollectionCheck(final Collection matchers,
+ final DocumentNameMatcher override) {
+ if (matchers.isEmpty()) {
+ throw new ConfigurationException("Empty matcher collection");
+ }
+ if (matchers.size() == 1) {
+ return Optional.of(matchers.iterator().next());
+ }
+ if (matchers.contains(override)) {
+ return Optional.of(override);
+ }
+ return Optional.empty();
+ }
+
/**
* Performs a logical {@code OR} across the collection of matchers.
* @param matchers the matchers to check.
* @return a matcher that returns {@code true} if any of the enclosed matchers returns {@code true}.
*/
public static DocumentNameMatcher or(final Collection matchers) {
- if (matchers.isEmpty()) {
- return MATCHES_NONE;
- }
- if (matchers.size() == 1) {
- return matchers.iterator().next();
- }
- if (matchers.contains(MATCHES_ALL)) {
- return MATCHES_ALL;
+ Optional opt = standardCollectionCheck(matchers, MATCHES_ALL);
+ if (opt.isPresent()) {
+ return opt.get();
}
- return new DocumentNameMatcher(format("or(%s)", join(matchers)), (Predicate) documentName -> {
- for (DocumentNameMatcher matcher : matchers) {
- if (matcher.matches(documentName)) {
- return true;
- }
- }
- return false;
- });
+ // preserve order
+ Set workingSet = new LinkedHashSet<>();
+ for (DocumentNameMatcher matcher : matchers) {
+ // check for nested or
+ if (matcher.predicate instanceof Or) {
+ ((Or) matcher.predicate).getMatchers().forEach(workingSet::add);
+ } else {
+ workingSet.add(matcher);
+ }
+ }
+ return standardCollectionCheck(matchers, MATCHES_ALL)
+ .orElseGet(() -> new DocumentNameMatcher(format("or(%s)", join(workingSet)), new Or(workingSet)));
}
/**
@@ -191,24 +265,45 @@ public static DocumentNameMatcher or(final DocumentNameMatcher... matchers) {
* @return a matcher that returns {@code true} if all the enclosed matchers return {@code true}.
*/
public static DocumentNameMatcher and(final Collection matchers) {
- if (matchers.isEmpty()) {
- return MATCHES_NONE;
- }
- if (matchers.size() == 1) {
- return matchers.iterator().next();
+ Optional opt = standardCollectionCheck(matchers, MATCHES_NONE);
+ if (opt.isPresent()) {
+ return opt.get();
}
- if (matchers.contains(MATCHES_NONE)) {
- return MATCHES_NONE;
+
+ // preserve order
+ Set workingSet = new LinkedHashSet<>();
+ for (DocumentNameMatcher matcher : matchers) {
+ // check for nexted And
+ if (matcher.predicate instanceof And) {
+ ((And) matcher.predicate).getMatchers().forEach(workingSet::add);
+ } else {
+ workingSet.add(matcher);
+ }
}
+ opt = standardCollectionCheck(matchers, MATCHES_NONE);
+ return opt.orElseGet(() -> new DocumentNameMatcher(format("and(%s)", join(workingSet)), new And(workingSet)));
+ }
- return new DocumentNameMatcher(format("and(%s)", join(matchers)), (Predicate) documentName -> {
- for (DocumentNameMatcher matcher : matchers) {
- if (!matcher.matches(documentName)) {
- return false;
- }
+ /**
+ * A particular matcher that will not match any excluded unless they are listed in the includes.
+ * @param includes the DocumentNameMatcher to match the includes.
+ * @param excludes the DocumentNameMatcher to match the excludes.
+ * @return a DocumentNameMatcher with the specified logic.
+ */
+ public static DocumentNameMatcher matcherSet(final DocumentNameMatcher includes,
+ final DocumentNameMatcher excludes) {
+ if (excludes == MATCHES_NONE) {
+ return MATCHES_ALL;
+ } else {
+ if (includes == MATCHES_NONE) {
+ return not(excludes);
}
- return true;
- });
+ }
+ if (includes == MATCHES_ALL) {
+ return MATCHES_ALL;
+ }
+ List workingSet = Arrays.asList(includes, excludes);
+ return new DocumentNameMatcher(format("matcherSet(%s)", join(workingSet)), new MatcherPredicate(workingSet));
}
/**
@@ -219,4 +314,225 @@ public static DocumentNameMatcher and(final Collection matc
public static DocumentNameMatcher and(final DocumentNameMatcher... matchers) {
return and(Arrays.asList(matchers));
}
+
+
+
+ /**
+ * A DocumentName predicate that uses MatchPatterns.
+ */
+ public static final class MatchPatternsPredicate implements Predicate {
+ /** The base diirectory for the pattern matches */
+ private final DocumentName basedir;
+ /** The patter matchers */
+ private final MatchPatterns patterns;
+
+ private MatchPatternsPredicate(final DocumentName basedir, final MatchPatterns patterns) {
+ this.basedir = basedir;
+ this.patterns = patterns;
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ return patterns.matches(documentName.getName(),
+ tokenize(documentName.getName(), basedir.getDirectorySeparator()),
+ basedir.isCaseSensitive());
+ }
+
+ @Override
+ public String toString() {
+ return patterns.toString();
+ }
+ }
+
+ /**
+ * A DocumentName predicate reverses another DocumentNameMatcher
+ */
+ public static final class NotPredicate implements Predicate {
+ /** The document name matcher to reverse */
+ private final DocumentNameMatcher nameMatcher;
+
+ private NotPredicate(final DocumentNameMatcher nameMatcher) {
+ this.nameMatcher = nameMatcher;
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ return !nameMatcher.matches(documentName);
+ }
+
+ @Override
+ public String toString() {
+ return nameMatcher.predicate.toString();
+ }
+ }
+
+ /**
+ * A DocumentName predicate that uses FileFilter.
+ */
+ public static final class FileFilterPredicate implements Predicate {
+ /** The file filter */
+ private final FileFilter fileFilter;
+
+ private FileFilterPredicate(final FileFilter fileFilter) {
+ this.fileFilter = fileFilter;
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ return fileFilter.accept(new File(documentName.getName()));
+ }
+
+ @Override
+ public String toString() {
+ return fileFilter.toString();
+ }
+ }
+
+ interface CollectionPredicate extends Predicate {
+ Iterable getMatchers();
+ }
+ /**
+ * A marker interface to indicate this predicate contains a collection of matchers.
+ */
+ abstract static class CollectionPredicateImpl implements CollectionPredicate {
+ /** The collection for matchers that make up this predicate */
+ private final Iterable matchers;
+
+ /**
+ * Constructs a collecton predicate from the collection of matchers
+ * @param matchers the colleciton of matchers to use.
+ */
+ protected CollectionPredicateImpl(final Iterable matchers) {
+ this.matchers = matchers;
+ }
+
+ /**
+ * Gets the internal matchers.
+ * @return an iterable over the internal matchers.
+ */
+ public Iterable getMatchers() {
+ return matchers;
+ }
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder(this.getClass().getName()).append(": ").append(System.lineSeparator());
+ for (DocumentNameMatcher matcher : matchers) {
+ builder.append(matcher.predicate.toString()).append(System.lineSeparator());
+ }
+ return builder.toString();
+ }
+ }
+
+ /**
+ * An implementation of "and" logic across a collection of DocumentNameMatchers.
+ */
+ // package private for testing access
+ static class And extends CollectionPredicateImpl {
+ And(final Iterable matchers) {
+ super(matchers);
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ for (DocumentNameMatcher matcher : getMatchers()) {
+ if (!matcher.matches(documentName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * An implementation of "or" logic across a collection of DocumentNameMatchers.
+ */
+ // package private for testing access
+ static class Or extends CollectionPredicateImpl {
+ Or(final Iterable matchers) {
+ super(matchers);
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ for (DocumentNameMatcher matcher : getMatchers()) {
+ if (matcher.matches(documentName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * An implementation of "or" logic across a collection of DocumentNameMatchers.
+ */
+ // package private for testing access
+ static class MatcherPredicate extends CollectionPredicateImpl {
+ MatcherPredicate(final Iterable matchers) {
+ super(matchers);
+ }
+
+ @Override
+ public boolean test(final DocumentName documentName) {
+ Iterator iter = getMatchers().iterator();
+ // included
+ if (iter.next().matches(documentName)) {
+ return true;
+ }
+ // excluded
+ if (iter.next().matches(documentName)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Data from a {@link DocumentNameMatcher#decompose(DocumentName)} call.
+ */
+ public static final class DecomposeData {
+ /** the level this data was generated at */
+ private final int level;
+ /** The name of the DocumentNameMatcher that created this result */
+ private final DocumentNameMatcher matcher;
+ /** The result of the check. */
+ private final boolean result;
+ /** The candidate */
+ private final DocumentName candidate;
+
+ private DecomposeData(final int level, final DocumentNameMatcher matcher, final DocumentName candidate, final boolean result) {
+ this.level = level;
+ this.matcher = matcher;
+ this.result = result;
+ this.candidate = candidate;
+ }
+
+ @Override
+ public String toString() {
+ final String fill = createFill(level);
+ return format("%s%s: >>%s<< %s%n%s",
+ fill, matcher.toString(), result,
+ level == 0 ? candidate.getName() : "",
+ matcher.predicate instanceof CollectionPredicate ?
+ decompose(level + 1, (CollectionPredicate) matcher.predicate, candidate) :
+ String.format("%s%s >>%s<<", createFill(level + 1), matcher.predicate.toString(), matcher.predicate.test(candidate)));
+ }
+
+ private String createFill(final int level) {
+ final char[] chars = new char[level * 2];
+ Arrays.fill(chars, ' ');
+ return new String(chars);
+ }
+
+ private String decompose(final int level, final CollectionPredicate predicate, final DocumentName candidate) {
+ List result = new ArrayList<>();
+
+ for (DocumentNameMatcher nameMatcher : predicate.getMatchers()) {
+ nameMatcher.decompose(level, nameMatcher, candidate, result);
+ }
+ StringBuilder sb = new StringBuilder();
+ result.forEach(x -> sb.append(x).append(System.lineSeparator()));
+ return sb.toString();
+ }
+ }
}
From 818618f21d572fab83bb03cbc53acacc0a8798f5 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Tue, 14 Jan 2025 18:12:26 +0000
Subject: [PATCH 06/17] added more descriptive failure messages
---
.../rat/config/exclusion/ExclusionProcessorTest.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/ExclusionProcessorTest.java b/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/ExclusionProcessorTest.java
index 580d10849..f8535a90b 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/ExclusionProcessorTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/config/exclusion/ExclusionProcessorTest.java
@@ -51,7 +51,13 @@ public void setup() {
}
private void testParseExclusion(DocumentNameMatcher nameMatcher, DocumentName name, boolean expected) {
- assertThat(nameMatcher.matches(name)).as(() -> format("Failed on [%s %s]", basedir, name)).isEqualTo(expected);
+ assertThat(nameMatcher.matches(name)).as(() -> format("Failed on [%s %s]%n%s", basedir, name, dump(nameMatcher, name))).isEqualTo(expected);
+ }
+
+ private String dump(DocumentNameMatcher nameMatcher, DocumentName name) {
+ StringBuilder sb = new StringBuilder();
+ nameMatcher.decompose(name).forEach(s -> sb.append(s).append("\n"));
+ return sb.toString();
}
private DocumentName mkName(String pth) {
From c8a5f9d544c135395e7060004398dd67a8434076 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Tue, 14 Jan 2025 19:07:07 +0000
Subject: [PATCH 07/17] modified test output
---
.../config/exclusion/plexus/MatchPattern.java | 7 +-
.../rat/test/AbstractOptionsProvider.java | 80 ++++++++++++++-----
2 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index c2c3ae7c9..ff6505986 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -19,6 +19,7 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
@@ -116,7 +117,7 @@ public boolean startsWith(final String string) {
@Override
public String toString() {
- return source;
+ return Arrays.asList(tokenized).toString();
}
public String source() {
@@ -140,8 +141,4 @@ static char[][] tokenizePathToCharArray(final String path, final String separato
}
return tokenizedNameChar;
}
-
- public static MatchPattern fromString(final String source) {
- return new MatchPattern(source, File.separator);
- }
}
diff --git a/apache-rat-core/src/test/java/org/apache/rat/test/AbstractOptionsProvider.java b/apache-rat-core/src/test/java/org/apache/rat/test/AbstractOptionsProvider.java
index baf44eada..3bc776b58 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/test/AbstractOptionsProvider.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/test/AbstractOptionsProvider.java
@@ -213,10 +213,16 @@ private void execExcludeTest(Option option, String[] args) {
ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
}
for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
@@ -252,11 +258,17 @@ protected void inputExcludeStdTest() {
try {
ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
- for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
- }
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
+ }
+ for (String fname : excluded) {
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
@@ -284,11 +296,17 @@ protected void inputExcludeParsedScmTest() {
try {
ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
- for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
- }
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
+ }
+ for (String fname : excluded) {
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
@@ -308,11 +326,17 @@ private void inputExcludeSizeTest() {
try {
ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
- for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
- }
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
+ }
+ for (String fname : excluded) {
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
@@ -328,11 +352,17 @@ private void execIncludeTest(Option option, String[] args) {
ReportConfiguration config = generateConfig(ImmutablePair.of(option, args),
ImmutablePair.of(excludeOption, EXCLUDE_ARGS));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
- for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
- }
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
+ }
+ for (String fname : excluded) {
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
@@ -370,11 +400,17 @@ protected void inputIncludeStdTest() {
try {
ReportConfiguration config = generateConfig(excludes, ImmutablePair.of(option, args));
DocumentNameMatcher excluder = config.getDocumentExcluder(baseName());
- for (String fname : excluded) {
- assertFalse(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
- }
for (String fname : notExcluded) {
- assertTrue(excluder.matches(mkDocName(fname)), () -> option.getKey() + " " + fname);
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isTrue();
+ }
+ for (String fname : excluded) {
+ final DocumentName docName = mkDocName(fname);
+ assertThat(excluder.matches(docName))
+ .as(() -> String.format("option: %s name: %s%n%s", option.getKey(), fname, excluder.decompose(docName)))
+ .isFalse();
}
} catch (IOException e) {
fail(e.getMessage());
From 2a20800f751b19b2a546954831aa156805d41223 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Tue, 14 Jan 2025 19:24:49 +0000
Subject: [PATCH 08/17] added debug info
---
.../org/apache/rat/config/exclusion/plexus/MatchPattern.java | 2 ++
.../org/apache/rat/config/exclusion/plexus/MatchPatterns.java | 1 +
2 files changed, 3 insertions(+)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index ff6505986..f5df27f2d 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -51,6 +51,7 @@ public final class MatchPattern {
private final char[][] tokenizedChar;
MatchPattern(final String source, final String separator) {
+ DefaultLog.getInstance().warn(String.format("Creating MatchPattern('%s', '%s')..."));
regexPattern = SelectorUtils.isRegexPrefixedPattern(source)
? source.substring(
SelectorUtils.REGEX_HANDLER_PREFIX.length(),
@@ -67,6 +68,7 @@ public final class MatchPattern {
for (int i = 0; i < tokenized.length; i++) {
tokenizedChar[i] = tokenized[i].toCharArray();
}
+ DefaultLog.getInstance().warn(String.format("... as %s", this.toString()));
}
public boolean matchPath(final String str, final boolean isCaseSensitive) {
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
index 9a6d443e4..f0d1cf0e3 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
@@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
+import org.apache.rat.utils.DefaultLog;
@SuppressWarnings({"checkstyle:RegexpSingleLine", "checkstyle:JavadocVariable"})
/**
From 074172509175fe724a87aa2b8a10a5c3411f4e64 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Tue, 14 Jan 2025 19:27:27 +0000
Subject: [PATCH 09/17] added debug info
---
.../org/apache/rat/config/exclusion/plexus/MatchPatterns.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
index f0d1cf0e3..9a6d443e4 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
@@ -25,7 +25,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
-import org.apache.rat.utils.DefaultLog;
@SuppressWarnings({"checkstyle:RegexpSingleLine", "checkstyle:JavadocVariable"})
/**
From be21fef7ce03d13abfb82ffed224d3d53d2c1991 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 17:13:49 +0000
Subject: [PATCH 10/17] added debug info
---
.../org/apache/rat/config/exclusion/plexus/MatchPattern.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index f5df27f2d..ce180b331 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -51,7 +51,7 @@ public final class MatchPattern {
private final char[][] tokenizedChar;
MatchPattern(final String source, final String separator) {
- DefaultLog.getInstance().warn(String.format("Creating MatchPattern('%s', '%s')..."));
+ DefaultLog.getInstance().warn(String.format("Creating MatchPattern('%s', '%s')...", source, separator));
regexPattern = SelectorUtils.isRegexPrefixedPattern(source)
? source.substring(
SelectorUtils.REGEX_HANDLER_PREFIX.length(),
From 6f8c7a02c9dfc788f3d4f7c4e7dea5e99f1dc5c2 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 17:35:09 +0000
Subject: [PATCH 11/17] added debug info
---
.../org/apache/rat/config/exclusion/plexus/MatchPattern.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index ce180b331..49c6cedf3 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -51,7 +51,6 @@ public final class MatchPattern {
private final char[][] tokenizedChar;
MatchPattern(final String source, final String separator) {
- DefaultLog.getInstance().warn(String.format("Creating MatchPattern('%s', '%s')...", source, separator));
regexPattern = SelectorUtils.isRegexPrefixedPattern(source)
? source.substring(
SelectorUtils.REGEX_HANDLER_PREFIX.length(),
@@ -68,7 +67,9 @@ public final class MatchPattern {
for (int i = 0; i < tokenized.length; i++) {
tokenizedChar[i] = tokenized[i].toCharArray();
}
- DefaultLog.getInstance().warn(String.format("... as %s", this.toString()));
+ if (DefaultLog.getInstance().isEnabled(Log.Level.DEBUG)) {
+ DefaultLog.getInstance().debug(String.format("Created MatchPattern('%s', '%s') as %s", source, separator, this.toString()));
+ }
}
public boolean matchPath(final String str, final boolean isCaseSensitive) {
From 32cd2d163c440c3a60d4c90125a30e226ba83ac3 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 17:48:40 +0000
Subject: [PATCH 12/17] Attempt to fix pattern match creation
---
.../org/apache/rat/config/exclusion/ExclusionProcessor.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
index 105312930..c1de611ff 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/ExclusionProcessor.java
@@ -255,10 +255,10 @@ public DocumentNameMatcher getNameMatcher(final DocumentName basedir) {
.addTo(new ArrayList<>());
if (!incl.isEmpty()) {
- inclMatchers.add(new DocumentNameMatcher("included patterns", MatchPatterns.from("/", incl), basedir));
+ inclMatchers.add(new DocumentNameMatcher("included patterns", MatchPatterns.from(basedir.getDirectorySeparator(), incl), basedir));
}
if (!excl.isEmpty()) {
- exclMatchers.add(new DocumentNameMatcher("excluded patterns", MatchPatterns.from("/", excl), basedir));
+ exclMatchers.add(new DocumentNameMatcher("excluded patterns", MatchPatterns.from(basedir.getDirectorySeparator(), excl), basedir));
}
if (!includedPaths.isEmpty()) {
From c02f80222da1f716a91b1ee98e697c340b9a05b9 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 22:52:36 +0000
Subject: [PATCH 13/17] added debug info
---
.../java/org/apache/rat/document/FileDocument.java | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
index 3e7dec89b..891fd33b9 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
@@ -29,6 +29,7 @@
import org.apache.rat.api.Document;
import org.apache.rat.config.exclusion.ExclusionUtils;
+import org.apache.rat.utils.DefaultLog;
/**
* Document wrapping a File object.
@@ -52,11 +53,14 @@ public FileDocument(final DocumentName basedir, final File file, final DocumentN
/**
* Creates a File document where the baseDir is the root directory.
* @param file the file to wrap.
- * @param nameExcluder the path matcher to filter files/directories with.
+ * @param nameMatcher the path matcher to filter files/directories with.
*/
- public FileDocument(final File file, final DocumentNameMatcher nameExcluder) {
- super(DocumentName.builder(file).setBaseName(File.separator).build(), nameExcluder);
+ public FileDocument(final File file, final DocumentNameMatcher nameMatcher) {
+ super(DocumentName.builder(file).setBaseName(File.separator).build(), nameMatcher);
this.file = file;
+ DefaultLog.getInstance().info("Created file document " + file.getAbsolutePath());
+ DefaultLog.getInstance().info("... as " + this.getName().getName());
+ DefaultLog.getInstance().info("... on root " + this.getName().getRoot());
}
@Override
From 3c32108f34ed9a659ee1ebdd015bf6c33d0611ea Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 23:06:36 +0000
Subject: [PATCH 14/17] added debug info
---
.../main/java/org/apache/rat/api/Document.java | 12 ++++++------
.../org/apache/rat/document/FileDocument.java | 16 ++++++----------
.../org/apache/rat/walker/ArchiveWalker.java | 4 ++--
.../org/apache/rat/walker/FileListWalker.java | 5 ++++-
4 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/api/Document.java b/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
index 3e29eb350..0dbfa10cf 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/api/Document.java
@@ -52,7 +52,7 @@ public enum Type {
}
/** The path matcher used by this document */
- protected final DocumentNameMatcher nameExcluder;
+ protected final DocumentNameMatcher nameMatcher;
/** The metadata for this document */
private final MetaData metaData;
/** The fully qualified name of this document */
@@ -61,11 +61,11 @@ public enum Type {
/**
* Creates an instance.
* @param name the native NameSet of the resource.
- * @param nameExcluder the document name matcher to filter directories/files.
+ * @param nameMatcher the document name matcher to filter directories/files.
*/
- protected Document(final DocumentName name, final DocumentNameMatcher nameExcluder) {
+ protected Document(final DocumentName name, final DocumentNameMatcher nameMatcher) {
this.name = name;
- this.nameExcluder = nameExcluder;
+ this.nameMatcher = nameMatcher;
this.metaData = new MetaData();
}
@@ -81,8 +81,8 @@ public final DocumentName getName() {
* Gets the file filter this document was created with.
* @return the file filter this document was created with.
*/
- public final DocumentNameMatcher getNameExcluder() {
- return nameExcluder;
+ public final DocumentNameMatcher getNameMatcher() {
+ return nameMatcher;
}
@Override
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
index 891fd33b9..d7596a3ef 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
@@ -29,7 +29,6 @@
import org.apache.rat.api.Document;
import org.apache.rat.config.exclusion.ExclusionUtils;
-import org.apache.rat.utils.DefaultLog;
/**
* Document wrapping a File object.
@@ -43,10 +42,10 @@ public class FileDocument extends Document {
* Creates a File document.
* @param basedir the base directory for this document.
* @param file the file to wrap.
- * @param nameExcluder the path matcher to filter files/directories with.
+ * @param nameMatcher the path matcher to filter files/directories with.
*/
- public FileDocument(final DocumentName basedir, final File file, final DocumentNameMatcher nameExcluder) {
- super(DocumentName.builder(file).setBaseName(basedir.getBaseName()).build(), nameExcluder);
+ public FileDocument(final DocumentName basedir, final File file, final DocumentNameMatcher nameMatcher) {
+ super(DocumentName.builder(file).setBaseName(basedir.getBaseName()).build(), nameMatcher);
this.file = file;
}
@@ -58,9 +57,6 @@ public FileDocument(final DocumentName basedir, final File file, final DocumentN
public FileDocument(final File file, final DocumentNameMatcher nameMatcher) {
super(DocumentName.builder(file).setBaseName(File.separator).build(), nameMatcher);
this.file = file;
- DefaultLog.getInstance().info("Created file document " + file.getAbsolutePath());
- DefaultLog.getInstance().info("... as " + this.getName().getName());
- DefaultLog.getInstance().info("... on root " + this.getName().getRoot());
}
@Override
@@ -74,12 +70,12 @@ public SortedSet listChildren() {
SortedSet result = new TreeSet<>();
File[] files = file.listFiles();
if (files != null) {
- FileFilter fileFilter = ExclusionUtils.asFileFilter(name, nameExcluder);
+ FileFilter fileFilter = ExclusionUtils.asFileFilter(name, nameMatcher);
for (File child : files) {
if (fileFilter.accept(child)) {
- result.add(new FileDocument(name, child, nameExcluder));
+ result.add(new FileDocument(name, child, nameMatcher));
} else {
- result.add(new IgnoredDocument(name, child, nameExcluder));
+ result.add(new IgnoredDocument(name, child, nameMatcher));
}
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
index e2cc470e6..d1e9a3dad 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/ArchiveWalker.java
@@ -90,11 +90,11 @@ public Collection getDocuments() throws RatException {
if (!entry.isDirectory() && input.canReadEntryData(entry)) {
DocumentName innerName = DocumentName.builder().setName(entry.getName())
.setBaseName(".").build();
- if (this.getDocument().getNameExcluder().matches(innerName)) {
+ if (this.getDocument().getNameMatcher().matches(innerName)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(input, baos);
ArchiveEntryName entryName = new ArchiveEntryName(getDocument().getName(), entry.getName());
- result.add(new ArchiveEntryDocument(entryName, baos.toByteArray(), getDocument().getNameExcluder()));
+ result.add(new ArchiveEntryDocument(entryName, baos.toByteArray(), getDocument().getNameMatcher()));
}
}
}
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
index 6e6c50e5a..9cad11462 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
@@ -49,6 +49,8 @@ public class FileListWalker implements IReportable {
* @param source The file document that is the source from which this walker will read.
*/
public FileListWalker(final FileDocument source) {
+ DefaultLog.getInstance().info("Created file list document on " + source.getName().getName());
+ DefaultLog.getInstance().info("... on root " + source.getName().getRoot());
this.source = source;
File baseDir = source.getFile().getParentFile().getAbsoluteFile();
this.baseDoc = new FileDocument(baseDir, DocumentNameMatcher.MATCHES_ALL);
@@ -65,7 +67,8 @@ private FileDocument createDocument(final String unixFileName) {
String finalName = "/".equals(sourceName.getDirectorySeparator()) ? unixFileName :
unixFileName.replace("/", sourceName.getDirectorySeparator());
FileDocument documentBase = unixFileName.startsWith("/") ? rootDoc : baseDoc;
- File documentFile = new File(documentBase.getFile(), finalName);
+ File documentFile = new File(documentBase.getFile(), finalName).getAbsoluteFile();
+ DefaultLog.getInstance().info("Created file document on " + documentFile);
return new FileDocument(rootDoc.getName(), documentFile, DocumentNameMatcher.MATCHES_ALL);
}
From 093dee0ecd5ca3710a36f3138506c82874692c1a Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 15 Jan 2025 23:21:03 +0000
Subject: [PATCH 15/17] added debug info
---
.../src/main/java/org/apache/rat/document/FileDocument.java | 4 ++++
.../src/main/java/org/apache/rat/walker/FileListWalker.java | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
index d7596a3ef..5b811b4e1 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
@@ -29,6 +29,7 @@
import org.apache.rat.api.Document;
import org.apache.rat.config.exclusion.ExclusionUtils;
+import org.apache.rat.utils.DefaultLog;
/**
* Document wrapping a File object.
@@ -47,6 +48,9 @@ public class FileDocument extends Document {
public FileDocument(final DocumentName basedir, final File file, final DocumentNameMatcher nameMatcher) {
super(DocumentName.builder(file).setBaseName(basedir.getBaseName()).build(), nameMatcher);
this.file = file;
+ DefaultLog.getInstance().info("Created file document on " + file);
+ DefaultLog.getInstance().info("... as " + getName().getName());
+ DefaultLog.getInstance().info("... on " + getName().getRoot());
}
/**
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
index 9cad11462..bdcd5aea8 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
@@ -68,7 +68,7 @@ private FileDocument createDocument(final String unixFileName) {
unixFileName.replace("/", sourceName.getDirectorySeparator());
FileDocument documentBase = unixFileName.startsWith("/") ? rootDoc : baseDoc;
File documentFile = new File(documentBase.getFile(), finalName).getAbsoluteFile();
- DefaultLog.getInstance().info("Created file document on " + documentFile);
+ DefaultLog.getInstance().info("Creating document from " + unixFileName);
return new FileDocument(rootDoc.getName(), documentFile, DocumentNameMatcher.MATCHES_ALL);
}
From d96420b1dd6deab6b567f23131ac774ca229f693 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Thu, 16 Jan 2025 13:56:04 +0000
Subject: [PATCH 16/17] fixed FileListWalker
---
.../org/apache/rat/document/DocumentName.java | 2 +-
.../org/apache/rat/walker/FileListWalker.java | 23 ++++++++-----------
.../apache/rat/walker/FileListWalkerTest.java | 7 ++----
3 files changed, 13 insertions(+), 19 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 9b0c6a0d9..5dad33e37 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
@@ -629,7 +629,7 @@ private void setEmptyRoot(final String root) {
}
/**
- * Sets the properties from the file. Will reset the baseName appropraitly.
+ * Sets the properties from the file. Will reset the baseName appropriately.
* @param file the file to set the properties from.
* @return this.
*/
diff --git a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
index bdcd5aea8..5aa48852d 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/walker/FileListWalker.java
@@ -25,6 +25,7 @@
import org.apache.commons.io.IOUtils;
import org.apache.rat.api.RatException;
import org.apache.rat.commandline.Arg;
+import org.apache.rat.config.exclusion.ExclusionUtils;
import org.apache.rat.document.DocumentName;
import org.apache.rat.document.DocumentNameMatcher;
import org.apache.rat.document.FileDocument;
@@ -40,36 +41,32 @@ public class FileListWalker implements IReportable {
/** The source document name */
private final FileDocument source;
/** The root document name */
- private final FileDocument rootDoc;
+ private final DocumentName rootDoc;
/** the base directory for the source document */
- private final FileDocument baseDoc;
+ private final DocumentName baseDoc;
/**
* Constructor.
* @param source The file document that is the source from which this walker will read.
*/
public FileListWalker(final FileDocument source) {
- DefaultLog.getInstance().info("Created file list document on " + source.getName().getName());
- DefaultLog.getInstance().info("... on root " + source.getName().getRoot());
this.source = source;
File baseDir = source.getFile().getParentFile().getAbsoluteFile();
- this.baseDoc = new FileDocument(baseDir, DocumentNameMatcher.MATCHES_ALL);
+ this.baseDoc = DocumentName.builder(baseDir).build();
File p = baseDir;
while (p.getParentFile() != null) {
p = p.getParentFile();
}
- File rootDir = p;
- rootDoc = new FileDocument(rootDir, DocumentNameMatcher.MATCHES_ALL);
+ this.rootDoc = DocumentName.builder(p).build();
}
private FileDocument createDocument(final String unixFileName) {
DocumentName sourceName = source.getName();
- String finalName = "/".equals(sourceName.getDirectorySeparator()) ? unixFileName :
- unixFileName.replace("/", sourceName.getDirectorySeparator());
- FileDocument documentBase = unixFileName.startsWith("/") ? rootDoc : baseDoc;
- File documentFile = new File(documentBase.getFile(), finalName).getAbsoluteFile();
- DefaultLog.getInstance().info("Creating document from " + unixFileName);
- return new FileDocument(rootDoc.getName(), documentFile, DocumentNameMatcher.MATCHES_ALL);
+ String finalName = ExclusionUtils.convertSeparator(unixFileName, "/", sourceName.getDirectorySeparator());
+ DocumentName documentBase = unixFileName.startsWith("/") ? rootDoc : baseDoc;
+ DocumentName documentName = documentBase.resolve(finalName);
+ File documentFile = documentName.asFile();
+ return new FileDocument(documentBase, documentFile, DocumentNameMatcher.MATCHES_ALL);
}
@Override
diff --git a/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java b/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
index 9bc554029..ec739f643 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/walker/FileListWalkerTest.java
@@ -83,7 +83,7 @@ public static void setUp() throws Exception {
source = new File(working, "source.txt");
- DocumentName sourceName = DocumentName.builder(source).setBaseName(working.getAbsolutePath()).build();
+ DocumentName sourceName = DocumentName.builder(source).build();
File regular = new File(working, "regular");
regular.mkdir();
fileWriter(regular, "regularFile", "regular file");
@@ -110,14 +110,11 @@ public static void setUp() throws Exception {
writer.flush();
System.out.flush();
}
-
- hiddenName = DocumentName.builder(hiddenFile).setBaseName(rootName.getBaseName()).build();
}
@Test
public void readFilesTest() throws RatException {
- FileDocument fileDocument = new FileDocument(source, DocumentNameMatcher.MATCHES_ALL);
- FileListWalker walker = new FileListWalker(fileDocument);
+ FileListWalker walker = new FileListWalker(new FileDocument(source, DocumentNameMatcher.MATCHES_ALL));
List scanned = new ArrayList<>();
walker.run(new TestRatReport(scanned));
String[] expected = {regularName.localized("/"), hiddenName.localized("/"),
From 46cd644f620e2c863c4931b52c6e8789b068ae63 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Thu, 16 Jan 2025 14:12:27 +0000
Subject: [PATCH 17/17] reduced logging noise
---
.../org/apache/rat/config/exclusion/plexus/MatchPattern.java | 3 ---
.../src/main/java/org/apache/rat/document/FileDocument.java | 4 ----
2 files changed, 7 deletions(-)
diff --git a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index 49c6cedf3..ff6505986 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -67,9 +67,6 @@ public final class MatchPattern {
for (int i = 0; i < tokenized.length; i++) {
tokenizedChar[i] = tokenized[i].toCharArray();
}
- if (DefaultLog.getInstance().isEnabled(Log.Level.DEBUG)) {
- DefaultLog.getInstance().debug(String.format("Created MatchPattern('%s', '%s') as %s", source, separator, this.toString()));
- }
}
public boolean matchPath(final String str, final boolean isCaseSensitive) {
diff --git a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
index 5b811b4e1..d7596a3ef 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/document/FileDocument.java
@@ -29,7 +29,6 @@
import org.apache.rat.api.Document;
import org.apache.rat.config.exclusion.ExclusionUtils;
-import org.apache.rat.utils.DefaultLog;
/**
* Document wrapping a File object.
@@ -48,9 +47,6 @@ public class FileDocument extends Document {
public FileDocument(final DocumentName basedir, final File file, final DocumentNameMatcher nameMatcher) {
super(DocumentName.builder(file).setBaseName(basedir.getBaseName()).build(), nameMatcher);
this.file = file;
- DefaultLog.getInstance().info("Created file document on " + file);
- DefaultLog.getInstance().info("... as " + getName().getName());
- DefaultLog.getInstance().info("... on " + getName().getRoot());
}
/**