You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2021/12/31 02:00:20 UTC

[sis] branch geoapi-4.0 updated (e13ceef -> a83df8e)

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

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


    from e13ceef  Fix an exception when opening a netCDF file with one-dimensional variables.
     add 7b8a6a6  chore(Storage): add a test case for column definition ambiguity.
     new 4cba6e6  Merge remote-tracking branch 'origin/fix/projection_name_clash' into geoapi-4.0 together with correction for the bug demonstrated by the new test.
     new a83df8e  Trivial comment formatting.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/sis/feature/DefaultFeatureType.java |  12 +--
 .../sis/feature/builder/FeatureTypeBuilder.java    |  13 ++-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |   8 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |   2 +-
 .../apache/sis/util/iso/DefaultNameFactory.java    |   4 +-
 .../org/apache/sis/util/iso/DefaultScopedName.java |   4 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |   4 +-
 .../java/org/apache/sis/util/iso/TypeNames.java    |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../org/apache/sis/storage/sql/SQLStoreTest.java   |   4 +-
 .../java/org/apache/sis/storage/FeatureQuery.java  | 113 +++++++++++++++------
 .../org/apache/sis/storage/FeatureQueryTest.java   |  26 ++++-
 14 files changed, 147 insertions(+), 52 deletions(-)

[sis] 01/02: Merge remote-tracking branch 'origin/fix/projection_name_clash' into geoapi-4.0 together with correction for the bug demonstrated by the new test.

Posted by de...@apache.org.
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 4cba6e649c62b3a8a6a4eb330f8f7f376a12a665
Merge: e13ceef 7b8a6a6
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Dec 31 02:51:25 2021 +0100

    Merge remote-tracking branch 'origin/fix/projection_name_clash' into geoapi-4.0 together with correction for the bug demonstrated by the new test.

 .../sis/feature/builder/FeatureTypeBuilder.java    |  13 ++-
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../org/apache/sis/storage/sql/SQLStoreTest.java   |   4 +-
 .../java/org/apache/sis/storage/FeatureQuery.java  | 113 +++++++++++++++------
 .../org/apache/sis/storage/FeatureQueryTest.java   |  26 ++++-
 7 files changed, 129 insertions(+), 34 deletions(-)

diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
index 55457bc,55457bc..3ab4bdc
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
@@@ -692,6 -692,6 +692,8 @@@ public class FeatureTypeBuilder extend
  
      /**
       * Creates a new {@code AttributeType} builder initialized to the same characteristics than the given template.
++     * If the new attribute duplicates an existing one (for example if the same template is used many times),
++     * caller should use the returned builder for modifying some attributes.
       *
       * @param  <V>       the compile-time type of values in the {@code template} argument.
       * @param  template  an existing attribute type to use as a template.
@@@ -795,7 -795,7 +797,9 @@@
  
      /**
       * Creates a new {@code FeatureAssociationRole} builder initialized to the same characteristics
--     * than the given template.
++     * than the given template. If the new association duplicates an existing one (for example if the
++     * same template is used many times), caller should use the returned builder for modifying some
++     * associations.
       *
       * @param  template  an existing feature association to use as a template.
       * @return a builder for an {@code FeatureAssociationRole}, initialized with the values of the given template.
@@@ -813,6 -813,6 +817,7 @@@
      /**
       * Adds the given property in the feature type properties.
       * The given property shall be an instance of one of the following types:
++     *
       * <ul>
       *   <li>{@link AttributeType}, in which case this method delegate to {@link #addAttribute(AttributeType)}.</li>
       *   <li>{@link FeatureAssociationRole}, in which case this method delegate to {@link #addAssociation(FeatureAssociationRole)}.</li>
@@@ -820,8 -820,8 +825,12 @@@
       *       this builder does not create new operations.</li>
       * </ul>
       *
++     * This method does not verify if the given property duplicates an existing property.
++     * If the same template is used many times, then the caller should use the returned builder
++     * for modifying some properties.
++     *
       * @param  template  the property to add to the feature type.
--     * @return a builder initialized to the given builder.
++     * @return a builder initialized to the given template.
       *         In the {@code Operation} case, the builder is a read-only accessor on the operation properties.
       *
       * @see #properties()
diff --cc core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
index 97b2e11,a3fa6f8..0f7d994
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
@@@ -1285,6 -1265,6 +1285,11 @@@ public final class Vocabulary extends I
          public static final short Unnamed = 208;
  
          /**
++         * Unnamed #{0}
++         */
++        public static final short Unnamed_1 = 266;
++
++        /**
           * Unspecified
           */
          public static final short Unspecified = 209;
diff --cc core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
index 3737547,23535c1..62e15b9
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
@@@ -259,6 -255,6 +259,7 @@@ TypeOfResource          = Type of resou
  Units                   = Units
  Unknown                 = Unknown
  Unnamed                 = Unnamed
++Unnamed_1               = Unnamed #{0}
  Unspecified             = Unspecified
  Untitled                = Untitled
  UnavailableContent      = Unavailable content.
diff --cc core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
index 959ad86,873cf3d..8440b29
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
@@@ -266,6 -262,6 +266,7 @@@ TypeOfResource          = Type de resso
  Units                   = Unit\u00e9s
  Unknown                 = Inconnu
  Unnamed                 = Sans nom
++Unnamed_1               = Sans nom \u2116{0}
  Unspecified             = Non-sp\u00e9cifi\u00e9
  Untitled                = Sans titre
  UnavailableContent      = Contenu non-disponible.
diff --cc storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java
index cd2cb95,094ceb4..5756e44
--- a/storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java
+++ b/storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java
@@@ -380,7 -369,7 +380,7 @@@ public final strictfp class SQLStoreTes
           */
          final FeatureSet   parks = dataset.findResource("Parks");
          final FeatureQuery query = new FeatureQuery();
--        query.setProjection(new FeatureQuery.NamedExpression(FF.property(desiredProperty)));
++        query.setProjection(FF.property(desiredProperty));
          query.setSortBy(FF.sort(FF.property("country"),       SortOrder.DESCENDING),
                          FF.sort(FF.property(desiredProperty), SortOrder.ASCENDING));
          final FeatureSet subset = parks.subset(query);
@@@ -541,7 -501,7 +541,7 @@@
              final FeatureQuery query = new FeatureQuery();
              query.setSortBy(FF.sort(FF.property("native_name"), SortOrder.DESCENDING));
              query.setSelection(FF.equal(FF.property("country"), FF.literal("FRA")));
--            query.setProjection(new FeatureQuery.NamedExpression(FF.property("native_name")));
++            query.setProjection(FF.property("native_name"));
              final FeatureSet frenchParks = parks.subset(query);
              /*
               * Verify the feature type.
diff --cc storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
index ffee909,ffee909..9368d53
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureQuery.java
@@@ -17,6 -17,6 +17,8 @@@
  package org.apache.sis.storage;
  
  import java.util.Arrays;
++import java.util.Set;
++import java.util.HashSet;
  import java.util.Map;
  import java.util.LinkedHashMap;
  import java.util.Objects;
@@@ -35,9 -35,9 +37,10 @@@ import org.apache.sis.internal.storage.
  import org.apache.sis.filter.DefaultFilterFactory;
  import org.apache.sis.filter.Optimization;
  import org.apache.sis.util.ArgumentChecks;
--import org.apache.sis.util.Classes;
++import org.apache.sis.util.CharSequences;
  import org.apache.sis.util.collection.Containers;
  import org.apache.sis.util.iso.Names;
++import org.apache.sis.util.resources.Vocabulary;
  
  // Branch-dependent imports
  import org.opengis.feature.Feature;
@@@ -218,9 -218,9 +221,12 @@@ public class FeatureQuery extends Quer
              for (int i=0; i<properties.length; i++) {
                  final NamedExpression c = properties[i];
                  ArgumentChecks.ensureNonNullElement("properties", i, c);
--                final Object key = c.alias != null ? c.alias : c.expression;
++                Object key = (c.alias != null) ? c.alias : c.expression;
                  final Integer p = uniques.putIfAbsent(key, i);
                  if (p != null) {
++                    if (key instanceof Expression) {
++                        key = label((Expression) key);
++                    }
                      throw new IllegalArgumentException(Resources.format(Resources.Keys.DuplicatedQueryProperty_3, key, p, i));
                  }
              }
@@@ -396,6 -396,6 +402,9 @@@
       * An expression to be retrieved by a {@code Query}, together with the name to assign to it.
       * In relational database terminology, subset of columns is called <cite>projection</cite>.
       * Columns can be given to the {@link FeatureQuery#setProjection(NamedExpression[])} method.
++     *
++     * @version 1.2
++     * @since   1.1
       */
      public static class NamedExpression implements Serializable {
          /**
@@@ -451,30 -451,30 +460,6 @@@
          }
  
          /**
--         * Adds in the given builder the type of results computed by this column.
--         *
--         * @param  column     index of this column. Used for error message only.
--         * @param  valueType  the type of features to be evaluated by the expression in this column.
--         * @param  addTo      where to add the type of properties evaluated by expression in this column.
--         * @throws IllegalArgumentException if this method can operate only on some feature types
--         *         and the given type is not one of them.
--         * @throws InvalidFilterValueException if this method can not determine the result type of the expression
--         *         in this column. It may be because that expression is backed by an unsupported implementation.
--         *
--         * @see FeatureQuery#expectedType(FeatureType)
--         */
--        final void expectedType(final int column, final FeatureType valueType, final FeatureTypeBuilder addTo) {
--            final PropertyTypeBuilder resultType = FeatureExpression.expectedType(expression, valueType, addTo);
--            if (resultType == null) {
--                throw new InvalidFilterValueException(Resources.format(Resources.Keys.InvalidExpression_2,
--                            expression.getFunctionName().toInternationalString(), column));
--            }
--            if (alias != null && !alias.equals(resultType.getName())) {
--                resultType.setName(alias);
--            }
--        }
--
--        /**
           * Returns a hash code value for this column.
           *
           * @return a hash code value.
@@@ -524,7 -524,7 +509,7 @@@
              } else if (expression instanceof ValueReference<?,?>) {
                  buffer.append(((ValueReference<?,?>) expression).getXPath());
              } else {
--                buffer.append(Classes.getShortClassName(expression));   // Class name with enclosing class if any.
++                buffer.append(expression.getFunctionName());
              }
              if (alias != null) {
                  buffer.append(" AS “").append(alias).append('”');
@@@ -533,6 -533,6 +518,23 @@@
      }
  
      /**
++     * Returns a label for the given expression for reporting to human (e.g. in exception messages).
++     * This method uses the value reference (XPath) or literal value if applicable, truncated to an
++     * arbitrary length.
++     */
++    private static String label(final Expression<?,?> expression) {
++        final String text;
++        if (expression instanceof Literal<?,?>) {
++            text = String.valueOf(((Literal<?,?>) expression).getValue());
++        } else if (expression instanceof ValueReference<?,?>) {
++            text = ((ValueReference<?,?>) expression).getXPath();
++        } else {
++            return expression.getFunctionName().toString();
++        }
++        return CharSequences.shortSentence(text, 40).toString();
++    }
++
++    /**
       * Applies this query on the given feature set.
       * This method is invoked by the default implementation of {@link FeatureSet#subset(Query)}.
       * The default implementation executes the query using the default {@link java.util.stream.Stream} methods.
@@@ -565,6 -565,6 +567,13 @@@
  
      /**
       * Returns the type of values evaluated by this query when executed on features of the given type.
++     * If some expressions have no name, default names are computed as below:
++     *
++     * <ul>
++     *   <li>If the expression is an instance of {@link ValueReference},
++     *       the tip of the {@linkplain ValueReference#getXPath() x-path}.</li>
++     *   <li>Otherwise the localized string "Unnamed #1" with increasing numbers.</li>
++     * </ul>
       *
       * @param  valueType  the type of features to be evaluated by the expressions in this query.
       * @return type resulting from expressions evaluation (never null).
@@@ -577,9 -577,9 +586,55 @@@
          if (projection == null) {
              return valueType;           // All columns included: result is of the same type.
          }
++        int unnamedNumber = 0;          // Sequential number for unnamed expressions.
++        Set<String> names = null;       // Names already used, for avoiding collisions.
          final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName(valueType.getName());
--        for (int i=0; i<projection.length; i++) {
--            projection[i].expectedType(i, valueType, ftb);
++        for (int column = 0; column < projection.length; column++) {
++            /*
++             * For each property, get the expected type (mandatory) and its name (optional).
++             * A default name will be computed if no alias were explicitly given by user.
++             */
++            GenericName name = projection[column].alias;
++            final Expression<?,?> expression = projection[column].expression;
++            final PropertyTypeBuilder resultType = FeatureExpression.expectedType(expression, valueType, ftb);
++            if (resultType == null) {
++                throw new InvalidFilterValueException(Resources.format(Resources.Keys.InvalidExpression_2,
++                            expression.getFunctionName().toInternationalString(), column));
++            }
++            if (name == null) {
++                /*
++                 * Build a list of aliases declared by the user, for making sure that we do not collide with them.
++                 * No check for `GenericName` collision here because it was already verified by `setProjection(…)`.
++                 * We may have collision of their `String` representations however, which is okay.
++                 */
++                if (names == null) {
++                    names = new HashSet<>(Containers.hashMapCapacity(projection.length));
++                    for (final NamedExpression p : projection) {
++                        if (p.alias != null) {
++                            names.add(p.alias.tip().toString());
++                        }
++                    }
++                }
++                /*
++                 * The rules for creating a default name are documented in this method Javadoc.
++                 * Note that despite the use of `Vocabulary` resources, the name will be unlocalized
++                 * (for easier programmatic use) because `GenericName` implementation is designed for
++                 * providing localized names only if explicitly requested.
++                 */
++                CharSequence text = null;
++                if (expression instanceof ValueReference<?,?>) {
++                    String xpath = ((ValueReference<?,?>) expression).getXPath().trim();
++                    xpath = xpath.substring(xpath.lastIndexOf('/') + 1);    // Works also if '/' is not found.
++                    if (!(xpath.isEmpty() || names.contains(xpath))) {
++                        text = xpath;
++                    }
++                }
++                if (text == null) do {
++                    text = Vocabulary.formatInternational(Vocabulary.Keys.Unnamed_1, ++unnamedNumber);
++                } while (!names.add(text.toString()));
++                name = Names.createLocalName(null, null, text);
++            }
++            resultType.setName(name);
          }
          return ftb.build();
      }
diff --cc storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
index 6918ac9,f675e4f..7f6af73
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureQueryTest.java
@@@ -18,6 -18,6 +18,7 @@@ package org.apache.sis.storage
  
  import java.util.List;
  import java.util.Arrays;
++import java.util.Iterator;
  import java.util.stream.Collectors;
  import org.apache.sis.feature.builder.FeatureTypeBuilder;
  import org.apache.sis.internal.storage.MemoryFeatureSet;
@@@ -43,7 -44,7 +45,9 @@@ import org.opengis.filter.SortProperty
   * Tests {@link FeatureQuery} and (indirectly) {@link FeatureSubset}.
   *
   * @author  Johann Sorel (Geomatys)
-- * @version 1.1
++ * @author  Alexis Manin (Geomatys)
++ * @author  Martin Desruisseaux (Geomatys)
++ * @version 1.2
   * @since   1.0
   * @module
   */
@@@ -209,4 -210,15 +213,24 @@@ public final strictfp class FeatureQuer
          final PropertyType p = TestUtilities.getSingleton(result.getType().getProperties(true));
          assertEquals("value2", p.getName().toString());
      }
+ 
++    /**
++     * Tests the creation of default column names when no alias where explicitly specified.
++     * Note that the string representations of default names shall be unlocalized.
++     *
++     * @throws DataStoreException if an error occurred while executing the query.
++     */
+     @Test
 -    public void testColumnNameClash() throws DataStoreException {
++    public void testDefaultColumnName() throws DataStoreException {
+         final FilterFactory<Feature,?,?> ff = DefaultFilterFactory.forFeatures();
+         query.setProjection(
+                 ff.add(ff.property("value1", Number.class), ff.literal(1)),
+                 ff.add(ff.property("value2", Number.class), ff.literal(1)));
 -        final FeatureSet subset = featureSet.subset(query); // NOTE: I would expect an error here
++        final FeatureSet subset = featureSet.subset(query);
+         final FeatureType type = subset.getType();
 -        assertEquals(2, type.getProperties(true).size());
++        final Iterator<? extends PropertyType> properties = type.getProperties(true).iterator();
++        assertEquals("Unnamed #1", properties.next().getName().toString());
++        assertEquals("Unnamed #2", properties.next().getName().toString());
++        assertFalse(properties.hasNext());
+     }
  }

[sis] 02/02: Trivial comment formatting.

Posted by de...@apache.org.
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 a83df8e6cdaeba95a5b845d83061959df69fd1f9
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Dec 31 02:58:11 2021 +0100

    Trivial comment formatting.
---
 .../main/java/org/apache/sis/feature/DefaultFeatureType.java | 12 ++++++------
 .../main/java/org/apache/sis/util/iso/DefaultLocalName.java  |  8 ++++----
 .../main/java/org/apache/sis/util/iso/DefaultMemberName.java |  2 +-
 .../java/org/apache/sis/util/iso/DefaultNameFactory.java     |  4 ++--
 .../main/java/org/apache/sis/util/iso/DefaultScopedName.java |  4 ++--
 .../main/java/org/apache/sis/util/iso/DefaultTypeName.java   |  4 ++--
 .../src/main/java/org/apache/sis/util/iso/TypeNames.java     |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java b/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
index 8990704..e2ebc82 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
@@ -293,7 +293,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
         }
         /*
          * Before to resolve cyclic associations, verify that operations depend only on existing properties.
-         * Note: the 'allProperties' collection has been created by computeTransientFields(…) above.
+         * Note: the `allProperties` collection has been created by computeTransientFields(…) above.
          */
         for (final PropertyType property : allProperties) {
             if (property instanceof AbstractOperation) {
@@ -329,7 +329,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
         in.defaultReadObject();
         computeTransientFields(properties);
         /*
-         * Set isResolved to a conservative value. The 'resolve' method will compute a more accurate value if needed,
+         * Set isResolved to a conservative value. The `resolve` method will compute a more accurate value if needed,
          * the first time that another DefaultFeatureType will have a dependency to this DefaultFeatureType through a
          * DefaultAssociationRole.
          */
@@ -392,7 +392,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
          * name for convenience, provided that it does not create ambiguity.  If a short alias could map to two or
          * more properties, then that alias is not added.
          *
-         * In the 'aliases' map below, null values will be assigned to ambiguous short names.
+         * In the `aliases` map below, null values will be assigned to ambiguous short names.
          */
         final Map<String, PropertyType> aliases = new LinkedHashMap<>();
         for (final PropertyType property : allProperties) {
@@ -411,7 +411,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
                 if (byName.putIfAbsent(tip, property) == null) {
                     /*
                      * This block is skipped if there is properties named "tip" and "head:tip".
-                     * The 'indices' value may be null if the property is an operation.
+                     * The `indices` value may be null if the property is an operation.
                      */
                     final Integer value = indices.get(property.getName().toString());
                     if (value != null && indices.put(tip, value) != null) {
@@ -525,7 +525,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
         /*
          * The isResolved field is used only as a cache for skipping completely the DefaultFeatureType instance if
          * we have determined that there is no unresolved name.  If the given argument is not a DefaultFeatureType
-         * instance, conservatively assumes 'isSimple'. It may cause more calculation than needed, but should not
+         * instance, conservatively assumes `isSimple`. It may cause more calculation than needed, but should not
          * change the result.
          */
         if (feature instanceof DefaultFeatureType) {
@@ -566,7 +566,7 @@ public class DefaultFeatureType extends AbstractIdentifiedType implements Featur
                     }
                     /*
                      * Resolve recursively the associated features, with a check against infinite recursivity.
-                     * If we fall in a loop (for example A → B → C → A), conservatively returns 'false'. This
+                     * If we fall in a loop (for example A → B → C → A), conservatively returns `false`. This
                      * may not be the most accurate answer, but will not cause any more hurt than checking more
                      * often than necessary.
                      */
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
index e1616f2..e11a7b1 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
@@ -139,18 +139,18 @@ public class DefaultLocalName extends AbstractName implements LocalName {
                  * flavor instead of InternationalString (this is done by name.toString() at
                  * the end of this constructor). It will not cause any lost of information since
                  * SimpleInternationalString contains only one String. This simplification allows
-                 * the equals(Object) method to return "true" for DefaultLocalName that would
+                 * the equals(Object) method to return `true` for `DefaultLocalName` that would
                  * otherwise be considered different.
                  *
                  * In order to reduce the amount of objects created, we retain the full
-                 * InternationalString in the "asString" field, which is NOT considered
+                 * InternationalString in the `asString` field, which is NOT considered
                  * by equals(Object). This is the value returned by toInternationalString().
                  */
                 asString = name;
             } else {
                 /*
                  * For any InternationalString that are not SimpleInternationalString, we retain
-                 * the given name and we do NOT set the "asString" field. It will be computed on
+                 * the given name and we do NOT set the `asString` field. It will be computed on
                  * the fly when first needed.
                  */
                 this.name = name;
@@ -365,7 +365,7 @@ public class DefaultLocalName extends AbstractName implements LocalName {
 
     /**
      * Empty constructor to be used by JAXB only, or by sub-classes empty constructors
-     * themselves used only by JAXB. Despite its "final" declaration, the {@link #name}
+     * themselves used only by JAXB. Despite its `final` declaration, the {@link #name}
      * field will be set by JAXB during unmarshalling.
      */
     DefaultLocalName() {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
index 2271562..462b151 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
@@ -148,7 +148,7 @@ public class DefaultMemberName extends DefaultLocalName implements MemberName {
     //////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
-     * Empty constructor to be used by JAXB only. Despite its "final" declaration,
+     * Empty constructor to be used by JAXB only. Despite its `final` declaration,
      * the {@link #attributeType} field will be set by JAXB during unmarshalling.
      */
     private DefaultMemberName() {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
index 4dac9a1..cc78ce2 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
@@ -446,11 +446,11 @@ public class DefaultNameFactory extends AbstractFactory implements NameFactory {
             /*
              * Create TypeNames outide the synchronized block because the TypeNames constructor will call back
              * methods from this class. Since those methods are overrideable, this could invoke user's code.
-             * Note also that methods in this class use the 'pool', which is itself synchronized, so we are
+             * Note also that methods in this class use the `pool`, which is itself synchronized, so we are
              * better to avoid double synchronization for reducing the risk of dead-lock.
              */
             final TypeNames c = new TypeNames(this);
-            synchronized (this) {                       // Double-check strategy is ok if 'typeNames' is volatile.
+            synchronized (this) {                       // Double-check strategy is ok if `typeNames` is volatile.
                 t = typeNames;
                 if (t == null) {
                     typeNames = t = c;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
index 6ca4f1b..b2c20c8 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
@@ -150,7 +150,7 @@ public class DefaultScopedName extends AbstractName implements ScopedName {
         if (i != size) {                                        // Paranoiac check.
             throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1, "names"));
         }
-        // Following line is safe because 'parsedNames' type is <? extends LocalName>.
+        // Following line is safe because `parsedNames` type is <? extends LocalName>.
         parsedNames = UnmodifiableArrayList.wrap(locals);
     }
 
@@ -214,7 +214,7 @@ public class DefaultScopedName extends AbstractName implements ScopedName {
         if (index != locals.length) {               // Paranoiac check.
             throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1, "tail"));
         }
-        // Following line is safe because 'parsedNames' type is <? extends LocalName>.
+        // Following line is safe because `parsedNames` type is <? extends LocalName>.
         parsedNames = UnmodifiableArrayList.wrap(locals);
         if (tail instanceof LocalName) {
             this.path = path;
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
index 9b691b8..c065bd6 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
@@ -258,7 +258,7 @@ public class DefaultTypeName extends DefaultLocalName implements TypeName {
             /*
              * Invoke super.foo() instead of this.foo() because we do not want to invoke any overridden method.
              * This is for ensuring that two TypeNames constructed with the same name will map to the same class.
-             * See 'valueClass' javadoc for more information.
+             * See `valueClass` javadoc for more information.
              */
             try {
                 c = TypeNames.toClass(TypeNames.namespace(super.scope()), super.toString());
@@ -288,7 +288,7 @@ public class DefaultTypeName extends DefaultLocalName implements TypeName {
     //////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
-     * Empty constructor to be used by JAXB only. Despite its "final" declaration,
+     * Empty constructor to be used by JAXB only. Despite its `final` declaration,
      * the {@link #name} field will be set by JAXB during unmarshalling.
      */
     private DefaultTypeName() {
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
index 3e87004..48325ec 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
@@ -128,7 +128,7 @@ final class TypeNames {
             }
         }
         /*
-         * Now create the name and remember the 'valueClass' for that name if the implementation allows that.
+         * Now create the name and remember the `valueClass` for that name if the implementation allows that.
          */
         final TypeName t = factory.createTypeName(ns, name);
         if (t instanceof DefaultTypeName) {