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 6b2e63471f Upgrade JSR-363 dependency to JSR-385. This is the dependency that defines unit of measurements in the `javax.measure` package. 6b2e63471f is described below commit 6b2e63471fc87b98cfa312090f6c6c833a943dfe Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Mon Dec 26 17:32:07 2022 +0100 Upgrade JSR-363 dependency to JSR-385. This is the dependency that defines unit of measurements in the `javax.measure` package. https://github.com/opengeospatial/geoapi/issues/66 --- NOTICE | 4 +- README | 2 +- .../java/org/apache/sis/xml/ValueConverter.java | 4 +- .../java/org/apache/sis/io/wkt/AbstractParser.java | 4 +- .../apache/sis/io/wkt/GeodeticObjectParser.java | 4 +- .../org/apache/sis/io/wkt/MathTransformParser.java | 4 +- .../referencing/factory/sql/EPSGDataAccess.java | 4 +- .../sis/internal/converter/StringConverter.java | 4 +- .../java/org/apache/sis/io/CompoundFormat.java | 2 +- .../org/apache/sis/measure/AbstractConverter.java | 8 +- .../java/org/apache/sis/measure/AbstractUnit.java | 86 +++++++++++++++- .../org/apache/sis/measure/ConventionalUnit.java | 10 +- .../apache/sis/measure/DefaultQuantityFactory.java | 75 ++++++++++++++ .../org/apache/sis/measure/LinearConverter.java | 8 +- .../java/org/apache/sis/measure/Quantities.java | 4 +- .../org/apache/sis/measure/QuantityFormat.java | 110 ++++++++++++++++++++- .../main/java/org/apache/sis/measure/Scalar.java | 53 +++++++++- .../java/org/apache/sis/measure/SystemUnit.java | 18 +++- .../java/org/apache/sis/measure/UnitFormat.java | 44 +++++---- .../java/org/apache/sis/measure/UnitRegistry.java | 25 ++++- .../java/org/apache/sis/measure/UnitServices.java | 83 +++++++++++----- .../main/java/org/apache/sis/measure/Units.java | 8 +- .../java/org/apache/sis/measure/package-info.java | 2 +- .../org/apache/sis/measure/QuantitiesTest.java | 5 +- .../org/apache/sis/measure/SystemUnitTest.java | 4 +- .../org/apache/sis/measure/UnitDimensionTest.java | 4 +- .../org/apache/sis/measure/UnitFormatTest.java | 12 +-- .../org/apache/sis/measure/UnitServicesTest.java | 13 +-- ide-project/NetBeans/nbproject/project.properties | 4 +- .../apache/sis/internal/earth/netcdf/GCOM_C.java | 6 +- .../apache/sis/internal/earth/netcdf/GCOM_W.java | 6 +- .../org/apache/sis/internal/netcdf/Convention.java | 6 +- .../org/apache/sis/internal/netcdf/Variable.java | 4 +- .../sis/internal/netcdf/impl/ChannelDecoder.java | 4 +- .../sis/internal/netcdf/impl/VariableInfo.java | 6 +- .../apache/sis/storage/netcdf/MetadataReader.java | 6 +- 36 files changed, 518 insertions(+), 128 deletions(-) diff --git a/NOTICE b/NOTICE index 888bab1447..80a7402733 100644 --- a/NOTICE +++ b/NOTICE @@ -10,8 +10,8 @@ specifications (https://www.ogc.org/standards/), also known as OpenGIS. Apache SIS depends on GeoAPI published by OGC under BSD-style license. https://www.ogc.org/ogc/software/1.0 -Apache SIS depends on JSR-363 (API only) published under BSD license. -https://jcp.org/en/jsr/detail?id=363 +Apache SIS depends on JSR-385 (API only) published under BSD license. +https://jcp.org/en/jsr/detail?id=385 Apache SIS depends on JAXB (API only) published under Eclipse Distribution License license. http://www.eclipse.org/org/documents/edl-v10.php diff --git a/README b/README index d617b55a6d..6d6ccb228f 100644 --- a/README +++ b/README @@ -57,7 +57,7 @@ See the License for the specific language governing permissions and limitations under the License. Some Apache SIS subcomponents have dependencies subject to different -license terms. All those dependencies except GeoAPI, JSR-363 and JAXB API +license terms. All those dependencies except GeoAPI, JSR-385 and JAXB API are optional. Your use of those dependencies is subject to the terms and conditions of the licenses listed in the NOTICE file. diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/ValueConverter.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/ValueConverter.java index 72404ba57e..895f00fb99 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/ValueConverter.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/ValueConverter.java @@ -27,7 +27,7 @@ import java.util.UUID; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.internal.util.Strings; import org.apache.sis.measure.Units; import org.apache.sis.util.Locales; @@ -356,7 +356,7 @@ public class ValueConverter { } } return Units.valueOf(value); - } catch (ParserException e) { + } catch (MeasurementParseException e) { if (!exceptionOccured(context, value, String.class, Unit.class, e)) { throw e; } diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java index 9ac37aa939..bbcf6b9344 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java @@ -30,7 +30,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.LogRecord; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.util.FactoryException; import org.opengis.util.InternationalString; import org.apache.sis.internal.system.Loggers; @@ -388,7 +388,7 @@ abstract class AbstractParser implements Parser { * Parses the given unit name or symbol. Contrarily to other {@code parseFoo()} methods, * this method has no {@link ParsePosition} and expects the given string to be the full unit symbol. */ - final Unit<?> parseUnit(final String text) throws ParserException { + final Unit<?> parseUnit(final String text) throws MeasurementParseException { if (unitFormat == null) { final Locale locale = symbols.getLocale(); if (locale == Locale.ROOT) { diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java index 8185465657..f3aa4afcf8 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java @@ -37,7 +37,7 @@ import javax.measure.quantity.Angle; import javax.measure.quantity.Length; import javax.measure.Quantity; import javax.measure.quantity.Time; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import javax.measure.IncommensurableException; import org.opengis.metadata.Identifier; @@ -638,7 +638,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo if (verify == null) { try { verify = parseUnit(name); - } catch (ParserException e) { + } catch (MeasurementParseException e) { log(new LogRecord(Level.FINE, e.toString())); } if (verify != null) try { diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java index 6a1c697638..be1eed1c03 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java @@ -24,7 +24,7 @@ import java.text.NumberFormat; import java.text.ParseException; import javax.measure.Unit; import javax.measure.quantity.Angle; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.util.FactoryException; import org.opengis.util.NoSuchIdentifierException; import org.opengis.parameter.ParameterValue; @@ -285,7 +285,7 @@ class MathTransformParser extends AbstractParser { // If we cannot infer the base type, we have to rely on the name. try { return parseUnit(name); - } catch (ParserException e) { + } catch (MeasurementParseException e) { throw new UnparsableObjectException(errorLocale, Errors.Keys.UnknownUnit_1, new Object[] {name}, element.offset).initCause(e); } diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java index 0730a71e19..f9a24349b0 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java @@ -45,7 +45,7 @@ import java.net.URISyntaxException; import javax.measure.Unit; import javax.measure.quantity.Angle; import javax.measure.quantity.Length; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.util.NameSpace; import org.opengis.util.GenericName; @@ -2489,7 +2489,7 @@ codes: for (int i=0; i<codes.length; i++) { unit = Units.multiply(base, b, c); } else try { unit = Units.valueOf(getString(code, result, 5)); // Try parsing the unit symbol as a fallback. - } catch (ParserException e) { + } catch (MeasurementParseException e) { throw new FactoryDataException(error().getString(Errors.Keys.UnknownUnit_1, code), e); } } diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java b/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java index 0f8b663c54..7c694b6416 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java +++ b/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java @@ -23,7 +23,7 @@ import java.nio.charset.UnsupportedCharsetException; import java.net.URISyntaxException; import java.net.MalformedURLException; import java.nio.file.InvalidPathException; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.math.FunctionProperty; import org.apache.sis.util.Locales; import org.apache.sis.util.Numbers; @@ -307,7 +307,7 @@ abstract class StringConverter<T> extends SystemConverter<String, T> { @SuppressWarnings("unchecked") public Unit() {super((Class) javax.measure.Unit.class);} // Instantiated by ServiceLoader. - @Override javax.measure.Unit<?> doConvert(String source) throws ParserException { + @Override javax.measure.Unit<?> doConvert(String source) throws MeasurementParseException { return Units.valueOf(source); } } diff --git a/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java b/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java index bf249b7ec6..4774db51ac 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java +++ b/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java @@ -407,7 +407,7 @@ public abstract class CompoundFormat<T> extends Format implements Localized { * We tried the given class directly. If it didn't worked, try the interfaces before * to try the parent class. The reason is that we may have for example: * - * interface Length extends Quantity; // From JSR-363. + * interface Length extends Quantity; // From JSR-385. * * class MyLength extends Number implements Length; * diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java index bffbb99d93..3b60184506 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java @@ -54,7 +54,7 @@ abstract class AbstractConverter implements UnitConverter, Serializable { } /** - * Indicates if this converter is linear in JSR-363 sense (not the usual mathematical sense). + * Indicates if this converter is linear in JSR-385 sense (not the usual mathematical sense). * The default implementation returns {@code false} for convenience of non-linear conversions. * Subclasses should override if their conversions may be identity. */ @@ -109,8 +109,10 @@ abstract class AbstractConverter implements UnitConverter, Serializable { */ static double scale(final UnitConverter converter) { if (converter != null && converter.isLinear() && converter.convert(0) == 0) { - // Above check for converter(0) is a paranoiac check since - // JSR-363 said that a "linear" converter has no offset. + /* + * Above check for `converter(0)` is a paranoiac check because + * JSR-385 said that a "linear" converter has no offset. + */ return converter.convert(1); } return Double.NaN; diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java index 357d56d8ed..b623ade23b 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java @@ -23,10 +23,11 @@ import java.util.MissingResourceException; import java.io.ObjectStreamException; import java.io.Serializable; import javax.measure.Unit; +import javax.measure.Prefix; import javax.measure.Quantity; import org.apache.sis.math.Fraction; +import org.apache.sis.math.MathFunctions; import org.apache.sis.util.Characters; -import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.LenientComparable; import org.apache.sis.util.resources.Errors; @@ -57,7 +58,7 @@ import static java.util.logging.Logger.getLogger; * All unit instances shall be immutable and thread-safe. * * @author Martin Desruisseaux (MPO, Geomatys) - * @version 1.0 + * @version 1.4 * * @param <Q> the kind of quantity to be measured using this units. * @@ -348,10 +349,20 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo */ @Override public final boolean isCompatible(final Unit<?> that) { - ArgumentChecks.ensureNonNull("that", that); return getDimension().equals(that.getDimension()); } + /** + * Indicates if this unit is equal to the given unit, ignoring unit symbol. + * + * @param that the other unit to compare for equivalence. + * @return {@code true} if the given unit is equivalent to this unit. + */ + @Override + public final boolean isEquivalentTo(final Unit<Q> that) { + return getConverterTo(that).isIdentity(); + } + /** * Returns the error message for an incompatible unit. */ @@ -359,6 +370,75 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo return Errors.format(Errors.Keys.IncompatibleUnits_2, this, that); } + /** + * Returns a new unit equals to this unit prefixed by the specified {@code prefix}. + * + * @param prefix the prefix to apply on this unit. + * @return the unit with the given prefix applied. + */ + @Override + public final Unit<Q> prefix(final Prefix prefix) { + final Number base = prefix.getValue(); + final int exponent = prefix.getExponent(); + if (exponent == 1) { + return multiply(base); + } + double value = AbstractConverter.doubleValue(base); + if (value == 10) { + value = MathFunctions.pow10(exponent); // Avoid rounding errors for some values. + } else { + value = Math.pow(value, exponent); + } + return multiply(value); + } + + /** + * Returns the result of setting the origin of the scale of measurement to the given value. + * + * @param offset the value to add when converting from the new unit to this unit. + * @return this unit offset by the specified value, or {@code this} if the given offset is zero. + */ + @Override + public final Unit<Q> shift(final Number offset) { + if (offset instanceof Fraction) { + final Fraction f = (Fraction) offset; + return transform(LinearConverter.offset(f.numerator, f.denominator)); + } + return shift(AbstractConverter.doubleValue(offset)); + } + + /** + * Returns the result of multiplying this unit by the specified factor. + * For example {@code KILOMETRE = METRE.multiply(1000)} returns a unit where 1 km is equal to 1000 m. + * + * @param multiplier the scale factor when converting from the new unit to this unit. + * @return this unit scaled by the specified multiplier. + */ + @Override + public final Unit<Q> multiply(final Number multiplier) { + if (multiplier instanceof Fraction) { + final Fraction f = (Fraction) multiplier; + return transform(LinearConverter.scale(f.numerator, f.denominator)); + } + return multiply(AbstractConverter.doubleValue(multiplier)); + } + + /** + * Returns the result of dividing this unit by an approximate divisor. + * For example {@code GRAM = KILOGRAM.divide(1000)} returns a unit where 1 g is equal to 0.001 kg. + * + * @param divisor the inverse of the scale factor when converting from the new unit to this unit. + * @return this unit divided by the specified divisor. + */ + @Override + public final Unit<Q> divide(final Number divisor) { + if (divisor instanceof Fraction) { + final Fraction f = (Fraction) divisor; + return transform(LinearConverter.scale(f.denominator, f.numerator)); + } + return divide(AbstractConverter.doubleValue(divisor)); + } + /** * Returns the result of setting the origin of the scale of measurement to the given value. * For example, {@code CELSIUS = KELVIN.shift(273.15)} returns a unit where 0°C is equal to 273.15 K. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/ConventionalUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/ConventionalUnit.java index 19f645f80d..0b2afa4fec 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/ConventionalUnit.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/ConventionalUnit.java @@ -21,6 +21,7 @@ import javax.measure.Unit; import javax.measure.Quantity; import javax.measure.Dimension; import javax.measure.UnitConverter; +import javax.measure.MeasurementException; import javax.measure.UnconvertibleException; import javax.measure.IncommensurableException; import org.apache.sis.util.resources.Errors; @@ -35,7 +36,7 @@ import org.apache.sis.math.Fraction; * A unit of measure which is related to a base or derived unit through a conversion formula. * * @author Martin Desruisseaux (Geomatys) - * @version 1.0 + * @version 1.4 * * @param <Q> the kind of quantity to be measured using this units. * @@ -59,6 +60,7 @@ final class ConventionalUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> { /** * The conversion from this unit to the {@linkplain #target} unit. */ + @SuppressWarnings("serial") // Not statically typed as Serializable. final UnitConverter toTarget; /** @@ -371,17 +373,17 @@ final class ConventionalUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> { } /** - * Unsupported operation for conventional units, as required by JSR-363 specification. + * Unsupported operation for conventional units, as required by JSR-385 specification. * * @param symbol the new symbol for the alternate unit. * @return the alternate unit. - * @throws UnsupportedOperationException always thrown since this unit is not an unscaled standard unit. + * @throws MeasurementException always thrown because this unit is not an unscaled standard unit. * * @see SystemUnit#alternate(String) */ @Override public Unit<Q> alternate(final String symbol) { - throw new UnsupportedOperationException(Errors.format(Errors.Keys.NonSystemUnit_1, this)); + throw new MeasurementException(Errors.format(Errors.Keys.NonSystemUnit_1, this)); } /** diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/DefaultQuantityFactory.java b/core/sis-utility/src/main/java/org/apache/sis/measure/DefaultQuantityFactory.java new file mode 100644 index 0000000000..915e151a72 --- /dev/null +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/DefaultQuantityFactory.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.measure; + +import java.util.Objects; +import javax.measure.Unit; +import javax.measure.Quantity; +import javax.measure.spi.QuantityFactory; + + +/** + * Default factory when {@link SystemUnit} can not be used directly. + * + * @author Martin Desruisseaux (MPO, Geomatys) + * @version 1.4 + * @since 1.4 + */ +class DefaultQuantityFactory<Q extends Quantity<Q>> implements QuantityFactory<Q> { + /** + * Creates a new factory. + */ + DefaultQuantityFactory() { + } + + /** + * Unconditionally returns {@code null} because this factory + * should be used only when the type is not for a system unit. + */ + @Override + public final Unit<Q> getSystemUnit() { + return null; + } + + /** + * Creates a quantity for the given number stated in the specified unit. + * + * @param value the numeric value stated in the specified unit. + * @param unit the unit of the value. + * @return the requested quantity. + */ + @Override + public Quantity<Q> create(final Number value, final Unit<Q> unit) { + return new Scalar<>(AbstractConverter.doubleValue(value), unit); + } + + /** + * Creates a quantity for the given number stated in the specified unit and scale. + * + * @param value the numeric value stated in the specified unit. + * @param unit the unit of the value. + * @param scale the {@code ABSOLUTE} / {@code RELATIVE} scale of the quantity to create. + * @return the requested quantity. + */ + @Override + public final Quantity<Q> create(final Number value, final Unit<Q> unit, final Quantity.Scale scale) { + if (Objects.requireNonNull(scale) != Scalar.SCALE) { + throw new UnsupportedOperationException("Relative scale is not yet supported."); + } + return create(value, unit); + } +} diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java index a631cf9b0d..568291a246 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java @@ -31,7 +31,7 @@ import org.apache.sis.internal.util.Numerics; /** * Conversions between units that can be represented by a linear operation (scale or offset). * Note that the "linear" word in this class does not have the same meaning than the same word - * in the {@link #isLinear()} method inherited from JSR-363. + * in the {@link #isLinear()} method inherited from JSR-385. * * <p><b>Implementation note:</b> * for performance reason we should create specialized subtypes for the case where there is only a scale to apply, @@ -187,7 +187,7 @@ final class LinearConverter extends AbstractConverter implements LenientComparab /** * Indicates if this converter is linear. - * JSR-363 defines a converter as linear if: + * JSR-385 defines a converter as linear if: * * <ul> * <li>{@code convert(u + v) == convert(u) + convert(v)}</li> @@ -354,8 +354,8 @@ final class LinearConverter extends AbstractConverter implements LenientComparab otherDivisor = lc.divisor; } else if (converter.isLinear()) { /* - * Fallback for foreigner implementations. Note that 'otherOffset' should be restricted to zero - * according JSR-363 definition of 'isLinear()', but let be safe; maybe we are not the only one + * Fallback for foreigner implementations. Note that `otherOffset` should be restricted to zero + * according JSR-385 definition of `isLinear()`, but let be safe; maybe we are not the only one * to have a different interpretation about the meaning of "linear". */ otherOffset = converter.convert(0.0); diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java index 49a9d3b93e..90fe3d7cd5 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java @@ -24,7 +24,7 @@ import javax.measure.UnitConverter; import javax.measure.quantity.Time; import javax.measure.quantity.Angle; import javax.measure.quantity.Length; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.util.Static; import org.apache.sis.util.Numbers; import org.apache.sis.util.ArgumentChecks; @@ -61,7 +61,7 @@ public final class Quantities extends Static { * @param value the quantity magnitude. * @param unit symbol of the unit of measurement associated to the given value. * @return a quantity of the given type for the given value and unit of measurement. - * @throws ParserException if the given symbol cannot be parsed. + * @throws MeasurementParseException if the given symbol cannot be parsed. */ public static Quantity<?> create(final double value, final String unit) { return create(value, Units.valueOf(unit)); diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java index 847156378e..875fa10e6f 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java @@ -21,11 +21,13 @@ import java.text.Format; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; +import java.io.IOException; import javax.measure.Quantity; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.internal.system.Loggers; import org.apache.sis.util.logging.Logging; +import org.apache.sis.util.resources.Errors; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.internal.util.FinalFieldSetter; @@ -36,7 +38,7 @@ import static java.util.logging.Logger.getLogger; * Parses and formats numbers with units of measurement. * * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.4 * * @see NumberFormat * @see UnitFormat @@ -44,7 +46,7 @@ import static java.util.logging.Logger.getLogger; * @since 1.1 * @module */ -public class QuantityFormat extends Format { +public class QuantityFormat extends Format implements javax.measure.format.QuantityFormat { /** * For cross-version compatibility. */ @@ -90,6 +92,50 @@ public class QuantityFormat extends Format { this.unitFormat = unitFormat; } + /** + * Returns whether this format depends on a {@code Locale} to perform its tasks. + * This is {@code true} in this {@code QuantityFormat} implementation. + * + * @return whether this format depends on the locale, which is true in this implementation. + * @since 1.4 + */ + @Override + public boolean isLocaleSensitive() { + return true; + } + + /** + * Formats the specified quantity. + * The default implementation delegates to {@link #format(Object, StringBuffer, FieldPosition)}. + * + * @param quantity the quantity to format. + * @return the string representation of the given quantity. + * @since 1.4 + */ + @Override + public String format(final Quantity<?> quantity) { + return format(quantity, new StringBuffer(), null).toString(); + } + + /** + * Formats the specified quantity in the given destination. + * The default implementation delegates to {@link #format(Object, StringBuffer, FieldPosition)}. + * + * @param quantity the quantity to format. + * @param toAppendTo where to format the quantity. + * @return the given {@code toAppendTo} argument, for method calls chaining. + * @throws IOException if an I/O exception occurred. + * @since 1.4 + */ + @Override + public Appendable format(final Quantity<?> quantity, final Appendable toAppendTo) throws IOException { + if (toAppendTo instanceof StringBuffer) { + return format(quantity, (StringBuffer) toAppendTo, null); + } else { + return toAppendTo.append(format(quantity, new StringBuffer(), null)); + } + } + /** * Formats the specified quantity in the given buffer. * The given object shall be a {@link Quantity} instance. @@ -108,6 +154,62 @@ public class QuantityFormat extends Format { return toAppendTo; } + /** + * Parses the specified text to produce a {@link Quantity}. + * + * @param source the text to parse. + * @return the quantity parsed from the specified text. + * @throws MeasurementParseException if the given text can not be parsed. + * @since 1.4 + */ + @Override + public Quantity<?> parse(final CharSequence source) throws MeasurementParseException { + return parse(source, new ParsePosition(0)); + } + + /** + * Parses a portion of the specified {@code CharSequence} from the specified position to produce a {@link Quantity}. + * If parsing succeeds, then the index of the {@code pos} argument is updated to the index after the last character used. + * + * @param source the text, part of which should be parsed. + * @param pos index and error index information. + * @return the quantity parsed from the specified character sub-sequence. + * @throws MeasurementParseException if the given text can not be parsed. + * @since 1.4 + */ + @Override + public Quantity<?> parse(final CharSequence source, final ParsePosition pos) throws MeasurementParseException { + final int start = pos.getIndex(); + final int shift; + final String text; + if (start == 0 || source instanceof String) { + shift = 0; + text = source.toString(); + } else { + shift = start; + text = source.subSequence(start, source.length()).toString(); + pos.setIndex(0); + } + try { + final Number value = numberFormat.parse(text, pos); + if (value != null) { + final Unit<?> unit = unitFormat.parse(text, pos); + if (unit != null) { + return Quantities.create(value.doubleValue(), unit); + } + } + } finally { + if (shift != 0) { + pos.setIndex(pos.getIndex() + shift); + final int i = pos.getErrorIndex(); + if (i >= 0) { + pos.setErrorIndex(i + shift); + } + } + } + throw new MeasurementParseException(Errors.format(Errors.Keys.CanNotParse_1, source), source, pos.getErrorIndex()); + } + /** * Parses text from a string to produce a quantity, or returns {@code null} if the parsing failed. * @@ -125,7 +227,7 @@ public class QuantityFormat extends Format { if (unit != null) { return Quantities.create(value.doubleValue(), unit); } - } catch (ParserException e) { + } catch (MeasurementParseException e) { Logging.ignorableException(getLogger(Loggers.MEASURE), QuantityFormat.class, "parseObject", e); } pos.setIndex(start); // By `Format.parseObject(…)` method contract. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java index d379279c60..8824027bb6 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java @@ -20,9 +20,14 @@ import java.lang.reflect.Proxy; import javax.measure.Unit; import javax.measure.Quantity; import javax.measure.UnitConverter; +import javax.measure.UnconvertibleException; +import org.apache.sis.internal.system.Loggers; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.StringBuilders; import org.apache.sis.internal.util.Numerics; +import org.apache.sis.util.logging.Logging; + +import static java.util.logging.Logger.getLogger; /** @@ -33,7 +38,7 @@ import org.apache.sis.internal.util.Numerics; * * @author Martin Desruisseaux (Geomatys) * @author Alexis Manin (Geomatys) - * @version 1.2 + * @version 1.4 * * @param <Q> the type of quantity implemented by this scalar. * @@ -46,6 +51,11 @@ class Scalar<Q extends Quantity<Q>> extends Number implements Quantity<Q>, Compa */ private static final long serialVersionUID = -381805117700594712L; + /** + * The scale of this quantity. Currently only absolute scale is supported. + */ + static final Scale SCALE = Scale.ABSOLUTE; + /** * The numerical value of this quantity. */ @@ -113,6 +123,16 @@ class Scalar<Q extends Quantity<Q>> extends Number implements Quantity<Q>, Compa return this; } + /** + * Returns the scale of this quantity, which can be absolute or relative. + * + * @return whether this quantity uses absolute or relative scale. + */ + @Override + public final Scale getScale() { + return SCALE; + } + /** * Returns the unit of measurement specified at construction time. * The method shall not return {@code null}. @@ -292,6 +312,14 @@ class Scalar<Q extends Quantity<Q>> extends Number implements Quantity<Q>, Compa return of(1 / value, unit.inverse()); } + /** + * Returns a quantity whose value is {@code −getValue()}. + */ + @Override + public final Quantity<Q> negate() { + return of(-value); + } + /** * Ensures that this quantity is of the given type. */ @@ -300,6 +328,29 @@ class Scalar<Q extends Quantity<Q>> extends Number implements Quantity<Q>, Compa return type.cast(this); } + /** + * Compares this quantity with the given quantity, doing the conversion of unit if necessary. + * + * @param that the quantity to be compared with this instance. + * @return {@code true} if the two quantities are equivalent. + */ + @Override + public final boolean isEquivalentTo(final Quantity<Q> that) { + final Unit<Q> otherUnit = that.getUnit(); + try { + final Number r = otherUnit.getConverterTo(unit).convert(that.getValue()); + if (r instanceof Float) { + return Math.abs(value - r.doubleValue()) < Math.ulp(r.floatValue()); + } else { + return value == r.doubleValue(); + } + } catch (UnconvertibleException e) { + Logging.ignorableException(getLogger(Loggers.MEASURE), Scalar.class, "isEquivalentTo", e); + // Non-convertible quantities are not equivalent. + } + return false; + } + /** * Returns {@code true} if the given object is another {@code Scalar} with the same value and same unit * of measurement. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java index 7538f52752..7d0dd9d534 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java @@ -43,7 +43,7 @@ import org.apache.sis.math.Fraction; * without scale factor or offset. * * @author Martin Desruisseaux (MPO, Geomatys) - * @version 1.1 + * @version 1.4 * * @param <Q> the kind of quantity to be measured using this units. * @@ -634,4 +634,20 @@ final class SystemUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> implements return new Scalar<>(v, unit); } } + + /** + * Creates a quantity for the given number stated in the specified unit and scale. + * + * @param value the numeric value stated in the specified unit. + * @param unit the unit of the value. + * @param scale the {@code ABSOLUTE} / {@code RELATIVE} scale of the quantity to create. + * @return the requested quantity. + */ + @Override + public Quantity<Q> create(final Number value, final Unit<Q> unit, final Quantity.Scale scale) { + if (Objects.requireNonNull(scale) != Scalar.SCALE) { + throw new UnsupportedOperationException("Relative scale is not yet supported."); + } + return create(value, unit); + } } 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 8c7a70f071..c412f7b2e5 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 @@ -32,7 +32,7 @@ import java.io.IOException; import java.io.UncheckedIOException; import javax.measure.Dimension; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.internal.system.Loggers; import org.apache.sis.internal.util.Constants; import org.apache.sis.internal.util.DefinitionURI; @@ -1062,19 +1062,19 @@ appPow: if (unit == null) { * * @param symbols the unit symbols or URI to parse. * @return the unit parsed from the specified symbols. - * @throws ParserException if a problem occurred while parsing the given symbols. + * @throws MeasurementParseException if a problem occurred while parsing the given symbols. * * @see Units#valueOf(String) */ @Override - public Unit<?> parse(final CharSequence symbols) throws ParserException { + public Unit<?> parse(final CharSequence symbols) throws MeasurementParseException { final Position position = new Position(); Unit<?> unit = parse(symbols, position); final int length = symbols.length(); int unrecognized; while ((unrecognized = CharSequences.skipLeadingWhitespaces(symbols, position.getIndex(), length)) < length) { if (position.finished || !Character.isLetter(Character.codePointAt(symbols, unrecognized))) { - throw new ParserException(Errors.format(Errors.Keys.UnexpectedCharactersAfter_2, + throw new MeasurementParseException(Errors.format(Errors.Keys.UnexpectedCharactersAfter_2, CharSequences.trimWhitespaces(symbols, 0, unrecognized), CharSequences.trimWhitespaces(symbols, unrecognized, length)), symbols, unrecognized); @@ -1096,16 +1096,16 @@ appPow: if (unit == null) { * Exponent after symbol can be decimal digits as in “m2” or a superscript as in “m²”.</p> * * <p>Note that contrarily to {@link #parseObject(String, ParsePosition)}, this method never return {@code null}. - * If an error occurs at parsing time, an unchecked {@link ParserException} is thrown.</p> + * If an error occurs at parsing time, an unchecked {@link MeasurementParseException} is thrown.</p> * * @param symbols the unit symbols to parse. * @param position on input, index of the first character to parse. * On output, index after the last parsed character. * @return the unit parsed from the specified symbols. - * @throws ParserException if a problem occurred while parsing the given symbols. + * @throws MeasurementParseException if a problem occurred while parsing the given symbols. */ @SuppressWarnings({"null", "fallthrough"}) - public Unit<?> parse(CharSequence symbols, final ParsePosition position) throws ParserException { + public Unit<?> parse(CharSequence symbols, final ParsePosition position) throws MeasurementParseException { ArgumentChecks.ensureNonNull("symbols", symbols); ArgumentChecks.ensureNonNull("position", position); /* @@ -1129,7 +1129,8 @@ appPow: if (unit == null) { } catch (NumberFormatException e) { failure = e; } - throw (ParserException) new ParserException(Errors.format(Errors.Keys.UnknownUnit_1, + throw (MeasurementParseException) new MeasurementParseException( + Errors.format(Errors.Keys.UnknownUnit_1, Constants.EPSG + Constants.DEFAULT_SEPARATOR + code), symbols, start + Math.max(0, symbols.toString().lastIndexOf(code))).initCause(failure); } @@ -1228,8 +1229,8 @@ scan: for (int n; i < end; i += n) { final Unit<?> term = parse(symbols, sub); i = CharSequences.skipLeadingWhitespaces(symbols, sub.getIndex(), end); if (i >= end || Character.codePointAt(symbols, i) != Style.CLOSE) { - throw new ParserException(Errors.format(Errors.Keys.NonEquilibratedParenthesis_2, - symbols.subSequence(start, i), Style.CLOSE), symbols, start); + throw new MeasurementParseException(Errors.format(Errors.Keys.NonEquilibratedParenthesis_2, + symbols.subSequence(start, i), Style.CLOSE), symbols, start); } unit = operation.apply(unit, term, pos); operation.code = Operation.IMPLICIT; // Default operation if there is no × or / symbol after parenthesis. @@ -1374,7 +1375,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) } } } - throw new ParserException(Errors.format(Errors.Keys.NotAnInteger_1, term), symbols, position); + throw new MeasurementParseException(Errors.format(Errors.Keys.NotAnInteger_1, term), symbols, position); } default: throw new AssertionError(code); } @@ -1407,11 +1408,11 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) * @param upper index after the last character to parse in the {@code symbols} string. * @param operation the operation to be applied (e.g. the term to be parsed is a multiplier or divisor of another unit). * @return the parsed unit symbol (never {@code null}). - * @throws ParserException if a problem occurred while parsing the given symbols. + * @throws MeasurementParseException if a problem occurred while parsing the given symbols. */ @SuppressWarnings("fallthrough") private Unit<?> parseTerm(final CharSequence symbols, final int lower, final int upper, final Operation operation) - throws ParserException + throws MeasurementParseException { final String uom = CharSequences.trimWhitespaces(symbols, lower, upper).toString(); /* @@ -1453,7 +1454,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) } multiplier = parseMultiplicationFactor(uom); } catch (NumberFormatException e) { - throw (ParserException) new ParserException(Errors.format( + throw (MeasurementParseException) new MeasurementParseException(Errors.format( Errors.Keys.UnknownUnit_1, uom), symbols, lower).initCause(e); } if (operation.code == Operation.IMPLICIT) { @@ -1489,7 +1490,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) power = new Fraction(uom.substring(i)); } catch (NumberFormatException e) { // Should never happen unless the number is larger than `int` capacity. - throw (ParserException) new ParserException(Errors.format( + throw (MeasurementParseException) new MeasurementParseException(Errors.format( Errors.Keys.UnknownUnit_1, uom), symbols, lower+i).initCause(e); } break; @@ -1543,7 +1544,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) if (CharSequences.regionMatches(symbols, lower, UNITY, true)) { return Units.UNITY; } - throw new ParserException(Errors.format(Errors.Keys.UnknownUnit_1, uom), symbols, lower); + throw new MeasurementParseException(Errors.format(Errors.Keys.UnknownUnit_1, uom), symbols, lower); } } } @@ -1580,8 +1581,9 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) } /** - * Parses text from a string to produce a unit. The default implementation delegates to {@link #parse(CharSequence)} - * and wraps the {@link ParserException} into a {@link ParseException} for compatibility with {@code java.text} API. + * Parses text from a string to produce a unit. The default implementation delegates + * to {@link #parse(CharSequence)} and wraps the {@link MeasurementParseException} + * into a {@link ParseException} for compatibility with {@code java.text} API. * * @param source the text, part of which should be parsed. * @return a unit parsed from the string. @@ -1591,7 +1593,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) public Object parseObject(final String source) throws ParseException { try { return parse(source); - } catch (ParserException e) { + } catch (MeasurementParseException e) { throw (ParseException) new ParseException(e.getLocalizedMessage(), e.getPosition()).initCause(e); } } @@ -1599,7 +1601,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) /** * Parses text from a string to produce a unit, or returns {@code null} if the parsing failed. * The default implementation delegates to {@link #parse(CharSequence, ParsePosition)} and catches - * the {@link ParserException}. + * the {@link MeasurementParseException}. * * @param source the text, part of which should be parsed. * @param pos index and error index information as described above. @@ -1609,7 +1611,7 @@ search: while ((i = CharSequences.skipTrailingWhitespaces(symbols, start, i) public Object parseObject(final String source, final ParsePosition pos) { try { return parse(source, pos); - } catch (ParserException e) { + } catch (MeasurementParseException e) { pos.setErrorIndex(e.getPosition()); return null; } diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java index d80df4a229..62d2a342bb 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitRegistry.java @@ -26,9 +26,14 @@ import javax.measure.Unit; import javax.measure.Quantity; import javax.measure.Dimension; import javax.measure.spi.SystemOfUnits; +import javax.measure.format.MeasurementParseException; import org.apache.sis.math.Fraction; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.collection.WeakValueHashMap; +import org.apache.sis.util.logging.Logging; +import org.apache.sis.internal.system.Loggers; + +import static java.util.logging.Logger.getLogger; /** @@ -37,7 +42,7 @@ import org.apache.sis.util.collection.WeakValueHashMap; * rather uses the static methods directly since we define all units in terms of SI. * * @author Martin Desruisseaux (Geomatys) - * @version 1.2 + * @version 1.4 * @since 0.8 * @module */ @@ -245,6 +250,24 @@ final class UnitRegistry implements SystemOfUnits, Serializable { return Units.get(type); } + /** + * Returns a unit with the given string representation, + * or {@code null} if none is found in this unit system. + * + * @param symbols the string representation of a unit. + * @return the unit with the given string representation, + * or {@code null} if the give symbols can not be parsed. + */ + @Override + public Unit<?> getUnit(final String symbols) { + try { + return Units.valueOf(symbols); + } catch (MeasurementParseException e) { + Logging.ignorableException(getLogger(Loggers.MEASURE), UnitRegistry.class, "getUnit", e); + return null; + } + } + /** * Returns a read only view over the units explicitly defined by this system. * This include the base and derived units which are assigned a special name and symbol. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java index c21f7131d5..86a65df55a 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java @@ -20,14 +20,16 @@ import java.util.Collection; import java.util.HashSet; import java.util.Locale; import java.util.Set; +import java.text.NumberFormat; import javax.measure.Unit; import javax.measure.Quantity; import javax.measure.format.UnitFormat; +import javax.measure.format.QuantityFormat; import javax.measure.spi.QuantityFactory; import javax.measure.spi.ServiceProvider; import javax.measure.spi.SystemOfUnits; import javax.measure.spi.SystemOfUnitsService; -import javax.measure.spi.UnitFormatService; +import javax.measure.spi.FormatService; import org.apache.sis.internal.util.UnmodifiableArrayList; import org.apache.sis.internal.system.Loggers; import org.apache.sis.util.logging.Logging; @@ -42,15 +44,15 @@ import static java.util.logging.Logger.getLogger; * The central point from which all unit services (parsing, formatting, listing, <i>etc</i>) can be obtained. * Apache SIS does not use this class (SIS rather uses {@link Units} predefined constants and {@link UnitFormat} * directly since they are designed specifically for SIS needs). - * This class is provided for allowing other applications to discover Apache SIS implementation of JSR-363 + * This class is provided for allowing other applications to discover Apache SIS implementation of JSR-385 * without direct dependency. A {@code UnitServices} instance can be obtained by call to {@link #current()}. * * @author Martin Desruisseaux (Geomatys) - * @version 1.2 + * @version 1.4 * @since 0.8 * @module */ -public class UnitServices extends ServiceProvider implements SystemOfUnitsService, UnitFormatService { +public class UnitServices extends ServiceProvider implements SystemOfUnitsService, FormatService { /** * All system of units known to this provider. * The last element in the array is the default system with all units known to SIS. @@ -181,7 +183,7 @@ public class UnitServices extends ServiceProvider implements SystemOfUnitsServic try { style = org.apache.sis.measure.UnitFormat.Style.valueOf(name); } catch (IllegalArgumentException e) { - // JSR-363 specification mandate that we return null. + // JSR-385 specification mandate that we return null. Logging.recoverableException(getLogger(Loggers.MEASURE), UnitServices.class, "getUnitFormat", e); return null; } @@ -190,14 +192,60 @@ public class UnitServices extends ServiceProvider implements SystemOfUnitsServic return f; } + /** + * Returns the unit format having the specified name or {@code null} if none. + * The variant is an optional argument for requesting e.g. ASCII-only format, + * or for choosing case-sensitive versus case-insensitive variants. + * In current implementation the variant argument is ignored. + * + * @param name the name of the desired format. + * @param variant indicates a variation of a unit format. + * @return the corresponding unit format, or {@code null} if none. + * @since 1.4 + */ + @Override + public UnitFormat getUnitFormat(final String name, final String variant) { + return getUnitFormat(name); + } + + /** + * Returns a quantity format for the default locale. + * + * @return a {@link tech.uom.seshat.QuantityFormat} instance for quantities. + * @since 1.4 + */ + @Override + public QuantityFormat getQuantityFormat() { + return new org.apache.sis.measure.QuantityFormat(Locale.getDefault(Locale.Category.FORMAT)); + } + + /** + * Returns the quantity format having the specified name or {@code null} if none. + * The names accepted by this method are those documented in {@link #getUnitFormat(String)}. + * + * @param name the name of the format. + * @return the corresponding quantity format, or {@code null} if none. + * @since 1.4 + */ + @Override + public QuantityFormat getQuantityFormat(final String name) { + final UnitFormat unitFormat = getUnitFormat(name); + if (unitFormat instanceof org.apache.sis.measure.UnitFormat) { + return new org.apache.sis.measure.QuantityFormat(NumberFormat.getInstance(), + (org.apache.sis.measure.UnitFormat) unitFormat); + } + return null; + } + /** * Returns a list of available format names. The default implementation returns the names * of all values in the {@link org.apache.sis.measure.UnitFormat.Style} enumeration. * + * @param type the type of formats (for units or for quantities). * @return list of available formats. */ @Override - public Set<String> getAvailableFormatNames() { + public Set<String> getAvailableFormatNames(final FormatType type) { final Set<String> names = new HashSet<>(4); for (final Enum<?> e : org.apache.sis.measure.UnitFormat.Style.values()) { names.add(e.name()); @@ -213,13 +261,13 @@ public class UnitServices extends ServiceProvider implements SystemOfUnitsServic * <ul> * <li>{@link #getUnitFormat()}</li> * <li>{@link #getUnitFormat(String)}</li> - * <li>{@link #getAvailableFormatNames()}</li> + * <li>{@link #getAvailableFormatNames(FormatType)}</li> * </ul> * * @return the service to obtain a {@link UnitFormat}, or {@code null} if none. */ @Override - public UnitFormatService getUnitFormatService() { + public FormatService getFormatService() { return this; } @@ -239,29 +287,14 @@ public class UnitServices extends ServiceProvider implements SystemOfUnitsServic QuantityFactory<Q> factory = Units.get(type); if (factory == null) { if (type != null) { - factory = new QuantityFactory<Q>() { + factory = new DefaultQuantityFactory<Q>() { @Override public Quantity<Q> create(final Number value, final Unit<Q> unit) { return ScalarFallback.factory(AbstractConverter.doubleValue(value), unit, type); } - - @Override - public Unit<Q> getSystemUnit() { - return null; - } }; } else { - factory = new QuantityFactory<Q>() { - @Override - public Quantity<Q> create(final Number value, final Unit<Q> unit) { - return new Scalar<>(AbstractConverter.doubleValue(value), unit); - } - - @Override - public Unit<Q> getSystemUnit() { - return null; - } - }; + factory = new DefaultQuantityFactory<>(); } } return factory; diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java index 9d4a217e28..8354f331cd 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java @@ -19,7 +19,7 @@ package org.apache.sis.measure; import javax.measure.Dimension; import javax.measure.Unit; import javax.measure.UnitConverter; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import javax.measure.Quantity; import javax.measure.quantity.*; import javax.measure.quantity.Angle; // Because of name collision with Angle in this SIS package. @@ -1665,7 +1665,7 @@ public final class Units extends Static { return new Number[0]; } if (converter.isLinear()) { - final double offset = converter.convert(0); // Should be zero as per JSR-363 specification, but we are paranoiac. + final double offset = converter.convert(0); // Should be zero as per JSR-385 specification, but we are paranoiac. final double scale = converter.convert(1) - offset; final Number[] c = new Number[(scale != 1) ? 2 : (offset != 0) ? 1 : 0]; switch (c.length) { @@ -1713,11 +1713,11 @@ public final class Units extends Static { * * @param uom the symbol to parse, or {@code null}. * @return the parsed symbol, or {@code null} if {@code uom} was null. - * @throws ParserException if the given symbol cannot be parsed. + * @throws MeasurementParseException if the given symbol cannot be parsed. * * @see UnitFormat#parse(CharSequence) */ - public static Unit<?> valueOf(String uom) throws ParserException { + public static Unit<?> valueOf(String uom) throws MeasurementParseException { return (uom != null) ? UnitFormat.INSTANCE.parse(uom) : null; } diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java b/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java index b5db469858..662ee16193 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java @@ -97,7 +97,7 @@ * * @author Martin Desruisseaux (MPO, IRD, Geomatys) * @author Alexis Manin (Geomatys) - * @version 1.3 + * @version 1.4 * @since 0.3 * @module */ diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java index 1fa30b9ce0..f5a612f4c6 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java @@ -31,7 +31,7 @@ import static org.opengis.test.Assert.*; * Tests {@link Quantities}. * * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.4 * @since 0.8 * @module */ @@ -58,6 +58,7 @@ public final strictfp class QuantitiesTest extends TestCase { q = new Quantity<Length>() { @Override public Number getValue() {return 8;} @Override public Unit<Length> getUnit () {return Units.CENTIMETRE;} + @Override public Scale getScale() {return Scale.ABSOLUTE;} @Override public Quantity<Length> add (Quantity<Length> ignored) {return null;} @Override public Quantity<Length> subtract(Quantity<Length> ignored) {return null;} @Override public Quantity<?> multiply(Quantity<?> ignored) {return null;} @@ -65,7 +66,9 @@ public final strictfp class QuantitiesTest extends TestCase { @Override public Quantity<Length> multiply(Number ignored) {return null;} @Override public Quantity<Length> divide (Number ignored) {return null;} @Override public Quantity<?> inverse () {return null;} + @Override public Quantity<Length> negate () {return null;} @Override public Quantity<Length> to (Unit<Length> ignored) {return null;} + @Override public boolean isEquivalentTo(Quantity<Length> ignored) {return false;} @Override public <T extends Quantity<T>> Quantity<T> asType(Class<T> ignored) {return null;} }; final Length c = Quantities.castOrCopy(q); diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java index ced8c18b29..ba5754cfb5 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java @@ -130,7 +130,7 @@ public final strictfp class SystemUnitTest extends TestCase { */ @Test public void testGetBaseDimensions() { - assertNull("METRE", Units.METRE .getBaseUnits()); // Null value as per JSR-363 specification. + assertNull("METRE", Units.METRE .getBaseUnits()); // Null value as per JSR-385 specification. assertNull("SECOND", Units.SECOND.getBaseUnits()); assertTrue("UNITY", Units.UNITY .getBaseUnits().isEmpty()); @@ -199,7 +199,7 @@ public final strictfp class SystemUnitTest extends TestCase { assertTrue (Units.RADIAN.isCompatible(Units.RADIAN)); assertFalse(Units.RADIAN.isCompatible(Units.METRE )); assertFalse(Units.METRE .isCompatible(Units.RADIAN)); - assertTrue (Units.UNITY .isCompatible(Units.RADIAN)); // Really true (not false) as per JSR-363 specification. + assertTrue (Units.UNITY .isCompatible(Units.RADIAN)); // Really true (not false) as per JSR-385 specification. assertTrue (Units.RADIAN.isCompatible(Units.UNITY )); } diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitDimensionTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitDimensionTest.java index b1f9588efc..b886b7bf73 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitDimensionTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitDimensionTest.java @@ -140,7 +140,7 @@ public final strictfp class UnitDimensionTest extends TestCase { */ @Test public void testGetBaseDimensions() { - assertNull("LENGTH", LENGTH .getBaseDimensions()); // Null value as per JSR-363 specification. + assertNull("LENGTH", LENGTH .getBaseDimensions()); // Null value as per JSR-385 specification. assertNull("TIME", TIME .getBaseDimensions()); assertTrue("DIMENSIONLESS", DIMENSIONLESS.getBaseDimensions().isEmpty()); assertMapEquals(Map.of(LENGTH, 3), VOLUME.getBaseDimensions()); @@ -165,7 +165,7 @@ public final strictfp class UnitDimensionTest extends TestCase { verifyEqualsAndHashCode("Derived dimensions", false, Units.NEWTON, Units.JOULE); verifyEqualsAndHashCode("Dimensionsless", true, Units.UNITY, Units.UNITY); verifyEqualsAndHashCode("Dimensionsless", true, Units.DEGREE, Units.DEGREE); - verifyEqualsAndHashCode("Dimensionsless", true, Units.UNITY, Units.DEGREE); // Really true (not false) as per JSR-363 specification. + verifyEqualsAndHashCode("Dimensionsless", true, Units.UNITY, Units.DEGREE); // Really true (not false) as per JSR-385 specification. verifyEqualsAndHashCode("Mixed types", false, Units.METRE, Units.UNITY); verifyEqualsAndHashCode("Mixed types", false, Units.METRE, Units.NEWTON); } 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 ef17c2998a..d955a9be98 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 @@ -23,7 +23,7 @@ import java.text.ParsePosition; import java.lang.reflect.Field; import javax.measure.Unit; import javax.measure.quantity.Length; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Characters; import org.apache.sis.test.DependsOn; @@ -193,7 +193,7 @@ public final strictfp class UnitFormatTest extends TestCase { try { f.parse("mFoo"); fail("“mFoo” should not be assigned to unit anymore."); - } catch (ParserException e) { + } catch (MeasurementParseException e) { final String message = e.getMessage(); assertTrue(message, message.contains("mFoo")); } @@ -393,7 +393,7 @@ public final strictfp class UnitFormatTest extends TestCase { try { f.parse("degree foo"); fail("Should not accept unknown unit."); - } catch (ParserException e) { + } catch (MeasurementParseException e) { final String message = e.getMessage(); assertTrue(message, message.contains("degree")); assertTrue(message, message.contains("foo")); @@ -402,7 +402,7 @@ public final strictfp class UnitFormatTest extends TestCase { try { f.parse("mètre cube"); fail("Should not accept localized unit unless requested."); - } catch (ParserException e) { + } catch (MeasurementParseException e) { final String message = e.getMessage(); assertTrue(message, message.contains("mètre")); assertTrue(message, message.contains("cube")); @@ -485,7 +485,7 @@ public final strictfp class UnitFormatTest extends TestCase { try { f.parse("ka"); fail("Should not accept prefix in ConventionalUnit."); - } catch (ParserException e) { + } catch (MeasurementParseException e) { final String message = e.getMessage(); assertTrue(message, message.contains("ka")); } @@ -519,7 +519,7 @@ public final strictfp class UnitFormatTest extends TestCase { try { f.parse("degree minute"); fail("Should not accept unknown sentence even if each individual word is known."); - } catch (ParserException e) { + } catch (MeasurementParseException e) { final String message = e.getMessage(); assertTrue(message, message.contains("degree")); assertTrue(message, message.contains("minute")); diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitServicesTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitServicesTest.java index 3c1e667751..af79a1d2cc 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitServicesTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitServicesTest.java @@ -17,10 +17,10 @@ package org.apache.sis.measure; import java.util.Set; -import java.util.List; import java.util.Locale; import javax.measure.Unit; import javax.measure.format.UnitFormat; +import javax.measure.spi.FormatService; import javax.measure.spi.ServiceProvider; import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; @@ -33,7 +33,7 @@ import static org.apache.sis.test.Assert.*; * Test {@link UnitServices}. * * @author Martin Desruisseaux (Geomatys) - * @version 0.8 + * @version 1.4 * @since 0.8 * @module */ @@ -115,13 +115,14 @@ public final strictfp class UnitServicesTest extends TestCase { } /** - * Tests {@link UnitServices#getAvailableFormatNames()}. + * Tests {@link UnitServices#getAvailableFormatNames(UnitServices.FormatType)}. */ @Test public void testGetAvailableFormatNames() { final ServiceProvider provider = ServiceProvider.current(); - assertSetEquals(List.of("SYMBOL", "UCUM", "NAME"), - provider.getUnitFormatService().getAvailableFormatNames()); + final FormatService service = provider.getFormatService(); + final Set<String> formats = service.getAvailableFormatNames(FormatService.FormatType.UNIT_FORMAT); + assertSetEquals(Set.of("SYMBOL", "UCUM", "NAME"), formats); } /** @@ -130,7 +131,7 @@ public final strictfp class UnitServicesTest extends TestCase { @Test public void testGetUnitFormat() { final ServiceProvider provider = ServiceProvider.current(); - final UnitFormat f = provider.getUnitFormatService().getUnitFormat("name"); + final UnitFormat f = provider.getFormatService().getUnitFormat("name"); ((org.apache.sis.measure.UnitFormat) f).setLocale(Locale.US); assertEquals("CUBIC_METRE", "cubic meter", f.format(Units.CUBIC_METRE)); } diff --git a/ide-project/NetBeans/nbproject/project.properties b/ide-project/NetBeans/nbproject/project.properties index e537f44c7a..7a129754dd 100644 --- a/ide-project/NetBeans/nbproject/project.properties +++ b/ide-project/NetBeans/nbproject/project.properties @@ -98,7 +98,7 @@ project.GeoAPI = ../../../../GeoAPI/master/ide-project/NetBeans # Those dependencies must exist in the local Maven repository. # Those numbers should match the ones declared in the pom.xml files. # -jsr363.version = 1.0 +jsr385.version = 2.1.3 jaxb.version = 2.3.3 jaxb.runtime = 2.3.7 istack.version = 3.0.12 @@ -131,7 +131,7 @@ maven.repository = ${user.home}/.m2/repository endorsed.classpath = javac.classpath=\ ${project.GeoAPI}/dist/geoapi.jar:\ - ${maven.repository}/javax/measure/unit-api/${jsr363.version}/unit-api-${jsr363.version}.jar:\ + ${maven.repository}/javax/measure/unit-api/${jsr385.version}/unit-api-${jsr385.version}.jar:\ ${maven.repository}/jakarta/xml/bind/jakarta.xml.bind-api/${jaxb.version}/jakarta.xml.bind-api-${jaxb.version}.jar:\ ${maven.repository}/com/esri/geometry/esri-geometry-api/${esri.api.version}/esri-geometry-api-${esri.api.version}.jar:\ ${maven.repository}/org/locationtech/jts/jts-core/${jts.version}/jts-core-${jts.version}.jar:\ diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java index 2d31d1553c..5a6e3a2920 100644 --- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java +++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java @@ -25,7 +25,7 @@ import java.util.regex.Pattern; import java.util.function.Function; import java.awt.Color; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; @@ -568,10 +568,10 @@ public final class GCOM_C extends Convention { * * @param data the variable for which to get the unit of measurement. * @return the unit of measurement, or {@code null} if none or unknown. - * @throws ParserException if the unit symbol cannot be parsed. + * @throws MeasurementParseException if the unit symbol cannot be parsed. */ @Override - public Unit<?> getUnitFallback(final Variable data) throws ParserException { + public Unit<?> getUnitFallback(final Variable data) throws MeasurementParseException { if ("Image_data".equals(data.getGroupName())) { final String symbol = data.getAttributeAsString("Unit"); if (symbol != null && !symbol.equalsIgnoreCase("NA")) { diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java index 90e0cd85b6..a77f0f9e76 100644 --- a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java +++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java @@ -20,7 +20,7 @@ import java.util.Set; import java.util.Map; import java.util.regex.Pattern; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.apache.sis.measure.Units; import org.apache.sis.storage.netcdf.AttributeNames; import org.apache.sis.internal.netcdf.Convention; @@ -262,10 +262,10 @@ public final class GCOM_W extends Convention { * * @param data the variable for which to get the unit of measurement. * @return the unit of measurement, or {@code null} if none or unknown. - * @throws ParserException if the unit symbol cannot be parsed. + * @throws MeasurementParseException if the unit symbol cannot be parsed. */ @Override - public Unit<?> getUnitFallback(final Variable data) throws ParserException { + public Unit<?> getUnitFallback(final Variable data) throws MeasurementParseException { final String symbol = data.getAttributeAsString("UNIT"); if (symbol == null) { return super.getUnitFallback(data); diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java index 4ebf91fd61..f8c2581ca7 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java @@ -25,7 +25,7 @@ import java.util.Locale; import java.util.function.Function; import java.awt.Color; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.operation.MathTransform; @@ -768,9 +768,9 @@ public class Convention { * * @param data the variable for which to get the unit of measurement. * @return the unit of measurement, or {@code null} if none or unknown. - * @throws ParserException if the unit symbol cannot be parsed. + * @throws MeasurementParseException if the unit symbol cannot be parsed. */ - public Unit<?> getUnitFallback(final Variable data) throws ParserException { + public Unit<?> getUnitFallback(final Variable data) throws MeasurementParseException { return null; } diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java index e6806fd169..fb0254c035 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java @@ -25,7 +25,7 @@ import java.util.regex.Pattern; import java.io.IOException; import java.time.Instant; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.referencing.operation.Matrix; import org.apache.sis.referencing.operation.transform.TransferFunction; import org.apache.sis.storage.DataStoreException; @@ -401,7 +401,7 @@ public abstract class Variable extends Node { } if (unit == null) try { unit = decoder.convention().getUnitFallback(this); - } catch (ParserException ex) { + } catch (MeasurementParseException ex) { if (error == null) error = ex; else error.addSuppressed(ex); if (symbols == null) { diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java index 47098327d6..17c125a46b 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java @@ -39,7 +39,7 @@ import java.nio.charset.StandardCharsets; import java.nio.channels.ReadableByteChannel; import javax.measure.UnitConverter; import javax.measure.IncommensurableException; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.parameter.InvalidParameterCardinalityException; import org.apache.sis.internal.netcdf.DataType; import org.apache.sis.internal.netcdf.Decoder; @@ -899,7 +899,7 @@ public final class ChannelDecoder extends Decoder { dates[i] = new Date(epoch + Math.round(converter.convert(value.doubleValue()))); } } - } catch (IncommensurableException | ParserException | DateTimeException | ArithmeticException e) { + } catch (IncommensurableException | MeasurementParseException | DateTimeException | ArithmeticException e) { listeners.warning(e); } return dates; diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java index cf36e097d4..997e0aa9ff 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.nio.charset.Charset; import java.time.format.DateTimeParseException; import javax.measure.Unit; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import ucar.nc2.constants.CF; import ucar.nc2.constants.CDM; import ucar.nc2.constants._Coordinate; @@ -416,7 +416,7 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { * Parses the given unit symbol and set the {@link #epoch} if the parsed unit is a temporal unit. * This method is called by {@link #getUnit()}. * - * @throws ParserException if the given symbol cannot be parsed. + * @throws MeasurementParseException if the given symbol cannot be parsed. */ @Override protected Unit<?> parseUnit(String symbols) { @@ -443,7 +443,7 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { final Unit<?> unit; try { unit = Units.valueOf(symbols); - } catch (ParserException e) { + } catch (MeasurementParseException e) { if (dateError != null) { e.addSuppressed(dateError); } 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 4ee557155e..839493059d 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 @@ -31,7 +31,7 @@ import java.io.IOException; import javax.measure.Unit; import javax.measure.UnitConverter; import javax.measure.IncommensurableException; -import javax.measure.format.ParserException; +import javax.measure.format.MeasurementParseException; import org.opengis.util.CodeList; import org.opengis.util.NameFactory; @@ -725,7 +725,7 @@ split: while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt final String symbol = res.substring(s+1).trim(); if (!symbol.isEmpty()) try { units = Units.valueOf(symbol); - } catch (ParserException e) { + } catch (MeasurementParseException e) { warning(Errors.Keys.CanNotAssignUnitToDimension_2, name, units, e); } } @@ -816,7 +816,7 @@ split: while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt final UnitConverter c = Units.valueOf(symbol).getConverterToAny(targetUnit); min = c.convert(min); max = c.convert(max); - } catch (ParserException | IncommensurableException e) { + } catch (MeasurementParseException | IncommensurableException e) { warning(e); } boolean reverse = false;