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 5b53df22a7eb2eb00be4849c3b311ff1bae1d6f7
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Apr 14 16:06:40 2022 +0200

    `MetadataSource.lookup(…)` should verify if the metadata record exists
    (otherwise the `catch (MetadataStoreException)` blocks are ineffective).
---
 .../org/apache/sis/metadata/sql/Dispatcher.java    |   6 +-
 .../apache/sis/metadata/sql/MetadataSource.java    | 114 ++++++++++++++-------
 .../apache/sis/metadata/sql/TableHierarchy.java    |   4 +
 .../apache/sis/storage/landsat/MetadataReader.java |   4 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |   2 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  |   2 +-
 .../internal/storage/DocumentedStoreProvider.java  |  45 ++++----
 .../sis/internal/storage/MetadataBuilder.java      |  22 ++--
 .../apache/sis/internal/storage/ascii/Store.java   |   2 +-
 .../org/apache/sis/internal/storage/csv/Store.java |   2 +-
 .../apache/sis/internal/storage/image/Store.java   |   2 +-
 11 files changed, 124 insertions(+), 81 deletions(-)

diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
index 9eb83a9151..63a15907e4 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/Dispatcher.java
@@ -56,7 +56,7 @@ import org.apache.sis.internal.util.Numerics;
  *
  * @author  Touraïvane (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.2
  * @since   0.8
  * @module
  */
@@ -83,7 +83,7 @@ final class Dispatcher implements InvocationHandler {
      * have different {@code preferredIndex} values even if their {@link 
CachedStatement#type} value is the same,
      * since their {@link #identifier} values are different.</div>
      */
-    byte preferredIndex;
+    int preferredIndex;
 
     /**
      * The metadata instance where to store the property (column) values, or 
{@code null} if not yet created.
@@ -266,7 +266,7 @@ final class Dispatcher implements InvocationHandler {
                                     hasValue |= (fetchValue(info, 
impl.getMethod(dep)) != null);
                                 }
                                 if (hasValue) {
-                                    cache = this.cache;             // Created 
by recursive 'invoke(…)' call above.
+                                    cache = this.cache;             // Created 
by recursive `invoke(…)` call above.
                                     if (cache != null) {
                                         synchronized (cache) {
                                             value = method.invoke(cache);      
       // Attempt a new computation.
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
index 269d2c570e..4cf0c3509c 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
@@ -110,7 +110,7 @@ import org.apache.sis.util.iso.Types;
  *
  * @author  Touraïvane (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.8
  * @module
  */
@@ -193,7 +193,7 @@ public class MetadataSource implements AutoCloseable {
      *     }
      * }
      *
-     * @see #take(Class, int)
+     * @see #prepareStatement(Class, String, int)
      * @see #recycle(CachedStatement, int)
      */
     private final CachedStatement[] statements;
@@ -332,7 +332,7 @@ public class MetadataSource implements AutoCloseable {
                 }
                 /*
                  * If the error is transient or has a transient cause, we will 
not save MetadataFallback.INSTANCE
-                 * in the 'instance' field. The intent is to try again next 
time this method will be invoked, in
+                 * in the `instance` field. The intent is to try again next 
time this method will be invoked, in
                  * case the transient error has disappeared.
                  */
                 for (Throwable cause = e; cause != null; cause = 
cause.getCause()) {
@@ -508,13 +508,17 @@ public class MetadataSource implements AutoCloseable {
     }
 
     /**
-     * Returns a statement that can be reused for the given interface, or 
{@code null} if none.
+     * Returns a statement that can be reused for performing queries on the 
table for the specified interface.
+     * Callers must invoke this method in a block synchronized on {@code this}.
      *
      * @param  type            the interface for which to reuse a prepared 
statement.
+     * @param  tableName       value of {@code getTableName(type)}, or {@code 
null} for computing by this method.
      * @param  preferredIndex  index in the cache array where to search first. 
This is only a hint for increasing
      *         the chances to find quickly a {@code CachedStatement} instance 
for the right type and identifier.
      */
-    private CachedStatement take(final Class<?> type, final int 
preferredIndex) {
+    private CachedStatement prepareStatement(final Class<?> type, String 
tableName, final int preferredIndex)
+            throws SQLException
+    {
         assert Thread.holdsLock(this);
         if (preferredIndex >= 0 && preferredIndex < statements.length) {
             final CachedStatement statement = statements[preferredIndex];
@@ -530,7 +534,14 @@ public class MetadataSource implements AutoCloseable {
                 return statement;
             }
         }
-        return null;
+        if (tableName == null) {
+            tableName = getTableName(type);
+        }
+        final SQLBuilder helper = helper();
+        final String query = helper.clear().append("SELECT * FROM ")
+                .appendIdentifier(schema, tableName).append(" WHERE ")
+                .appendIdentifier(ID_COLUMN).append("=?").toString();
+        return new CachedStatement(type, connection().prepareStatement(query), 
logFilter);
     }
 
     /**
@@ -548,7 +559,7 @@ public class MetadataSource implements AutoCloseable {
             while (statements[preferredIndex] != null) {
                 if (++preferredIndex >= statements.length) {
                     /*
-                     * If we reach this point, this means that the 
'statements' pool has reached its maximal capacity.
+                     * If we reach this point, this means that the 
`statements` pool has reached its maximal capacity.
                      * Loop again on all statements in order to find the 
oldest one. We will close that old statement
                      * and cache the given one instead.
                      */
@@ -837,26 +848,64 @@ public class MetadataSource implements AutoCloseable {
      * @param  identifier  the identifier of the record for the metadata 
entity to be created.
      *                     This is usually the primary key of the record to 
search for.
      * @return an implementation of the required interface, or the code list 
element.
-     * @throws MetadataStoreException if a SQL query failed.
+     * @throws MetadataStoreException if a SQL query failed or if the metadata 
has not been found.
      */
     public <T> T lookup(final Class<T> type, final String identifier) throws 
MetadataStoreException {
         ArgumentChecks.ensureNonNull("type", type);
         ArgumentChecks.ensureNonEmpty("identifier", identifier);
+        return type.cast(lookup(type, identifier, true));
+    }
+
+    /**
+     * Implementation of public {@link #lookup(Class, String)} method.
+     *
+     * <h4>Deferred database access</h4>
+     * This method may or may not query the database immediately, at 
implementation choice.
+     * It the database is not queried immediately, invalid identifiers may not 
be detected
+     * during this method invocation. Instead, an invalid identifier may be 
detected only
+     * when a getter method is invoked on the returned metadata object. In 
such case,
+     * an {@link org.apache.sis.util.collection.BackingStoreException} will be 
thrown
+     * at getter method invocation time.
+     *
+     * @param  type        the interface to implement or the {@link 
ControlledVocabulary} type.
+     * @param  identifier  the identifier of the record for the metadata 
entity to be created.
+     * @param  verify      whether to check for record existence.
+     * @return an implementation of the required interface, or the code list 
element.
+     * @throws MetadataStoreException if a SQL query failed or if the metadata 
has not been found.
+     */
+    private Object lookup(final Class<?> type, final String identifier, 
boolean verify) throws MetadataStoreException {
         Object value;
         if (ControlledVocabulary.class.isAssignableFrom(type)) {
             value = getCodeList(type, identifier);
         } else {
             final CacheKey key = new CacheKey(type, identifier);
             /*
-             * IMPLEMENTATION NOTE: be careful to not invoke any method that 
may synchronize on 'this'
-             * inside the block synchronized on 'pool'.
+             * IMPLEMENTATION NOTE: be careful to not invoke any method that 
may synchronize on `this`
+             * inside a block synchronized on `pool` (implicit synchronization 
of `pool` method calls).
              */
-            synchronized (pool) {
-                value = pool.get(key);
-                if (value == null && type.isInterface()) {
-                    value = Proxy.newProxyInstance(classloader,
-                            new Class<?>[] {type, MetadataProxy.class}, new 
Dispatcher(identifier, this));
-                    pool.put(key, value);
+            value = pool.get(key);
+            if (value == null && type.isInterface()) {
+                final Dispatcher toSearch = new Dispatcher(identifier, this);
+                value = Proxy.newProxyInstance(classloader, new Class<?>[] 
{type, MetadataProxy.class}, toSearch);
+                if (verify) try {
+                    /*
+                     * If the caller asked to verify whether the record 
exists, perform a query now.
+                     * We trivially request the identifier, so the 
`getValue(…)` result should be
+                     * the identifier itself (this is not verified). If the 
record does not exist,
+                     * a `MetadataStoreException` is thrown by `getValue(…)`.
+                     */
+                    synchronized (this) {
+                        final Class<?> subType = TableHierarchy.subType(type, 
identifier);
+                        CachedStatement result = prepareStatement(subType, 
null, toSearch.preferredIndex);
+                        result.getValue(identifier, ID_COLUMN);               
// Check record existence.
+                        toSearch.preferredIndex = recycle(result, 
toSearch.preferredIndex);
+                    }
+                } catch (SQLException e) {
+                    throw new 
MetadataStoreException(Errors.format(Errors.Keys.DatabaseError_2, type, 
identifier), e);
+                }
+                final Object replacement = pool.putIfAbsent(key, value);
+                if (replacement != null) {
+                    value = replacement;
                 }
             }
             /*
@@ -908,12 +957,14 @@ public class MetadataSource implements AutoCloseable {
 
     /**
      * Invoked by {@link MetadataProxy} for fetching an attribute value from a 
table.
+     * It the database table does not contains a column for the property, this 
method returns {@code null}.
+     * A {@code null} value may also mean that the column exists but contains 
an SQL {@code NULL} value.
      *
      * @param  info      the interface type (together with cached information).
      *                   This is mapped to the table name in the database.
      * @param  method    the method invoked. This is mapped to the column name 
in the database.
      * @param  toSearch  contains the identifier and preferred index of the 
record to search.
-     * @return the value of the requested attribute.
+     * @return the value of the requested attribute, or {@code null} if none.
      * @throws SQLException if the SQL query failed.
      * @throws MetadataStoreException if a value was not found or can not be 
converted to the expected type.
      */
@@ -922,7 +973,7 @@ public class MetadataSource implements AutoCloseable {
     {
         /*
          * If the identifier is prefixed with a table name as in 
"{Organisation}identifier",
-         * the name between bracket is a subtype of the given 'type' argument.
+         * the name between bracket is a subtype of the given `type` argument.
          */
         final Class<?> type           = 
TableHierarchy.subType(info.getMetadataType(), toSearch.identifier);
         final Class<?> returnType     = method.getReturnType();
@@ -940,17 +991,10 @@ public class MetadataSource implements AutoCloseable {
             } else {
                 /*
                  * Prepares the statement and executes the SQL query in this 
synchronized block.
-                 * Note that the usage of 'result' must stay inside this 
synchronized block
+                 * Note that the usage of `result` must stay inside this 
synchronized block
                  * because we can not assume that JDBC connections are 
thread-safe.
                  */
-                CachedStatement result = take(type, 
Byte.toUnsignedInt(toSearch.preferredIndex));
-                if (result == null) {
-                    final SQLBuilder helper = helper();
-                    final String query = helper.clear().append("SELECT * FROM 
")
-                            .appendIdentifier(schema, tableName).append(" 
WHERE ")
-                            
.appendIdentifier(ID_COLUMN).append("=?").toString();
-                    result = new CachedStatement(type, 
connection().prepareStatement(query), logFilter);
-                }
+                CachedStatement result = prepareStatement(type, tableName, 
toSearch.preferredIndex);
                 value = result.getValue(toSearch.identifier, columnName);
                 isArray = (value instanceof java.sql.Array);
                 if (isArray) {
@@ -958,7 +1002,7 @@ public class MetadataSource implements AutoCloseable {
                     value = array.getArray();
                     array.free();
                 }
-                toSearch.preferredIndex = (byte) recycle(result, 
Byte.toUnsignedInt(toSearch.preferredIndex));
+                toSearch.preferredIndex = recycle(result, 
toSearch.preferredIndex);
             }
         }
         /*
@@ -971,7 +1015,7 @@ public class MetadataSource implements AutoCloseable {
                 Object element = Array.get(value, i);
                 if (element != null) {
                     if (isMetadata) {
-                        element = lookup(elementType, element.toString());
+                        element = lookup(elementType, element.toString(), 
false);
                     } else try {
                         element = info.convert(elementType, element);
                     } catch (UnconvertibleObjectException e) {
@@ -987,13 +1031,13 @@ public class MetadataSource implements AutoCloseable {
             }
         }
         /*
-         * Now converts the value to its final type. To be strict, we should 
convert null values into empty collections
-         * if the return type is a collection type. But we leave this task to 
the caller (which is the Dispatcher class)
-         * for making easier to detect when a value is absent, for allowing 
Dispatcher to manage its cache.
+         * Now convert the value to its final type. To be strict, we should 
convert null values to empty collections
+         * if the return type is a collection type. But we leave this task to 
the caller (which is the `Dispatcher`)
+         * for making easier to detect when a value is absent, for allowing 
`Dispatcher` to manage its cache.
          */
         if (value != null) {
             if (isMetadata) {
-                value = lookup(elementType, value.toString());
+                value = lookup(elementType, value.toString(), false);
             } else try {
                 value = info.convert(elementType, value);
             } catch (UnconvertibleObjectException e) {
@@ -1045,7 +1089,7 @@ public class MetadataSource implements AutoCloseable {
             enumeration = EnumSet.noneOf((Class) elementType);
         } else {
             /*
-             * If 'returnType' is Collection.class, do not copy into a Set 
since a List
+             * If `returnType` is Collection.class, do not copy into a Set 
since a List
              * is probably good enough. Copy only if a Set is explicitly 
requested.
              */
             if (Set.class.isAssignableFrom(returnType)) {
@@ -1185,7 +1229,7 @@ public class MetadataSource implements AutoCloseable {
             isCloseScheduled = true;
         } else {
             // No more prepared statements.
-            final Connection c = this.connection;
+            final Connection c = connection;
             connection = null;
             helper = null;
             closeQuietly(c);
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
index bd8c757bf9..d362793ca4 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
@@ -112,6 +112,10 @@ final class TableHierarchy {
      * For example if the given type is {@code Party.class} and the given 
identifier is
      * {@code "{Organisation}EPSG"}, then this method returns {@code 
Organisation.class}.
      * Otherwise this method returns {@code type} unchanged.
+     *
+     * @param  type        base metadata type.
+     * @param  identifier  primary key in the database.
+     * @return actual type of the metadata object.
      */
     static Class<?> subType(Class<?> type, final String identifier) {
         if (identifier.charAt(0) == TYPE_OPEN) {
diff --git 
a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/MetadataReader.java
 
b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/MetadataReader.java
index 4b0f2be036..411542f275 100644
--- 
a/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/MetadataReader.java
+++ 
b/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/landsat/MetadataReader.java
@@ -476,8 +476,8 @@ final class MetadataReader extends MetadataBuilder {
             case "OUTPUT_FORMAT": {
                 String name = value;
                 if (Constants.GEOTIFF.equalsIgnoreCase(name)) try {
-                    name = Constants.GEOTIFF;               // Because 
'metadata.setFormat(…)' is case-sensitive.
-                    setFormat(name);
+                    name = Constants.GEOTIFF;       // Because 
`metadata.setPredefinedFormat(…)` is case-sensitive.
+                    setPredefinedFormat(name);
                     break;
                 } catch (MetadataStoreException e) {
                     warning(key, null, e);
diff --git 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
index 783f177233..d0a2c77d26 100644
--- 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -285,7 +285,7 @@ public class GeoTiffStore extends DataStore implements 
Aggregate {
      */
     final void setFormatInfo(final MetadataBuilder builder) {
         try {
-            builder.setFormat(Constants.GEOTIFF);
+            builder.setPredefinedFormat(Constants.GEOTIFF);
         } catch (MetadataStoreException e) {
             builder.addFormatName(Constants.GEOTIFF);
             listeners.warning(e);
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index 92fe35edd9..15c099b14b 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -666,7 +666,7 @@ split:  while ((start = 
CharSequences.skipLeadingWhitespaces(value, start, lengt
         final String[] format = decoder.getFormatDescription();
         String id = format[0];
         if (NetcdfStoreProvider.NAME.equalsIgnoreCase(id)) try {
-            setFormat(NetcdfStoreProvider.NAME);
+            setPredefinedFormat(NetcdfStoreProvider.NAME);
             id = null;
         } catch (MetadataStoreException e) {
             // Will add `id` at the end of this method.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
index 3e27da39ea..0ea7a4eb80 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/DocumentedStoreProvider.java
@@ -31,7 +31,7 @@ import org.apache.sis.internal.system.Modules;
  * The primary key in the {@code MD_Format} table must be the name given at 
construction time.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.2
  * @since   0.8
  * @module
  */
@@ -43,11 +43,11 @@ public abstract class DocumentedStoreProvider extends 
URIDataStore.Provider {
     private final String name;
 
     /**
-     * {@code true} if the call to {@link #getFormat()} caught an exception. 
In such case,
-     * we log a warning only the first time and use a finer logging level the 
other times.
-     * The intent is to avoid polluting the logs with too many warnings.
+     * The format, created when first requested.
+     *
+     * @see #getFormat(StoreListeners)
      */
-    private volatile boolean logged;
+    private transient Format format;
 
     /**
      * Creates a new provider.
@@ -88,29 +88,24 @@ public abstract class DocumentedStoreProvider extends 
URIDataStore.Provider {
      * @param  listeners  where to report the warning in case of error, or 
{@code null} if none.
      * @return a description of the data format.
      */
-    public final Format getFormat(final StoreListeners listeners) {
-        /*
-         * Note: this method does not cache the format because such caching is 
already done by MetadataSource.
-         */
-        if (name != null) try {
-            return MetadataSource.getProvided().lookup(Format.class, name);
-        } catch (MetadataStoreException e) {
-            if (listeners != null) {
-                listeners.warning(e);
-            } else {
-                final Level level;
-                if (!logged) {
-                    logged = true;      // Not atomic - not a big deal if we 
use warning level twice.
-                    level = Level.WARNING;
-                } else {
-                    level = Level.FINE;
-                }
-                final LogRecord record = 
Resources.forLocale(null).getLogRecord(level,
+    public final synchronized Format getFormat(final StoreListeners listeners) 
{
+        if (format == null) {
+            if (name != null) try {
+                return format = 
MetadataSource.getProvided().lookup(Format.class, name);
+            } catch (MetadataStoreException e) {
+                final LogRecord record = 
Resources.forLocale(null).getLogRecord(Level.WARNING,
                         Resources.Keys.CanNotGetCommonMetadata_2, 
getShortName(), e.getLocalizedMessage());
+                record.setSourceClassName(getClass().getCanonicalName());
+                record.setSourceMethodName("getFormat");
                 record.setLoggerName(Modules.STORAGE);
-                Logging.log(getClass(), "getFormat", record);
+                if (listeners != null) {
+                    listeners.warning(record);
+                } else {
+                    Logging.getLogger(Modules.STORAGE).log(record);
+                }
             }
+            format = super.getFormat();
         }
-        return super.getFormat();
+        return format;
     }
 }
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
index 2e83572902..dac07899b8 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
@@ -1008,7 +1008,7 @@ public class MetadataBuilder {
      *
      * {@preformat java
      *     try {
-     *         metadata.setFormat("MyFormat");
+     *         metadata.setPredefinedFormat("MyFormat");
      *     } catch (MetadataStoreException e) {
      *         metadata.addFormatName("MyFormat");
      *         listeners.warning(null, e);
@@ -1023,7 +1023,7 @@ public class MetadataBuilder {
      * @see #addCompression(CharSequence)
      * @see #addFormatName(CharSequence)
      */
-    public final void setFormat(final String abbreviation) throws 
MetadataStoreException {
+    public final void setPredefinedFormat(final String abbreviation) throws 
MetadataStoreException {
         if (abbreviation != null && abbreviation.length() != 0) {
             if (format == null) {
                 format = MetadataSource.getProvided().lookup(Format.class, 
abbreviation);
@@ -3089,12 +3089,12 @@ parse:      for (int i = 0; i < length;) {
      *   <li>{@code 
metadata/identificationInfo/resourceFormat/formatSpecificationCitation/alternateTitle}</li>
      * </ul>
      *
-     * If this method is used together with {@link #setFormat(String)},
-     * then {@code setFormat} should be invoked <strong>before</strong> this 
method.
+     * If this method is used together with {@link 
#setPredefinedFormat(String)},
+     * then {@code setPredefinedFormat(…)} should be invoked 
<strong>before</strong> this method.
      *
      * @param value  the format name, or {@code null} for no-operation.
      *
-     * @see #setFormat(String)
+     * @see #setPredefinedFormat(String)
      * @see #setFormatEdition(CharSequence)
      * @see #addCompression(CharSequence)
      */
@@ -3119,12 +3119,12 @@ parse:      for (int i = 0; i < length;) {
      *   <li>{@code 
metadata/identificationInfo/resourceFormat/formatSpecificationCitation/edition}</li>
      * </ul>
      *
-     * If this method is used together with {@link #setFormat(String)},
-     * then {@code setFormat} should be invoked <strong>before</strong> this 
method.
+     * If this method is used together with {@link 
#setPredefinedFormat(String)},
+     * then {@code setPredefinedFormat(…)} should be invoked 
<strong>before</strong> this method.
      *
      * @param value  the format edition, or {@code null} for no-operation.
      *
-     * @see #setFormat(String)
+     * @see #setPredefinedFormat(String)
      * @see #addFormatName(CharSequence)
      */
     public final void setFormatEdition(final CharSequence value) {
@@ -3148,12 +3148,12 @@ parse:      for (int i = 0; i < length;) {
      *   <li>{@code 
metadata/identificationInfo/resourceFormat/fileDecompressionTechnique}</li>
      * </ul>
      *
-     * If this method is used together with {@link #setFormat(String)},
-     * then {@code setFormat} should be invoked <strong>before</strong> this 
method.
+     * If this method is used together with {@link 
#setPredefinedFormat(String)},
+     * then {@code setPredefinedFormat(…)} should be invoked 
<strong>before</strong> this method.
      *
      * @param value  the compression name, or {@code null} for no-operation.
      *
-     * @see #setFormat(String)
+     * @see #setPredefinedFormat(String)
      * @see #addFormatName(CharSequence)
      */
     public final void addCompression(final CharSequence value) {
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ascii/Store.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ascii/Store.java
index 2409b120e0..ead3dceeca 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ascii/Store.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ascii/Store.java
@@ -332,7 +332,7 @@ cellsize:       if (value != null) {
             readHeader();
             final MetadataBuilder builder = new MetadataBuilder();
             try {
-                builder.setFormat("ASCGRD");
+                builder.setPredefinedFormat("ASCGRD");
             } catch (MetadataStoreException e) {
                 builder.addFormatName(StoreProvider.NAME);
                 listeners.warning(e);
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
index 0398172c9e..7580d9ce41 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
@@ -640,7 +640,7 @@ final class Store extends URIDataStore implements 
FeatureSet {
             final MetadataBuilder builder = new MetadataBuilder();
             final String format = (timeEncoding != null) && hasTrajectories ? 
StoreProvider.MOVING : StoreProvider.NAME;
             try {
-                builder.setFormat(format);
+                builder.setPredefinedFormat(format);
             } catch (MetadataStoreException e) {
                 builder.addFormatName(format);
                 listeners.warning(e);
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
index 299b1db493..148c7f50d7 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
@@ -344,7 +344,7 @@ loop:   for (int convention=0;; convention++) {
             final MetadataBuilder builder = new MetadataBuilder();
             final String format = reader().getFormatName();
             try {
-                builder.setFormat(format);
+                builder.setPredefinedFormat(format);
             } catch (MetadataStoreException e) {
                 builder.addFormatName(format);
                 listeners.warning(Level.FINE, null, e);

Reply via email to