From fa752ad46668ab1b813a940c69bca6fe6cc582c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Dr=C4=83ghici?= Date: Fri, 28 Nov 2025 11:39:23 +0200 Subject: [PATCH 1/5] [SNAP-4097](snap-virtual-file-system): Fix the issue with loading the VFS folder contents when opening a folder from the VFS. --- .../java/org/esa/snap/vfs/remote/s3/S3ResponseHandler.java | 6 ++++++ .../src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3ResponseHandler.java b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3ResponseHandler.java index 2e42ba78828..5cc0e6eae63 100644 --- a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3ResponseHandler.java +++ b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3ResponseHandler.java @@ -44,6 +44,11 @@ public class S3ResponseHandler extends DefaultHandler { */ private static final String NEXT_CONTINUATION_TOKEN_ELEMENT = "NextContinuationToken"; + /** + * The name of XML element for NextContinuationToken, used on parsing VFS service response XML. + */ + private static final String NEXT_MARKER_ELEMENT = "NextMarker"; + /** * The name of XML element for IsTruncated, used on parsing VFS service response XML. */ @@ -195,6 +200,7 @@ public void characters(char[] ch, int start, int length) throws SAXException { this.isTruncated = getBooleanValue(ch, start, length); break; case NEXT_CONTINUATION_TOKEN_ELEMENT: + case NEXT_MARKER_ELEMENT: this.nextContinuationToken = getTextValue(ch, start, length); break; case PREFIX_ELEMENT: diff --git a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java index a51ce260f4a..04faa98b440 100644 --- a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java +++ b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java @@ -143,7 +143,7 @@ private String buildS3URL(String prefix, String nextContinuationToken) throws IO addParam(paramBase, "prefix", prefix); addParam(paramBase, "delimiter", this.delimiter); StringBuilder params = new StringBuilder(paramBase); - addParam(params, "continuation-token", nextContinuationToken); + addParam(params, "marker", nextContinuationToken); String s3URL = this.address + (this.address.endsWith(this.delimiter) ? "" : this.delimiter) + currentBucket; if (params.length() > 0) { s3URL += "?" + params; From 93327c1018df1e5f5582d24a8a0c99ea3b92d3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Dr=C4=83ghici?= Date: Tue, 2 Dec 2025 17:38:25 +0200 Subject: [PATCH 2/5] [SNAP-4097](snap-virtual-file-system): Fix the issue with fetching the VFS entry basicFileAttributes which makes the browsing to the parent VFS folder or selecting other VFS folder from the tree to not work. --- .../org/esa/snap/vfs/remote/AbstractRemoteWalker.java | 9 +++++++-- .../main/java/org/esa/snap/vfs/remote/s3/S3Walker.java | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/AbstractRemoteWalker.java b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/AbstractRemoteWalker.java index e1514e9bae6..5e83ffa6f23 100644 --- a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/AbstractRemoteWalker.java +++ b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/AbstractRemoteWalker.java @@ -29,9 +29,8 @@ protected AbstractRemoteWalker(IRemoteConnectionBuilder remoteConnectionBuilder) public BasicFileAttributes readBasicFileAttributes(VFSPath path) throws IOException { // check if the address represents a directory String address = path.buildURL().toString(); - String fileSystemSeparator = path.getFileSystem().getSeparator(); String fileSystemRoot = path.getFileSystem().getRoot().getPath(); - URL directoryURL = new URL(address + (address.endsWith(fileSystemSeparator) ? "" : fileSystemSeparator)); + URL directoryURL = getDirectoryURL(path); HttpURLConnection connection = this.remoteConnectionBuilder.buildConnection(fileSystemRoot, directoryURL, "GET", null); try { int responseCode = connection.getResponseCode(); @@ -46,6 +45,12 @@ public BasicFileAttributes readBasicFileAttributes(VFSPath path) throws IOExcept return readFileAttributes(address, path.toString(), fileSystemRoot); } + protected URL getDirectoryURL(VFSPath path) throws IOException{ + final String address = path.buildURL().toString(); + final String fileSystemSeparator = path.getFileSystem().getSeparator(); + return new URL(address + (address.endsWith(fileSystemSeparator) ? "" : fileSystemSeparator)); + } + private BasicFileAttributes readFileAttributes(String urlAddress, String filePath, String fileSystemRoot) throws IOException { RegularFileMetadata regularFileMetadata = HttpUtils.readRegularFileMetadata(urlAddress, this.remoteConnectionBuilder, fileSystemRoot); return VFSFileAttributes.newFile(filePath, regularFileMetadata); diff --git a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java index 04faa98b440..238aab87543 100644 --- a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java +++ b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/s3/S3Walker.java @@ -130,6 +130,12 @@ public synchronized List walk(VFSPath dir) throws IOExcepti return items; } + protected URL getDirectoryURL(VFSPath dir) throws IOException { + String dirPath = dir.toString(); + String s3Prefix = buildPrefix(dirPath + (dirPath.endsWith("/") ? "" : "/")); + return new URL(buildS3URL(s3Prefix, "")); + } + private String buildPrefix(String prefix) { prefix = prefix.replace(this.root, ""); prefix = prefix.replaceAll("^/", ""); From 2762c7b365f0331df850848f0af4dcea175db70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Dr=C4=83ghici?= Date: Wed, 3 Dec 2025 18:53:39 +0200 Subject: [PATCH 3/5] [SNAP-4097](snap-geotiff): Fix the compatibility issue of GeoTiff reader with VFS. --- .../snap/dataio/geotiff/GeoTiffProductReaderPlugIn.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/GeoTiffProductReaderPlugIn.java b/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/GeoTiffProductReaderPlugIn.java index 149dd0cc037..d114b2eb2a3 100644 --- a/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/GeoTiffProductReaderPlugIn.java +++ b/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/GeoTiffProductReaderPlugIn.java @@ -36,6 +36,7 @@ import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.Arrays; import java.util.Iterator; import java.util.Locale; @@ -76,8 +77,10 @@ public DecodeQualification getDecodeQualification(Object productInputFile) { if (fileExtension != null) { boolean extensionMatches = Arrays.stream(TIFF_FILE_EXTENSION).anyMatch(fileExtension::equalsIgnoreCase); if (extensionMatches) { - try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(productInputFile)) { - return getDecodeQualificationImpl(imageInputStream); + try (InputStream fileInputStream = productPath.getFileSystem().provider().newInputStream(productPath, StandardOpenOption.READ)) { + try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(fileInputStream)) { + return getDecodeQualificationImpl(imageInputStream); + } } } else if (fileExtension.equalsIgnoreCase(ZIP_FILE_EXTENSION)) { return checkZipArchive(productPath); From 84f17178bb1e90e0f3da690f82067ae22580f316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Dr=C4=83ghici?= Date: Wed, 3 Dec 2025 18:57:31 +0200 Subject: [PATCH 4/5] [SNAP-4097](snap-geotiff): Fix the compatibility issue with VFS. --- .../org/esa/snap/dataio/geotiff/Utils.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/Utils.java b/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/Utils.java index 71362cf02ee..33bbee5ddc5 100644 --- a/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/Utils.java +++ b/snap-geotiff/src/main/java/org/esa/snap/dataio/geotiff/Utils.java @@ -39,9 +39,11 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.IOException; +import java.io.InputStream; import java.io.StringReader; import java.nio.ByteOrder; import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -57,22 +59,24 @@ public class Utils { * @param filePath The file path */ public static boolean isCOGGeoTIFF(Path filePath) throws Exception { - try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(filePath.toFile())) { - final Iterator imageReaders = ImageIO.getImageReaders(imageInputStream); - TIFFImageReader tiffReader = null; - while (imageReaders.hasNext()) { - final ImageReader reader = imageReaders.next(); - if (reader instanceof TIFFImageReader) { - tiffReader = (TIFFImageReader) reader; - tiffReader.setInput(imageInputStream); - break; + try (InputStream fileInputStream = filePath.getFileSystem().provider().newInputStream(filePath, StandardOpenOption.READ)) { + try (ImageInputStream imageInputStream = ImageIO.createImageInputStream(fileInputStream)) { + final Iterator imageReaders = ImageIO.getImageReaders(imageInputStream); + TIFFImageReader tiffReader = null; + while (imageReaders.hasNext()) { + final ImageReader reader = imageReaders.next(); + if (reader instanceof TIFFImageReader) { + tiffReader = (TIFFImageReader) reader; + tiffReader.setInput(imageInputStream); + break; + } + } + if (tiffReader == null) { + throw new Exception("No tiff reader found!"); } - } - if (tiffReader == null) { - throw new Exception("No tiff reader found!"); - } - return isCOGGeoTIFF(tiffReader); + return isCOGGeoTIFF(tiffReader); + } } } From 44f63bdd53c7e60b45c593e9c265607e22666571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Dr=C4=83ghici?= Date: Wed, 3 Dec 2025 18:58:43 +0200 Subject: [PATCH 5/5] [SNAP-4097](snap-virtual-file-system): Fix the issue with reading the files from VFS. --- .../src/main/java/org/esa/snap/vfs/remote/VFSByteChannel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/VFSByteChannel.java b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/VFSByteChannel.java index 16ac2a57b94..cbaf023f214 100644 --- a/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/VFSByteChannel.java +++ b/snap-virtual-file-system/src/main/java/org/esa/snap/vfs/remote/VFSByteChannel.java @@ -138,7 +138,7 @@ public int read(ByteBuffer destinationBuffer) throws IOException { int bytesToRead = destinationBuffer.remaining(); if (destinationBuffer.hasArray()) { bytes = destinationBuffer.array(); - offset = destinationBuffer.arrayOffset(); + offset = destinationBuffer.position(); } else { bytes = new byte[bytesToRead]; offset = 0;