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

commit a83a431ca031215ada40d8adbbc530f87f66e1c1
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Sep 6 11:58:09 2021 +0200

    Modify (again) the way schema is customized, reverting back to an interface 
but specifying it with `OptionKey` instead than by the provider.
    The interface is kept in internal package for now, waiting to gain more 
experience with its use before to move (with changes) in public API.
---
 .../apache/sis/internal/sql/feature/Analyzer.java  | 20 +++++---
 .../sis/internal/sql/feature/SchemaModifier.java   | 18 +++++++-
 .../sis/internal/sql/feature/TableReference.java   | 28 ------------
 .../java/org/apache/sis/storage/sql/SQLStore.java  | 53 ++++------------------
 .../sql/feature/SelectionClauseWriterTest.java     | 45 +++++++-----------
 5 files changed, 57 insertions(+), 107 deletions(-)

diff --git 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
index 748ad0e..178b9f9 100644
--- 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
+++ 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
@@ -134,7 +134,7 @@ final class Analyzer {
     private transient NameSpace namespace;
 
     /**
-     * User-specified modification to the features. Shall not be {@code null}.
+     * User-specified modification to the features, or {@code null} if none.
      */
     private final SchemaModifier customizer;
 
@@ -145,7 +145,7 @@ final class Analyzer {
      * @param  connection  an existing connection to the database, used only 
for the lifetime of this {@code Analyzer}.
      * @param  metadata    value of {@code connection.getMetaData()} (provided 
because already known by caller).
      * @param  isSpatial   whether the database contains "GEOMETRY_COLUMNS" 
and "SPATIAL_REF_SYS" tables.
-     * @param  customizer  user-specified modification to the features. Shall 
not be {@code null}.
+     * @param  customizer  user-specified modification to the features, or 
{@code null} if none.
      */
     Analyzer(final Database<?> database, final Connection connection, final 
DatabaseMetaData metadata,
              final boolean isSpatial, final SchemaModifier customizer)
@@ -299,6 +299,16 @@ final class Analyzer {
     }
 
     /**
+     * Creates the feature type from the content of the given builder.
+     */
+    private FeatureType createFeatureType(final TableReference id, final 
FeatureTypeBuilder feature)
+            throws DataStoreException
+    {
+        feature.setName(id.getName(this));
+        return (customizer != null) ? customizer.editFeatureType(id, feature) 
: feature.build();
+    }
+
+    /**
      * Initializes the value getter on the given column.
      * This method shall be invoked only after geometry columns have been 
identifier.
      */
@@ -602,7 +612,6 @@ final class Analyzer {
          */
         @Override
         public FeatureType buildFeatureType() throws DataStoreException, 
SQLException {
-            feature.setName(id.getName(Analyzer.this));
             String remarks = id.freeText;
             if (id instanceof Relation) {
                 try (ResultSet reflect = metadata.getTables(id.catalog, 
schemaEsc, tableEsc, null)) {
@@ -617,7 +626,7 @@ final class Analyzer {
             if (remarks != null) {
                 feature.setDefinition(remarks);
             }
-            return customizer.editFeatureType(id, feature);
+            return createFeatureType(id, feature);
         }
     }
 
@@ -717,11 +726,10 @@ final class Analyzer {
          */
         @Override
         FeatureType buildFeatureType() throws DataStoreException {
-            feature.setName(id.getName(Analyzer.this));
             if (id.freeText != null) {
                 feature.setDefinition(id.freeText);
             }
-            return customizer.editFeatureType(id, feature);
+            return createFeatureType(id, feature);
         }
     }
 }
diff --git 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
index 728173e..8902ce3 100644
--- 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
+++ 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SchemaModifier.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.sql.feature;
 
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.setup.OptionKey;
 
 // Branch-dependent imports
 import org.opengis.feature.FeatureType;
@@ -26,6 +27,8 @@ import org.opengis.feature.FeatureType;
 /**
  * Modifies the feature types inferred from database analysis.
  *
+ * @todo May move to public API (in revised form) in a future version.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.1
  * @since   1.1
@@ -37,11 +40,24 @@ public interface SchemaModifier {
      * The given builder is initialized with all properties inferred from the 
table definition.
      * Implementation of this method can add, remove or modify properties.
      *
+     * <p>The default implementation returns {@code feature.build()} without 
making any change.</p>
+     *
      * @param  table    the catalog (if present), schema (if present) and 
table name.
      * @param  feature  a feature type builder initialized with all properties 
inferred by the analysis of a table.
      *                  This builder can be modified in-place.
      * @throws DataStoreException if an error occurred while modifying the 
feature type.
      * @return the feature type to use for the specified table.
      */
-    FeatureType editFeatureType(TableReference table, FeatureTypeBuilder 
feature) throws DataStoreException;
+    default FeatureType editFeatureType(TableReference table, 
FeatureTypeBuilder feature) throws DataStoreException {
+        return feature.build();
+    }
+
+    /**
+     * The option for declaring a schema modifier at {@link 
org.apache.sis.storage.sql.SQLStore} creation time.
+     *
+     * @todo if we move this key in public API in the future, then it would be 
a
+     *       value in existing {@link org.apache.sis.storage.DataOptionKey} 
class.
+     */
+    OptionKey<SchemaModifier> OPTION = new 
OptionKey<SchemaModifier>("SCHEMA_MODIFIER", SchemaModifier.class) {
+    };
 }
diff --git 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableReference.java
 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableReference.java
index 3fdcb81..eef3f54 100644
--- 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableReference.java
+++ 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableReference.java
@@ -83,34 +83,6 @@ public class TableReference {
     }
 
     /**
-     * Returns the components of the table identification.
-     * The returned array has a length of 1, 2 or 3 with the following content:
-     *
-     * <ul>
-     *   <li>If a catalog name exists, then the array has a length of 3 with 
<var>catalog name</var>,
-     *       <var>schema name</var> (possibly null) and <var>table name</var> 
elements in that order.</li>
-     *   <li>Otherwise if a schema name exists, then the array has a length of 
2 with
-     *       <var>schema name</var> and <var>table name</var> elements in that 
order.</li>
-     *   <li>Otherwise the array has a length of 1 with the <var>table 
name</var> element.</li>
-     * </ul>
-     *
-     * @return the catalog (if present), schema (if present) and table names.
-     */
-    @SuppressWarnings("fallthrough")
-    public final String[] getNames() {
-        final String c = trimOrNull(catalog);
-        final String s = trimOrNull(schema);
-        final String[] names = new String[c != null ? 3 : s != null ? 2 : 1];
-        int n = 0;
-        switch (names.length) {
-            default: names[n++] = c;      // Fall through.
-            case 2:  names[n++] = s;
-            case 1:  names[n] = table;
-        }
-        return names;
-    }
-
-    /**
      * Creates a name for the feature type backed by this table.
      * This method does not cache the value;
      * caller is expected to invoke only once and store the name.
diff --git 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
index bd7d41f..dabf372 100644
--- 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
+++ 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
@@ -34,7 +34,6 @@ import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.event.StoreEvent;
 import org.apache.sis.storage.event.StoreListener;
 import org.apache.sis.storage.event.WarningEvent;
-import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.internal.sql.feature.Database;
 import org.apache.sis.internal.sql.feature.Resources;
 import org.apache.sis.internal.sql.feature.SchemaModifier;
@@ -45,9 +44,6 @@ import org.apache.sis.setup.OptionKey;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Exceptions;
 
-// Branch-dependent imports
-import org.opengis.feature.FeatureType;
-
 
 /**
  * A data store capable to read and create features from a spatial database.
@@ -100,6 +96,12 @@ public class SQLStore extends DataStore implements 
Aggregate {
     private Metadata metadata;
 
     /**
+     * The user-specified method for customizing the schema inferred by table 
analysis.
+     * This is {@code null} if there is none.
+     */
+    private final SchemaModifier customizer;
+
+    /**
      * Creates a new instance for the given storage.
      * The given {@code connector} shall contain a {@link DataSource}.
      * The given table names shall be qualified names of 1, 2 or 3 components.
@@ -138,6 +140,7 @@ public class SQLStore extends DataStore implements 
Aggregate {
             }
         }
         this.tableNames = tableNames;
+        this.customizer = connector.getOption(SchemaModifier.OPTION);
     }
 
     /**
@@ -169,21 +172,12 @@ public class SQLStore extends DataStore implements 
Aggregate {
     }
 
     /**
-     * Returns customizations on the feature type inferred from the database 
analysis.
-     * This is a workaround for giving access to protected method {@code 
customize(…)}
-     * from a different package.
-     */
-    private SchemaModifier customizer() {
-        return (id,f) -> customize(id.getNames(), f);
-    }
-
-    /**
      * Returns the database model, analyzing the database schema when first 
needed.
      */
     private synchronized Database<?> model() throws DataStoreException {
         if (model == null) {
             try (Connection c = source.getConnection()) {
-                model = Database.create(this, source, c, geomLibrary, 
tableNames, customizer(), listeners);
+                model = Database.create(this, source, c, geomLibrary, 
tableNames, customizer, listeners);
             } catch (DataStoreException e) {
                 throw e;
             } catch (Exception e) {
@@ -202,7 +196,7 @@ public class SQLStore extends DataStore implements 
Aggregate {
      */
     private Database<?> model(final Connection c) throws Exception {
         if (model == null) {
-            model = Database.create(this, source, c, geomLibrary, tableNames, 
customizer(), listeners);
+            model = Database.create(this, source, c, geomLibrary, tableNames, 
customizer, listeners);
         }
         return model;
     }
@@ -255,35 +249,6 @@ public class SQLStore extends DataStore implements 
Aggregate {
     }
 
     /**
-     * Invoked after analysis of a table for allowing modifications of the 
inferred feature type.
-     * The given builder is initialized with all properties inferred from the 
table definition.
-     * Implementation of this method can add, remove or modify properties.
-     *
-     * <p>The database table for which a feature type is created is identified 
by the {@code table} argument.
-     * This argument is an array of length of 1, 2 or 3 with the following 
content:</p>
-     *
-     * <ul>
-     *   <li>If a catalog name exists, then the array has a length of 3 with 
<var>catalog name</var>,
-     *       <var>schema name</var> (possibly null) and <var>table name</var> 
elements in that order.</li>
-     *   <li>Otherwise if a schema name exists, then the array has a length of 
2 with
-     *       <var>schema name</var> and <var>table name</var> elements in that 
order.</li>
-     *   <li>Otherwise the array has a length of 1 with the <var>table 
name</var> element.</li>
-     * </ul>
-     *
-     * The default implementation returns {@code feature.build()} without 
making any change.
-     *
-     * @param  table    the catalog (if present), schema (if present) and 
table name.
-     * @param  feature  a feature type builder initialized with all properties 
inferred by the analysis of a table.
-     *                  This builder can be modified in-place.
-     * @return the feature type to use for the specified table.
-     *
-     * @since 1.1
-     */
-    protected FeatureType customize(String[] table, FeatureTypeBuilder 
feature) {
-        return feature.build();
-    }
-
-    /**
      * Returns the resources (features or coverages) in this SQL store.
      * The list contains only the tables explicitly named at construction time.
      *
diff --git 
a/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
 
b/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
index 5707e9a..357984f 100644
--- 
a/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
+++ 
b/storage/sis-sqlstore/src/test/java/org/apache/sis/internal/sql/feature/SelectionClauseWriterTest.java
@@ -19,8 +19,6 @@ package org.apache.sis.internal.sql.feature;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStore;
-import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.sql.SQLStore;
 import org.apache.sis.storage.sql.SQLStoreProvider;
 import org.apache.sis.feature.builder.AttributeTypeBuilder;
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
@@ -50,7 +48,7 @@ import org.opengis.filter.SpatialOperator;
  * @since   1.1
  * @module
  */
-public final strictfp class SelectionClauseWriterTest extends TestCase {
+public final strictfp class SelectionClauseWriterTest extends TestCase 
implements SchemaModifier {
     /**
      * The factory to use for creating the filter objects.
      */
@@ -69,30 +67,6 @@ public final strictfp class SelectionClauseWriterTest 
extends TestCase {
     }
 
     /**
-     * The data store to use for testing purpose.
-     * This data store modifies the schema for simulating a spatial database.
-     */
-    private static final class Store extends SQLStore {
-        /**
-         * Creates a new data store.
-         */
-        Store(final StorageConnector connector) throws DataStoreException {
-            super(null, connector, SQLStoreProvider.createTableName(null, 
null, Database.WILDCARD));
-        }
-
-        /**
-         * Invoked when the feature type interred from the test database is 
created.
-         * This method add a CRS on a property for testing purpose.
-         */
-        @Override
-        protected FeatureType customize(final String[] table, final 
FeatureTypeBuilder builder) {
-            assertArrayEquals(new String[] {"APP", "TEST"}, table);
-            ((AttributeTypeBuilder<?>) 
builder.getProperty("BETA")).setCRS(HardCodedCRS.WGS84);
-            return super.customize(table, builder);
-        }
-    }
-
-    /**
      * Tests on Derby.
      *
      * @throws Exception if an error occurred while testing the database.
@@ -103,7 +77,9 @@ public final strictfp class SelectionClauseWriterTest 
extends TestCase {
             db.executeSQL(SelectionClauseWriterTest.class,
                     "CREATE TABLE TEST (ALPHA INTEGER, BETA INTEGER, GAMMA 
INTEGER, PI FLOAT);");
 
-            try (DataStore store = new Store(new StorageConnector(db.source))) 
{
+            final StorageConnector connector = new StorageConnector(db.source);
+            connector.setOption(SchemaModifier.OPTION, this);
+            try (DataStore store = new SQLStoreProvider().open(connector)) {
                 table = (Table) store.findResource("TEST");
                 testSimpleFilter();
                 testGeometricFilter();
@@ -137,6 +113,19 @@ public final strictfp class SelectionClauseWriterTest 
extends TestCase {
     }
 
     /**
+     * Invoked when the feature type interred from the test database is 
created.
+     * This method add a CRS on a property for testing purpose.
+     */
+    @Override
+    public FeatureType editFeatureType(final TableReference table, final 
FeatureTypeBuilder feature) {
+        assertEquals("",     table.catalog);
+        assertEquals("APP",  table.schema);
+        assertEquals("TEST", table.table);
+        ((AttributeTypeBuilder<?>) 
feature.getProperty("BETA")).setCRS(HardCodedCRS.WGS84);
+        return feature.build();
+    }
+
+    /**
      * Verifies that a spatial operator transforms literal value before-hand 
if possible.
      */
     private void testGeometricFilterWithTransform() {

Reply via email to