This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit e2c3b3af00e1c4f28574719a6d634fd36f8df5ae
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Dec 7 18:30:25 2022 +0100

    Fix a `ClassCastException` and an `EOFException`.
    The latter was caused by wrong `ChannelData.channelOffset` value.
---
 .../apache/sis/gui/metadata/StandardMetadataTree.java    |  2 +-
 .../java/org/apache/sis/metadata/MetadataStandard.java   | 10 +++++-----
 .../org/apache/sis/internal/storage/io/ChannelData.java  | 16 ++++++++++++++++
 .../apache/sis/internal/storage/io/ChannelDataInput.java | 12 ++++++++++++
 .../sis/internal/storage/io/ChannelImageInputStream.java |  6 +++---
 5 files changed, 37 insertions(+), 9 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
index ea4acb7a42..98963bd146 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
@@ -106,7 +106,7 @@ public class StandardMetadataTree extends MetadataTree {
             tree = ((AbstractMetadata) metadata).asTreeTable();
         } else {
             // `COMPACT` is the default policy of 
`AbstractMetadata.asTreeTable()`.
-            tree = MetadataStandard.ISO_19115.asTreeTable(metadata, null, 
ValueExistencePolicy.COMPACT);
+            tree = MetadataStandard.ISO_19115.asTreeTable(metadata, 
Metadata.class, ValueExistencePolicy.COMPACT);
         }
         setContent(tree);
     }
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
index e931ee9325..88a2d59c1f 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
@@ -442,7 +442,7 @@ public class MetadataStandard implements Serializable {
         }
         /*
          * At this point, all cached values (including those in dependencies) 
have been checked.
-         * Performs the 'findInterface' computation only in last resort. 
Current implementation
+         * Performs the `findInterface(…)` computation only in last resort. 
Current implementation
          * does not store negative results in order to avoid filling the cache 
with unrelated classes.
          */
         final Class<?> standardType = findInterface(key);
@@ -489,7 +489,7 @@ public class MetadataStandard implements Serializable {
             }
         } else {
             /*
-             * Gets every interfaces from the supplied package in declaration 
order,
+             * Gets every interfaces from the supplied class in declaration 
order,
              * including the ones declared in the super-class.
              */
             final Set<Class<?>> interfaces = new LinkedHashSet<>();
@@ -517,7 +517,7 @@ public class MetadataStandard implements Serializable {
                 }
                 /*
                  * Found more than one interface; we don't know which one to 
pick.
-                 * Returns 'null' for now; the caller will thrown an exception.
+                 * Returns `null` for now; the caller will thrown an exception.
                  */
             } else if (IMPLEMENTATION_CAN_ALTER_API) {
                 /*
@@ -1049,7 +1049,7 @@ public class MetadataStandard implements Serializable {
             }
         } else {
             /*
-             * If we get here, a cycle has been found. Returns 'true' in order 
to allow the caller to continue
+             * If we get here, a cycle has been found. Returns `true` in order 
to allow the caller to continue
              * comparing other properties. It is okay because someone else is 
comparing those two same objects,
              * and that later comparison will do the actual check for property 
values.
              */
@@ -1074,7 +1074,7 @@ public class MetadataStandard implements Serializable {
             final Integer hash = HashCode.getOrCreate().walk(this, null, 
metadata, true);
             if (hash != null) return hash;
             /*
-             * 'hash' may be null if a cycle has been found. Example: A 
depends on B which depends on A,
+             * `hash` may be null if a cycle has been found. Example: A 
depends on B which depends on A,
              * in which case the null value is returned for the second 
occurrence of A (not the first one).
              * We cannot compute a hash code value here, but it should be okay 
since that metadata is part
              * of a bigger metadata object, and that enclosing object should 
have other properties for computing
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
index aca1c0db2b..cc4150ea86 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelData.java
@@ -125,6 +125,22 @@ public abstract class ChannelData implements Markable {
         this.channelOffset = (channel instanceof SeekableByteChannel) ? 
((SeekableByteChannel) channel).position() : 0;
     }
 
+    /**
+     * Creates a new instance from the given {@code ChannelData}.
+     * This constructor is invoked when we need to change the implementation 
class.
+     * The old {@code ChannelData} should not be used anymore after this 
constructor.
+     *
+     * @param  old  the existing instance from which to takes the channel and 
buffer.
+     */
+    ChannelData(final ChannelData old) {
+        filename      = old.filename;
+        buffer        = old.buffer;
+        channelOffset = old.channelOffset;
+        bufferOffset  = old.bufferOffset;
+        bitPosition   = old.bitPosition;
+        mark          = old.mark;
+    }
+
     /**
      * Creates a new instance for a buffer filled with the bytes to use.
      * This constructor uses an independent, read-only view of the given 
buffer.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
index 314f2decc3..99e54c8be8 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelDataInput.java
@@ -106,6 +106,18 @@ public class ChannelDataInput extends ChannelData {
         }
     }
 
+    /**
+     * Creates a new input stream from the given {@code ChannelDataInput}.
+     * This constructor is invoked when we need to change the implementation 
class.
+     * The old input should not be used anymore after this constructor has 
been invoked.
+     *
+     * @param  input  the existing instance from which to takes the channel 
and buffer.
+     */
+    ChannelDataInput(final ChannelDataInput input) {
+        super(input);
+        channel = input.channel;
+    }
+
     /**
      * Creates a new instance for a buffer filled with the bytes to use.
      * This constructor uses an independent, read-only view of the given 
buffer.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
index 00ca785041..a2b26a6c3d 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/ChannelImageInputStream.java
@@ -84,12 +84,12 @@ public class ChannelImageInputStream extends 
ChannelDataInput implements ImageIn
      * Creates a new input stream from the given {@code ChannelDataInput}.
      * This constructor is invoked when we need to change the implementation 
class
      * from {@code ChannelDataInput} to {@code ChannelImageInputStream}.
+     * The old input should not be used anymore after this constructor has 
been invoked.
      *
      * @param  input  the existing instance from which to takes the channel 
and buffer.
-     * @throws IOException if an error occurred while reading the channel.
      */
-    public ChannelImageInputStream(final ChannelDataInput input) throws 
IOException {
-        super(input.filename, input.channel, input.buffer, true);
+    public ChannelImageInputStream(final ChannelDataInput input) {
+        super(input);
     }
 
     /**

Reply via email to