This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sis.git
commit 465f0bf78cc712a9620096488dee26a5b47ade22 Merge: 90e1d9d 1e0f827 Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu Oct 14 18:29:16 2021 +0200 Merge branch 'geoapi-3.1'. This is mostly post 1.1-release cleanup and fixes of some of the bugs discovered in this process. NOTICE | 2 +- application/sis-console/src/main/artifact/bin/sis | 2 +- application/sis-javafx/src/main/artifact/bin/sisfx | 4 +- .../sis-javafx/src/main/artifact/bin/sisfx.bat | 2 +- .../org/apache/sis/internal/book/Assembler.java | 84 +++++++----- .../org/apache/sis/internal/book/package-info.java | 30 +++-- .../org/apache/sis/coverage/BandedCoverage.java | 24 +++- .../java/org/apache/sis/coverage/CategoryList.java | 4 +- .../org/apache/sis/coverage/SampleDimension.java | 46 +++++-- .../org/apache/sis/coverage/grid/GridCoverage.java | 21 ++- .../sis/coverage/grid/GridCoverageBuilder.java | 2 +- .../apache/sis/coverage/grid/GridDerivation.java | 136 ++----------------- .../org/apache/sis/coverage/grid/GridExtent.java | 29 +---- .../apache/sis/coverage/grid/GridExtentCRS.java | 36 +++++- .../org/apache/sis/coverage/grid/GridGeometry.java | 26 +--- .../apache/sis/coverage/grid/ImageRenderer.java | 32 +---- .../org/apache/sis/coverage/grid/package-info.java | 2 +- .../java/org/apache/sis/coverage/package-info.java | 2 +- .../org/apache/sis/feature/AbstractFeature.java | 66 ++++++++-- .../java/org/apache/sis/feature/DenseFeature.java | 12 +- .../java/org/apache/sis/feature/SparseFeature.java | 40 +++--- .../java/org/apache/sis/image/PixelIterator.java | 7 +- .../apache/sis/coverage/grid/GridExtentTest.java | 29 ++++- .../apache/sis/internal/jaxb/gts/package-info.java | 5 +- .../sis/metadata/iso/quality/AbstractElement.java | 3 +- .../iso/quality/AbstractTemporalAccuracy.java | 6 +- .../DefaultNonQuantitativeAttributeAccuracy.java | 6 +- .../main/java/org/apache/sis/xml/Namespaces.java | 14 +- .../main/java/org/apache/sis/xml/package-info.java | 2 +- .../java/org/apache/sis/test/sql/TestDatabase.java | 2 +- .../sis/test/xml/AnnotationConsistencyCheck.java | 2 +- .../org/apache/sis/geometry/CoordinateFormat.java | 16 +-- .../java/org/apache/sis/geometry/package-info.java | 2 +- .../main/java/org/apache/sis/io/wkt/Symbols.java | 26 +--- .../java/org/apache/sis/io/wkt/package-info.java | 2 +- .../org/apache/sis/referencing/datum/formulas.html | 24 ++-- .../apache/sis/referencing/datum/package-info.java | 3 +- .../sis/referencing/factory/sql/EPSGInstaller.java | 28 +++- .../operation/builder/LocalizationGridBuilder.java | 41 +----- .../operation/builder/package-info.java | 2 +- .../referencing/operation/matrix/MatrixSIS.java | 2 +- .../referencing/operation/transform/formulas.html | 54 +++++--- .../org/apache/sis/referencing/package-info.java | 3 +- .../sis/referencing/factory/TestFactorySource.java | 2 +- .../java/org/apache/sis/setup/Configuration.java | 2 +- .../main/java/org/apache/sis/util/Characters.java | 26 +--- .../apache/sis/util/logging/PerformanceLevel.java | 27 +--- .../org/apache/sis/util/logging/package-info.java | 2 +- .../java/org/apache/sis/util/package-info.java | 2 +- .../sis/util/logging/PerformanceLevelTest.java | 8 +- pom.xml | 1 - .../sis/storage/earthobservation/LandsatStore.java | 73 ----------- .../earthobservation/LandsatStoreProvider.java | 44 ------- .../sis/storage/earthobservation/package-info.java | 45 ------- .../java/org/apache/sis/storage/landsat/Band.java | 4 +- .../sis/storage/landsat/LandsatStoreProvider.java | 4 +- .../sis/internal/geotiff/SchemaModifier.java | 23 +++- .../apache/sis/internal/geotiff/package-info.java | 2 +- .../sis/storage/geotiff/ImageFileDirectory.java | 19 ++- .../apache/sis/storage/geotiff/package-info.java | 2 +- .../sis/storage/netcdf/NetcdfStoreProvider.java | 17 ++- .../apache/sis/internal/sql/feature/Analyzer.java | 16 +-- .../apache/sis/internal/sql/feature/Database.java | 6 +- .../sis/internal/sql/feature/FeatureAdapter.java | 6 +- .../sis/internal/sql/feature/FeatureAnalyzer.java | 12 +- .../sis/internal/sql/feature/FeatureStream.java | 9 +- .../sis/internal/sql/feature/QueryAnalyzer.java | 2 +- .../apache/sis/internal/sql/feature/Relation.java | 28 +++- .../sis/internal/sql/feature/SchemaModifier.java | 14 +- .../org/apache/sis/internal/sql/feature/Table.java | 8 +- .../sis/internal/sql/feature/TableAnalyzer.java | 35 +++-- .../sis/internal/sql/feature/package-info.java | 2 +- .../java/org/apache/sis/storage/sql/SQLStore.java | 33 +---- .../apache/sis/storage/sql/SQLStoreProvider.java | 5 +- .../org/apache/sis/storage/sql/package-info.java | 2 +- .../org/apache/sis/storage/sql/SQLStoreTest.java | 144 +++++++++++++++------ .../sis/internal/storage/TiledGridCoverage.java | 52 ++++++-- .../sis/internal/storage/csv/StoreProvider.java | 4 +- .../apache/sis/internal/storage/package-info.java | 2 +- .../sis/internal/storage/wkt/FirstKeywordPeek.java | 11 +- .../org/apache/sis/internal/storage/wkt/Store.java | 4 +- .../sis/internal/storage/wkt/StoreProvider.java | 4 +- .../sis/internal/storage/xml/AbstractProvider.java | 5 +- .../apache/sis/storage/CanNotProbeException.java | 78 +++++++++++ .../java/org/apache/sis/storage/DataStore.java | 19 --- .../org/apache/sis/storage/StorageConnector.java | 2 +- 86 files changed, 813 insertions(+), 874 deletions(-) diff --cc core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java index b34b324,6f03f88..ea3e0f7 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java @@@ -18,7 -18,11 +18,9 @@@ package org.apache.sis.coverage import java.util.List; import java.util.function.Function; + import org.opengis.geometry.Envelope; import org.opengis.geometry.DirectPosition; -import org.opengis.coverage.CannotEvaluateException; -import org.opengis.coverage.PointOutsideCoverageException; + import org.opengis.referencing.crs.CoordinateReferenceSystem; /** diff --cc core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java index 040cc2f,866b38d..c04057f --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java @@@ -61,10 -61,14 +61,11 @@@ import org.apache.sis.util.LenientCompa import org.apache.sis.util.iso.Types; import org.apache.sis.util.logging.Logging; import org.apache.sis.internal.system.Modules; +import org.apache.sis.coverage.CannotEvaluateException; +import org.apache.sis.coverage.PointOutsideCoverageException; -// Branch-dependent imports -import org.opengis.coverage.grid.GridEnvelope; -import org.opengis.coverage.grid.GridCoordinates; -import org.opengis.coverage.CannotEvaluateException; -import org.opengis.coverage.PointOutsideCoverageException; + /** * A range of grid coverage coordinates, also known as "grid envelope". * {@code GridExtent} are defined by {@linkplain #getLow() low} coordinates (often all zeros) @@@ -79,13 -83,9 +80,13 @@@ * <p>{@code GridExtent} instances are immutable and thread-safe. * The same instance can be shared by different {@link GridGeometry} instances.</p> * + * <div class="note"><b>Upcoming API generalization:</b> + * this class may implement the {@code GridEnvelope} interface in a future Apache SIS version. + * This is pending GeoAPI update.</div> + * * @author Martin Desruisseaux (IRD, Geomatys) * @author Alexis Manin (Geomatys) - * @version 1.1 + * @version 1.2 * @since 1.0 * @module */ diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java index 0deb035,dcc2fd6..711d3f7 --- a/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java +++ b/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java @@@ -823,14 -870,18 +859,18 @@@ public abstract class AbstractFeature i @Override public int hashCode() { int code = type.hashCode() * 37; - for (final AbstractIdentifiedType pt : type.getProperties(true)) { - final String name = pt.getName().toString(); - if (name != null) { // Paranoiac check. - final Object value = getPropertyValue(name); - if (value != null) { - code += name.hashCode() ^ value.hashCode(); + if (comparisonStart()) try { - for (final PropertyType pt : type.getProperties(true)) { ++ for (final AbstractIdentifiedType pt : type.getProperties(true)) { + final String name = pt.getName().toString(); + if (name != null) { // Paranoiac check. + final Object value = getPropertyValue(name); + if (value != null) { + code += name.hashCode() ^ value.hashCode(); + } } } + } finally { + comparisonEnd(); } return code; } @@@ -867,11 -918,15 +907,15 @@@ if (!type.equals(that.type)) { return false; } - for (final AbstractIdentifiedType pt : type.getProperties(true)) { - final String name = pt.getName().toString(); - if (!Objects.equals(getPropertyValue(name), that.getPropertyValue(name))) { - return false; + if (comparisonStart()) try { - for (final PropertyType pt : type.getProperties(true)) { ++ for (final AbstractIdentifiedType pt : type.getProperties(true)) { + final String name = pt.getName().toString(); + if (!Objects.equals(getPropertyValue(name), that.getPropertyValue(name))) { + return false; + } } + } finally { + comparisonEnd(); } } return true; diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java index 5e97429,0d3e38c..2426dee --- a/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java +++ b/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java @@@ -382,21 -388,25 +382,25 @@@ final class SparseFeature extends Abstr @Override public int hashCode() { int code = type.hashCode() * 37; - if (valuesKind == PROPERTIES) { - for (final Map.Entry<Integer,Object> entry : properties.entrySet()) { - final Object p = entry.getValue(); - final Object value; - if (p instanceof AbstractAttribute<?>) { - value = getAttributeValue((AbstractAttribute<?>) p); - } else if (p instanceof AbstractAssociation) { - value = getAssociationValue((AbstractAssociation) p); - } else { - value = null; + if (comparisonStart()) try { + if (valuesKind == PROPERTIES) { + for (final Map.Entry<Integer,Object> entry : properties.entrySet()) { + final Object p = entry.getValue(); + final Object value; - if (p instanceof Attribute<?>) { - value = getAttributeValue((Attribute<?>) p); - } else if (p instanceof FeatureAssociation) { - value = getAssociationValue((FeatureAssociation) p); ++ if (p instanceof AbstractAttribute<?>) { ++ value = getAttributeValue((AbstractAttribute<?>) p); ++ } else if (p instanceof AbstractAssociation) { ++ value = getAssociationValue((AbstractAssociation) p); + } else { + value = null; + } + code += Objects.hashCode(entry.getKey()) ^ Objects.hashCode(value); } - code += Objects.hashCode(entry.getKey()) ^ Objects.hashCode(value); + } else { + code += properties.hashCode(); } - } else { - code += properties.hashCode(); + } finally { + comparisonEnd(); } return code; } diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java index b9cea23,2b4ab6b..ca764b2 --- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java +++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/FeatureStream.java @@@ -391,8 -390,8 +390,8 @@@ final class FeatureStream extends Defer * @throws SQLException if an error occurs while executing the SQL statement. */ @Override - protected Spliterator<Feature> createSourceIterator() throws Exception { + protected Spliterator<AbstractFeature> createSourceIterator() throws Exception { - final String filter = (selection != null) ? selection.toString() : null; + final String filter = (selection != null && !selection.isEmpty()) ? selection.toString() : null; selection = null; // Let the garbage collector do its work. filterToSQL = null; diff --cc storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java index 9a9f9dd,094ceb4..6c4729d --- a/storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java +++ b/storage/sis-sqlstore/src/test/java/org/apache/sis/storage/sql/SQLStoreTest.java @@@ -199,11 -188,68 +186,68 @@@ public final strictfp class SQLStoreTes } /** + * Creates a {@link SQLStore} instance with the specified table as a resource, then tests some queries. + */ + private void testTableQuery(final StorageConnector connector, final ResourceDefinition table) throws Exception { + try (SQLStore store = new SQLStore(new SQLStoreProvider(), connector, table)) { + verifyFeatureTypes(store); + final Map<String,Integer> countryCount = new HashMap<>(); - try (Stream<Feature> features = store.findResource("Cities").features(false)) { ++ try (Stream<AbstractFeature> features = store.findResource("Cities").features(false)) { + features.forEach((f) -> verifyContent(f, countryCount)); + } + assertEquals(Integer.valueOf(2), countryCount.remove("CAN")); + assertEquals(Integer.valueOf(1), countryCount.remove("FRA")); + assertEquals(Integer.valueOf(1), countryCount.remove("JPN")); + assertTrue(countryCount.isEmpty()); + /* + * Verify overloaded stream operations (sorting, etc.). + */ + verifySimpleQuerySorting(store); + verifySimpleQueryWithLimit(store); + verifySimpleWhere(store); + verifyStreamOperations(store.findResource("Cities")); + } + canada = null; + } + + /** + * Verifies the feature types of the "Cities" resource and its dependencies. + * Feature properties should be in same order than columns in the database table, except for + * the generated identifier. Note that the country is an association to another feature. + * + * @param isCyclicAssociationAllowed whether dependencies are allowed to have an association + * to their dependent feature, which create a cyclic dependency. + */ + private void verifyFeatureTypes(final SQLStore store) throws DataStoreException { + verifyFeatureType(store.findResource("Cities").getType(), + new String[] {"sis:identifier", "pk:country", "country", "native_name", "english_name", "population", "parks"}, + new Object[] {null, String.class, "Countries", String.class, String.class, Integer.class, "Parks"}); + + verifyFeatureType(store.findResource("Countries").getType(), + new String[] {"sis:identifier", "code", "native_name"}, + new Object[] {null, String.class, String.class}); + /* + * If cyclic dependencies are allowed, an additional properties "FK_City" is present + * compared to the case where cyclic dependencies are avoided. + */ + final String[] expectedNames; + final Object[] expectedTypes; + if (isCyclicAssociationAllowed) { + expectedNames = new String[] {"sis:identifier", "pk:country", "FK_City", "city", "native_name", "english_name"}; + expectedTypes = new Object[] {null, String.class, "Cities", String.class, String.class, String.class}; + } else { + expectedNames = new String[] {"sis:identifier", "country", "city", "native_name", "english_name"}; + expectedTypes = new Object[] {null, String.class, String.class, String.class, String.class}; + } + verifyFeatureType(store.findResource("Parks").getType(), expectedNames, expectedTypes); + } + + /** * Verifies the result of analyzing the structure of the {@code "Cities"} table. */ - private static void verifyFeatureType(final FeatureType type, final String[] expectedNames, final Object[] expectedTypes) { + private static void verifyFeatureType(final DefaultFeatureType type, final String[] expectedNames, final Object[] expectedTypes) { int i = 0; - for (PropertyType pt : type.getProperties(false)) { + for (AbstractIdentifiedType pt : type.getProperties(false)) { if (i >= expectedNames.length) { fail("Returned feature-type contains more properties than expected. Example: " + pt.getName()); } @@@ -232,9 -278,8 +276,8 @@@ * * @param feature a feature returned by the stream. * @param countryCount number of time that the each country has been seen while iterating over the cities. - * @param isTable {@code true} if the resource is from a table, or {@code false} if from a query. */ - private void verifyContent(final AbstractFeature feature, final Map<String,Integer> countryCount, final boolean isTable) { - private void verifyContent(final Feature feature, final Map<String,Integer> countryCount) { ++ private void verifyContent(final AbstractFeature feature, final Map<String,Integer> countryCount) { final String city = feature.getPropertyValue("native_name").toString(); final City c; boolean isCanada = false; @@@ -415,8 -476,8 +472,8 @@@ { final FeatureSet cities = store.findResource("LargeCities"); final Map<String,Integer> countryCount = new HashMap<>(); - try (Stream<Feature> features = cities.features(false)) { + try (Stream<AbstractFeature> features = cities.features(false)) { - features.forEach((f) -> verifyContent(f, countryCount, false)); + features.forEach((f) -> verifyContent(f, countryCount)); } assertEquals(Integer.valueOf(1), countryCount.remove("CAN")); assertEquals(Integer.valueOf(1), countryCount.remove("FRA"));
