Merge branch 'geoapi-3.1': port fixes from Apache SIS 1.0-RC1.
diff --git a/application/sis-console/pom.xml b/application/sis-console/pom.xml
index ba3cdb3..0296b0d 100644
--- a/application/sis-console/pom.xml
+++ b/application/sis-console/pom.xml
@@ -145,6 +145,10 @@
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ </dependency>
<!-- Test dependencies -->
<dependency>
diff --git a/application/sis-console/src/main/artifact/README b/application/sis-console/src/main/artifact/README
index ce5f727..d7f1562 100644
--- a/application/sis-console/src/main/artifact/README
+++ b/application/sis-console/src/main/artifact/README
@@ -13,7 +13,9 @@
Installation
============
-SIS is based on Java 8 and provided as a unique standalone JAR file.
+SIS requires Java 8 or later. If running on Java 9 or later,
+then the Derby JAR file should be added in the bin/ directory.
+See http://sis.apache.org/epsg.html#command-line
Unix
----
diff --git a/application/sis-console/src/main/artifact/lib/README b/application/sis-console/src/main/artifact/lib/README
index ab4d188..aeb28ea 100644
--- a/application/sis-console/src/main/artifact/lib/README
+++ b/application/sis-console/src/main/artifact/lib/README
@@ -2,6 +2,7 @@
Recognized optional dependencies are:
- Derby database
+ - JAXB implementation
- UCAR netCDF library
- ESRI Geometry API
- Java Topology Suite
diff --git a/core/sis-build-helper/src/main/ant/prepare-release.xml b/core/sis-build-helper/src/main/ant/prepare-release.xml
index a821354..6fffb54 100644
--- a/core/sis-build-helper/src/main/ant/prepare-release.xml
+++ b/core/sis-build-helper/src/main/ant/prepare-release.xml
@@ -34,34 +34,10 @@
match = "MINOR_VERSION\s*\+\s*"-SNAPSHOT""
replace = "MINOR_VERSION"/>
- <!-- Replace URL to trunk by URL to the branch on Subversion. -->
- <replace dir="${user.dir}" failOnNoReplacements="true">
- <include name="**/pom.xml"/>
- <replacefilter token="svn.apache.org/repos/asf/sis/trunk"
- value="svn.apache.org/repos/asf/sis/branches/${branch.version}"/>
- <replacefilter token="svn.apache.org/viewvc/sis/trunk"
- value="svn.apache.org/viewvc/sis/branches/${branch.version}"/>
- </replace>
- </target>
-
-
-
- <!-- Invoked after a tag has been created from the branch. -->
- <target name="tag">
-
- <!-- Replace URL to branch by URL to the branch on Subversion. -->
- <replace dir="${user.dir}" failOnNoReplacements="true">
- <include name="**/pom.xml"/>
- <replacefilter token="svn.apache.org/repos/asf/sis/branches/${branch.version}"
- value="svn.apache.org/repos/asf/sis/tags/${sis.version}"/>
- <replacefilter token="svn.apache.org/viewvc/sis/branches/${branch.version}"
- value="svn.apache.org/viewvc/sis/tags/${sis.version}"/>
- </replace>
-
<!-- Replace version numbers. Note that no snapshot other than SIS can exist at this point. -->
<replace dir="${user.dir}" failOnNoReplacements="true">
<include name="**/pom.xml"/>
- <replacefilter token="<version>${branch.version}-SNAPSHOT</version>"
+ <replacefilter token="<version>${sis.version}-SNAPSHOT</version>"
value="<version>${sis.version}</version>"/>
</replace>
</target>
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
index dce22e1..7fa4ec8 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
@@ -20,6 +20,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
+import java.util.function.Supplier;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.File;
@@ -34,7 +35,6 @@
import jdk.javadoc.doclet.Doclet.Option;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.StandardDoclet;
-import com.sun.source.util.DocTrees;
/**
@@ -58,7 +58,7 @@
* @since 0.5
* @module
*/
-public final class Doclet extends StandardDoclet {
+public final class Doclet extends StandardDoclet implements Supplier<Reporter> {
/**
* The name of the SIS-specific stylesheet file.
*/
@@ -71,25 +71,8 @@
/**
* Where to report warnings, or {@code null} if unknown.
- *
- * @todo make package-private after {@link #workaround8201817} has been removed.
*/
- public Reporter reporter;
-
- /**
- * Utility methods for locating the path of elements, or {@code null} if unknown.
- *
- * @todo make package-private after {@link #workaround8201817} has been removed.
- */
- public DocTrees trees;
-
- /**
- * Temporary Workaround for https://bugs.openjdk.java.net/browse/JDK-8201817
- *
- * @deprecated to be removed after we upgraded Apache SIS build requirement to JDK 11.
- */
- @Deprecated
- public static Doclet workaround8201817;
+ private Reporter reporter;
/**
* Invoked by the Javadoc tools for instantiating the custom doclet.
@@ -107,7 +90,18 @@
public void init(final Locale locale, final Reporter reporter) {
super.init(locale, reporter);
this.reporter = reporter;
- workaround8201817 = this;
+ }
+
+ /**
+ * Returns the {@link Reporter} associated to this doclet environment.
+ * This method is hack for giving that information to the taglets. We have to use a standard Java interfaces
+ * because the class loader of this {@code Doclet} will not be the same than the {@link Taglet} class loader.
+ *
+ * @return implementation-dependent information to give to taglets.
+ */
+ @Override
+ public Reporter get() {
+ return reporter;
}
/**
@@ -156,7 +150,6 @@
*/
@Override
public boolean run(final DocletEnvironment environment) {
- trees = environment.getDocTrees();
final boolean success = super.run(environment);
if (success && outputDirectory != null) try {
final Path output = Paths.get(outputDirectory);
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Taglet.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Taglet.java
index b55fafe..b7be2cf 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Taglet.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Taglet.java
@@ -25,11 +25,13 @@
import javax.lang.model.element.Element;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
+import jdk.javadoc.doclet.Doclet;
import com.sun.source.util.DocTrees;
import com.sun.source.util.TreePath;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.UnknownInlineTagTree;
+import java.util.function.Supplier;
/**
@@ -70,24 +72,9 @@
* @param doclet the doclet that instantiated this taglet.
*/
@Override
- public void init(final DocletEnvironment env, final jdk.javadoc.doclet.Doclet doclet) {
- if (doclet instanceof Doclet) {
- reporter = ((Doclet) doclet).reporter;
- trees = ((Doclet) doclet).trees;
- } else {
- // Temporary workaround for https://bugs.openjdk.java.net/browse/JDK-8201817
- StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk(stream ->
- stream.filter(frame -> frame.getClassName().equals("org.apache.sis.internal.doclet.Doclet"))
- .map(frame -> frame.getDeclaringClass()).findFirst()).ifPresent(docletClass -> {
- try {
- Object instance = docletClass.getDeclaredField("workaround8201817").get(null);
- reporter = (Reporter) docletClass.getDeclaredField("reporter").get(instance);
- trees = (DocTrees) docletClass.getDeclaredField("trees").get(instance);
- } catch (ReflectiveOperationException e) {
- printError("Unsupported doclet implementation. Caused by: " + e);
- }
- });
- }
+ public void init(final DocletEnvironment env, final Doclet doclet) {
+ reporter = (Reporter) ((Supplier<?>) doclet).get();
+ trees = env.getDocTrees();
}
/**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/SequenceType.java b/core/sis-feature/src/main/java/org/apache/sis/image/SequenceType.java
index 8e42823..241d372 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/SequenceType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/SequenceType.java
@@ -21,8 +21,11 @@
* Placeholder for {@code org.opengis.coverage.grid.SequenceType}.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.0
- * @since 1.0
+ * @version 1.1
+ *
+ * @see <a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter Encoding 2.0 Encoding Standard</a>
+ *
+ * @since 1.1
* @module
*/
enum SequenceType {
diff --git a/core/sis-referencing-by-identifiers/pom.xml b/core/sis-referencing-by-identifiers/pom.xml
index 9410fba..efe20e3 100644
--- a/core/sis-referencing-by-identifiers/pom.xml
+++ b/core/sis-referencing-by-identifiers/pom.xml
@@ -112,6 +112,10 @@
<artifactId>sis-referencing</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ </dependency>
<!-- Test dependencies -->
<dependency>
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
index e608226..7132271 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
@@ -1049,7 +1049,7 @@
case IGNORE_METADATA: return equals(m1, m2, 0, false);
case DEBUG: // Fall through
case ALLOW_VARIANT: // Fall through
- case APPROXIMATE: return equals(m1, m2, Numerics.COMPARISON_THRESHOLD, true);
+ case APPROXIMATE: return equals(m1, m2, Numerics.COMPARISON_THRESHOLD, true);
default: throw new IllegalArgumentException(Errors.format(
Errors.Keys.UnknownEnumValue_2, ComparisonMode.class, mode));
}
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/epsg/package.html b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/epsg/package.html
index 1393b05..1aa0ff7 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/epsg/package.html
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/epsg/package.html
@@ -145,20 +145,24 @@
<pre>mvn install -Dorg.apache.sis.test.extensive=true</pre></li>
- <li><p>Upgrade the <code>FACTORY.VERSION</code> value defined in the
- <code>org.apache.sis.referencing.report.CoordinateReferenceSystems</code> class, then execute that class.
- It can be executed from the IDE since the <code>main</code> method takes no argument.
- This class will write a <code>CoordinateReferenceSystems.html</code> file in current directory
- (the full path will be printed in the standard output).
- That file should be moved to the <code>site/content/tables/</code> directory,
- where <code>site</code> is the directory containing a local checkout of
- <a href="http://svn.apache.org/repos/asf/sis/site/trunk">http://svn.apache.org/repos/asf/sis/site/trunk</a>.</p></li>
+ <li><p>Regenerate the HTML pages listing available CRS and coordinate operation methods.
+ Those pages will be copied into the
+ <code><a href="http://svn.apache.org/repos/asf/sis/site/trunk/content/tables/">site/content/tables/</a></code>
+ directory during the <a href="http://sis.apache.org/release-management.html#update-crs-list">release process</a>,
+ but for now the purpose is only to check if there is errors:</p>
+ <ul>
+ <li><p>Upgrade the <code>FACTORY.VERSION</code> value defined in the
+ <code>org.apache.sis.referencing.report.CoordinateReferenceSystems</code> class, then execute that class.
+ It can be executed from the IDE since the <code>main</code> method takes no argument.
+ This class will write a <code>CoordinateReferenceSystems.html</code> file in current directory
+ (the full path will be printed in the standard output).</p></li>
- <li><p>Execute the <code>org.apache.sis.referencing.report.CoordinateOperationMethods</code> class.
- It can be executed from the IDE since the <code>main</code> method takes no argument.
- This class will write a <code>CoordinateOperationMethods.html</code> file in current directory.
- That file should be moved to the <code>site/content/tables/</code> directory,
- where <code>site</code> is the directory than above.</p></li>
+ <li><p>Execute the <code>org.apache.sis.referencing.report.CoordinateOperationMethods</code> class.
+ It can be executed from the IDE since the <code>main</code> method takes no argument.
+ This class will write a <code>CoordinateOperationMethods.html</code> file in current directory.</p></li>
+ </ul>
+ <p>Open those generated HTML files in a web browser and verify the result.</p>
+ </li>
</ol>
</body>
</html>
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/package-info.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/package-info.java
index 12ecd02..1ba2b7e 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/package-info.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/package-info.java
@@ -22,7 +22,7 @@
* The reports are for example the list of all supported EPSG codes.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.7
* @module
*/
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 4649573..a85e44d 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
@@ -140,7 +140,7 @@
public UnitConverter concatenate(final UnitConverter converter) {
ArgumentChecks.ensureNonNull("converter", converter);
if (equals(converter.inverse())) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
return new ConcatenatedConverter(converter, this);
}
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/ConcatenatedConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/ConcatenatedConverter.java
index 18b4340..1569206 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/ConcatenatedConverter.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/ConcatenatedConverter.java
@@ -126,7 +126,7 @@
public UnitConverter concatenate(final UnitConverter converter) {
ArgumentChecks.ensureNonNull("converter", converter);
if (equals(converter.inverse())) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
// Delegate to c1 and c2 because they may provide more intelligent 'concatenate' implementations.
return c2.concatenate(c1.concatenate(converter));
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 603a4ba..20cc956 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
@@ -310,7 +310,7 @@
@Override
public UnitConverter getConverterTo(final Unit<Q> that) throws UnconvertibleException {
if (that == this) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
ArgumentChecks.ensureNonNull("that", that);
UnitConverter c = toTarget;
@@ -340,7 +340,7 @@
@Override
public UnitConverter getConverterToAny(final Unit<?> that) throws IncommensurableException {
if (that == this) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
ArgumentChecks.ensureNonNull("that", that);
UnitConverter c = toTarget;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/IdentityConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/IdentityConverter.java
new file mode 100644
index 0000000..721342e
--- /dev/null
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/IdentityConverter.java
@@ -0,0 +1,109 @@
+/*
+ * 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 javax.measure.UnitConverter;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.LenientComparable;
+
+
+/**
+ * Linear converter with a scale factor of 1 and an offset of 0. We define a class for this special case
+ * instead than using the more generic {@link LinearConverter} class because we want to avoid performing
+ * any arithmetic operation in the {@link #convert(double)} method, in order to preserve negative zero:
+ *
+ * {@preformat java
+ * convert(-0d) ≡ -0d
+ * }
+ *
+ * When the value is used in a map projection parameter, its sign can have implications in the chain of
+ * concatenated transforms. The final result is numerically equivalent, but intermediate steps may differ
+ * depending on the parameter sign.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+final class IdentityConverter extends AbstractConverter implements LenientComparable {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 1230536100139464866L;
+
+ /**
+ * The identity linear converter.
+ */
+ static final IdentityConverter INSTANCE = new IdentityConverter();
+
+ /**
+ * For {@link #INSTANCE} only.
+ */
+ private IdentityConverter() {
+ }
+
+ /** Straight forward implementation. */
+ @Override public boolean isLinear() {return true;}
+ @Override public boolean isIdentity() {return true;}
+ @Override public UnitConverter inverse() {return this;}
+ @Override public double convert(double value) {return value;}
+ @Override public double derivative(double value) {return 1;}
+ @Override public UnitConverter concatenate(UnitConverter c) {return c;}
+ @Override public String toString() {return "y = x";}
+
+ /**
+ * Returns the value unchanged, with a check against null values
+ * for consistency with {@link LinearConverter#convert(Number)}.
+ */
+ @Override
+ public Number convert(Number value) {
+ ArgumentChecks.ensureNonNull("value", value);
+ return value;
+ }
+
+ /**
+ * Returns a hash code value for this unit converter.
+ */
+ @Override
+ public int hashCode() {
+ return (int) serialVersionUID;
+ }
+
+ /**
+ * Compares this converter with the given object for equality. This method may return {@code true}
+ * only if {@code Object} is an instance of {@link IdentityConverter} or {@link LinearConverter}.
+ * We apply this restriction in order to be symmetric with those cases,
+ * i.e. {@code A.equals(B)} = {@code B.equals(A)}.
+ */
+ @Override
+ public boolean equals(final Object other) {
+ // See method javadoc for why we restrict to AbstractConverter instead of UnitConverter.
+ return (other instanceof AbstractConverter) && ((AbstractConverter) other).isIdentity();
+ }
+
+ /**
+ * Compares this converter with the given object for equality, optionally ignoring rounding errors.
+ */
+ @Override
+ public boolean equals(final Object other, final ComparisonMode mode) {
+ if (mode.isApproximate() && other instanceof LinearConverter) {
+ return ((LinearConverter) other).almostIdentity();
+ }
+ return (other instanceof UnitConverter) && ((UnitConverter) other).isIdentity();
+ }
+}
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 75e7acd..dc81ec3 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
@@ -53,11 +53,6 @@
private static final long serialVersionUID = -3759983642723729926L;
/**
- * The identity linear converter.
- */
- static final LinearConverter IDENTITY = new LinearConverter(1, 0, 1);
-
- /**
* The scale to apply for converting values, before division by {@link #divisor}.
*/
private final double scale;
@@ -101,7 +96,7 @@
* Creates a linear converter from the given scale and offset, which may be {@link BigDecimal} instances.
* This is the implementation of public {@link Units#converter(Number, Number)} method.
*/
- static LinearConverter create(final Number scale, final Number offset) {
+ static AbstractConverter create(final Number scale, final Number offset) {
final double numerator, divisor;
double shift = (offset != null) ? doubleValue(offset) : 0;
if (scale instanceof Fraction) {
@@ -112,21 +107,16 @@
numerator = (scale != null) ? doubleValue(scale) : 1;
divisor = 1;
}
- final LinearConverter c = create(numerator, shift, divisor);
+ if (shift == 0 && numerator == divisor) {
+ return IdentityConverter.INSTANCE;
+ }
+ final LinearConverter c = new LinearConverter(numerator, shift, divisor);
if (scale instanceof BigDecimal) c.scale10 = (BigDecimal) scale;
if (offset instanceof BigDecimal) c.offset10 = (BigDecimal) offset;
return c;
}
/**
- * Returns a linear converter for the given scale and offset.
- */
- private static LinearConverter create(final double scale, final double offset, final double divisor) {
- if (offset == 0 && scale == divisor) return IDENTITY;
- return new LinearConverter(scale, offset, divisor);
- }
-
- /**
* Returns a linear converter for the given ratio. The scale factor is specified as a ratio because
* the unit conversion factors are often defined with a value in base 10. That value is considered
* exact by definition, but IEEE 754 has no exact representation of decimal fraction digits.
@@ -171,7 +161,7 @@
denominator = lc.divisor;
} else {
// Subtraction by convert(0) is a paranoiac safety.
- numerator = converter.convert(1.0) - converter.convert(0.0);
+ numerator = converter.convert(1d) - converter.convert(0d);
denominator = 1;
}
if (root) {
@@ -221,6 +211,13 @@
}
/**
+ * Returns {@code true} if this converter is close to an identity converter.
+ */
+ final boolean almostIdentity() {
+ return epsilonEquals(scale, divisor) && epsilonEquals(offset, 0);
+ }
+
+ /**
* Returns the inverse of this unit converter.
* Given that the formula applied by this converter is:
*
@@ -248,7 +245,7 @@
*/
@Override
@SuppressWarnings("fallthrough")
- Number[] coefficients() {
+ final Number[] coefficients() {
final Number[] c = new Number[(scale != divisor) ? 2 : (offset != 0) ? 1 : 0];
switch (c.length) {
case 2: c[1] = ratio(scale, divisor);
@@ -385,7 +382,10 @@
otherOffset /= cf;
otherDivisor /= cf;
}
- return create(otherScale, otherOffset, otherDivisor);
+ if (otherOffset == 0 && otherScale == otherDivisor) {
+ return IdentityConverter.INSTANCE;
+ }
+ return new LinearConverter(otherScale, otherOffset, otherDivisor);
}
/**
@@ -409,6 +409,9 @@
Numerics.equals(offset, o.offset) &&
Numerics.equals(divisor, o.divisor);
}
+ if (other instanceof IdentityConverter) {
+ return isIdentity();
+ }
return false;
}
@@ -418,7 +421,13 @@
@Override
public boolean equals(final Object other, final ComparisonMode mode) {
if (mode.isApproximate()) {
- return (other instanceof LinearConverter) && equivalent((LinearConverter) other);
+ if (other instanceof LinearConverter) {
+ return equivalent((LinearConverter) other);
+ } else if (other instanceof IdentityConverter) {
+ return almostIdentity();
+ } else {
+ return false;
+ }
} else {
return equals(other);
}
@@ -428,7 +437,7 @@
* Returns {@code true} if the given converter perform the same conversion than this converter,
* except for rounding errors.
*/
- boolean equivalent(final LinearConverter other) {
+ final boolean equivalent(final LinearConverter other) {
return epsilonEquals(scale * other.divisor, other.scale * divisor) &&
epsilonEquals(offset * other.divisor, other.offset * divisor);
}
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 d7caac0..fdaa50d 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
@@ -359,7 +359,7 @@
throw new UnconvertibleException(incompatible(unit));
}
if (step == unit) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
/*
* At this point we know that the given units is not a system unit. Ask the conversion
@@ -389,7 +389,7 @@
throw new IncommensurableException(incompatible(unit));
}
if (step == unit) {
- return LinearConverter.IDENTITY;
+ return IdentityConverter.INSTANCE;
}
// Same remark than in getConverterTo(Unit).
return unit.getConverterToAny(step).inverse();
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 2381eff..d4800d1 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
@@ -1329,7 +1329,7 @@
* This method shall be invoked in a single thread by the {@code Units} class initializer only.
*
* <p>The {@code target} argument should be an instance of {@link SystemUnit}.
- * The only exception is for creating the {@link DECIBEL} unit base on the bel conventional unit.</p>
+ * The only exception is for creating the {@link #DECIBEL} unit base on the bel conventional unit.</p>
*
* <p>If the {@code target} unit holds a list of {@linkplain SystemUnit#related() related units}
* (i.e. conventional units that can not be computed easily by appending a SI prefix), then the new
diff --git a/core/sis-utility/src/main/java/org/apache/sis/setup/Configuration.java b/core/sis-utility/src/main/java/org/apache/sis/setup/Configuration.java
index a27973d..964de1d 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/setup/Configuration.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/setup/Configuration.java
@@ -86,14 +86,32 @@
/**
* Specifies the data source to use if no {@code "jdbc/SpatialMetadata"} source is binded to a JNDI environment.
* Data source specified by JNDI has precedence over data source specified by this method in order to let users
- * control their data source.
+ * control their data source. The following example shows how to setup a connection to a PostgreSQL database:
*
- * <p>This method can be invoked only before the first attempt to {@linkplain #getDatabase() get the database}.
- * If the {@link DataSource} has already be obtained, then this method throws {@link IllegalStateException}.</p>
+ * {@preformat java
+ * import org.postgresql.ds.PGSimpleDataSource;
+ *
+ * // Class and method declarations omitted for brevity.
+ * PGSimpleDataSource ds = new PGSimpleDataSource();
+ * ds.setServerName("localhost");
+ * ds.setDatabaseName("SpatialMetadata");
+ *
+ * // Registration assuming that a JNDI implementation is available
+ * Context env = (Context) InitialContext.doLookup("java:comp/env");
+ * env.bind("jdbc/SpatialMetadata", ds);
+ *
+ * // Registration without JNDI.
+ * Configuration.current().setDatabase(() -> ds);
+ * }
+ *
+ * This method can be invoked only before the first attempt to {@linkplain #getDatabase() get the database}.
+ * If the {@link DataSource} has already be obtained, then this method throws {@link IllegalStateException}.
*
* @param source supplier of data source to set.
* The supplier may return {@code null}, in which case it will be ignored.
* @throws IllegalStateException if {@link DataSource} has already be obtained before this method call.
+ *
+ * @see <a href="http://sis.apache.org/epsg.html#jndi">How to use EPSG geodetic dataset</a>
*/
public void setDatabase(final Supplier<DataSource> source) {
ArgumentChecks.ensureNonNull("source", source);
diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
index c4b3ca0..d8138ce 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
@@ -43,7 +43,7 @@
* @param denominator the expected denominator in the conversion factor.
* @param converter the converter to verify.
*/
- static void assertScale(final int numerator, final int denominator, final LinearConverter converter) {
+ static void assertScale(final int numerator, final int denominator, final AbstractConverter converter) {
final double derivative = numerator / (double) denominator;
final Number[] coefficients = converter.coefficients();
assertEquals("coefficients.length", 2, coefficients.length);
@@ -88,7 +88,7 @@
*/
@Test
public void testIsIdentityAndLinear() {
- LinearConverter c = LinearConverter.IDENTITY;
+ AbstractConverter c = IdentityConverter.INSTANCE;
assertTrue(c.isIdentity());
assertTrue(c.isLinear());
assertEquals("coefficients.length", 0, c.coefficients().length);
@@ -185,15 +185,15 @@
*/
@Test
public void testConcatenate() {
- LinearConverter c = LinearConverter.scale(254, 100); // inches to centimetres
+ AbstractConverter c = LinearConverter.scale(254, 100); // inches to centimetres
assertScale(254, 100, c);
- c = (LinearConverter) c.concatenate(LinearConverter.scale(10, 1)); // centimetres to millimetres
+ c = (AbstractConverter) c.concatenate(LinearConverter.scale(10, 1)); // centimetres to millimetres
assertScale(254, 10, c);
- c = (LinearConverter) c.concatenate(LinearConverter.scale(1, 1000)); // millimetres to metres
+ c = (AbstractConverter) c.concatenate(LinearConverter.scale(1, 1000)); // millimetres to metres
assertScale(254, 10000, c);
c = LinearConverter.offset(27315, 100); // Celsius to kelvin
- c = (LinearConverter) c.concatenate(LinearConverter.offset(-54630, 200));
+ c = (AbstractConverter) c.concatenate(LinearConverter.offset(-54630, 200));
assertTrue(c.isIdentity());
}
@@ -228,7 +228,7 @@
*/
@Test
public void testToString() {
- assertEquals("y = x", LinearConverter.IDENTITY .toString());
+ assertEquals("y = x", IdentityConverter.INSTANCE .toString());
assertEquals("y = 100⋅x", LinearConverter.scale ( 100, 1).toString());
assertEquals("y = x∕100", LinearConverter.scale ( 1, 100).toString());
assertEquals("y = 254⋅x∕100", LinearConverter.scale ( 254, 100).toString());
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 5d726d2..bfab6bf 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
@@ -110,4 +110,21 @@
r = q1.multiply(1);
assertSame(q1, r);
}
+
+ /**
+ * Tests {@link Scalar#equals(Object)} and {@link Scalar#hashCode()}.
+ * This test uses a unit without specific {@link Scalar} subclass, in order to
+ * verify that tested methods work even though the {@link ScalarFallback} proxy.
+ */
+ @Test
+ public void testEqualsAndHashcode() {
+ Quantity<?> q1 = Quantities.create(2, Units.VOLT);
+ Quantity<?> q2 = Quantities.create(2, Units.VOLT);
+ Quantity<?> q3 = Quantities.create(3, Units.VOLT);
+ assertTrue (q1.hashCode() == q2.hashCode());
+ assertFalse(q1.hashCode() == q3.hashCode());
+ assertTrue (q1.hashCode() != 0);
+ assertTrue (q1.equals(q2));
+ assertFalse(q1.equals(q3));
+ }
}
diff --git a/ide-project/NetBeans/nbproject/project.properties b/ide-project/NetBeans/nbproject/project.properties
index a91ab13..0b1421b 100644
--- a/ide-project/NetBeans/nbproject/project.properties
+++ b/ide-project/NetBeans/nbproject/project.properties
@@ -110,7 +110,7 @@
rome.version = 0.9
jdom1.version = 1.0
jdom2.version = 2.0.4
-jee.version = 8.0
+jee.version = 8.0.1
osgi.version = 6.0.0
netcdf.version = 4.6.14
joda-time.version = 2.8.1
diff --git a/pom.xml b/pom.xml
index f73ce66..44eaa62 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
Maven 2 project configuration file
http://maven.apache.org/maven2/
- Apache SIS build requires Java 10 or higher, but compiled files can be executed on Java 8.
+ Apache SIS build requires Java 11 or higher, but compiled files can be executed on Java 8.
Setting the SIS_DATA environment variable before build is optional but recommended.
Build development snapshot: mvn clean install
@@ -560,7 +560,7 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<sis.plugin.version>${project.version}</sis.plugin.version>
- <sis.non-free.version>1.0-M1</sis.non-free.version> <!-- Used only if "non-free" profile is enabled. -->
+ <sis.non-free.version>1.0</sis.non-free.version> <!-- Used only if "non-free" profile is enabled. -->
<geoapi.version>3.0.1</geoapi.version>
<jaxb.version>2.3.2</jaxb.version>
</properties>
@@ -624,7 +624,7 @@
<configuration>
<rules>
<requireJavaVersion>
- <version>10</version>
+ <version>11</version>
</requireJavaVersion>
</rules>
</configuration>
@@ -873,6 +873,7 @@
<additionalOptions>
<additionalOption>--add-stylesheet "${maven.multiModuleProjectDirectory}/src/main/javadoc/sis.css"</additionalOption>
+ <additionalOption>--no-module-directories</additionalOption> <!-- https://bugs.openjdk.java.net/browse/JDK-8215291 -->
</additionalOptions>
<!-- Separates packages on the overview page into the groups specified. -->
@@ -920,8 +921,6 @@
<!-- Custom taglets, some of them implemented in Java. -->
<tags>
- <tag><placement>t</placement> <name>goal</name> <head>Maven goal:</head></tag>
- <tag><placement>t</placement> <name>phase</name> <head>Maven phase:</head></tag>
<tag><placement>X</placement> <name>category</name> <head>Category:</head></tag>
<tag><placement>a</placement> <name>todo</name> <head>TODO:</head></tag>
</tags>
diff --git a/profiles/sis-japan-profile/src/main/java/org/apache/sis/profile/japan/JapaneseProfile.java b/profiles/sis-japan-profile/src/main/java/org/apache/sis/profile/japan/JapaneseProfile.java
new file mode 100644
index 0000000..84b6c05
--- /dev/null
+++ b/profiles/sis-japan-profile/src/main/java/org/apache/sis/profile/japan/JapaneseProfile.java
@@ -0,0 +1,43 @@
+/*
+ * 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.profile.japan;
+
+import org.apache.sis.util.Static;
+
+
+/**
+ * Provides implementations of Japanese extensions.
+ * There is not yet public methods provided in this class.
+ * Just having this module presents on the classpath is sufficient for enabling the reading of following data:
+ *
+ * <ul>
+ * <li>Global Change Observation Mission - Climate (GCOM-C), a.k.a. "Shikisai".</li>
+ * <li>Global Change Observation Mission - Water (GCOM-W), a.k.a. "Shizuku".</li>
+ * </ul>
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+public final class JapaneseProfile extends Static {
+ /**
+ * Do not allow instantiation of this class.
+ */
+ private JapaneseProfile() {
+ }
+}
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableGridCoverageResource.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableGridCoverageResource.java
index e377c97..098680e 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableGridCoverageResource.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableGridCoverageResource.java
@@ -26,8 +26,8 @@
* be controlled by options, which may be {@link DataStore}-specific.
*
* @author Johann Sorel (Geomatys)
- * @version 1.0
- * @since 1.0
+ * @version 1.1
+ * @since 1.1
* @module
*/
public interface WritableGridCoverageResource extends GridCoverageResource {