sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Upgrade UCAR netCDF dependency from version 4.6.15 to 5.4.1. Changes in UCAR API are documented at there: https://docs.unidata.ucar.edu/netcdf-java/current/userguide/upgrade_to_50.html
Date Tue, 23 Feb 2021 15:21:53 GMT
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 da11a2e  Upgrade UCAR netCDF dependency from version 4.6.15 to 5.4.1. Changes in UCAR API are documented at there: https://docs.unidata.ucar.edu/netcdf-java/current/userguide/upgrade_to_50.html
da11a2e is described below

commit da11a2edf52a0715f0c56dbb673d37faf083b5c2
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Feb 23 15:03:51 2021 +0100

    Upgrade UCAR netCDF dependency from version 4.6.15 to 5.4.1.
    Changes in UCAR API are documented at there:
    https://docs.unidata.ucar.edu/netcdf-java/current/userguide/upgrade_to_50.html
---
 NOTICE                                             |  2 +-
 .../sis/parameter/MapProjectionDescriptor.java     |  5 +-
 ide-project/NetBeans/nbproject/project.properties  | 12 +--
 pom.xml                                            |  6 +-
 profiles/sis-japan-profile/pom.xml                 |  2 +-
 storage/sis-netcdf/pom.xml                         |  2 +-
 .../org/apache/sis/internal/netcdf/AxisType.java   |  4 +-
 .../org/apache/sis/internal/netcdf/Convention.java |  4 +-
 .../apache/sis/internal/netcdf/GridMapping.java    |  1 -
 .../apache/sis/internal/netcdf/RasterResource.java |  2 +-
 .../internal/netcdf/ucar/CSBuilderFallback.java    |  5 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   | 58 +++++++++----
 .../sis/internal/netcdf/ucar/DimensionWrapper.java |  3 +-
 .../sis/internal/netcdf/ucar/FeaturesWrapper.java  |  8 +-
 .../sis/internal/netcdf/ucar/GridWrapper.java      | 64 ++++++++-------
 .../sis/internal/netcdf/ucar/GroupWrapper.java     |  8 +-
 .../org/apache/sis/internal/netcdf/ucar/Utils.java |  4 +-
 .../sis/internal/netcdf/ucar/VariableWrapper.java  | 95 ++++++++++++----------
 .../sis/internal/netcdf/ucar/package-info.java     |  4 +-
 .../apache/sis/storage/netcdf/AttributeNames.java  |  1 -
 .../sis/storage/netcdf/NetcdfStoreProvider.java    | 26 ++++--
 .../apache/sis/storage/netcdf/package-info.java    | 14 +---
 22 files changed, 178 insertions(+), 152 deletions(-)

diff --git a/NOTICE b/NOTICE
index 974c2ba..db21daa 100644
--- a/NOTICE
+++ b/NOTICE
@@ -26,7 +26,7 @@ http://github.com/Esri/geometry-api-java/
 
 The `sis-netcdf` module can optionally use the UCAR netCDF library
 developed by Unidata under MIT-style license.
-http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/
+https://www.unidata.ucar.edu/software/netcdf-java/
 
 The test suite uses software developed by the JUnit community
 under Eclipse public license version 2.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionDescriptor.java b/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionDescriptor.java
index 20ccab2..26ff399 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionDescriptor.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/MapProjectionDescriptor.java
@@ -47,10 +47,7 @@ import org.apache.sis.util.Workaround;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.6
- *
- * @see <a href="http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/reference/StandardCoordinateTransforms.html">NetCDF projection parameters</a>
- *
- * @since 0.6
+ * @since   0.6
  * @module
  */
 @XmlTransient
diff --git a/ide-project/NetBeans/nbproject/project.properties b/ide-project/NetBeans/nbproject/project.properties
index 50860be..db3a8df 100644
--- a/ide-project/NetBeans/nbproject/project.properties
+++ b/ide-project/NetBeans/nbproject/project.properties
@@ -111,14 +111,15 @@ istack.version       = 3.0.8
 activation.version   = 1.1
 jama.version         = 1.0.3
 geographlib.version  = 1.51
-guava.version        = 27.0.1-jre
+guava.version        = 28.0-jre
+re2j.version         = 1.3
 esri.api.version     = 2.2.4
 jts.version          = 1.18.0
 jdom1.version        = 1.0
 jdom2.version        = 2.0.4
 jee.version          = 8.0.1
 osgi.version         = 6.0.0
-netcdf.version       = 4.6.15
+netcdf.version       = 5.4.1
 joda-time.version    = 2.8.1
 httpclient.version   = 4.5.1
 httpcore.version     = 4.4.4
@@ -145,7 +146,9 @@ javac.classpath=\
     ${maven.repository}/org/locationtech/jts/jts-core/${jts.version}/jts-core-${jts.version}.jar:\
     ${maven.repository}/jdom/jdom/${jdom1.version}/jdom-${jdom1.version}.jar:\
     ${maven.repository}/javax/javaee-api/${jee.version}/javaee-api-${jee.version}.jar:\
-    ${maven.repository}/edu/ucar/cdm/${netcdf.version}/cdm-${netcdf.version}.jar:\
+    ${maven.repository}/edu/ucar/cdm-core/${netcdf.version}/cdm-core-${netcdf.version}.jar:\
+    ${maven.repository}/edu/ucar/udunits/${netcdf.version}/udunits-${netcdf.version}.jar:\
+    ${maven.repository}/com/google/guava/guava/${guava.version}/guava-${guava.version}.jar:\
     ${maven.repository}/org/osgi/org.osgi.core/${osgi.version}/org.osgi.core-${osgi.version}.jar
 javac.processorpath=\
     ${javac.classpath}
@@ -168,10 +171,9 @@ run.jaxb.classpath=\
     ${maven.repository}/org/glassfish/jaxb/txw2/${jaxb.version}/txw2-${jaxb.version}.jar:\
     ${maven.repository}/com/sun/istack/istack-commons-runtime/${istack.version}/istack-commons-runtime-${istack.version}.jar
 run.netcdf.classpath=\
-    ${maven.repository}/com/google/guava/guava/${guava.version}/guava-${guava.version}.jar:\
+    ${maven.repository}/com/google/re2j/re2j/${re2j.version}/re2j-${re2j.version}.jar:\
     ${maven.repository}/joda-time/joda-time/${joda-time.version}/joda-time-${joda-time.version}.jar:\
     ${maven.repository}/org/jdom/jdom2/${jdom2.version}/jdom2-${jdom2.version}.jar:\
-    ${maven.repository}/edu/ucar/udunits/${netcdf.version}/udunits-${netcdf.version}.jar:\
     ${maven.repository}/edu/ucar/httpservices/${netcdf.version}/httpservices-${netcdf.version}.jar:\
     ${maven.repository}/org/apache/httpcomponents/httpcore/${httpcore.version}/httpcore-${httpcore.version}.jar:\
     ${maven.repository}/org/apache/httpcomponents/httpclient/${httpclient.version}/httpclient-${httpclient.version}.jar:\
diff --git a/pom.xml b/pom.xml
index b03bd02..04f3661 100644
--- a/pom.xml
+++ b/pom.xml
@@ -520,7 +520,7 @@
       </dependency>
       <dependency>
         <groupId>edu.ucar</groupId>
-        <artifactId>cdm</artifactId>
+        <artifactId>cdm-core</artifactId>
         <version>${netcdf.version}</version>
       </dependency>
       <dependency>
@@ -569,7 +569,7 @@
          The last properties in this list depend on the Apache SIS branch.
        =================================================================== -->
   <properties>
-    <netcdf.version>4.6.15</netcdf.version>
+    <netcdf.version>5.4.1</netcdf.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <website.encoding>UTF-8</website.encoding>
     <website.locale>en</website.locale>
@@ -900,7 +900,7 @@
             <link>https://docs.oracle.com/javase/8/docs/api</link>
             <link>http://unitsofmeasurement.github.io/unit-api/site/apidocs</link>
             <link>http://www.geoapi.org/snapshot/pending</link>
-            <link>http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/javadoc</link>
+            <link>https://docs.unidata.ucar.edu/netcdf-java/current/javadoc</link>
           </links>
 
           <additionalOptions>
diff --git a/profiles/sis-japan-profile/pom.xml b/profiles/sis-japan-profile/pom.xml
index 3fd6009..9dc8bcd 100644
--- a/profiles/sis-japan-profile/pom.xml
+++ b/profiles/sis-japan-profile/pom.xml
@@ -97,7 +97,7 @@
     </dependency>
     <dependency>
       <groupId>edu.ucar</groupId>
-      <artifactId>cdm</artifactId>
+      <artifactId>cdm-core</artifactId>
       <scope>compile</scope>
       <optional>false</optional>
     </dependency>
diff --git a/storage/sis-netcdf/pom.xml b/storage/sis-netcdf/pom.xml
index 4fde6a6..3914bd3 100644
--- a/storage/sis-netcdf/pom.xml
+++ b/storage/sis-netcdf/pom.xml
@@ -116,7 +116,7 @@
     </dependency>
     <dependency>
       <groupId>edu.ucar</groupId>
-      <artifactId>cdm</artifactId>
+      <artifactId>cdm-core</artifactId>
       <scope>provided</scope>
       <optional>true</optional>
     </dependency>
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/AxisType.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/AxisType.java
index 6fcf3f1..b6c3f40 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/AxisType.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/AxisType.java
@@ -61,9 +61,7 @@ public enum AxisType {
      * Mapping from values of the {@code "_CoordinateAxisType"} attribute or axis name to the abbreviation.
      * Keys are lower cases and values are controlled vocabulary documented in {@link Axis#abbreviation}.
      *
-     * <div class="note">"GeoX" and "GeoY" stands for projected coordinates, not geocentric coordinates
-     * (<a href="https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/reference/CoordinateAttributes.html#AxisTypes">source</a>).
-     * </div>
+     * <div class="note">"GeoX" and "GeoY" stands for projected coordinates, not geocentric coordinates.</div>
      *
      * @see abbreviation(String)
      */
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 012e366..dd99dd0 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
@@ -588,7 +588,7 @@ public class Convention {
      * </ol>
      *
      * Whether the returned range is a range of packed values or a range of real values is ambiguous.
-     * An heuristic rule is documented in UCAR {@link ucar.nc2.dataset.EnhanceScaleMissing} interface.
+     * An heuristic rule is documented in {@link ucar.nc2.dataset.EnhanceScaleMissingUnsigned} interface.
      * If both types of range are available, then this method should return the range of packed value.
      * Otherwise if this method returns the range of real values, then that range shall be an instance
      * of {@link MeasurementRange} for allowing the caller to distinguish the two cases.
@@ -633,7 +633,7 @@ public class Convention {
              */
             if (minimum != null && maximum != null) {
                 /*
-                 * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissing interface):
+                 * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissingUnsigned):
                  * if the type of the range is equal to the type of the scale, and the type of the
                  * data is not wider, then assume that the minimum and maximum are real values.
                  */
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
index 5c7f2fe..2de7c0b 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridMapping.java
@@ -83,7 +83,6 @@ import ucar.nc2.constants.CF;
  * @version 1.1
  *
  * @see <a href="http://cfconventions.org/cf-conventions/cf-conventions.html#grid-mappings-and-projections">CF-conventions</a>
- * @see <a href="https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/reference/StandardCoordinateTransforms.html">UCAR projections</a>
  *
  * @since 1.0
  * @module
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
index bd6c364..cbd9f76 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
@@ -468,7 +468,7 @@ public final class RasterResource extends AbstractGridResource implements Resour
             final MathTransform1D mt = band.getTransferFunction().getTransform();
             if (!mt.isIdentity() && range instanceof MeasurementRange<?>) {
                 /*
-                 * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissing interface):
+                 * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissingUnsigned):
                  * if the type of the range is equal to the type of the scale, and the type of the
                  * data is not wider, then assume that the minimum and maximum are real values.
                  * This is identified in Apache SIS by the range given as a MeasurementRange.
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/CSBuilderFallback.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/CSBuilderFallback.java
index fb88041..581304e 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/CSBuilderFallback.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/CSBuilderFallback.java
@@ -45,10 +45,7 @@ import org.apache.sis.util.CharSequences;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.0
- *
- * @see <a href="https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/tutorial/CoordSysBuilder.html">UCAR tutorial</a>
- *
- * @since 1.0
+ * @since   1.0
  * @module
  */
 final class CSBuilderFallback extends CoordSysBuilder {
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
index fda8c82..9f3923a 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
@@ -22,13 +22,12 @@ import java.util.List;
 import java.util.EnumSet;
 import java.util.Formatter;
 import java.util.Collection;
-import java.util.Collections;
 import java.io.IOException;
 import ucar.nc2.Group;
 import ucar.nc2.Attribute;
-import ucar.nc2.VariableIF;
 import ucar.nc2.NetcdfFile;
 import ucar.nc2.dataset.NetcdfDataset;
+import ucar.nc2.dataset.NetcdfDatasets;
 import ucar.nc2.dataset.CoordinateSystem;
 import ucar.nc2.util.CancelTask;
 import ucar.nc2.units.DateUnit;
@@ -38,7 +37,7 @@ import ucar.nc2.time.CalendarDateFormatter;
 import ucar.nc2.ft.FeatureDataset;
 import ucar.nc2.ft.FeatureDatasetPoint;
 import ucar.nc2.ft.FeatureDatasetFactoryManager;
-import ucar.nc2.ft.FeatureCollection;
+import ucar.nc2.ft.DsgFeatureCollection;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TableColumn;
@@ -105,6 +104,13 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
     private transient Grid[] geometries;
 
     /**
+     * Sets to {@code true} for declaring that the operation completed, either successfully or with an error.
+     *
+     * @see #isDone()
+     */
+    private boolean done;
+
+    /**
      * Creates a new decoder for the given netCDF file. While this constructor accepts arbitrary
      * {@link NetcdfFile} instance, the {@link NetcdfDataset} subclass is necessary in order to
      * get coordinate system information.
@@ -133,9 +139,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
             throws IOException
     {
         super(geomlib, listeners);
-        final NetcdfDataset ds = NetcdfDataset.openDataset(filename, false, this);
-        ds.enhance(Collections.singleton(NetcdfDataset.Enhance.CoordSystems));
-        file = ds;
+        file = NetcdfDatasets.openDataset(filename, true, this);
         groups = new Group[1];
         initialize();
     }
@@ -244,7 +248,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
      * @return the attribute, or {@code null} if none.
      */
     private Attribute findAttribute(final Group group, final String name) {
-        Attribute value = (group != null) ? group.findAttributeIgnoreCase(name)
+        Attribute value = (group != null) ? group.attributes().findAttributeIgnoreCase(name)
                                           : file.findGlobalAttributeIgnoreCase(name);
         if (value == null) {
             final String mappedName = convention().mapAttributeName(name);
@@ -253,7 +257,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
              * since this is only an optimization for a common case.
              */
             if (mappedName != name) {
-                value = (group != null) ? group.findAttributeIgnoreCase(mappedName)
+                value = (group != null) ? group.attributes().findAttributeIgnoreCase(mappedName)
                                         : file.findGlobalAttributeIgnoreCase(mappedName);
             }
         }
@@ -295,7 +299,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
                 if (attribute != null) {
                     final Number value = attribute.getNumericValue();
                     if (value != null) {
-                        return Utils.fixSign(value, attribute.isUnsigned());
+                        return Utils.fixSign(value, attribute.getDataType().isUnsigned());
                     }
                     String asString = Utils.nonEmpty(attribute.getStringValue());
                     if (asString != null) {
@@ -392,7 +396,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
     @SuppressWarnings({"ReturnOfCollectionOrArrayField", "null"})
     public Variable[] getVariables() {
         if (variables == null) {
-            final List<? extends VariableIF> all = file.getVariables();
+            final List<? extends ucar.nc2.Variable> all = file.getVariables();
             variables = new VariableWrapper[(all != null) ? all.size() : 0];
             for (int i=0; i<variables.length; i++) {
                 variables[i] = new VariableWrapper(this, all.get(i));
@@ -405,7 +409,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
      * Returns the Apache SIS wrapper for the given UCAR variable. The given variable shall be non-null
      * and should be one of the variables wrapped by the instances returned by {@link #getVariables()}.
      */
-    final VariableWrapper getWrapperFor(final VariableIF variable) {
+    final VariableWrapper getWrapperFor(final ucar.nc2.Variable variable) {
         for (VariableWrapper c : (VariableWrapper[]) getVariables()) {
             if (c.isWrapperFor(variable)) {
                 return c;
@@ -431,7 +435,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
                     new Formatter(new LogAdapter(listeners), listeners.getLocale()));
         }
         if (features instanceof FeatureDatasetPoint) {
-            final List<FeatureCollection> fc = ((FeatureDatasetPoint) features).getPointFeatureCollectionList();
+            final List<DsgFeatureCollection> fc = ((FeatureDatasetPoint) features).getPointFeatureCollectionList();
             if (fc != null && !fc.isEmpty()) {
                 final FeaturesWrapper[] wrappers = new FeaturesWrapper[fc.size()];
                 try {
@@ -516,7 +520,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
      */
     @Override
     protected Variable findVariable(final String name) {
-        final VariableIF v = file.findVariable(name);
+        final ucar.nc2.Variable v = file.findVariable(name);
         return (v != null) ? getWrapperFor(v) : null;
     }
 
@@ -528,7 +532,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
      */
     @Override
     protected Node findNode(final String name) {
-        final VariableIF v = file.findVariable(name);
+        final ucar.nc2.Variable v = file.findVariable(name);
         if (v != null) {
             return getWrapperFor(v);
         }
@@ -563,9 +567,9 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
         for (final ucar.nc2.Variable variable : group.getVariables()) {
             final TreeTable.Node node = branch.newChild();
             node.setValue(TableColumn.NAME, variable.getShortName());
-            addAttributesTo(node, variable.getAttributes());
+            addAttributesTo(node, variable.attributes());
         }
-        addAttributesTo(branch, group.getAttributes());
+        addAttributesTo(branch, group.attributes());
     }
 
     /**
@@ -576,7 +580,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
      * @param  branch      where to add new nodes for the given attributes.
      * @param  attributes  the attributes to add to the specified branch.
      */
-    private static void addAttributesTo(final TreeTable.Node branch, final List<Attribute> attributes) {
+    private static void addAttributesTo(final TreeTable.Node branch, final Iterable<Attribute> attributes) {
         if (attributes != null) {
             for (final Attribute attribute : attributes) {
                 final TreeTable.Node node = branch.newChild();
@@ -635,6 +639,26 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
     }
 
     /**
+     * Invoked by UCAR netCDF library when the operation completed, either successfully or with an error.
+     *
+     * @param  done  the completion status.
+     */
+    @Override
+    public void setDone(final boolean done) {
+        this.done = done;
+    }
+
+    /**
+     * Returns {@code true} if the operation completed, either successfully or with an error.
+     *
+     * @return the completion status.
+     */
+    @Override
+    public boolean isDone() {
+        return done;
+    }
+
+    /**
      * Closes the netCDF file.
      *
      * @throws IOException if an error occurred while closing the file.
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
index 06377f3..fde99e4 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.netcdf.ucar;
 
 import java.util.List;
+import java.util.Collection;
 import java.util.stream.Collectors;
 import ucar.nc2.Dimension;
 
@@ -36,7 +37,7 @@ final class DimensionWrapper extends org.apache.sis.internal.netcdf.Dimension {
     /**
      * Wraps all given dimensions.
      */
-    static List<org.apache.sis.internal.netcdf.Dimension> wrap(final List<Dimension> dimensions) {
+    static List<org.apache.sis.internal.netcdf.Dimension> wrap(final Collection<Dimension> dimensions) {
         return dimensions.stream().map(DimensionWrapper::new).collect(Collectors.toList());
     }
 
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
index 3daa109..cd9a7cf 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
@@ -20,7 +20,7 @@ import java.util.stream.Stream;
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.internal.netcdf.DiscreteSampling;
 import org.apache.sis.storage.event.StoreListeners;
-import ucar.nc2.ft.FeatureCollection;
+import ucar.nc2.ft.DsgFeatureCollection;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
@@ -32,7 +32,7 @@ import org.opengis.feature.FeatureType;
  * Created by {@link DecoderWrapper#getDiscreteSampling(Object)}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   0.8
  * @module
  *
@@ -43,7 +43,7 @@ final class FeaturesWrapper extends DiscreteSampling {
     /**
      * The feature dataset provided by the UCAR library.
      */
-    private final FeatureCollection features;
+    private final DsgFeatureCollection features;
 
     /**
      * Creates a new discrete sampling parser.
@@ -53,7 +53,7 @@ final class FeaturesWrapper extends DiscreteSampling {
      * @param  lock       the lock to use in {@code synchronized(lock)} statements.
      * @throws IllegalArgumentException if the given library is non-null but not available.
      */
-    FeaturesWrapper(final FeatureCollection features, final GeometryLibrary factory, final StoreListeners listeners,
+    FeaturesWrapper(final DsgFeatureCollection features, final GeometryLibrary factory, final StoreListeners listeners,
                     final Object lock)
     {
         super(factory, listeners, lock);
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java
index e102591..b31df7f 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java
@@ -22,7 +22,6 @@ import java.util.Map;
 import java.util.HashMap;
 import java.io.IOException;
 import ucar.nc2.Dimension;
-import ucar.nc2.VariableIF;
 import ucar.nc2.constants.AxisType;
 import ucar.nc2.dataset.CoordinateAxis;
 import ucar.nc2.dataset.CoordinateAxis2D;
@@ -83,17 +82,41 @@ final class GridWrapper extends Grid {
      */
     GridWrapper(final CoordinateSystem cs) {
         netcdfCS  = cs;
-        domain    = cs.getDomain();
         reordered = new HashMap<>(4);               // Will typically contain 0 or 1 entry.
+        domain    = new ArrayList<>(cs.getDomain());
+        /*
+         * We need dimensions in netCDF order as declared in variables. But the netCDF UCAR library sometime provides
+         * axes in a different order, I'm not sure why. Maybe it uses the order in which dimensions are declared in
+         * the global header (not the order declared on variables). We apply a standard order below. It is okay
+         * if that order is not appropriate for a particular variable because the order will be reajusted by
+         * `forDimensions(…)` method. We use the order which is most likely to be the order used by variables.
+         */
+        final Map<Dimension,AxisType> types = new HashMap<>();
+        for (final CoordinateAxis axis : cs.getCoordinateAxes()) {
+            final AxisType type = axis.getAxisType();
+            for (final Dimension dim : axis.getDimensions()) {
+                if (types.putIfAbsent(dim, type) == null) break;
+            }
+        }
+        domain.sort((d1, d2) -> {
+            final AxisType t1 = types.get(d1);
+            final AxisType t2 = types.get(d2);
+            if (t1 == t2)   return 0;
+            if (t1 == null) return +1;
+            if (t2 == null) return -1;
+            return t1.axisOrder() - t2.axisOrder();
+        });
     }
 
     /**
-     * Creates a new grid geometry with the same coordinate system than the given parent.
+     * Creates a new grid geometry with the same coordinate system than the given parent
+     * but dimensions in a different order. This is used for building coordinate systems
+     * with axis order matching the order of dimensions in variables.
      */
     private GridWrapper(final GridWrapper parent, final List<Dimension> dimensions) {
         netcdfCS  = parent.netcdfCS;
-        domain    = dimensions;
         reordered = parent.reordered;
+        domain    = dimensions;
         assert netcdfCS.getDomain().containsAll(dimensions);
     }
 
@@ -109,8 +132,8 @@ final class GridWrapper extends Grid {
     }
 
     /**
-     * Implementation of {@link #forDimensions(org.apache.sis.internal.netcdf.Dimension[])} after the Apache SIS objects
-     * have been unwrapped into UCAR objects.
+     * Implementation of {@link #forDimensions(org.apache.sis.internal.netcdf.Dimension[])}
+     * after the Apache SIS objects have been unwrapped into UCAR objects.
      *
      * @param  dimensions  the desired dimensions, in order. May contain more dimensions than this grid.
      * @return localization grid with the exact same set of dimensions than this grid (no more and no less),
@@ -142,7 +165,7 @@ final class GridWrapper extends Grid {
      * @param  systems   the coordinate systems of the given variable.
      * @return grid for the given variable, or {@code null} if none.
      */
-    final GridWrapper forVariable(final VariableIF variable, final List<CoordinateSystem> systems, final String[] axisNames) {
+    final GridWrapper forVariable(final ucar.nc2.Variable variable, final List<CoordinateSystem> systems, final String[] axisNames) {
         if (systems.contains(netcdfCS) && containsAllNamedAxes(axisNames)) {
             return forDimensions(variable.getDimensions());
         }
@@ -228,11 +251,12 @@ next:       for (final String name : axisNames) {
     protected Axis[] createAxes(final Decoder decoder) throws IOException, DataStoreException {
         final List<CoordinateAxis> range = netcdfCS.getCoordinateAxes();
         /*
-         * In this method, 'sourceDim' and 'targetDim' are relative to "grid to CRS" conversion.
-         * So 'sourceDim' is the grid (domain) dimension and 'targetDim' is the CRS (range) dimension.
+         * In this method, `sourceDim` and `targetDim` are relative to "grid to CRS" conversion.
+         * So `sourceDim` is the grid (domain) dimension and `targetDim` is the CRS (range) dimension.
          */
         int targetDim = range.size();
         final Axis[] axes = new Axis[targetDim];
+        final int lastDim = targetDim - 1;
         while (--targetDim >= 0) {
             final CoordinateAxis axis = range.get(targetDim);
             final Variable wrapper = ((DecoderWrapper) decoder).getWrapperFor(axis);
@@ -280,29 +304,9 @@ next:       for (final String name : axisNames) {
                  * package, we can proceed as if the dimension does not exist (`i` not incremented).
                  */
             }
-            axes[targetDim] = new Axis(abbreviation, axis.getPositive(),
+            axes[lastDim - targetDim] = new Axis(abbreviation, axis.getPositive(),
                     ArraysExt.resize(indices, i), ArraysExt.resize(sizes, i), wrapper);
         }
-        /*
-         * We want axes in "natural" order. But the netCDF UCAR library sometime provides axes already
-         * in that order and sometime in reverse order (netCDF order). I'm not aware of a reliable way
-         * to determine whether axis order provided by UCAR library needs to be reverted since I don't
-         * know what determines that order (the file format? the presence of "coordinates" attribute?).
-         * For now we compare axis order with dimension order, and if the axis contains all dimensions
-         * in the same order we presume that this is the "netCDF" order (as opposed to a "coordinates"
-         * attribute value order).
-         */
-        int i = range.size();
-        int j = domain.size();
-        while (--i >= 0) {
-            final List<Dimension> dimensions = range.get(i).getDimensions();
-            switch (dimensions.size()) {
-                case 0: continue;           // Ignore scalars as they can appear anywhere.
-                case 1: if (--j >= 0 && dimensions.get(0).equals(domain.get(j))) continue;
-            }
-            return axes;
-        }
-        ArraysExt.reverse(axes);
         return axes;
     }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GroupWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GroupWrapper.java
index 605beb4..55d4ed6 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GroupWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GroupWrapper.java
@@ -26,7 +26,7 @@ import org.apache.sis.internal.netcdf.Decoder;
  * Wrapper for a netCDF group.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   1.0
  * @module
  */
@@ -57,7 +57,7 @@ final class GroupWrapper extends Node {
      */
     @Override
     public Collection<String> getAttributeNames() {
-        return VariableWrapper.toNames(group.getAttributes());
+        return VariableWrapper.toNames(group.attributes());
     }
 
     /**
@@ -65,7 +65,7 @@ final class GroupWrapper extends Node {
      */
     @Override
     public Class<?> getAttributeType(final String attributeName) {
-        return VariableWrapper.getAttributeType(group.findAttributeIgnoreCase(attributeName));
+        return VariableWrapper.getAttributeType(group.attributes().findAttributeIgnoreCase(attributeName));
     }
 
     /**
@@ -75,6 +75,6 @@ final class GroupWrapper extends Node {
      */
     @Override
     protected Object getAttributeValue(final String attributeName) {
-        return VariableWrapper.getAttributeValue(group.findAttributeIgnoreCase(attributeName));
+        return VariableWrapper.getAttributeValue(group.attributes().findAttributeIgnoreCase(attributeName));
     }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/Utils.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/Utils.java
index 2d07542..60f0bb1 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/Utils.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/Utils.java
@@ -22,7 +22,7 @@ package org.apache.sis.internal.netcdf.ucar;
  * Some methods are workarounds for UCAR library methods having a different behavior than what we would expect.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   1.0
  * @module
  */
@@ -67,7 +67,7 @@ final class Utils {
             if (number instanceof Byte) {
                 final byte value = (byte) number;
                 if (value < 0) {
-                    number = Byte.toUnsignedInt(value);
+                    number = (short) Byte.toUnsignedInt(value);
                 }
             } else if (number instanceof Short) {
                 final short value = (Short) number;
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
index b277617..0308091 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.netcdf.ucar;
 
 import java.util.Map;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.io.File;
 import java.io.IOException;
@@ -27,14 +28,14 @@ import ucar.ma2.Section;
 import ucar.ma2.InvalidRangeException;
 import ucar.nc2.Group;
 import ucar.nc2.Attribute;
-import ucar.nc2.VariableIF;
-import ucar.nc2.dataset.Enhancements;
+import ucar.nc2.Variable;
+import ucar.nc2.dataset.VariableDS;
 import ucar.nc2.dataset.VariableEnhanced;
 import ucar.nc2.dataset.CoordinateAxis;
 import ucar.nc2.dataset.CoordinateAxis1D;
 import ucar.nc2.dataset.CoordinateAxis2D;
 import ucar.nc2.dataset.CoordinateSystem;
-import ucar.nc2.dataset.EnhanceScaleMissing;
+import ucar.nc2.dataset.EnhanceScaleMissingUnsigned;
 import ucar.nc2.units.SimpleUnit;
 import ucar.nc2.units.DateUnit;
 import ucar.nc2.constants._Coordinate;
@@ -45,8 +46,6 @@ import org.apache.sis.internal.netcdf.DataType;
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.netcdf.Grid;
 import org.apache.sis.internal.netcdf.GridAdjustment;
-import org.apache.sis.internal.netcdf.Variable;
-import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.jdk9.JDK9;
 import org.apache.sis.storage.DataStoreException;
@@ -57,7 +56,7 @@ import ucar.nc2.constants.AxisType;
 
 
 /**
- * A {@link Variable} backed by the UCAR netCDF library.
+ * A {@link org.apache.sis.internal.netcdf.Variable} backed by the UCAR netCDF library.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
@@ -65,11 +64,11 @@ import ucar.nc2.constants.AxisType;
  * @since   0.3
  * @module
  */
-final class VariableWrapper extends Variable {
+final class VariableWrapper extends org.apache.sis.internal.netcdf.Variable {
     /**
      * The netCDF variable. This is typically an instance of {@link VariableEnhanced}.
      */
-    private final VariableIF variable;
+    private final Variable variable;
 
     /**
      * The variable without enhancements. May be the same instance than {@link #variable}
@@ -78,12 +77,12 @@ final class VariableWrapper extends Variable {
      * attributes are hidden by {@link VariableEnhanced}. In order to allow metadata reader
      * to find them, we query attributes in the original variable instead.
      */
-    private final VariableIF raw;
+    private final Variable raw;
 
     /**
      * Creates a new variable wrapping the given netCDF interface.
      */
-    VariableWrapper(final Decoder decoder, VariableIF v) {
+    VariableWrapper(final Decoder decoder, Variable v) {
         super(decoder);
         variable = v;
         if (v instanceof VariableEnhanced) {
@@ -98,8 +97,8 @@ final class VariableWrapper extends Variable {
          * Only if UCAR did not recognized the enumeration, fallback on Apache SIS implementation.
          */
         Map<Integer,String> enumeration = null;
-        if (variable.getDataType().isEnum() && (variable instanceof ucar.nc2.Variable)) {
-            enumeration = ((ucar.nc2.Variable) variable).getEnumTypedef().getMap();
+        if (variable.getDataType().isEnum()) {
+            enumeration = variable.getEnumTypedef().getMap();
         }
         setEnumeration(enumeration);        // Use SIS fallback if `enumeration` is null.
     }
@@ -109,11 +108,9 @@ final class VariableWrapper extends Variable {
      */
     @Override
     public String getFilename() {
-        if (variable instanceof ucar.nc2.Variable) {
-            final String name = Utils.nonEmpty(((ucar.nc2.Variable) variable).getDatasetLocation());
-            if (name != null) {
-                return name.substring(Math.max(name.lastIndexOf('/'), name.lastIndexOf(File.separatorChar)) + 1);
-            }
+        final String name = Utils.nonEmpty(variable.getDatasetLocation());
+        if (name != null) {
+            return name.substring(Math.max(name.lastIndexOf('/'), name.lastIndexOf(File.separatorChar)) + 1);
         }
         return super.getFilename();
     }
@@ -203,19 +200,20 @@ final class VariableWrapper extends Variable {
      */
     @Override
     public DataType getDataType() {
-        final DataType type;
         switch (variable.getDataType()) {
             case STRING: return DataType.STRING;
             case CHAR:   return DataType.CHAR;
-            case BYTE:   type = DataType.BYTE;   break;
-            case SHORT:  type = DataType.SHORT;  break;
-            case INT:    type = DataType.INT;    break;
-            case LONG:   type = DataType.INT64;  break;
+            case BYTE:   return DataType.BYTE;
+            case UBYTE:  return DataType.UBYTE;
+            case SHORT:  return DataType.SHORT;
+            case USHORT: return DataType.USHORT;
+            case INT:    return DataType.INT;
+            case UINT:   return DataType.UINT;
+            case LONG:   return DataType.INT64;
             case FLOAT:  return DataType.FLOAT;
             case DOUBLE: return DataType.DOUBLE;
             default:     return DataType.UNKNOWN;
         }
-        return type.unsigned(variable.isUnsigned());
     }
 
     /**
@@ -231,7 +229,8 @@ final class VariableWrapper extends Variable {
      */
     @Override
     protected boolean isCoordinateSystemAxis() {
-        return variable.isCoordinateVariable();
+        // `isCoordinateVariable()` is not sufficient in the case of "runtime" axis.
+        return variable.isCoordinateVariable() || (variable instanceof CoordinateAxis);
     }
 
     /**
@@ -272,9 +271,9 @@ final class VariableWrapper extends Variable {
          * systems identified by UCAR for this variable while super.getGrid(…) inspects all dimensions found in
          * the file. Note that those coordinate systems may have been set by the user.
          */
-        if (variable instanceof Enhancements) {
+        if (variable instanceof VariableDS) {
             final Grid[] grids = decoder.getGrids();    // Must be first for forcing some UCAR CS constructions.
-            final List<CoordinateSystem> systems = ((Enhancements) variable).getCoordinateSystems();
+            final List<CoordinateSystem> systems = ((VariableDS) variable).getCoordinateSystems();
             if (!systems.isEmpty()) {
                 GridWrapper grid = null;
                 final String[] axisNames = decoder.convention().namesOfAxisVariables(this);
@@ -329,7 +328,7 @@ final class VariableWrapper extends Variable {
      */
     @Override
     public Collection<String> getAttributeNames() {
-        return toNames(variable.getAttributes());
+        return toNames(variable.attributes());
     }
 
     /**
@@ -338,7 +337,7 @@ final class VariableWrapper extends Variable {
      */
     @Override
     public Class<?> getAttributeType(final String attributeName) {
-        return getAttributeType(raw.findAttributeIgnoreCase(attributeName));
+        return getAttributeType(raw.attributes().findAttributeIgnoreCase(attributeName));
     }
 
     /**
@@ -351,8 +350,11 @@ final class VariableWrapper extends Variable {
             }
             switch (attribute.getDataType()) {
                 case BYTE:   return Byte.class;
+                case UBYTE:
                 case SHORT:  return Short.class;
+                case USHORT:
                 case INT:    return Integer.class;
+                case UINT:
                 case LONG:   return Long.class;
                 case FLOAT:  return Float.class;
                 case DOUBLE: return Double.class;
@@ -372,7 +374,7 @@ final class VariableWrapper extends Variable {
      */
     @Override
     protected Object getAttributeValue(final String attributeName) {
-        return getAttributeValue(raw.findAttributeIgnoreCase(attributeName));
+        return getAttributeValue(raw.attributes().findAttributeIgnoreCase(attributeName));
     }
 
     /**
@@ -388,7 +390,7 @@ final class VariableWrapper extends Variable {
                     if (value instanceof String) {
                         return Utils.nonEmpty((String) value);
                     } else if (value instanceof Number) {
-                        return Utils.fixSign((Number) value, attribute.isUnsigned());
+                        return Utils.fixSign((Number) value, attribute.getDataType().isUnsigned());
                     }
                     break;
                 }
@@ -405,7 +407,9 @@ final class VariableWrapper extends Variable {
                         }
                     } else {
                         final Array array = attribute.getValues();
-                        return createDecimalVector(array.get1DJavaArray(array.getElementType()), attribute.isUnsigned());
+                        return createDecimalVector(array.get1DJavaArray(
+                                ucar.ma2.DataType.getType(array)),
+                                attribute.getDataType().isUnsigned());
                     }
                 }
             }
@@ -414,14 +418,14 @@ final class VariableWrapper extends Variable {
     }
 
     /**
-     * Returns the names of all attributes in the given list.
+     * Returns the names of all attributes in the given container.
      */
-    static List<String> toNames(final List<Attribute> attributes) {
-        final String[] names = new String[attributes.size()];
-        for (int i=0; i<names.length; i++) {
-            names[i] = attributes.get(i).getShortName();
+    static List<String> toNames(final Iterable<Attribute> attributes) {
+        final List<String> names = new ArrayList<>();
+        for (final Attribute at : attributes) {
+            names.add(at.getShortName());
         }
-        return UnmodifiableArrayList.wrap(names);
+        return names;
     }
 
     /**
@@ -432,9 +436,9 @@ final class VariableWrapper extends Variable {
      */
     @Override
     protected NumberRange<?> getRangeFallback() {
-        if (variable instanceof EnhanceScaleMissing) {
-            final EnhanceScaleMissing ev = (EnhanceScaleMissing) variable;
-            if (ev.hasInvalidData()) {
+        if (variable instanceof EnhanceScaleMissingUnsigned) {
+            final EnhanceScaleMissingUnsigned ev = (EnhanceScaleMissingUnsigned) variable;
+            if (ev.hasValidData()) {
                 // Returns a MeasurementRange instance for signaling the caller that this is converted values.
                 return MeasurementRange.create(ev.getValidMin(), true, ev.getValidMax(), true, getUnit());
             }
@@ -477,7 +481,7 @@ final class VariableWrapper extends Variable {
     @Override
     public Vector read(final GridExtent area, final int[] subsampling) throws IOException, DataStoreException {
         final Object array = readArray(area, subsampling);
-        return Vector.create(array, variable.isUnsigned());
+        return Vector.create(array, variable.getDataType().isUnsigned());
     }
 
     /**
@@ -491,10 +495,11 @@ final class VariableWrapper extends Variable {
     @Override
     public List<?> readAnyType(final GridExtent area, final int[] subsampling) throws IOException, DataStoreException {
         final Object array = readArray(area, subsampling);
-        if (variable.getDataType() == ucar.ma2.DataType.CHAR && variable.getRank() >= STRING_DIMENSION) {
+        final ucar.ma2.DataType type = variable.getDataType();
+        if (type == ucar.ma2.DataType.CHAR && variable.getRank() >= STRING_DIMENSION) {
             return createStringList(array, area);
         }
-        return Vector.create(array, variable.isUnsigned());
+        return Vector.create(array, type.isUnsigned());
     }
 
     /**
@@ -538,7 +543,7 @@ final class VariableWrapper extends Variable {
      * values by {@code NaN} values.
      */
     private Object get1DJavaArray(final Array array) {
-        final Object data = array.get1DJavaArray(array.getElementType());
+        final Object data = array.get1DJavaArray(ucar.ma2.DataType.getType(array));
         replaceNaN(data);
         return data;
     }
@@ -622,7 +627,7 @@ final class VariableWrapper extends Variable {
     /**
      * Returns {@code true} if this Apache SIS variable is a wrapper for the given UCAR variable.
      */
-    final boolean isWrapperFor(final VariableIF v) {
+    final boolean isWrapperFor(final Variable v) {
         return (variable == v) || (raw == v);
     }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
index f6e3b2e..3138597 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
@@ -20,9 +20,9 @@
  * as wrappers around the UCAR netCDF library.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.1
  *
- * @see <a href="https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/javadoc/index.html">UCAR javadoc</a>
+ * @see <a href="https://docs.unidata.ucar.edu/netcdf-java/current/javadoc/index.html">UCAR javadoc</a>
  *
  * @since 0.3
  * @module
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
index 19a2d83..507e4f9 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
@@ -137,7 +137,6 @@ import org.opengis.metadata.extent.GeographicDescription;
  * <ul>
  *   <li><a href="http://wiki.esipfed.org/index.php/Category:Attribute_Conventions_Dataset_Discovery">NetCDF
  *       Attribute Convention for Dataset Discovery</a> wiki</li>
- *   <li><a href="https://github.com/Unidata/threddsIso/blob/master/src/main/resources/xsl/nciso/UnidataDD2MI.xsl">UnidataDD2MI.xsl</a> file</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
index 49f7072..5c8a60a 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
@@ -97,6 +97,12 @@ public class NetcdfStoreProvider extends DataStoreProvider {
     private static final String UCAR_CLASSNAME = "ucar.nc2.NetcdfFile";
 
     /**
+     * The name of the {@link ucar.nc2.NetcdfFiles} class, which is {@value}.
+     * This class provides static methods for opening netCDF files.
+     */
+    private static final String FACTORY_CLASSNAME = "ucar.nc2.NetcdfFiles";
+
+    /**
      * The {@link ucar.nc2.NetcdfFile} class, or {@code null} if not found. An attempt to load this class
      * will be performed when first needed since the UCAR library is optional. If not found, then this field
      * will be assigned the {@link Void#TYPE} sentinel value, meaning "No UCAR library on the classpath".
@@ -104,20 +110,20 @@ public class NetcdfStoreProvider extends DataStoreProvider {
     private static Class<?> netcdfFileClass;
 
     /**
-     * If the {@link #netcdfFileClass} has been found, then the {@link ucar.nc2.NetcdfFile#canOpen(String)}
-     * static method.
+     * If the {@value #FACTORY_CLASSNAME} class has been found,
+     * then the {@link ucar.nc2.NetcdfFiles#canOpen(String)} static method.
      */
     private static volatile Method canOpenFromPath;
 
     /**
-     * If the {@link #netcdfFileClass} has been found, then the {@link DecoderWrapper} constructor receiving
-     * in argument the name of the netCDF file as a {@link String} object. Otherwise {@code null}.
+     * If the {@value #FACTORY_CLASSNAME} class has been found, then the {@link DecoderWrapper} constructor
+     * receiving in argument the name of the netCDF file as a {@link String} object. Otherwise {@code null}.
      */
     private static volatile Constructor<? extends Decoder> createFromPath;
 
     /**
-     * If the {@link #netcdfFileClass} has been found, then the {@link DecoderWrapper} constructor receiving
-     * in argument a UCAR {@code NetcdfFile} object. Otherwise {@code null}.
+     * If the {@value #FACTORY_CLASSNAME} class has been found, then the {@link DecoderWrapper} constructor
+     * receiving in argument a UCAR {@code NetcdfFile} object. Otherwise {@code null}.
      */
     private static volatile Constructor<? extends Decoder> createFromUCAR;
 
@@ -218,7 +224,7 @@ public class NetcdfStoreProvider extends DataStoreProvider {
                          * in which case UCAR tries to open it as a file even if it is not a file. For example
                          * we get this exception for "jar:file:/file.jar!/entry.nc".
                          */
-                        Logging.recoverableException(getLogger(), netcdfFileClass, "canOpen", cause);
+                        Logging.recoverableException(getLogger(), NetcdfStoreProvider.class, "probeContent", cause);
                         return ProbeResult.UNSUPPORTED_STORAGE;
                     }
                     throw new DataStoreException(e);                        // The cause may be IOException.
@@ -365,8 +371,10 @@ public class NetcdfStoreProvider extends DataStoreProvider {
                  * The sychronization is mostly a safety against concurrent execution of 'reset()'.
                  */
                 try {
-                    netcdfFileClass = Class.forName(UCAR_CLASSNAME);
-                    canOpenFromPath = netcdfFileClass.getMethod("canOpen", String.class);
+                    final Class<?> netcdfFactoryClass;
+                    netcdfFileClass    = Class.forName(UCAR_CLASSNAME);
+                    netcdfFactoryClass = Class.forName(FACTORY_CLASSNAME);
+                    canOpenFromPath    = netcdfFactoryClass.getMethod("canOpen", String.class);
                     if (canOpenFromPath.getReturnType() == Boolean.TYPE) {
                         /*
                          * At this point we found the class and method from UCAR API. Now get the Apache SIS wrapper
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
index 468b167..491fc02 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
@@ -16,15 +16,7 @@
  */
 
 /**
- * Maps ISO metadata elements from/to the <a href="http://www.cfconventions.org">Climate and Forecast (CF)</a>
- * attributes in a netCDF file. The mapping is defined in the following web pages:
- *
- * <ul>
- *   <li><a href="http://wiki.esipfed.org/index.php/Category:Attribute_Conventions_Dataset_Discovery">NetCDF
- *       Attribute Convention for Dataset Discovery</a> version 1.0.</li>
- *   <li><a href="https://github.com/Unidata/threddsIso/blob/master/src/main/resources/xsl/nciso/UnidataDD2MI.xsl">UnidataDD2MI.xsl</a> file.</li>
- * </ul>
- *
+ * Reads netCDF files conforming to the <a href="http://www.cfconventions.org">Climate and Forecast (CF)</a>.
  * The netCDF attributes recognized by this package are listed in the
  * {@link org.apache.sis.storage.netcdf.AttributeNames} class.
  *
@@ -32,8 +24,8 @@
  * The UCAR library sometime uses the same words than the ISO/OGC standards for different things.
  * In particular the words <cite>"domain"</cite> and <cite>"range"</cite> can be applied to arbitrary functions,
  * and the UCAR library chooses to apply it to the function that converts grid indices to geodetic coordinates.
- * The ISO 19123 standard on the other hand considers coverage as a function, and applies those <cite>domain</cite>
- * and <cite>range</cite> words to that function. More specifically:
+ * This is a different usage than ISO 19123 which uses the <cite>domain</cite> and <cite>range</cite> words for
+ * the coverage function. More specifically:
  *
  * <ul>
  *   <li>UCAR <cite>"coordinate system"</cite> is actually a mix of <cite>coordinate system</cite>,


Mime
View raw message