Change containsDirectory to hasNamedPathSegment

This commit is contained in:
Joakim Erdfelt 2022-08-01 10:57:11 -05:00
parent 84f6dc7f4c
commit a9516453c2
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
2 changed files with 82 additions and 79 deletions

View File

@ -26,28 +26,6 @@ import java.util.Locale;
*/
public class FileID
{
/**
* Does the provided path have a directory segment with
* the configured name.
*
* @param path the path to search
* @param directoryName the directory name to look for (case insensitive lookup)
* @return true if the directory name exists in path, false if otherwise
*/
public static boolean containsDirectory(Path path, String directoryName)
{
if (path == null)
return false;
int segmentCount = path.getNameCount();
for (int i = segmentCount - 1; i >= 0; i--)
{
Path segment = path.getName(i);
if (segment.getFileName().toString().equalsIgnoreCase(directoryName))
return true;
}
return false;
}
/**
* Retrieve the basename of a path. This is the name of the
* last segment of the path, with any dot suffix (e.g. ".war") removed
@ -109,6 +87,29 @@ public class FileID
return filename.substring(lastDot).toLowerCase(Locale.ENGLISH);
}
/**
* Does the provided path have a directory segment with the given name.
*
* @param path the path to search
* @param segmentName the segment name (of the given path) to look for (case insensitive lookup),
* only capable of searching 1 segment name at a time, does not support "foo/bar" multi-segment
* names.
* @return true if the directory name exists in path, false if otherwise
*/
public static boolean hasNamedPathSegment(Path path, String segmentName)
{
if (path == null)
return false;
int segmentCount = path.getNameCount();
for (int i = segmentCount - 1; i >= 0; i--)
{
Path segment = path.getName(i);
if (segment.getFileName().toString().equalsIgnoreCase(segmentName))
return true;
}
return false;
}
/**
* Test if Path is any supported Java Archive type (ends in {@code .jar}, {@code .war}, or {@code .zip}).
*
@ -288,6 +289,40 @@ public class FileID
path2.getFileName().toString().matches("[0-9]+"));
}
/**
* Predicate to skip {@code META-INF/versions/*} tree from walk/stream results.
*
* <p>
* This only works with a zipfs based FileSystem
* </p>
*
* @param path the path to test
* @return true if not in {@code META-INF/versions/*} tree
*/
public static boolean isNotMetaInfVersions(Path path)
{
return !isMetaInfVersions(path);
}
/**
* Predicate to skip {@code module-info.class} files.
*
* <p>
* This is a simple test against the last path segment using {@link Path#getFileName()}
* </p>
*
* @param path the path to test
* @return true if not a {@code module-info.class} file
*/
public static boolean isNotModuleInfoClass(Path path)
{
Path filenameSegment = path.getFileName();
if (filenameSegment == null)
return true;
return !filenameSegment.toString().equalsIgnoreCase("module-info.class");
}
/**
* Is the path a TLD File
*
@ -298,7 +333,7 @@ public class FileID
{
if (path == null)
return false;
if (!containsDirectory(path, "META-INF"))
if (!hasNamedPathSegment(path, "META-INF"))
return false;
return ".tld".equals(getExtension(path));
}
@ -346,38 +381,4 @@ public class FileID
{
return ".xml".equals(getExtension(filename));
}
/**
* Predicate to skip {@code META-INF/versions/*} tree from walk/stream results.
*
* <p>
* This only works with a zipfs based FileSystem
* </p>
*
* @param path the path to test
* @return true if not in {@code META-INF/versions/*} tree
*/
public static boolean isNotMetaInfVersions(Path path)
{
return !isMetaInfVersions(path);
}
/**
* Predicate to skip {@code module-info.class} files.
*
* <p>
* This is a simple test against the last path segment using {@link Path#getFileName()}
* </p>
*
* @param path the path to test
* @return true if not a {@code module-info.class} file
*/
public static boolean isNotModuleInfoClass(Path path)
{
Path filenameSegment = path.getFileName();
if (filenameSegment == null)
return true;
return !filenameSegment.toString().equalsIgnoreCase("module-info.class");
}
}

View File

@ -96,7 +96,7 @@ public class FileIDTest
}
}
public static Stream<Arguments> containsDirectoryTrueCases()
public static Stream<Arguments> hasNamedPathSegmentTrueCases()
{
return Stream.of(
Arguments.of("path/to/webapps/root.war", "webapps"),
@ -108,17 +108,17 @@ public class FileIDTest
}
/**
* Tests of {@link FileID#containsDirectory(Path, String)} on a real file system
* Tests of {@link FileID#hasNamedPathSegment(Path, String)} on a real file system
*/
@ParameterizedTest
@MethodSource("containsDirectoryTrueCases")
public void testContainsDirectoryTrue(String input, String dirname) throws IOException
@MethodSource("hasNamedPathSegmentTrueCases")
public void testHasNamedPathSegmentTrue(String input, String dirname) throws IOException
{
Path path = touchTestPath(input);
assertTrue(FileID.containsDirectory(path, dirname), "containsDirectory(%s, \"%s\")".formatted(path, dirname));
assertTrue(FileID.hasNamedPathSegment(path, dirname), "hasNamedPathSegment(%s, \"%s\")".formatted(path, dirname));
}
public static Stream<Arguments> containsDirectoryFalseCases()
public static Stream<Arguments> hasNamedPathSegmentFalseCases()
{
return Stream.of(
Arguments.of("path/to/webapps/root.war", "WEB-INF"),
@ -129,31 +129,32 @@ public class FileIDTest
}
/**
* Tests of {@link FileID#containsDirectory(Path, String)} on a real file system
* Tests of {@link FileID#hasNamedPathSegment(Path, String)} on a real file system
*/
@ParameterizedTest
@MethodSource("containsDirectoryFalseCases")
public void testContainsDirectoryFalse(String input, String dirname) throws IOException
@MethodSource("hasNamedPathSegmentFalseCases")
public void testHasNamedPathSegmentFalse(String input, String dirname) throws IOException
{
Path path = touchTestPath(input);
assertFalse(FileID.containsDirectory(path, dirname), "containsDirectory(%s, \"%s\")".formatted(path, dirname));
assertFalse(FileID.hasNamedPathSegment(path, dirname), "hasNamedPathSegment(%s, \"%s\")".formatted(path, dirname));
}
public static Stream<Arguments> containsDirectoryTrueZipFsCases()
public static Stream<Arguments> hasNamedPathSegmentCasesTrue()
{
return Stream.of(
Arguments.of("/META-INF/services/org.eclipse.jetty.FooService", "META-INF"),
Arguments.of("/WEB-INF/lib/lib-1.jar", "WEB-INF"),
Arguments.of("/WEB-INF/dir/foo.tld", "WEB-INF")
Arguments.of("/WEB-INF/dir/foo.tld", "WEB-INF"),
Arguments.of("/opt/web/base/webapps/root.war", "webapps")
);
}
/**
* Tests of {@link FileID#containsDirectory(Path, String)} on a ZipFS based file system
* Tests of {@link FileID#hasNamedPathSegment(Path, String)} on a ZipFS based file system
*/
@ParameterizedTest
@MethodSource("containsDirectoryTrueZipFsCases")
public void containsDirectoryTrueZipFs(String input, String dirname) throws IOException
@MethodSource("hasNamedPathSegmentCasesTrue")
public void testHasNamedPathSegmentsTrueZipFs(String input, String dirname) throws IOException
{
Path outputJar = workDir.getEmptyPathDir().resolve("test.jar");
Map<String, String> env = new HashMap<>();
@ -164,26 +165,26 @@ public class FileIDTest
{
Path root = zipfs.getPath("/");
Path path = touchTestPath(root, input);
assertTrue(FileID.containsDirectory(path, dirname), "containsDirectory(%s, \"%s\")".formatted(path, dirname));
assertTrue(FileID.hasNamedPathSegment(path, dirname), "hasNamedPathSegment(%s, \"%s\")".formatted(path, dirname));
}
}
public static Stream<Arguments> containsDirectoryFalseZipFsCases()
public static Stream<Arguments> hasNamedPathSegmentFalseZipFsCases()
{
return Stream.of(
Arguments.of("/css/main.css", "WEB-INF"),
Arguments.of("/META-INF/classes/module-info.class", "WEB-INF"),
Arguments.of("/", "util"),
Arguments.of("/", "tmp"),
Arguments.of("/index.html", "target") // shouldn't detect that the zipfs archive is in the target directory
);
}
/**
* Tests of {@link FileID#containsDirectory(Path, String)} on a ZipFS based file system
* Tests of {@link FileID#hasNamedPathSegment(Path, String)} on a ZipFS based file system
*/
@ParameterizedTest
@MethodSource("containsDirectoryFalseZipFsCases")
public void containsDirectoryFalseZipFs(String input, String dirname) throws IOException
@MethodSource("hasNamedPathSegmentFalseZipFsCases")
public void testHasNamedPathSegmentFalseZipFs(String input, String dirname) throws IOException
{
Path outputJar = workDir.getEmptyPathDir().resolve("test.jar");
Map<String, String> env = new HashMap<>();
@ -194,8 +195,9 @@ public class FileIDTest
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env))
{
Path root = zipfs.getPath("/");
FS.ensureDirExists(root.resolve("/tmp"));
Path path = touchTestPath(root, input);
assertFalse(FileID.containsDirectory(path, dirname), "containsDirectory(%s, \"%s\")".formatted(path, dirname));
assertFalse(FileID.hasNamedPathSegment(path, dirname), "hasNamedPathSegment(%s, \"%s\")".formatted(path, dirname));
}
}