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'])"));