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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 1e926955f7 Simplify `DefinitionURI.codeOf(String)` by leveraging the 
existing `parse` method. Simplification in return values is also possible 
because that method, which was previously used by authority factories, is now 
used only by `UnitFormat`.
1e926955f7 is described below

commit 1e926955f72f9a662e134972edf74651ac2fa15a
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sun Jul 17 21:08:27 2022 +0200

    Simplify `DefinitionURI.codeOf(String)` by leveraging the existing `parse` 
method.
    Simplification in return values is also possible because that method, which 
was previously used by authority factories, is now used only by `UnitFormat`.
---
 .../apache/sis/internal/util/DefinitionURI.java    | 82 ++++++----------------
 .../java/org/apache/sis/measure/UnitFormat.java    | 34 ++++-----
 .../sis/internal/util/DefinitionURITest.java       | 29 +++++---
 .../org/apache/sis/measure/UnitFormatTest.java     |  1 +
 4 files changed, 58 insertions(+), 88 deletions(-)

diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
 
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
index 2e86876a7d..54037e0455 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
@@ -106,7 +106,7 @@ import static 
org.apache.sis.util.ArgumentChecks.ensureNonNull;
  * {@code "urn:ogc:def:crs,crs:EPSG:6.3:27700,crs:EPSG:6.3:5701"}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.3
  *
  * @see org.apache.sis.internal.metadata.NameMeaning
  * @see <a href="https://portal.ogc.org/files/?artifact_id=24045";>Definition 
identifier URNs in OGC namespace</a>
@@ -403,7 +403,7 @@ public final class DefinitionURI {
                         do {
                             /*
                              * Find indices of URI sub-component to parse. The 
sub-component will
-                             * go from 'splitAt' to 'next' exclusive 
('splitAt' is exclusive too).
+                             * go from `splitAt` to `next` exclusive 
(`splitAt` is exclusive too).
                              */
                             int next = uri.indexOf(componentSeparator, 
splitAt+1);
                             hasMore = next >= 0 && next < componentsEnd;
@@ -495,8 +495,8 @@ public final class DefinitionURI {
     /**
      * Returns the substring of the given URN, ignoring whitespaces and 
version number if present.
      * The substring is expected to contains at most one {@code ':'} 
character. If such separator
-     * character is present, then that character and everything before it are 
ignored. The ignored
-     * part should be the version number, but this is not verified.
+     * character is present, then that character and everything before it are 
ignored.
+     * The ignored part should be the version number, but this is not verified.
      *
      * <p>If the remaining substring is empty or contains more {@code ':'} 
characters, then this method
      * returns {@code null}. The presence of more {@code ':'} characters means 
that the code has parameters,
@@ -525,7 +525,7 @@ public final class DefinitionURI {
 
     /**
      * Returns the code part of the given URI, provided that it matches the 
given object type and authority.
-     * This lightweight method is useful when:
+     * This method is useful when:
      *
      * <ul>
      *   <li>the URI is expected to have a specific <cite>object type</cite> 
and <cite>authority</cite>;</li>
@@ -536,11 +536,11 @@ public final class DefinitionURI {
      * This method accepts the following URI representations:
      *
      * <ul>
-     *   <li>Code alone, without any {@code ':'} character (e.g. {@code 
"4326"}).</li>
      *   <li>The given authority followed by the code (e.g. {@code 
"EPSG:4326"}).</li>
      *   <li>The URN form (e.g. {@code "urn:ogc:def:crs:EPSG::4326"}), 
ignoring version number.
      *       This method accepts also the former {@code "x-ogc"} in place of 
{@code "ogc"}.</li>
-     *   <li>The HTTP form (e.g. {@code 
"http://www.opengis.net/gml/srs/epsg.xml#4326"}).</li>
+     *   <li>The HTTP form (e.g. {@code 
"http://www.opengis.net/def/crs/EPSG/0/4326"}).</li>
+     *   <li>The GML form (e.g. {@code 
"http://www.opengis.net/gml/srs/epsg.xml#4326"}).</li>
      * </ul>
      *
      * @param  type       the expected object type (e.g. {@code "crs"}) in 
lower cases. See class javadoc for a list of types.
@@ -552,61 +552,25 @@ public final class DefinitionURI {
     public static String codeOf(final String type, final String authority, 
final String uri) {
         ensureNonNull("type",      type);
         ensureNonNull("authority", authority);
-        ensureNonNull("uri",       uri);
-        /*
-         * Get the part before the first ':' character. If none, assume that 
the given URI is already the code.
-         * Otherwise the part may be either "http" or "urn" protocol, or the 
given authority (typically "EPSG").
-         * In the latter case, we return immediately the code after the 
authority part.
-         */
         int upper = uri.indexOf(SEPARATOR);
-        if (upper < 0) {
-            return trimWhitespaces(uri);
-        }
-        int lower  = skipLeadingWhitespaces(uri, 0, upper);
-        int length = skipTrailingWhitespaces(uri, lower, upper) - lower;
-        if (length == authority.length() && uri.regionMatches(true, lower, 
authority, 0, length)) {
-            return codeIgnoreVersion(uri, upper+1);
-        }
-        /*
-         * Check for supported protocols: only "urn" and "http" at this time.
-         * All other protocols are rejected as unrecognized.
-         */
-        String part;
-        switch (length) {
-            case 3:  part = "urn";  break;
-            case 4:  part = "http"; break;
-            default: return null;
-        }
-        if (!uri.regionMatches(true, lower, part, 0, length)) {
-            return null;
-        }
-        if (length == 4) {
-            return codeForGML(type, authority, uri, upper+1, null);
-        }
-        /*
-         * At this point we have determined that the protocol is URN. The next 
parts after "urn"
-         * shall be "ogc" or "x-ogc", then "def", then the type and authority 
given in arguments.
-         */
-        for (int p=0; p!=4; p++) {
-            lower = upper + 1;
-            upper = uri.indexOf(SEPARATOR, lower);
-            if (upper < 0) {
-                return null;                                                   
 // No more parts.
-            }
-            switch (p) {
-                // "ogc" is tested before "x-ogc" because more common.
-                case 0: if (regionMatches("ogc", uri, lower, upper)) continue;
-                        part = "x-ogc";   break;       // Fallback if the part 
is not "ogc".
-                case 1: part = "def";     break;
-                case 2: part = type;      break;
-                case 3: part = authority; break;
-                default: throw new AssertionError(p);
+        if (upper >= 0) {
+            int lower  = skipLeadingWhitespaces(uri, 0, upper);
+            int length = skipTrailingWhitespaces(uri, lower, upper) - lower;
+            if (length == authority.length() && uri.regionMatches(true, lower, 
authority, 0, length)) {
+                return codeIgnoreVersion(uri, upper+1);
             }
-            if (!regionMatches(part, uri, lower, upper)) {
-                return null;
+            final DefinitionURI def = parse(uri);
+            if (def != null && def.parameters == null) {
+                if (type.equalsIgnoreCase(def.type) && 
authority.equalsIgnoreCase(def.authority)) {
+                    String code = def.code;
+                    if (code == null) {
+                        code = def.version;     // May happen with for example 
"EPSG:4326" instead of "EPSG::4326".
+                    }
+                    return code;
+                }
             }
         }
-        return codeIgnoreVersion(uri, upper+1);
+        return null;
     }
 
     /**
@@ -632,7 +596,7 @@ public final class DefinitionURI {
                 return null;
             }
             // TODO: For now do nothing since PATHS is a singleton. However if 
a future SIS version
-            //       defines more PATHS entries, then we should replace here 
the 'paths' reference by
+            //       defines more PATHS entries, then we should replace here 
the `paths` reference by
             //       a new Collections.singletonMap containing only the entry 
of interest.
         }
         for (final Map.Entry<String,String> entry : paths.entrySet()) {
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
index 73ca72bff9..a48a31776e 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
@@ -74,7 +74,7 @@ import static java.util.logging.Logger.getLogger;
  * each thread should have its own {@code UnitFormat} instance.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.3
  *
  * @see Units#valueOf(String)
  *
@@ -547,7 +547,7 @@ public class UnitFormat extends Format implements 
javax.measure.format.UnitForma
             nameToUnit = map;
         }
         /*
-         * The 'nameToUnit' map contains plural forms (declared in 
UnitAliases.properties),
+         * The `nameToUnit` map contains plural forms (declared in 
UnitAliases.properties),
          * but we make a special case for "degrees", "metres" and "meters" 
because they
          * appear in numerous places.
          */
@@ -675,7 +675,7 @@ appPow: if (unit == null) {
          * have been created by SystemUnit.transform(…), in which case "Choice 
3" above would have been executed.
          */
         final Unit<?> unscaled = unit.getSystemUnit();
-        @SuppressWarnings("unchecked")          // Both 'unit' and 'unscaled' 
are 'Unit<Q>'.
+        @SuppressWarnings("unchecked")          // Both `unit` and `unscaled` 
are `Unit<Q>`.
         final double scale = 
AbstractConverter.scale(unit.getConverterTo((Unit) unscaled));
         if (Double.isNaN(scale)) {
             throw new 
IllegalArgumentException(Errors.format(Errors.Keys.NonRatioUnit_1,
@@ -731,7 +731,7 @@ appPow: if (unit == null) {
          * Append the scale factor. If we can use a prefix (e.g. "km" instead 
of "1000⋅m"), we will do that.
          * Otherwise if the scale is a power of 10 and we are allowed to use 
Unicode symbols, we will write
          * for example 10⁵⋅m instead of 100000⋅m. If the scale is not a power 
of 10, or if we are requested
-         * to format UCUM symbol, then we fallback on the usual 
'Double.toString(double)' representation.
+         * to format UCUM symbol, then we fallback on the usual 
`Double.toString(double)` representation.
          */
         if (scale != 1) {
             final char prefix = Prefixes.symbol(scale, prefixPower);
@@ -757,9 +757,9 @@ appPow: if (unit == null) {
                     toAppendTo.append(text, 0, length);
                 }
                 /*
-                 * The 'formatComponents' method appends division symbol only, 
no multiplication symbol.
+                 * The `formatComponents` method appends division symbol only, 
no multiplication symbol.
                  * If we have formatted a scale factor and there is at least 
one component to multiply,
-                 * we need to append the multiplication symbol ourselves. Note 
that 'formatComponents'
+                 * we need to append the multiplication symbol ourselves. Note 
that `formatComponents`
                  * put numerators before denominators, so we are sure that the 
first term after the
                  * multiplication symbol is a numerator.
                  */
@@ -804,7 +804,7 @@ appPow: if (unit == null) {
         /*
          * At this point, all numerators have been appended. Now append the 
denominators together.
          * For example pressure dimension is formatted as M∕(L⋅T²) no matter 
if 'M' was the first
-         * dimension in the given 'components' map or not.
+         * dimension in the given `components` map or not.
          */
         if (!deferred.isEmpty()) {
             toAppendTo.append(style.divide);
@@ -1114,13 +1114,7 @@ appPow: if (unit == null) {
         if (endOfURI >= 0) {
             final String uom = symbols.subSequence(start, endOfURI).toString();
             String code = DefinitionURI.codeOf("uom", Constants.EPSG, uom);
-            /*
-             * DefinitionURI.codeOf(…) returns 'uom' directly (provided that 
whitespaces were already trimmed)
-             * if no ':' character were found, in which case the string is 
assumed to be the code directly.
-             * This is the intended behavior for AuthorityFactory, but in the 
particular case of this method
-             * we want to try to parse as a xpointer before to give up.
-             */
-            if (code != null && code != uom) {
+            if (code != null) {
                 NumberFormatException failure = null;
                 try {
                     final Unit<?> unit = 
Units.valueOfEPSG(Integer.parseInt(code));
@@ -1140,9 +1134,9 @@ appPow: if (unit == null) {
              * Not an EPSG code. Maybe it is a URI like this example:
              * 
http://www.isotc211.org/2005/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])
              *
-             * If we find such 'uom' value, we could replace 'symbols' by that 
'uom'. But it would cause a wrong
+             * If we find such `uom` value, we could replace `symbols` by that 
`uom`. But it would cause a wrong
              * error index to be reported in case of parsing failure. We will 
rather try to adjust the indices
-             * (and replace 'symbols' only in last resort).
+             * (and replace `symbols` only in last resort).
              */
             code = XPointer.UOM.reference(uom);
             if (code != null) {
@@ -1162,7 +1156,7 @@ appPow: if (unit == null) {
          * Split the unit around the multiplication and division operators and 
parse each term individually.
          * Note that exponentation need to be kept as part of a single unit 
symbol.
          *
-         * The 'start' variable is the index of the first character of the 
next unit term to parse.
+         * The `start` variable is the index of the first character of the 
next unit term to parse.
          */
         final Operation operation = new Operation(symbols);    // Enumeration 
value: NOOP, IMPLICIT, MULTIPLY, DIVIDE.
         Unit<?> unit = null;
@@ -1277,7 +1271,7 @@ scan:   for (int n; i < end; i += n) {
              * between the previously parsed units and the next unit to parse. 
A special case is IMPLICIT, which is
              * a multiplication without explicit × symbol after the 
parenthesis. The implicit multiplication can be
              * overridden by an explicit × or / symbol, which is what happened 
if we reach this point (tip: look in
-             * the above 'switch' statement all cases that end with 'break', 
not 'break scan' or 'continue').
+             * the above `switch` statement all cases that end with `break`, 
not `break scan` or `continue`).
              */
             if (operation.code != Operation.IMPLICIT) {
                 unit = operation.apply(unit, parseTerm(symbols, start, i, 
operation), start);
@@ -1326,7 +1320,7 @@ search:     while ((i = 
CharSequences.skipTrailingWhitespaces(symbols, start, i)
             }
         }
         if (!(operation.finished = (component != null))) {
-            component = parseTerm(symbols, start, i, operation);            // 
May set 'operation.finished' flag.
+            component = parseTerm(symbols, start, i, operation);            // 
May set `operation.finished` flag.
         }
         if (operation.finished) {
             finish(position);           // For preventing interpretation of 
"degree minute" as "degree × minute".
@@ -1512,7 +1506,7 @@ search:     while ((i = 
CharSequences.skipTrailingWhitespaces(symbols, start, i)
                                 try {
                                     power = new Fraction(uom.substring(i));
                                 } catch (NumberFormatException e) {
-                                    // Should never happen unless the number 
is larger than 'int' capacity.
+                                    // Should never happen unless the number 
is larger than `int` capacity.
                                     throw (ParserException) new 
ParserException(Errors.format(
                                             Errors.Keys.UnknownUnit_1, uom), 
symbols, lower+i).initCause(e);
                                 }
diff --git 
a/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java
 
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java
index 22965fabcf..c4facb3792 100644
--- 
a/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java
+++ 
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java
@@ -27,7 +27,7 @@ import static org.junit.Assert.*;
  * Tests {@link DefinitionURI}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.3
  * @since   0.4
  * @module
  */
@@ -188,11 +188,12 @@ public final strictfp class DefinitionURITest extends 
TestCase {
     }
 
     /**
-     * Tests {@link DefinitionURI#codeOf(String, String, String)} with URI 
like {@code "EPSG:4326"}.
+     * Tests {@link DefinitionURI#codeOf(String, String, String)}
+     * with URI like {@code "EPSG:4326"}.
      */
     @Test
     public void testCodeOfEPSG() {
-        assertEquals("4326", DefinitionURI.codeOf("crs", "EPSG", "4326"));
+        assertNull  (        DefinitionURI.codeOf("crs", "EPSG", "4326"));
         assertEquals("4326", DefinitionURI.codeOf("crs", "EPSG", "EPSG:4326"));
         assertEquals("4326", DefinitionURI.codeOf("crs", "EPSG", 
"EPSG::4326"));
         assertNull  (        DefinitionURI.codeOf("crs", "EPSG", 
"EPSG:::4326"));
@@ -203,8 +204,8 @@ public final strictfp class DefinitionURITest extends 
TestCase {
     }
 
     /**
-     * Tests {@link DefinitionURI#codeOf(String, String, String)} with URN like
-     * {@code "urn:ogc:def:crs:EPSG::4326"}.
+     * Tests {@link DefinitionURI#codeOf(String, String, String)}
+     * with URN like {@code "urn:ogc:def:crs:EPSG::4326"}.
      */
     @Test
     public void testCodeOfURN() {
@@ -214,16 +215,26 @@ public final strictfp class DefinitionURITest extends 
TestCase {
         assertEquals("4326",  DefinitionURI.codeOf("crs", "EPSG", 
"urn:x-ogc:def:crs:EPSG::4326"));
         assertNull  (         DefinitionURI.codeOf("crs", "EPSG", 
"urn:n-ogc:def:crs:EPSG::4326"));
         assertEquals("4326",  DefinitionURI.codeOf("crs", "EPSG", " urn : ogc 
: def : crs : epsg : : 4326"));
-        assertNull  (         DefinitionURI.codeOf("crs", "EPSG", 
"urn:ogc:def:uom:EPSG:9102"));
-        assertEquals("9102",  DefinitionURI.codeOf("uom", "EPSG", 
"urn:ogc:def:uom:EPSG:9102"));
+        assertNull  (         DefinitionURI.codeOf("crs", "EPSG", 
"urn:ogc:def:uom:EPSG::9102"));
+        assertEquals("9102",  DefinitionURI.codeOf("uom", "EPSG", 
"urn:ogc:def:uom:EPSG::9102"));
         assertNull  (         DefinitionURI.codeOf("crs", "EPSG", 
"urn:ogc:def:crs:OGC:1.3:CRS84"));
         assertEquals("CRS84", DefinitionURI.codeOf("crs", "OGC",  
"urn:ogc:def:crs:OGC:1.3:CRS84"));
         assertNull  (         DefinitionURI.codeOf("crs", "OGC",  
"urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45"));
     }
 
     /**
-     * Tests {@link DefinitionURI#codeOf(String, String, String)} with URL like
-     * {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}.
+     * Tests {@link DefinitionURI#codeOf(String, String, String)}
+     * with URL like {@code "http://www.opengis.net/def/crs/EPSG/0/4326"}.
+     */
+    @Test
+    public void testCodeOfDefinitionServer() {
+        assertEquals("4326", DefinitionURI.codeOf("crs", "EPSG", 
"http://www.opengis.net/def/crs/EPSG/0/4326";));
+        assertEquals("9102", DefinitionURI.codeOf("uom", "EPSG", 
"http://www.opengis.net/def/uom/EPSG/0/9102";));
+    }
+
+    /**
+     * Tests {@link DefinitionURI#codeOf(String, String, String)}
+     * with URL like {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}.
      */
     @Test
     public void testCodeOfGML() {
diff --git 
a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java 
b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java
index e5a88a38f8..a7374d5857 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java
@@ -428,6 +428,7 @@ public final strictfp class UnitFormatTest extends TestCase 
{
     @Test
     public void testParseEPSG() {
         final UnitFormat f = new UnitFormat(Locale.UK);
+        assertSame(Units.METRE,             f.parse("EPSG:9001"));
         assertSame(Units.METRE,             
f.parse("urn:ogc:def:uom:EPSG::9001"));
         assertSame(Units.METRES_PER_SECOND, 
f.parse("urn:ogc:def:uom:EPSG::1026"));
         assertSame(Units.METRE, 
f.parse("http://www.isotc211.org/2005/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])"));

Reply via email to