diff --git a/src/main/java/software/amazon/nio/spi/s3/S3FileSystemProvider.java b/src/main/java/software/amazon/nio/spi/s3/S3FileSystemProvider.java index 269ffb8c..5d50bb49 100644 --- a/src/main/java/software/amazon/nio/spi/s3/S3FileSystemProvider.java +++ b/src/main/java/software/amazon/nio/spi/s3/S3FileSystemProvider.java @@ -321,7 +321,7 @@ public SeekableByteChannel newByteChannel(Path path, Set o options = Collections.emptySet(); } - final S3Path s3Path = (S3Path)path; + final S3Path s3Path = checkPath(path); final S3SeekableByteChannel channel; final S3FileSystem fs = s3Path.getFileSystem(); @@ -395,7 +395,7 @@ protected DirectoryStream newDirectoryStream(S3AsyncClient s3Client, Path */ @Override public DirectoryStream newDirectoryStream(Path dir, DirectoryStream.Filter filter) throws IOException { - S3Path s3Path = (S3Path) dir; + S3Path s3Path = checkPath(dir); String dirName = s3Path.toAbsolutePath().getKey(); @@ -482,9 +482,10 @@ private Iterator pathIteratorForPublisher ( */ @Override public void createDirectory(Path dir, FileAttribute... attrs) throws IOException { - S3FileSystem fs = ((S3Path)dir).getFileSystem(); + S3Path s3Directory = checkPath(dir); + S3FileSystem fs = s3Directory.getFileSystem(); try { - String directoryKey = ((S3Path)dir).toRealPath(NOFOLLOW_LINKS).getKey(); + String directoryKey = s3Directory.toRealPath(NOFOLLOW_LINKS).getKey(); if (!directoryKey.endsWith(S3Path.PATH_SEPARATOR) && !directoryKey.isEmpty()) { directoryKey = directoryKey + S3Path.PATH_SEPARATOR; } @@ -541,9 +542,9 @@ protected void createDirectory(S3AsyncClient s3Client, Path dir, FileAttribute copyOptions = Arrays.asList(options); - S3Path s3SourcePath = (S3Path) source; - S3Path s3TargetPath = (S3Path) target; + S3Path s3SourcePath = checkPath(source); + S3Path s3TargetPath = checkPath(target); - final S3FileSystem fs = ((S3Path)source).getFileSystem(); + final S3FileSystem fs = s3SourcePath.getFileSystem(); final S3AsyncClient s3Client = fs.client(); final String bucketName = fs.bucketName(); @@ -692,7 +693,7 @@ public void copy(Path source, Path target, CopyOption... options) throws IOExcep */ @Deprecated protected void copy(S3AsyncClient s3Client, Path source, Path target, CopyOption... options) throws IOException, ExecutionException, InterruptedException { - copy(forceAwsClient((S3Path)source, s3Client), target, options); + copy(forceAwsClient(source, s3Client), target, options); } protected boolean exists(S3AsyncClient s3Client, S3Path path) throws InterruptedException, TimeoutException { @@ -857,9 +858,7 @@ public FileStore getFileStore(Path path) { @Override public void checkAccess(Path path, AccessMode... modes) throws IOException { try { - assert path instanceof S3Path; - - final S3Path s3Path = (S3Path) path.toRealPath(NOFOLLOW_LINKS); + final S3Path s3Path = checkPath(path.toRealPath(NOFOLLOW_LINKS)); final S3FileSystem fs = s3Path.getFileSystem(); final String bucketName = fs.bucketName(); final S3AsyncClient s3Client = fs.client(); @@ -943,12 +942,8 @@ protected void checkAccess(S3AsyncClient s3Client, Path path, AccessMode... mode */ @Override public V getFileAttributeView(Path path, Class type, LinkOption... options) { - Objects.requireNonNull(path, "cannot obtain attributes for a null path"); Objects.requireNonNull(type, "the type of attribute view required cannot be null"); - - if (!(path instanceof S3Path)) - throw new IllegalArgumentException("path must be an S3 Path"); - S3Path s3Path = (S3Path) path; + S3Path s3Path = checkPath(path); if (type.equals(BasicFileAttributeView.class) || type.equals(S3FileAttributeView.class)) { @SuppressWarnings("unchecked") final V v = (V) new S3FileAttributeView(s3Path); @@ -971,11 +966,8 @@ public V getFileAttributeView(Path path, Class */ @Override public A readAttributes(Path path, Class type, LinkOption... options) { - Objects.requireNonNull(path); Objects.requireNonNull(type); - if (!(path instanceof S3Path)) - throw new IllegalArgumentException("path must be an S3Path instance"); - S3Path s3Path = (S3Path) path; + S3Path s3Path = checkPath(path); S3AsyncClient s3Client = s3Path.getFileSystem().client(); if (type.equals(BasicFileAttributes.class) || type.equals(S3BasicFileAttributes.class)) { @@ -1032,9 +1024,8 @@ protected A readAttributes(S3AsyncClient s3Async */ @Override public Map readAttributes(Path path, String attributes, LinkOption... options) { - Objects.requireNonNull(path); Objects.requireNonNull(attributes); - S3Path s3Path = (S3Path) path; + S3Path s3Path = checkPath(path); S3AsyncClient s3Client = s3Path.getFileSystem().client(); @@ -1142,4 +1133,11 @@ private S3Path forceAwsClient(final Path path, final S3AsyncClient client) { p.getFileSystem().clientProvider(new FixedS3ClientProvider(client)); return p; } + + protected static S3Path checkPath(Path obj) { + Objects.requireNonNull(obj); + if (!(obj instanceof S3Path)) + throw new ProviderMismatchException(); + return (S3Path)obj; + } } diff --git a/src/main/java/software/amazon/nio/spi/s3/S3Path.java b/src/main/java/software/amazon/nio/spi/s3/S3Path.java index 2b2f542d..eb2c1b9c 100644 --- a/src/main/java/software/amazon/nio/spi/s3/S3Path.java +++ b/src/main/java/software/amazon/nio/spi/s3/S3Path.java @@ -26,6 +26,8 @@ import java.util.Objects; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; +import static software.amazon.nio.spi.s3.S3FileSystemProvider.checkPath; + import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.nio.spi.s3.config.S3NioSpiConfiguration; @@ -448,8 +450,7 @@ public S3Path normalize() { */ @Override public S3Path resolve(Path other) { - if(!(other instanceof S3Path)) throw new ProviderMismatchException("a non s3 path cannot be resolved against and S3Path"); - S3Path s3Other = (S3Path) other; + S3Path s3Other = checkPath(other); if(!this.bucketName().equals(s3Other.bucketName())) throw new IllegalArgumentException("S3Paths cannot be resolved when they are from different buckets"); @@ -541,21 +542,20 @@ public S3Path resolveSibling(String other) { */ @Override public S3Path relativize(Path other) { - if(!(other instanceof S3Path)) throw new IllegalArgumentException("path is not an S3Path"); + S3Path otherPath = checkPath(other); - if(this.equals(other)) return from(""); + if(this.equals(otherPath)) return from(""); - if(this.isAbsolute() != other.isAbsolute()) throw new IllegalArgumentException("to obtain a relative path both must be absolute or both must be relative"); - if(!Objects.equals(this.bucketName(), ((S3Path) other).bucketName())) throw new IllegalArgumentException("cannot relativize S3Paths from different buckets"); + if(this.isAbsolute() != otherPath.isAbsolute()) throw new IllegalArgumentException("to obtain a relative path both must be absolute or both must be relative"); + if(!Objects.equals(this.bucketName(), otherPath.bucketName())) throw new IllegalArgumentException("cannot relativize S3Paths from different buckets"); - S3Path otherPath = (S3Path) other; if(this.isEmpty()) return otherPath; int nameCount = this.getNameCount(); - int otherNameCount = other.getNameCount(); + int otherNameCount = otherPath.getNameCount(); int limit = Math.min(nameCount, otherNameCount); - int differenceCount = getDifferenceCount(other, limit); + int differenceCount = getDifferenceCount(otherPath, limit); int parentDirCount = nameCount - differenceCount; if (differenceCount < otherNameCount) { @@ -781,9 +781,7 @@ public Iterator iterator() { */ @Override public int compareTo(Path other) { - if(!(other instanceof S3Path)) throw new ClassCastException("compared paths must be from the same provider"); - - S3Path o = (S3Path) other; + S3Path o = checkPath(other); if(o.fileSystem != this.fileSystem) throw new ClassCastException("compared S3 paths must be from the same bucket"); return this.toRealPath(NOFOLLOW_LINKS).toString().compareTo( o.toRealPath(NOFOLLOW_LINKS).toString());