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 d052d200..2b4512a3 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 @@ -22,6 +22,7 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.attribute.FileOwnerAttributeView; +import java.nio.file.attribute.FileTime; import java.nio.file.attribute.PosixFilePermission; import java.security.Principal; import java.util.Collections; @@ -39,6 +40,10 @@ public class FileAttributes implements PlexusIoResourceAttributes { + public static final LinkOption[] FOLLOW_LINK_OPTIONS = new LinkOption[] { }; + + public static final LinkOption[] NOFOLLOW_LINK_OPTIONS = new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; + @Nullable private final Integer groupId; @@ -52,69 +57,101 @@ public class FileAttributes private final boolean symbolicLink; + private final boolean regularFile; + + private final boolean directory; + + private final boolean other; + private final int octalMode; private final Set permissions; + private final long size; + + private final FileTime lastModifiedTime; + + /** + * @deprecated use {@link #FileAttributes(File)} and remove the unused userCache and groupCache parameters + */ + @Deprecated public FileAttributes( @Nonnull File file, @Nonnull Map userCache, @Nonnull Map groupCache ) throws IOException { + this( file ); + } + + public FileAttributes( @Nonnull File file ) + throws IOException + { + this( file, false ); + } + public FileAttributes( @Nonnull File file, boolean followLinks ) + throws IOException + { + LinkOption[] options = followLinks ? FOLLOW_LINK_OPTIONS : NOFOLLOW_LINK_OPTIONS; Path path = file.toPath(); - if ( AttributeUtils.isUnix( path ) ) + Set views = path.getFileSystem().supportedFileAttributeViews(); + String names; + if ( views.contains( "unix" ) ) + { + names = "unix:*"; + } + else if ( views.contains( "posix" ) ) { - Map attrs = Files.readAttributes( path, "unix:permissions,gid,uid,isSymbolicLink,mode", LinkOption.NOFOLLOW_LINKS ); - this.permissions = (Set) attrs.get( "permissions" ); - - groupId = (Integer) attrs.get( "gid" ); - - String groupName = groupCache.get( groupId ); - if ( groupName != null ) - { - this.groupName = groupName; - } - else - { - Object group = Files.getAttribute( path, "unix:group", LinkOption.NOFOLLOW_LINKS ); - this.groupName = ( (Principal) group ).getName(); - groupCache.put( groupId, this.groupName ); - } - userId = (Integer) attrs.get( "uid" ); - String userName = userCache.get( userId ); - if ( userName != null ) - { - this.userName = userName; - } - else - { - Object owner = Files.getAttribute( path, "unix:owner", LinkOption.NOFOLLOW_LINKS ); - this.userName = ( (Principal) owner ).getName(); - userCache.put( userId, this.userName ); - } - octalMode = (Integer) attrs.get( "mode" ) & 0xfff; // Mask off top bits for compatibilty. Maybe check if we - // can skip this - symbolicLink = (Boolean) attrs.get( "isSymbolicLink" ); + names = "posix:*"; } else { - FileOwnerAttributeView fa = AttributeUtils.getFileOwnershipInfo( file ); - this.userName = fa.getOwner().getName(); - userId = null; - this.groupName = null; - this.groupId = null; - octalMode = PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE; - permissions = Collections.emptySet(); - symbolicLink = Files.isSymbolicLink( path ); + names = "basic:*"; } + Map attrs = Files.readAttributes( path, names, options ); + if ( !attrs.containsKey( "group" ) && !attrs.containsKey( "owner" ) && views.contains( "owner" ) ) + { + Map ownerAttrs = Files.readAttributes( path, "owner:*", options ); + Map newAttrs = new HashMap<>( attrs ); + newAttrs.putAll( ownerAttrs ); + attrs = newAttrs; + } + this.groupId = (Integer) attrs.get( "gid" ); + this.groupName = attrs.containsKey( "group" ) ? ((Principal) attrs.get( "group" ) ).getName() : null; + this.userId = (Integer) attrs.get( "uid" ); + this.userName = attrs.containsKey( "owner" ) ? ((Principal) attrs.get( "owner" ) ).getName() : null; + this.symbolicLink = (Boolean) attrs.get( "isSymbolicLink" ); + this.regularFile = (Boolean) attrs.get( "isRegularFile" ); + this.directory = (Boolean) attrs.get( "isDirectory" ); + this.other = (Boolean) attrs.get( "isOther" ); + this.octalMode = attrs.containsKey( "mode" ) ? (Integer) attrs.get( "mode" ) & 0xfff : PlexusIoResourceAttributes.UNKNOWN_OCTAL_MODE; + this.permissions = attrs.containsKey( "permissions" ) ? (Set) attrs.get( "permissions" ) : Collections.emptySet(); + this.size = (Long) attrs.get( "size" ); + this.lastModifiedTime = (FileTime) attrs.get( "lastModifiedTime" ); + } + public FileAttributes( @Nullable Integer userId, String userName, @Nullable Integer groupId, @Nullable String groupName, + int octalMode, boolean symbolicLink, boolean regularFile, boolean directory, boolean other, + Set permissions, long size, FileTime lastModifiedTime ) + { + this.userId = userId; + this.userName = userName; + this.groupId = groupId; + this.groupName = groupName; + this.octalMode = octalMode; + this.symbolicLink = symbolicLink; + this.regularFile = regularFile; + this.directory = directory; + this.other = other; + this.permissions = permissions; + this.size = size; + this.lastModifiedTime = lastModifiedTime; } public static @Nonnull PlexusIoResourceAttributes uncached( @Nonnull File file ) throws IOException { - return new FileAttributes( file, new HashMap(), new HashMap() ); + return new FileAttributes( file ); } @Nullable @@ -290,4 +327,34 @@ public boolean isSymbolicLink() { return symbolicLink; } -} \ No newline at end of file + + public boolean isRegularFile() + { + return regularFile; + } + + public boolean isDirectory() + { + return directory; + } + + public boolean isOther() + { + return other; + } + + public long getSize() + { + return size; + } + + public FileTime getLastModifiedTime() + { + return lastModifiedTime; + } + + protected Set getPermissions() + { + return permissions; + } +} 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 526a7c2e..1cc81669 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 @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -43,69 +42,71 @@ public static PlexusIoResourceAttributes mergeAttributes( PlexusIoResourceAttrib { return base; } - SimpleResourceAttributes result; if ( base == null ) { - result = new SimpleResourceAttributes(); + return new SimpleResourceAttributes( + override.getUserId() != null && override.getUserId() != -1 + ? override.getUserId() + : def != null && def.getUserId() != null && def.getUserId() != -1 + ? def.getUserId() + : null, + override.getUserName() != null + ? override.getUserName() + : def != null + ? def.getUserName() + : null, + override.getGroupId() != null && override.getGroupId() != -1 + ? override.getGroupId() + : def != null && def.getGroupId() != null && def.getGroupId() != -1 + ? def.getGroupId() + : null, + override.getGroupName() != null + ? override.getGroupName() + : def != null + ? def.getGroupName() + : null, + override.getOctalMode() ); } else { - result = new SimpleResourceAttributes( base.getUserId(), base.getUserName(), base.getGroupId(), - base.getGroupName(), base.getOctalMode() ); - result.setSymbolicLink( base.isSymbolicLink() ); + Integer uid = override.getUserId() != null && override.getUserId() != -1 + ? override.getUserId() + : base.getUserId() != null && base.getUserId() != -1 + ? base.getUserId() + : def.getUserId() != null && def.getUserId() != -1 + ? def.getUserId() + : null; + String uname = override.getUserName() != null + ? override.getUserName() + : base.getUserName() != null + ? base.getUserName() + : def.getUserName(); + Integer gid = override.getGroupId() != null && override.getGroupId() != -1 + ? override.getGroupId() + : base.getGroupId() != null && base.getGroupId() != -1 + ? base.getGroupId() + : def.getGroupId() != null && def.getGroupId() != -1 + ? def.getGroupId() + : null; + String gname = override.getGroupName() != null + ? override.getGroupName() + : base.getGroupName() != null + ? base.getGroupName() + : def.getGroupName(); + int mode = override.getOctalMode() > 0 + ? override.getOctalMode() + : base.getOctalMode() >= 0 + ? base.getOctalMode() + : def.getOctalMode(); + if ( base instanceof FileAttributes ) + { + return new UserGroupModeFileAttributes( uid, uname, gid, gname, mode, (FileAttributes) base ); + } + else + { + return new SimpleResourceAttributes( uid, uname, gid, gname, mode, base.isSymbolicLink() ); + } } - - if ( override.getGroupId() != null && override.getGroupId() != -1 ) - { - result.setGroupId( override.getGroupId() ); - } - - if ( def != null && def.getGroupId() >= 0 && ( result.getGroupId() == null || result.getGroupId() < 0 ) ) - { - result.setGroupId( def.getGroupId() ); - } - - if ( override.getGroupName() != null ) - { - result.setGroupName( override.getGroupName() ); - } - - if ( def != null && result.getGroupName() == null ) - { - result.setGroupName( def.getGroupName() ); - } - - if ( override.getUserId() != null && override.getUserId() != -1 ) - { - result.setUserId( override.getUserId() ); - } - - if ( def != null && def.getUserId() >= 0 && ( result.getUserId() == null || result.getUserId() < 0 ) ) - { - result.setUserId( def.getUserId() ); - } - - if ( override.getUserName() != null ) - { - result.setUserName( override.getUserName() ); - } - - if ( def != null && result.getUserName() == null ) - { - result.setUserName( def.getUserName() ); - } - - if ( override.getOctalMode() > 0 ) - { - result.setOctalMode( override.getOctalMode() ); - } - - if ( def != null && result.getOctalMode() < 0 ) - { - result.setOctalMode( def.getOctalMode() ); - } - - return result; } public static boolean isGroupExecutableInOctal( int mode ) @@ -158,11 +159,16 @@ public static boolean isOctalModeEnabled( int mode, int targetMode ) return ( mode & targetMode ) != 0; } - @SuppressWarnings( { "UnusedDeclaration" } ) public static PlexusIoResourceAttributes getFileAttributes( File file ) throws IOException { - Map byPath = getFileAttributesByPath( file, false ); + return getFileAttributes( file, false ); + } + + 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 ) { @@ -184,8 +190,15 @@ Map getFileAttributesByPath( @Nonnull File d boolean recursive ) throws IOException { - Map userCache = new HashMap<>(); - Map groupCache = new HashMap<>(); + return getFileAttributesByPath( dir, recursive, false ); + } + + public static @Nonnull + Map getFileAttributesByPath( @Nonnull File dir, + boolean recursive, + boolean followLinks ) + throws IOException + { final List fileAndDirectoryNames; if ( recursive && dir.isDirectory() ) { @@ -200,8 +213,7 @@ Map getFileAttributesByPath( @Nonnull File d for ( String fileAndDirectoryName : fileAndDirectoryNames ) { - attributesByPath.put( fileAndDirectoryName, - new FileAttributes( new File( fileAndDirectoryName ), userCache, groupCache ) ); + attributesByPath.put( fileAndDirectoryName, new FileAttributes( new File( fileAndDirectoryName ), followLinks ) ); } return attributesByPath; } diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributes.java b/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributes.java index 21b29db9..4470ae6b 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributes.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/PlexusIoResourceAttributes.java @@ -74,7 +74,7 @@ public interface PlexusIoResourceAttributes */ int getOctalMode(); - @Nonnull + //@Nonnull //String getOctalModeString(); /** diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java b/src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java index 301905e5..a92d7411 100644 --- a/src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/SimpleResourceAttributes.java @@ -46,6 +46,16 @@ public SimpleResourceAttributes( Integer uid, String userName, Integer gid, Stri this.mode = mode; } + public SimpleResourceAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, boolean isSymbolicLink ) + { + this.uid = uid; + this.userName = userName; + this.gid = gid; + this.groupName = groupName; + this.mode = mode; + this.isSymbolicLink = isSymbolicLink; + } + public static PlexusIoResourceAttributes lastResortDummyAttributesForBrokenOS() { return new SimpleResourceAttributes(); diff --git a/src/main/java/org/codehaus/plexus/components/io/attributes/UserGroupModeFileAttributes.java b/src/main/java/org/codehaus/plexus/components/io/attributes/UserGroupModeFileAttributes.java new file mode 100644 index 00000000..37984b17 --- /dev/null +++ b/src/main/java/org/codehaus/plexus/components/io/attributes/UserGroupModeFileAttributes.java @@ -0,0 +1,47 @@ +package org.codehaus.plexus.components.io.attributes; + +/* + * Copyright 2007 The Codehaus Foundation. + * + * Licensed 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. + */ + +import javax.annotation.Nullable; + +/* + * A very simple pojo based PlexusIoResourceAttributes without any kind of backing + */ +public class UserGroupModeFileAttributes + extends FileAttributes +{ + + public UserGroupModeFileAttributes( Integer uid, String userName, Integer gid, String groupName, int mode, FileAttributes base ) + { + super( uid, userName, gid, groupName, mode, + base.isSymbolicLink(), base.isRegularFile(), base.isDirectory(), base.isOther(), + base.getPermissions(), base.getSize(), base.getLastModifiedTime() ); + } + + public String toString() + { + return String.format( + "%nResource Attributes:%n------------------------------%nuser: %s%ngroup: %s%nuid: %d%ngid: %d%nmode: %06o", + getUserName() == null ? "" : getUserName(), + getGroupName() == null ? "" : getGroupName(), + getUserId() != null ? getUserId() : 0, + getGroupId() != null ? getGroupId() : 0, + getOctalMode() ); + } + + +} diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResource.java b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResource.java index 5079b9b7..b6babcc5 100755 --- a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResource.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoFileResource.java @@ -22,10 +22,13 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.file.attribute.FileTime; +import java.util.function.Supplier; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.DeferredFileOutputStream; import org.codehaus.plexus.components.io.attributes.AttributeUtils; +import org.codehaus.plexus.components.io.attributes.FileAttributes; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; import org.codehaus.plexus.components.io.functions.ContentSupplier; import org.codehaus.plexus.components.io.functions.FileSupplier; @@ -34,6 +37,8 @@ import javax.annotation.Nonnull; +import static java.util.Objects.requireNonNull; + /** * Implementation of {@link PlexusIoResource} for files. */ @@ -48,6 +53,9 @@ public class PlexusIoFileResource @Nonnull private final PlexusIoResourceAttributes attributes; + @Nonnull + private final FileAttributes fileAttributes; + private final ContentSupplier contentSupplier; private final DeferredFileOutputStream dfos; @@ -59,23 +67,32 @@ protected PlexusIoFileResource( @Nonnull File file, @Nonnull String name, this( file, name, attrs, null, null ); } - @SuppressWarnings( "ConstantConditions" ) PlexusIoFileResource( @Nonnull final File file, @Nonnull String name, @Nonnull PlexusIoResourceAttributes attrs, final ContentSupplier contentSupplier, final InputStreamTransformer streamTransformer ) throws IOException { - super( name, file.lastModified(), file.length(), file.isFile(), file.isDirectory(), file.exists() ); - this.file = file; + this( file, name, attrs, + new FileAttributes( file, true ), + contentSupplier, streamTransformer ); + } + PlexusIoFileResource( @Nonnull final File file, @Nonnull String name, + @Nonnull PlexusIoResourceAttributes attrs, @Nonnull FileAttributes fileAttributes, + final ContentSupplier contentSupplier, final InputStreamTransformer streamTransformer ) + throws IOException + { + super( name, fileAttributes.getLastModifiedTime().toMillis(), fileAttributes.getSize(), + fileAttributes.isRegularFile(), fileAttributes.isDirectory(), + fileAttributes.isRegularFile() || fileAttributes.isDirectory() || fileAttributes.isSymbolicLink() || fileAttributes.isOther() ); + this.file = file; + this.attributes = requireNonNull( attrs, "attributes is null for file " + file.getName() ); + this.fileAttributes = requireNonNull( fileAttributes, "fileAttributes is null for file " + file.getName() ); this.contentSupplier = contentSupplier != null ? contentSupplier : getRootContentSupplier( file ); boolean hasTransformer = streamTransformer != null && streamTransformer != identityTransformer; InputStreamTransformer transToUse = streamTransformer != null ? streamTransformer : identityTransformer; dfos = hasTransformer && file.isFile() ? asDeferredStream( this.contentSupplier, transToUse, this ) : null; - if ( attrs == null ) - throw new IllegalArgumentException( "attrs is null for file " + file.getName() ); - this.attributes = attrs; } private static DeferredFileOutputStream asDeferredStream( @Nonnull ContentSupplier supplier, @@ -157,7 +174,7 @@ public long getSize() { if ( dfos == null ) { - return getFile().length(); + return fileAttributes.getSize(); } if ( dfos.isInMemory() ) { @@ -171,17 +188,21 @@ public long getSize() public boolean isDirectory() { - return getFile().isDirectory(); + return fileAttributes.isDirectory(); } public boolean isExisting() { + if ( attributes instanceof FileAttributes ) + { + return true; + } return getFile().exists(); } public boolean isFile() { - return getFile().isFile(); + return fileAttributes.isRegularFile(); } @Nonnull @@ -190,8 +211,19 @@ public PlexusIoResourceAttributes getAttributes() return attributes; } + @Nonnull + public FileAttributes getFileAttributes() + { + return fileAttributes; + } + public long getLastModified() { + FileTime lastModified = fileAttributes.getLastModifiedTime(); + if ( lastModified != null ) + { + return lastModified.toMillis(); + } return AttributeUtils.getLastModified( getFile() ); } @@ -201,5 +233,10 @@ public boolean isSymbolicLink() return getAttributes().isSymbolicLink(); } + protected DeferredFileOutputStream getDfos() + { + return dfos; + } + private static final InputStreamTransformer identityTransformer = AbstractPlexusIoResourceCollection.identityTransformer; } \ No newline at end of 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 2293de96..b1094797 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 @@ -152,15 +152,13 @@ private void addResources( List result, String[] resources ) { final File dir = getBaseDir(); - final HashMap cache1 = new HashMap<>(); - final HashMap cache2 = new HashMap<>(); for ( String name : resources ) { String sourceDir = name.replace( '\\', '/' ); File f = new File( dir, sourceDir ); - PlexusIoResourceAttributes attrs = new FileAttributes( f, cache1, cache2 ); - attrs = mergeAttributes( attrs, f.isDirectory() ); + FileAttributes fattrs = new FileAttributes( f ); + PlexusIoResourceAttributes attrs = mergeAttributes( fattrs, fattrs.isDirectory() ); String remappedName = getName( name ); diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoSymlinkResource.java b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoSymlinkResource.java index 05a24cfd..9cdf4eda 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoSymlinkResource.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/PlexusIoSymlinkResource.java @@ -1,5 +1,6 @@ package org.codehaus.plexus.components.io.resources; +import org.apache.commons.io.output.DeferredFileOutputStream; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; import org.codehaus.plexus.components.io.attributes.SymlinkUtils; import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier; @@ -7,23 +8,107 @@ import javax.annotation.Nonnull; import java.io.File; import java.io.IOException; +import java.nio.file.Path; public class PlexusIoSymlinkResource extends PlexusIoFileResource implements SymlinkDestinationSupplier { - private final File symnlinkDestination; + private final String symLinkDestination; + private final PlexusIoFileResource targetResource; PlexusIoSymlinkResource( @Nonnull File symlinkfile, String name, @Nonnull PlexusIoResourceAttributes attrs ) - throws IOException + throws IOException { - super( symlinkfile, name, attrs ); - this.symnlinkDestination = null; + this( symlinkfile, name, attrs, symlinkfile.toPath() ); + } + + PlexusIoSymlinkResource( @Nonnull File symlinkfile, String name, @Nonnull PlexusIoResourceAttributes attrs, + Path linkPath ) + throws IOException + { + this( symlinkfile, name, attrs, linkPath, java.nio.file.Files.readSymbolicLink( linkPath ) ); + } + + private PlexusIoSymlinkResource( @Nonnull File symlinkfile, String name, @Nonnull PlexusIoResourceAttributes attrs, + Path path, Path linkPath ) + throws IOException + { + this( symlinkfile, name, attrs, linkPath.toString(), + ( PlexusIoFileResource ) ResourceFactory.createResource( path.resolveSibling( linkPath ).toFile() ) ); + } + + private PlexusIoSymlinkResource( @Nonnull File symlinkfile, String name, @Nonnull PlexusIoResourceAttributes attrs, + String symLinkDestination, PlexusIoFileResource targetResource ) + throws IOException + { + super( symlinkfile, name, attrs, targetResource.getFileAttributes(), null, null ); + this.symLinkDestination = symLinkDestination; + this.targetResource = targetResource; } public String getSymlinkDestination() throws IOException { - return symnlinkDestination == null ? SymlinkUtils.readSymbolicLink( getFile() ).getPath() : symnlinkDestination.getPath(); + return targetResource.getName(); + } + + public PlexusIoResource getTarget() + { + return targetResource; + } + + public PlexusIoResource getLink() throws IOException + { + return new PlexusIoFileResource( getFile(), getName(), getAttributes() ); + } + + @Override + public long getSize() + { + DeferredFileOutputStream dfos = getDfos(); + if ( dfos == null ) + { + return targetResource.getSize(); + } + else if ( dfos.isInMemory() ) + { + return dfos.getByteCount(); + } + else + { + return dfos.getFile().length(); + } + } + + @Override + public boolean isDirectory() + { + return targetResource.isDirectory(); + } + + @Override + public boolean isExisting() + { + return targetResource.isExisting(); + } + + @Override + public boolean isFile() + { + return targetResource.isFile(); + } + + @Override + public long getLastModified() + { + return targetResource.getLastModified(); + } + + @Nonnull + @Override + public PlexusIoResourceAttributes getAttributes() + { + return super.getAttributes(); } } 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 5c0a7584..d8f97bba 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 @@ -1,5 +1,6 @@ package org.codehaus.plexus.components.io.resources; +import org.codehaus.plexus.components.io.attributes.FileAttributes; import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes; import org.codehaus.plexus.components.io.functions.ContentSupplier; import org.codehaus.plexus.components.io.functions.InputStreamTransformer; @@ -54,7 +55,8 @@ public static PlexusIoResource createResource( File f, String name, final Conten { boolean symbolicLink = attributes.isSymbolicLink(); return symbolicLink ? new PlexusIoSymlinkResource( f, name, attributes ) - : new PlexusIoFileResource( f, name, attributes, contentSupplier, inputStreamTransformer ); + : new PlexusIoFileResource( f, name, attributes, + new FileAttributes( f, true ), contentSupplier, inputStreamTransformer ); } } diff --git a/src/main/java/org/codehaus/plexus/components/io/resources/proxy/ProxyFactory.java b/src/main/java/org/codehaus/plexus/components/io/resources/proxy/ProxyFactory.java index 15597b03..4b4bf9bd 100644 --- a/src/main/java/org/codehaus/plexus/components/io/resources/proxy/ProxyFactory.java +++ b/src/main/java/org/codehaus/plexus/components/io/resources/proxy/ProxyFactory.java @@ -40,7 +40,7 @@ public static PlexusIoResource createProxy( @Nonnull PlexusIoResource target, Ob interfaces.add( ResourceAttributeSupplier.class ); return (PlexusIoResource) Proxy.newProxyInstance( PlexusIoResource.class.getClassLoader(), - interfaces.toArray( new Class[interfaces.size()] ), + interfaces.toArray( new Class[0] ), new ResourceInvocationHandler( target, alternateSupplier ) ); } } 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 dee75ad5..d3a762c2 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 @@ -54,14 +54,12 @@ public void testChmodBackAndForth() return; final File bxx = File.createTempFile( "bxx", "ff" ); AttributeUtils.chmod( bxx, 0422 ); - PlexusIoResourceAttributes firstAttrs = - new FileAttributes( bxx, new HashMap(), new HashMap() ); + PlexusIoResourceAttributes firstAttrs = new FileAttributes( bxx ); assertTrue( firstAttrs.isOwnerReadable() ); assertFalse( firstAttrs.isOwnerWritable() ); assertFalse( firstAttrs.isOwnerExecutable() ); AttributeUtils.chmod( bxx, 0777 ); - PlexusIoResourceAttributes secondAttrs = - new FileAttributes( bxx, new HashMap(), new HashMap() ); + 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 8e5073c8..04867004 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 @@ -39,10 +39,8 @@ public void testGetPosixFileAttributes() } File file = new File( "." ); - Map userCache = new HashMap<>(); - Map groupCache = new HashMap<>(); - PlexusIoResourceAttributes fa = new FileAttributes( file, userCache, groupCache ); + PlexusIoResourceAttributes fa = new FileAttributes( file ); assertNotNull( fa ); } diff --git a/src/test/java/org/codehaus/plexus/components/io/resources/PlexusIoPlexusIoFileResourceTest.java b/src/test/java/org/codehaus/plexus/components/io/resources/PlexusIoPlexusIoFileResourceTest.java index f636277a..e8722a1e 100644 --- a/src/test/java/org/codehaus/plexus/components/io/resources/PlexusIoPlexusIoFileResourceTest.java +++ b/src/test/java/org/codehaus/plexus/components/io/resources/PlexusIoPlexusIoFileResourceTest.java @@ -21,10 +21,44 @@ public void testRealSymlink() final File file = new File( "src/test/resources/symlinks/src/symDir" ); PlexusIoResourceAttributes attrs = FileAttributes.uncached( file ); assertTrue( attrs.isSymbolicLink() ); - PlexusIoFileResource r = new PlexusIoFileResource( file, "symDir", attrs ); + PlexusIoResource r = ResourceFactory.createResource( file ); assertTrue( r.isSymbolicLink() ); assertTrue( r.isDirectory() ); final File target = SymlinkUtils.readSymbolicLink( file ); assertTrue( target.getName().endsWith( "targetDir" ) ); } + + public void testSymSymlinkFile() + throws IOException + { + if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) + return; + final File file = new File( "src/test/resources/symlinks/src/symSymR" ); + PlexusIoResource r = ResourceFactory.createResource( file ); + assertTrue( r.isSymbolicLink() ); + assertEquals( 38, r.getSize() ); + PlexusIoResource rL = ( ( PlexusIoSymlinkResource ) r ).getLink(); + assertFalse( rL instanceof PlexusIoSymlinkResource ); + PlexusIoResource rT = ( ( PlexusIoSymlinkResource ) r ).getTarget(); + assertTrue( rT instanceof PlexusIoSymlinkResource ); + PlexusIoResource rTT = ( ( PlexusIoSymlinkResource ) rT ).getTarget(); + assertFalse( rTT instanceof PlexusIoSymlinkResource ); + } + + public void testSymlinkFile() + throws IOException + { + if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) + return; + final File file = new File( "src/test/resources/symlinks/src/symR" ); + PlexusIoResource r = ResourceFactory.createResource( file ); + assertTrue( r.isSymbolicLink() ); + assertEquals( 38, r.getSize() ); + + final File file2 = new File( "src/test/resources/symlinks/src/symSymR" ); + PlexusIoResource r2 = ResourceFactory.createResource( file2 ); + assertTrue( r2.isSymbolicLink() ); + assertEquals( 38, r2.getSize() ); + PlexusIoResource r3 = ( ( PlexusIoSymlinkResource ) r2 ).getTarget(); + } } \ No newline at end of file diff --git a/src/test/resources/symlinks/src/symSymR b/src/test/resources/symlinks/src/symSymR new file mode 120000 index 00000000..95277162 --- /dev/null +++ b/src/test/resources/symlinks/src/symSymR @@ -0,0 +1 @@ +symR \ No newline at end of file