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 f9c073b1c8158eaf27a017bb0ab2f45de4c38649
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Jun 13 17:34:47 2023 +0200

    Replace `TypeRegistration.hasRenameFile(…)` by a mechanism in which the 
`TypeRegistration` subclass fetches itself the resource.
    This is necessary in a context of Java module, because the resource can not 
be opened from `org.apache.sis.xml.Transformer`.
---
 .../apache/sis/internal/jaxb/TypeRegistration.java | 55 +++++++++++++---------
 .../main/java/org/apache/sis/xml/Transformer.java  | 16 +++----
 .../sis/internal/profile/fra/ProfileTypes.java     | 20 +++++---
 3 files changed, 55 insertions(+), 36 deletions(-)

diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
 
b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
index fac23dd33c..e70df4e54f 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.internal.jaxb;
 
-import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.ArrayList;
@@ -24,6 +23,10 @@ import java.util.Collection;
 import java.util.ServiceLoader;
 import java.util.concurrent.TimeUnit;
 import java.util.function.UnaryOperator;
+import java.util.function.Supplier;
+import java.util.Optional;
+import java.util.Iterator;
+import java.io.InputStream;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 import jakarta.xml.bind.JAXBContext;
@@ -39,10 +42,8 @@ import org.apache.sis.internal.system.DelayedRunnable;
  * Declares the classes of objects to be marshalled using a default {@code 
MarshallerPool}.
  * This class is not strictly necessary for marshalling a SIS object using 
JAXB, but makes
  * the job easier by allowing {@code MarshallerPool} to configure the JAXB 
context automatically.
- * To allow such automatic configuration, modules must declare instances of 
this interface in the
- * following file:
- *
- * <pre 
class="text">META-INF/services/org.org.apache.sis.internal.jaxb.TypeRegistration</pre>
+ * To allow such automatic configuration, modules must declare instances of 
this interface
+ * as a service in their {@code module-info}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.4
@@ -130,30 +131,42 @@ public abstract class TypeRegistration {
     }
 
     /**
-     * Returns {@code true} if {@code "RenameOnImport.lst"} and/or {@code 
"RenameOnExport.lst"} files are provided.
-     * If {@code true}, then those files shall be located in the same 
directory than this {@code TypeRegistration}
-     * subclass.
+     * Opens a stream on the {@code "RenameOnImport.lst"} or {@code 
"RenameOnExport.lst"} file if present.
+     * Those files are typically located in the same directory than this 
{@code TypeRegistration} subclass.
+     *
+     * <h4>Design note</h4>
+     * If a modularized project, the call to {@link 
Class#getResourceAsStream(String)} must be done in the
+     * module which contains the resource. It is not possible to only request 
the filename and open the
+     * resources in this metadata module.
      *
-     * @param  export  {@code true} for {@code "RenameOnImport.lst"}, {@code 
false} for {@code "RenameOnImport.lst"}.
-     * @return whether {@code "RenameOnImport.lst"} and/or {@code 
"RenameOnExport.lst"} files are provided.
+     * @param  export    {@code true} for {@code "RenameOnExport.lst"}, {@code 
false} for {@code "RenameOnImport.lst"}.
+     * @param  filename  the filename as documented in the {@code export} 
argument, for convenience.
+     * @return stream opened on the {@code "RenameOnImport.lst"} or the {@code 
"RenameOnExport.lst"} file.
      */
-    protected boolean hasRenameFile(boolean export) {
-        return false;
+    protected Optional<InputStream> getRenameDefinitionsFile(boolean export, 
String filename) {
+        return Optional.empty();
     }
 
     /**
-     * Adds in the given set the classes to use for loading  {@code 
"RenameOnImport.lst"} and/or {@code "RenameOnExport.lst"} files.
-     * The given set should preserve insertion order, since the order in which 
files are loaded may matter.
+     * Returns all input streams for loading the {@code "RenameOnImport.lst"} 
or {@code "RenameOnExport.lst"} file.
+     * Each stream will be opened only when requested. The supplier returns 
{@code null} after the last stream has
+     * been returned.
      *
-     * @param  export  {@code true} for {@code "RenameOnImport.lst"}, {@code 
false} for {@code "RenameOnImport.lst"}.
-     * @param  addTo   where to add the classes to use for loading the 
resource files.
+     * @param  export    {@code true} for {@code "RenameOnExport.lst"}, {@code 
false} for {@code "RenameOnImport.lst"}.
+     * @param  filename  the filename as documented in the {@code export} 
argument, for convenience.
+     * @return all input streams.
      */
-    public static synchronized void getRenameFileLoader(final boolean export, 
final Set<Class<?>> addTo) {
-        for (final TypeRegistration t : services()) {
-            if (t.hasRenameFile(export)) {
-                addTo.add(t.getClass());
+    public static synchronized Supplier<InputStream> 
getRenameDefinitionsFiles(final boolean export, final String filename) {
+        final Iterator<TypeRegistration> services = services().iterator();
+        return () -> {
+            synchronized (TypeRegistration.class) {
+                while (services.hasNext()) {
+                    final Optional<InputStream> next = 
services.next().getRenameDefinitionsFile(export, filename);
+                    if (next.isPresent()) return next.get();
+                }
+                return null;
             }
-        }
+        };
     }
 
     /**
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java 
b/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java
index b84bf47585..8cf53ae2fa 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java
@@ -19,12 +19,13 @@ package org.apache.sis.xml;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Set;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.InvalidPropertiesFormatException;
+import java.util.function.Supplier;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import javax.xml.XMLConstants;
@@ -83,7 +84,7 @@ import org.apache.sis.internal.jaxb.TypeRegistration;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Cullen Rombach (Image Matters)
- * @version 1.0
+ * @version 1.4
  *
  * @see javax.xml.transform.Transformer
  *
@@ -242,11 +243,10 @@ abstract class Transformer {
      */
     static Map<String, Map<String,String>> load(final boolean export, final 
String filename, final Set<String> targets, final int capacity) {
         final Map<String, Map<String,String>> m = new HashMap<>(capacity);
-        final Set<Class<?>> renameLoaders = new LinkedHashSet<>(8);
-        renameLoaders.add(Transformer.class);
-        TypeRegistration.getRenameFileLoader(export, renameLoaders);
-        for (final Class<?> loader : renameLoaders) {
-            try (LineNumberReader in = new LineNumberReader(new 
InputStreamReader(loader.getResourceAsStream(filename), "UTF-8"))) {
+        final Supplier<InputStream> plugins = 
TypeRegistration.getRenameDefinitionsFiles(export, filename);
+        InputStream resourceStream = 
Transformer.class.getResourceAsStream(filename);
+        do {
+            try (LineNumberReader in = new LineNumberReader(new 
InputStreamReader(resourceStream, "UTF-8"))) {
                 Map<String,String> attributes = null;               // All 
attributes for a given type.
                 String namespace = null;                            // Value 
to store in `attributes` map.
                 String line;
@@ -358,7 +358,7 @@ abstract class Transformer {
             } catch (IOException e) {
                 throw new ExceptionInInitializerError(e);
             }
-        }
+        } while ((resourceStream = plugins.get()) != null);
         /*
          * At this point we finished computing the map values. Many values are 
maps with only 1 entry.
          */
diff --git 
a/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/ProfileTypes.java
 
b/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/ProfileTypes.java
index 65706a5151..dc1519721e 100644
--- 
a/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/ProfileTypes.java
+++ 
b/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/ProfileTypes.java
@@ -16,7 +16,9 @@
  */
 package org.apache.sis.internal.profile.fra;
 
+import java.io.InputStream;
 import java.util.Collection;
+import java.util.Optional;
 import org.apache.sis.internal.jaxb.TypeRegistration;
 
 
@@ -25,7 +27,7 @@ import org.apache.sis.internal.jaxb.TypeRegistration;
  * This class is declared in the {@code 
META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration} file.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.4
  * @since   0.4
  */
 public final class ProfileTypes extends TypeRegistration {
@@ -43,14 +45,18 @@ public final class ProfileTypes extends TypeRegistration {
     }
 
     /**
-     * Returns {@code true} for {@code export = false} in order to notify that 
we provide
-     * a {@code "RenameOnImport.lst"} file that need to be read.
+     * Opens a stream on the {@code "RenameOnImport.lst"} if {@code export} is 
false.
      *
-     * @param  export  {@code true} for {@code "RenameOnImport.lst"}, {@code 
false} for {@code "RenameOnImport.lst"}.
-     * @return {@code true} for {@code "RenameOnImport.lst"}, {@code false} 
otherwise.
+     * @param  export    {@code false} for {@code "RenameOnImport.lst"}.
+     * @param  filename  a filename consistent with the {@code export} 
argument, for convenience.
+     * @return stream opened on the {@code "RenameOnImport.lst"} file if 
{@code export} is false.
      */
     @Override
-    protected boolean hasRenameFile(boolean export) {
-        return !export;
+    protected Optional<InputStream> getRenameDefinitionsFile(final boolean 
export, final String filename) {
+        if (export) {
+            return super.getRenameDefinitionsFile(export, filename);
+        } else {
+            return 
Optional.of(ProfileTypes.class.getResourceAsStream(filename));
+        }
     }
 }

Reply via email to