From 1f6bdc09382a87d07a21dd9f5e01bdc9c3d7f8fd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 14:25:34 +0000 Subject: [PATCH] Add Path-based methods and deprecate File-based methods Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- .../io/attributes/AttributeUtils.java | 65 +++++++++++--- .../io/attributes/FileAttributes.java | 22 ++++- .../PlexusIoResourceAttributeUtils.java | 67 +++++++++++--- .../io/attributes/SymlinkUtils.java | 38 ++++++-- ...ractPlexusIoArchiveResourceCollection.java | 22 ++++- ...xusIoCompressedFileResourceCollection.java | 16 ++++ .../PlexusIoFileResourceCollection.java | 18 ++++ .../io/resources/ResourceFactory.java | 84 +++++++++++++++--- .../io/attributes/AttributeUtilsTest.java | 18 ++++ .../io/attributes/FileAttributesTest.java | 25 ++++++ .../PlexusIoResourceAttributeUtilsTest.java | 47 ++++++++++ .../io/attributes/SymlinkUtilsTest.java | 22 +++++ .../io/resources/ResourceFactoryPathTest.java | 41 +++++++++ src/test/resources/symlinks/symlinks.tar | Bin 13824 -> 36864 bytes src/test/resources/symlinks/symlinks.zip | Bin 1616 -> 1774 bytes 15 files changed, 442 insertions(+), 43 deletions(-) create mode 100644 src/test/java/org/codehaus/plexus/components/io/resources/ResourceFactoryPathTest.java diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/AttributeUtils.java b/src/main/java/org/codehaus/plexus/components/io/attributes/AttributeUtils.java index be00c0a5..3b6ba15f 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/AttributeUtils.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/AttributeUtils.java @@ -38,22 +38,37 @@ public class AttributeUtils { /* Reads last-modified with proper failure handling if something goes wrong. */ - public static long getLastModified(@Nonnull File file) { + public static long getLastModified(@Nonnull Path path) { try { - BasicFileAttributes basicFileAttributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class); + BasicFileAttributes basicFileAttributes = Files.readAttributes(path, BasicFileAttributes.class); return basicFileAttributes.lastModifiedTime().toMillis(); } catch (IOException e) { throw new RuntimeException(e); } } - public static void chmod(@Nonnull File file, int mode) throws IOException { - final Path path = file.toPath(); + /** + * @deprecated Use {@link #getLastModified(Path)} instead + */ + @Deprecated + public static long getLastModified(@Nonnull File file) { + return getLastModified(file.toPath()); + } + + public static void chmod(@Nonnull Path path, int mode) throws IOException { if (!Files.isSymbolicLink(path)) { Files.setPosixFilePermissions(path, getPermissions(mode)); } } + /** + * @deprecated Use {@link #chmod(Path, int)} instead + */ + @Deprecated + public static void chmod(@Nonnull File file, int mode) throws IOException { + chmod(file.toPath(), mode); + } + @Nonnull public static Set getPermissions(int mode) { Set perms = new HashSet<>(); @@ -90,14 +105,22 @@ public static Set getPermissions(int mode) { return perms; } + /** + * @deprecated Use {@link Files#readAttributes(Path, Class, java.nio.file.LinkOption...)} directly + */ + @Deprecated @Nonnull - public static PosixFileAttributes getPosixFileAttributes(@Nonnull File file) throws IOException { - return Files.readAttributes(file.toPath(), PosixFileAttributes.class, LinkOption.NOFOLLOW_LINKS); + public static PosixFileAttributes getPosixFileAttributes(@Nonnull Path path) throws IOException { + return Files.readAttributes(path, PosixFileAttributes.class, LinkOption.NOFOLLOW_LINKS); } + /** + * @deprecated Use {@link Files#readAttributes(Path, Class, java.nio.file.LinkOption...)} directly + */ + @Deprecated @Nonnull - public static BasicFileAttributes getFileAttributes(@Nonnull File file) throws IOException { - return getFileAttributes(file.toPath()); + public static PosixFileAttributes getPosixFileAttributes(@Nonnull File file) throws IOException { + return getPosixFileAttributes(file.toPath()); } public static BasicFileAttributes getFileAttributes(Path path) throws IOException { @@ -111,16 +134,38 @@ public static BasicFileAttributes getFileAttributes(Path path) throws IOExceptio return Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); } + /** + * @deprecated Use {@link #getFileAttributes(Path)} instead + */ + @Deprecated + @Nonnull + public static BasicFileAttributes getFileAttributes(@Nonnull File file) throws IOException { + return getFileAttributes(file.toPath()); + } + public static boolean isUnix(Path path) { return path.getFileSystem().supportedFileAttributeViews().contains("unix"); } + /** + * @deprecated Use {@link Files#getFileAttributeView(Path, Class, java.nio.file.LinkOption...)} directly + */ + @Deprecated @Nullable - public static FileOwnerAttributeView getFileOwnershipInfo(@Nonnull File file) throws IOException { + public static FileOwnerAttributeView getFileOwnershipInfo(@Nonnull Path path) throws IOException { try { - return Files.getFileAttributeView(file.toPath(), FileOwnerAttributeView.class, LinkOption.NOFOLLOW_LINKS); + return Files.getFileAttributeView(path, FileOwnerAttributeView.class, LinkOption.NOFOLLOW_LINKS); } catch (UnsupportedOperationException e) { return null; } } + + /** + * @deprecated Use {@link Files#getFileAttributeView(Path, Class, java.nio.file.LinkOption...)} directly + */ + @Deprecated + @Nullable + public static FileOwnerAttributeView getFileOwnershipInfo(@Nonnull File file) throws IOException { + return getFileOwnershipInfo(file.toPath()); + } } diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java b/src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java index 214387c7..3a31c016 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/FileAttributes.java @@ -86,14 +86,26 @@ public FileAttributes( this(file); } + /** + * @deprecated Use {@link #FileAttributes(Path)} instead + */ + @Deprecated public FileAttributes(@Nonnull File file) throws IOException { this(file.toPath(), false); } + /** + * @deprecated Use {@link #FileAttributes(Path, boolean)} instead + */ + @Deprecated public FileAttributes(@Nonnull File file, boolean followLinks) throws IOException { this(file.toPath(), followLinks); } + public FileAttributes(@Nonnull Path path) throws IOException { + this(path, false); + } + private static Map getUserCache(FileSystem fs) { return UIDS_CACHE.computeIfAbsent(fs, f -> new ConcurrentHashMap<>()); } @@ -199,8 +211,16 @@ public FileAttributes( this.lastModifiedTime = lastModifiedTime; } + public static @Nonnull PlexusIoResourceAttributes uncached(@Nonnull Path path) throws IOException { + return new FileAttributes(path); + } + + /** + * @deprecated Use {@link #uncached(Path)} instead + */ + @Deprecated public static @Nonnull PlexusIoResourceAttributes uncached(@Nonnull File file) throws IOException { - return new FileAttributes(file); + return uncached(file.toPath()); } @Nullable diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java b/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java index 1d707385..8f7debb2 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtils.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -118,36 +119,48 @@ public static boolean isOctalModeEnabled(int mode, int targetMode) { return (mode & targetMode) != 0; } + public static PlexusIoResourceAttributes getFileAttributes(Path path) throws IOException { + return getFileAttributes(path, false); + } + + public static PlexusIoResourceAttributes getFileAttributes(Path path, boolean followLinks) throws IOException { + return new FileAttributes(path, followLinks); + } + + /** + * @deprecated Use {@link #getFileAttributes(Path)} instead + */ + @Deprecated public static PlexusIoResourceAttributes getFileAttributes(File file) throws IOException { - return getFileAttributes(file, false); + return getFileAttributes(file.toPath(), false); } + /** + * @deprecated Use {@link #getFileAttributes(Path, boolean)} instead + */ + @Deprecated public static PlexusIoResourceAttributes getFileAttributes(File file, boolean followLinks) throws IOException { - Map byPath = getFileAttributesByPath(file, false, followLinks); - final PlexusIoResourceAttributes o = byPath.get(file.getAbsolutePath()); - if (o == null) { - // We're on a crappy old java version (5) or the OS from hell. Just "fail". - return SimpleResourceAttributes.lastResortDummyAttributesForBrokenOS(); - } - return o; + return getFileAttributes(file.toPath(), followLinks); } - public static Map getFileAttributesByPath(File dir) throws IOException { + public static @Nonnull Map getFileAttributesByPath(Path dir) + throws IOException { return getFileAttributesByPath(dir, true); } public static @Nonnull Map getFileAttributesByPath( - @Nonnull File dir, boolean recursive) throws IOException { + @Nonnull Path dir, boolean recursive) throws IOException { return getFileAttributesByPath(dir, recursive, false); } public static @Nonnull Map getFileAttributesByPath( - @Nonnull File dir, boolean recursive, boolean followLinks) throws IOException { + @Nonnull Path dir, boolean recursive, boolean followLinks) throws IOException { final List fileAndDirectoryNames; - if (recursive && dir.isDirectory()) { - fileAndDirectoryNames = FileUtils.getFileAndDirectoryNames(dir, null, null, true, true, true, true); + File dirAsFile = dir.toFile(); + if (recursive && java.nio.file.Files.isDirectory(dir)) { + fileAndDirectoryNames = FileUtils.getFileAndDirectoryNames(dirAsFile, null, null, true, true, true, true); } else { - fileAndDirectoryNames = Collections.singletonList(dir.getAbsolutePath()); + fileAndDirectoryNames = Collections.singletonList(dirAsFile.getAbsolutePath()); } final Map attributesByPath = new LinkedHashMap<>(); @@ -157,4 +170,30 @@ public static Map getFileAttributesByPath(Fi } return attributesByPath; } + + /** + * @deprecated Use {@link #getFileAttributesByPath(Path)} instead + */ + @Deprecated + public static Map getFileAttributesByPath(File dir) throws IOException { + return getFileAttributesByPath(dir.toPath(), true); + } + + /** + * @deprecated Use {@link #getFileAttributesByPath(Path, boolean)} instead + */ + @Deprecated + public static @Nonnull Map getFileAttributesByPath( + @Nonnull File dir, boolean recursive) throws IOException { + return getFileAttributesByPath(dir.toPath(), recursive, false); + } + + /** + * @deprecated Use {@link #getFileAttributesByPath(Path, boolean, boolean)} instead + */ + @Deprecated + public static @Nonnull Map getFileAttributesByPath( + @Nonnull File dir, boolean recursive, boolean followLinks) throws IOException { + return getFileAttributesByPath(dir.toPath(), recursive, followLinks); + } } diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/SymlinkUtils.java b/src/main/java/org/codehaus/plexus/components/io/attributes/SymlinkUtils.java index 6c6ea684..de0d70a6 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/SymlinkUtils.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/SymlinkUtils.java @@ -27,22 +27,48 @@ * @author Kristian Rosenvold */ public class SymlinkUtils { + /** + * Reads the target of the symbolic link + * + * @param symlink A path that is a symlink + * @return A path that is the target of the symlink + * @throws java.io.IOException + * @deprecated Use {@link Files#readSymbolicLink(Path)} directly + */ + @Deprecated + public static @Nonnull Path readSymbolicLink(@Nonnull Path symlink) throws IOException { + return Files.readSymbolicLink(symlink); + } + /** * Reads the target of the symbolic link * * @param symlink A file that is a symlink * @return A file that is the target of the symlink * @throws java.io.IOException + * @deprecated Use {@link Files#readSymbolicLink(Path)} directly */ + @Deprecated public static @Nonnull File readSymbolicLink(@Nonnull File symlink) throws IOException { - return Files.readSymbolicLink(symlink.toPath()).toFile(); + return readSymbolicLink(symlink.toPath()).toFile(); } - public static @Nonnull File createSymbolicLink(@Nonnull File symlink, File target) throws IOException { - Path link = symlink.toPath(); - if (!Files.exists(link, LinkOption.NOFOLLOW_LINKS)) { - link = Files.createSymbolicLink(link, target.toPath()); + /** + * @deprecated Use {@link Files#createSymbolicLink(Path, Path, java.nio.file.attribute.FileAttribute[])} directly + */ + @Deprecated + public static @Nonnull Path createSymbolicLink(@Nonnull Path symlink, Path target) throws IOException { + if (!Files.exists(symlink, LinkOption.NOFOLLOW_LINKS)) { + return Files.createSymbolicLink(symlink, target); } - return link.toFile(); + return symlink; + } + + /** + * @deprecated Use {@link Files#createSymbolicLink(Path, Path, java.nio.file.attribute.FileAttribute[])} directly + */ + @Deprecated + public static @Nonnull File createSymbolicLink(@Nonnull File symlink, File target) throws IOException { + return createSymbolicLink(symlink.toPath(), target.toPath()).toFile(); } } diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/AbstractPlexusIoArchiveResourceCollection.java b/src/main/java/org/codehaus/plexus/components/io/resources/AbstractPlexusIoArchiveResourceCollection.java index 03d73cfa..65765719 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/AbstractPlexusIoArchiveResourceCollection.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/AbstractPlexusIoArchiveResourceCollection.java @@ -35,15 +35,33 @@ public abstract class AbstractPlexusIoArchiveResourceCollection extends Abstract protected AbstractPlexusIoArchiveResourceCollection() {} /** - * Sets the zip file + * Sets the archive file */ + public void setFile(java.nio.file.Path file) { + this.file = file.toFile(); + } + + /** + * Sets the archive file + * @deprecated Use {@link #setFile(java.nio.file.Path)} instead + */ + @Deprecated public void setFile(File file) { this.file = file; } /** - * Returns the zip file + * Returns the archive file as a Path + */ + public java.nio.file.Path getFileAsPath() { + return file != null ? file.toPath() : null; + } + + /** + * Returns the archive file + * @deprecated Use {@link #getFileAsPath()} instead */ + @Deprecated public File getFile() { return file; } diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoCompressedFileResourceCollection.java b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoCompressedFileResourceCollection.java index 64ba973c..4aeea2d4 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoCompressedFileResourceCollection.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoCompressedFileResourceCollection.java @@ -42,10 +42,26 @@ public abstract class PlexusIoCompressedFileResourceCollection private InputStreamTransformer streamTransformers = AbstractPlexusIoResourceCollection.identityTransformer; + public java.nio.file.Path getFileAsPath() { + return file != null ? file.toPath() : null; + } + + /** + * @deprecated Use {@link #getFileAsPath()} instead + */ + @Deprecated public File getFile() { return file; } + public void setFile(java.nio.file.Path file) { + this.file = file.toFile(); + } + + /** + * @deprecated Use {@link #setFile(java.nio.file.Path)} instead + */ + @Deprecated public void setFile(File file) { this.file = file; } diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResourceCollection.java b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResourceCollection.java index 71dcc5f3..8454d423 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResourceCollection.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResourceCollection.java @@ -75,13 +75,31 @@ public String getName(PlexusIoResource resource) { /** * @param baseDir The base directory of the file collection */ + public void setBaseDir(java.nio.file.Path baseDir) { + this.baseDir = baseDir.toFile(); + } + + /** + * @param baseDir The base directory of the file collection + * @deprecated Use {@link #setBaseDir(java.nio.file.Path)} instead + */ + @Deprecated public void setBaseDir(File baseDir) { this.baseDir = baseDir; } + /** + * @return Returns the file collections base directory as a Path. + */ + public java.nio.file.Path getBaseDirAsPath() { + return baseDir != null ? baseDir.toPath() : null; + } + /** * @return Returns the file collections base directory. + * @deprecated Use {@link #getBaseDirAsPath()} instead */ + @Deprecated public File getBaseDir() { return baseDir; } diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/ResourceFactory.java b/src/main/java/org/codehaus/plexus/components/io/resources/ResourceFactory.java index 8db319b4..edf3f2e9 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/ResourceFactory.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/ResourceFactory.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import org.codehaus.plexus.components.io.attributes.FileAttributes; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; @@ -15,31 +16,98 @@ * @author Kristian Rosenvold */ public class ResourceFactory { + public static PlexusIoResource createResource(Path path) throws IOException { + return createResource(path, getName(path.toFile()), null, null, getFileAttributes(path)); + } + + public static PlexusIoResource createResource(Path path, String name) throws IOException { + return createResource(path, name, null, null, getFileAttributes(path)); + } + + public static PlexusIoResource createResource( + Path path, String name, final ContentSupplier contentSupplier, PlexusIoResourceAttributes attributes) + throws IOException { + return createResource(path, name, contentSupplier, null, attributes); + } + + public static PlexusIoResource createResource(Path path, InputStreamTransformer inputStreamTransformer) + throws IOException { + return createResource(path, getName(path.toFile()), null, inputStreamTransformer, getFileAttributes(path)); + } + + public static PlexusIoResource createResource( + Path path, + String name, + final ContentSupplier contentSupplier, + InputStreamTransformer inputStreamTransformer) + throws IOException { + return createResource(path, name, contentSupplier, inputStreamTransformer, getFileAttributes(path)); + } + + public static PlexusIoResource createResource( + Path path, + String name, + final ContentSupplier contentSupplier, + InputStreamTransformer inputStreamTransformer, + PlexusIoResourceAttributes attributes) + throws IOException { + File f = path.toFile(); + boolean symbolicLink = attributes.isSymbolicLink(); + return symbolicLink + ? new PlexusIoSymlinkResource(f, name, attributes) + : new PlexusIoFileResource( + f, name, attributes, new FileAttributes(path, true), contentSupplier, inputStreamTransformer); + } + + /** + * @deprecated Use {@link #createResource(Path)} instead + */ + @Deprecated public static PlexusIoResource createResource(File f) throws IOException { - return createResource(f, getName(f), null, null, getFileAttributes(f)); + return createResource(f.toPath()); } + /** + * @deprecated Use {@link #createResource(Path, String)} instead + */ + @Deprecated public static PlexusIoResource createResource(File f, String name) throws IOException { - return createResource(f, name, null, null, getFileAttributes(f)); + return createResource(f.toPath(), name); } + /** + * @deprecated Use {@link #createResource(Path, String, ContentSupplier, PlexusIoResourceAttributes)} instead + */ + @Deprecated public static PlexusIoResource createResource( File f, String name, final ContentSupplier contentSupplier, PlexusIoResourceAttributes attributes) throws IOException { - return createResource(f, name, contentSupplier, null, attributes); + return createResource(f.toPath(), name, contentSupplier, attributes); } + /** + * @deprecated Use {@link #createResource(Path, InputStreamTransformer)} instead + */ + @Deprecated public static PlexusIoResource createResource(File f, InputStreamTransformer inputStreamTransformer) throws IOException { - return createResource(f, getName(f), null, inputStreamTransformer, getFileAttributes(f)); + return createResource(f.toPath(), inputStreamTransformer); } + /** + * @deprecated Use {@link #createResource(Path, String, ContentSupplier, InputStreamTransformer)} instead + */ + @Deprecated public static PlexusIoResource createResource( File f, String name, final ContentSupplier contentSupplier, InputStreamTransformer inputStreamTransformer) throws IOException { - return createResource(f, name, contentSupplier, inputStreamTransformer, getFileAttributes(f)); + return createResource(f.toPath(), name, contentSupplier, inputStreamTransformer); } + /** + * @deprecated Use {@link #createResource(Path, String, ContentSupplier, InputStreamTransformer, PlexusIoResourceAttributes)} instead + */ + @Deprecated public static PlexusIoResource createResource( File f, String name, @@ -47,10 +115,6 @@ public static PlexusIoResource createResource( InputStreamTransformer inputStreamTransformer, PlexusIoResourceAttributes attributes) throws IOException { - boolean symbolicLink = attributes.isSymbolicLink(); - return symbolicLink - ? new PlexusIoSymlinkResource(f, name, attributes) - : new PlexusIoFileResource( - f, name, attributes, new FileAttributes(f, true), contentSupplier, inputStreamTransformer); + return createResource(f.toPath(), name, contentSupplier, inputStreamTransformer, attributes); } } diff --git a/src/test/java/org/codehaus/plexus/components/io/attributes/AttributeUtilsTest.java b/src/test/java/org/codehaus/plexus/components/io/attributes/AttributeUtilsTest.java index 49cee7f5..1a60b7de 100644 --- a/src/test/java/org/codehaus/plexus/components/io/attributes/AttributeUtilsTest.java +++ b/src/test/java/org/codehaus/plexus/components/io/attributes/AttributeUtilsTest.java @@ -1,6 +1,8 @@ package org.codehaus.plexus.components.io.attributes; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.attribute.PosixFilePermission; import java.util.Set; @@ -62,4 +64,20 @@ void chmodBackAndForth() throws Exception { assertTrue(secondAttrs.isOwnerWritable()); assertTrue(secondAttrs.isOwnerExecutable()); } + + @Test + @DisabledOnOs(OS.WINDOWS) + void chmodBackAndForthWithPath() throws Exception { + final Path bxx = Files.createTempFile("bxx", "ff"); + AttributeUtils.chmod(bxx, 0422); + PlexusIoResourceAttributes firstAttrs = new FileAttributes(bxx); + assertTrue(firstAttrs.isOwnerReadable()); + assertFalse(firstAttrs.isOwnerWritable()); + assertFalse(firstAttrs.isOwnerExecutable()); + AttributeUtils.chmod(bxx, 0777); + PlexusIoResourceAttributes secondAttrs = new FileAttributes(bxx); + assertTrue(secondAttrs.isOwnerReadable()); + assertTrue(secondAttrs.isOwnerWritable()); + assertTrue(secondAttrs.isOwnerExecutable()); + } } diff --git a/src/test/java/org/codehaus/plexus/components/io/attributes/FileAttributesTest.java b/src/test/java/org/codehaus/plexus/components/io/attributes/FileAttributesTest.java index 65e917dc..ea46af48 100644 --- a/src/test/java/org/codehaus/plexus/components/io/attributes/FileAttributesTest.java +++ b/src/test/java/org/codehaus/plexus/components/io/attributes/FileAttributesTest.java @@ -18,6 +18,7 @@ import java.io.File; import java.nio.file.Files; +import java.nio.file.Path; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; @@ -52,4 +53,28 @@ void fileAttributesHandlesIOException() throws Exception { tempFile.delete(); } } + + @Test + @DisabledOnOs(OS.WINDOWS) + void getPosixFileAttributesWithPath() throws Exception { + Path path = java.nio.file.Paths.get("."); + PlexusIoResourceAttributes fa = new FileAttributes(path); + assertNotNull(fa); + } + + @Test + void fileAttributesHandlesIOExceptionWithPath() throws Exception { + // Test that FileAttributes can be constructed for a regular file using Path + // even if ownership information is not available (e.g., WSL2 mapped network drives) + Path tempPath = Files.createTempFile("plexus-io-test", ".tmp"); + try { + // This should not throw even if ownership info is unavailable + PlexusIoResourceAttributes fa = new FileAttributes(tempPath); + assertNotNull(fa); + // The attributes object should be usable even if userName/groupName are null + assertNotNull(fa.toString()); + } finally { + Files.deleteIfExists(tempPath); + } + } } diff --git a/src/test/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtilsTest.java b/src/test/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtilsTest.java index e14c3580..f1e67974 100644 --- a/src/test/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtilsTest.java +++ b/src/test/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributeUtilsTest.java @@ -19,6 +19,7 @@ import java.io.File; import java.net.URL; import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.util.Map; import org.codehaus.plexus.util.StringUtils; @@ -326,4 +327,50 @@ void mergeAttributesDefault() { assertNull(attributes.getGroupName()); assertEquals(0, attributes.getOctalMode()); } + + @Test + @DisabledOnOs(OS.WINDOWS) + void getAttributesForThisTestClassWithPath() throws Exception { + URL resource = Thread.currentThread() + .getContextClassLoader() + .getResource(getClass().getName().replace('.', '/') + ".class"); + + if (resource == null) { + throw new IllegalStateException("SOMETHING IS VERY WRONG. CANNOT FIND THIS TEST CLASS IN THE CLASSLOADER."); + } + + Path path = java.nio.file.Paths.get(resource.getPath().replaceAll("%20", " ")); + + Map attrs = + PlexusIoResourceAttributeUtils.getFileAttributesByPath(path, true); + + PlexusIoResourceAttributes fileAttrs = attrs.get(path.toFile().getAbsolutePath()); + + assertNotNull(fileAttrs); + assertTrue(fileAttrs.isOwnerReadable()); + assertEquals(System.getProperty("user.name"), fileAttrs.getUserName()); + } + + @Test + @DisabledOnOs(OS.WINDOWS) + void srcResourceWithPath() throws Exception { + Path dir = java.nio.file.Paths.get("src/test/resources/symlinks"); + final Map fileAttributesByPathScreenScrape = + PlexusIoResourceAttributeUtils.getFileAttributesByPath(dir, true); + assertNotNull(fileAttributesByPathScreenScrape); + PlexusIoResourceAttributes pr = null; + for (String s : fileAttributesByPathScreenScrape.keySet()) { + if (s.endsWith("targetFile.txt")) pr = fileAttributesByPathScreenScrape.get(s); + } + assertNotNull(pr); + + assertTrue(pr.getOctalMode() > 0); + } + + @Test + void nonExistingDirectoryWithPath() { + Path dir = java.nio.file.Paths.get("src/test/noSuchDirectory"); + assertThrows( + NoSuchFileException.class, () -> PlexusIoResourceAttributeUtils.getFileAttributesByPath(dir, true)); + } } diff --git a/src/test/java/org/codehaus/plexus/components/io/attributes/SymlinkUtilsTest.java b/src/test/java/org/codehaus/plexus/components/io/attributes/SymlinkUtilsTest.java index 4977a021..cfed4b7b 100644 --- a/src/test/java/org/codehaus/plexus/components/io/attributes/SymlinkUtilsTest.java +++ b/src/test/java/org/codehaus/plexus/components/io/attributes/SymlinkUtilsTest.java @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeEach; @@ -57,6 +58,27 @@ void create_read_symbolic_link_to_directory() throws Exception { assertEquals(new File("aSubDir"), SymlinkUtils.readSymbolicLink(new File(target, "symlinkToDir"))); } + @Test + void create_read_symbolic_link_to_file_with_path() throws Exception { + Path symlink = target.toPath().resolve("symlinkToTarget"); + File relativePath = createTargetFile(target); + SymlinkUtils.createSymbolicLink(symlink, relativePath.toPath()); + assertEquals(expected, FileUtils.readFileToString(symlink.toFile(), UTF_8)); + assertEquals(java.nio.file.Paths.get("actualFile"), SymlinkUtils.readSymbolicLink(symlink)); + } + + @Test + void create_read_symbolic_link_to_directory_with_path() throws Exception { + File subDir = new File(target, "aSubDir"); + createTargetFile(subDir); + Path symlink = target.toPath().resolve("symlinkToDir"); + SymlinkUtils.createSymbolicLink(symlink, java.nio.file.Paths.get("aSubDir")); + assertEquals( + expected, + FileUtils.readFileToString(symlink.resolve("actualFile").toFile(), UTF_8)); + assertEquals(java.nio.file.Paths.get("aSubDir"), SymlinkUtils.readSymbolicLink(symlink)); + } + private File createTargetFile(File target) throws IOException { File relativePath = new File("actualFile"); File actualFile = new File(target, relativePath.getPath()); diff --git a/src/test/java/org/codehaus/plexus/components/io/resources/ResourceFactoryPathTest.java b/src/test/java/org/codehaus/plexus/components/io/resources/ResourceFactoryPathTest.java new file mode 100644 index 00000000..657e40b2 --- /dev/null +++ b/src/test/java/org/codehaus/plexus/components/io/resources/ResourceFactoryPathTest.java @@ -0,0 +1,41 @@ +package org.codehaus.plexus.components.io.resources; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ResourceFactoryPathTest { + + @Test + void testCreateResourceWithPath() throws IOException { + Path tempPath = Files.createTempFile("test", ".txt"); + try { + FileUtils.write(tempPath.toFile(), "test content", UTF_8); + PlexusIoResource resource = ResourceFactory.createResource(tempPath); + assertNotNull(resource); + assertTrue(resource.isExisting()); + } finally { + Files.deleteIfExists(tempPath); + } + } + + @Test + void testCreateResourceWithPathAndName() throws IOException { + Path tempPath = Files.createTempFile("test", ".txt"); + try { + FileUtils.write(tempPath.toFile(), "test content", UTF_8); + PlexusIoResource resource = ResourceFactory.createResource(tempPath, "custom-name.txt"); + assertNotNull(resource); + assertTrue(resource.isExisting()); + } finally { + Files.deleteIfExists(tempPath); + } + } +} diff --git a/src/test/resources/symlinks/symlinks.tar b/src/test/resources/symlinks/symlinks.tar index c40706069c57c41ecbaed7982ba149672dc9f163..2f8324e4199dd2fd057f08b2f1b4def8abeefa9d 100644 GIT binary patch literal 36864 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 P<6OcNQUEEiXcYJlH?)Zl literal 13824 zcmeHNPfy!06c3ZoG_I4T9W(9P1lzG4$gQm9v1A7i(Dn|+jh zh8_2uKTQ*~(z3WMs*O+zQXWRSs#bq!Qr*<+)3^fTM#3?lmgs{ty{6&bQ zvdkgmy2!+YV&uS!9GeJJg0W#DHQlMUI*t=Rf-c=eL7W8ssQR>&;I+%kQhb!lRLPV> zpyW$QyYF5buMFdh-#1Ubn&)PoWSQ{>{)u7i{DNPQcm6DBM2tm8^5M zIW9Z!3III}PO5@k8~PASBqKZbW7*7Ln%NL@%)2a@#( zl63^hYD3EGiXD0v@m-hSE9RCxd{eLBfq4{4D=#&`OvffxT|Eu(UX~UBL=lMT8e#HM2Y5!k^ z|HC@jyx07`ilN@fZxsB0u9p8@#x(zLqycFD-+KO6>HE^=f&b_FKSJ~o|2tgs|0?E- z$z-D0e-#70q2G}F4*~Eik#vGcQ6Hc3f6Cq5|FJ`eo5ugStNmXQ9MxtQ;s0HzBIEyV zwd%j5nfSk~0daogXYJiQ{x8cHi2wip{N2p?`H?qz6;a1(oFV}d{^&fT|xC6#u|Hm+e z`yZs7oYalomaqQ+|IfkbrWb-0oQ!(c;$)n}!9X-Q;7j072m<^GT>pdkAF=Iy*s9HT ztNC4u#y`Vf4fLrQErEaL{{#~b_dg{5;fzf-yDP~pT;reL)ojw^t8FcfKc)=9{*TC@ zjmnG3vYQ(JvnpE6OV7a{Oa7PmtG=9~@jq`K@oJ0D!XNg3DgLStC$}8`DpFd~BcMlM Hn?~R-y5H2I diff --git a/src/test/resources/symlinks/symlinks.zip b/src/test/resources/symlinks/symlinks.zip index 309a853d75b3c2af122666cf71482a3f41e479ce..6873f75b5a5cc196f39dc01bfb283eb6282e069c 100644 GIT binary patch literal 1774 zcmWIWW@Zs#U|`^2u&FN$`+3shm?Ds;2E?2UG7M>%IjKQ}QznK0pdDO5 z6B)pEq`cqvoDIkZVVE7^gzQMn$x$fhLNzG8MD7v`&=3%Y85BXtpo)qLG-H6e;eZS1 z=aR&t^wbiU%p!fbr@5O&QqVk&>XhGqr@MiC2*PYYGm0y7fd;_!g8~jsKf)GNlcsL4 z=@tf>0>TmylYBDsvP1HL=K1G^WTg6+mK0~Eq~bGMPftGuRkc2-mAQCL0tSB& zsv$2I1zV%JC7h63z=;yo7zuj00bu>I zn^Z$U7%k8cwjfM8ztqZg>IR!`VW24>ECDgeCo?ZQBp+y=e_lvNs()!oab`*?*z8td zWPmW5*?M~VDX6OT5te|QyMNiv#V|{Rku5+~MFyP4y)tHxyg00bv2`6L>I3=MPV`0j?6U~?iLdJm8QGhoilN>Xy+#vz<90LO* z5HD#2vEZHv4Pk}k6|`u97>6q(AdK7Am;yBpnk|Sk4mCRf_)3hBzSy_nMGjcF)+McXaNjEScU<*4NGQ04mr$Bf^1e3#4H?H z2535#?1F4MX6`^X{W-Gf$a#gZvq1)5a0L&!BnS`1%kWK1?m;}rx#F>Pe gIgm}d3NZ