Revision: 4609
          http://sourceforge.net/p/jump-pilot/code/4609
Author:   elnico
Date:     2015-12-13 15:02:36 +0000 (Sun, 13 Dec 2015)
Log Message:
-----------
Spatialite and MySQL/MariaDB support:
refactor, new connection icons, better error management, Adhoc query support 
for all databases types

Modified Paths:
--------------
    core/trunk/ChangeLog
    core/trunk/pom.xml
    core/trunk/scripts/default-plugins.xml
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java
    
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSMetadata.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDataStoreDriver.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesFeatureInputStream.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesResultSetConverter.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesValueConverterFactory.java
    core/trunk/src/com/vividsolutions/jump/workbench/model/LayerManager.java
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ConnectionManagerPanel.java
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/RunDatastoreQueryPlugIn.java
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/renderer/ImageCachingRenderer.java
    core/trunk/src/language/jump.properties
    core/trunk/src/language/jump_de.properties
    core/trunk/src/language/jump_es.properties
    core/trunk/src/language/jump_fi.properties
    core/trunk/src/language/jump_fr.properties
    core/trunk/src/language/jump_hu.properties
    core/trunk/src/language/jump_it.properties
    core/trunk/src/language/jump_ja_JP.properties
    core/trunk/src/language/jump_ml.properties
    core/trunk/src/language/jump_pt.properties
    core/trunk/src/language/jump_pt_BR.properties
    core/trunk/src/language/jump_ta_IN.properties
    core/trunk/src/language/jump_te.properties
    core/trunk/src/language/jump_zh_CN.properties
    core/trunk/src/language/jump_zh_HK.properties
    
core/trunk/src/org/openjump/core/ui/plugin/datastore/AddDataStoreLayerWizard.java

Added Paths:
-----------
    core/trunk/licenseheader.txt
    core/trunk/src/com/vividsolutions/jump/datastore/mariadb/
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSMetadata.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreDriver.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreExtension.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbFeatureInputStream.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbResultSetConverter.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbSQLBuilder.java
    
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbValueConverterFactory.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreExtension.java
    core/trunk/src/com/vividsolutions/jump/datastore/spatialite/
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometricColumnType.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometryColumnsLayout.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSMetadata.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreDriver.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreExtension.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteFeatureInputStream.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteResultSetConverter.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteSQLBuilder.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteValueConverterFactory.java
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ko_mysql.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ko_oracle.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ko_pg.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ko_sqlite.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ko_sqlserver.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ok_mysql.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ok_oracle.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ok_pg.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ok_sqlite.png
    
core/trunk/src/com/vividsolutions/jump/workbench/ui/plugin/datastore/ok_sqlserver.png

Removed Paths:
-------------
    
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java

Modified: core/trunk/ChangeLog
===================================================================
--- core/trunk/ChangeLog        2015-12-13 14:24:16 UTC (rev 4608)
+++ core/trunk/ChangeLog        2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,5 +1,21 @@
 # for display continuity sake please use 2 spaces instead of tabs
 
+2015-13-11 Nicolas Ribot <nicolas.ri...@gmail.com>
+  * Spatial Databases support enhanced: support for Oracle Spatial, 
MySQL/MariaDB
+    Spatialite added.
+  * FilterQuery and Adhoc queries supported for these databases
+  * Error detection in case of bad WHERE clause detected when loading a layer 
(layer
+    removed from Panel)
+  * New connection icons according to database type
+  * Oracle Spatial: reads SDO_GEOMETRY with geotools code
+                    reflection used on com.oracle.* methods to avoid jar 
dependence
+                    (ede code)
+  * MariaDB: supports WKB and natives binary types, thanks to code from Larry 
Reeder
+  * Spatialite: supports Spatialite binary type, WKB and WKT.
+                supports several geometry_column metadata table layout (code 
from 
+    Larry Reeder DB Plugin)
+  * 
+
 2015-12-11 mmichaud <m.michael.mich...@orange.fr>
   * Switch pom to official jts-1.14 release
 

Added: core/trunk/licenseheader.txt
===================================================================
--- core/trunk/licenseheader.txt                                (rev 0)
+++ core/trunk/licenseheader.txt        2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,8 @@
+<#if licenseFirst??>
+${licenseFirst}
+</#if>
+${licensePrefix}Here comes the text of your license
+${licensePrefix}Each line should be prefixed with ${licensePrefix}
+<#if licenseLast??>
+${licenseLast}
+</#if>
\ No newline at end of file

Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml  2015-12-13 14:24:16 UTC (rev 4608)
+++ core/trunk/pom.xml  2015-12-13 15:02:36 UTC (rev 4609)
@@ -902,5 +902,34 @@
             <artifactId>org-netbeans-swing-outline</artifactId>
             <version>7.2</version>
         </dependency>
+        <!--for spatial database plugin-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.34</version>
+        </dependency>
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.8.7</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.oracle</groupId>
+            <artifactId>ojdbc6</artifactId>
+            <version>11.2.0.3</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt2-oracle-spatial</artifactId>
+            <version>2.3.2</version>
+            <scope>runtime</scope>
+        </dependency>
+<!--        <dependency>
+            <groupId>org.openjump.core.ui.plugin.datastore</groupId>
+            <artifactId>SpatialDatabasesPlugin</artifactId>
+            <version>0.1-SNAPSHOT</version>
+        </dependency>-->
     </dependencies>
 </project>

Modified: core/trunk/scripts/default-plugins.xml
===================================================================
--- core/trunk/scripts/default-plugins.xml      2015-12-13 14:24:16 UTC (rev 
4608)
+++ core/trunk/scripts/default-plugins.xml      2015-12-13 15:02:36 UTC (rev 
4609)
@@ -26,8 +26,15 @@
                
org.openjump.core.ui.plugin.datastore.postgis.SaveToPostGISPlugIn
        </plug-in>
        <extension>
-               com.vividsolutions.jump.datastore.OracleDataStoreExtension
+               
com.vividsolutions.jump.datastore.oracle.OracleDataStoreExtension
        </extension>
+        <!--adds other Spatial databases extensions-->
+       <extension>
+               
com.vividsolutions.jump.datastore.mariadb.MariadbDataStoreExtension
+       </extension>
+       <extension>
+               
com.vividsolutions.jump.datastore.spatialite.SpatialiteDataStoreExtension
+       </extension>
        <plug-in>
                
org.openjump.core.ccordsys.srid.EnsureAllLayersHaveSRIDStylePlugIn
        </plug-in>

Deleted: 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java  
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java  
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,60 +0,0 @@
-package com.vividsolutions.jump.datastore;
-
-import static 
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.JDBC_CLASS;
-import static 
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.GT_SDO_CLASS_NAME;
-
-import com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver;
-import com.vividsolutions.jump.workbench.WorkbenchContext;
-import com.vividsolutions.jump.workbench.plugin.Extension;
-import com.vividsolutions.jump.workbench.plugin.PlugInContext;
-import java.sql.Driver;
-import java.sql.DriverManager;
-
-/**
- * 
- * @author nicolas ribot
- */
-public class OracleDataStoreExtension extends Extension {
-  private static boolean disabled = false;
-
-  public String getName() {
-    return "Oracle Spatial Datastore Extension";
-  }
-
-  public String getVersion() {
-    return "0.3 (2015-12-04)";
-  }
-
-  public String getMessage() {
-    return disabled ? "Disabled: Missing either ojdbc6.jar or 
gt2-oracle-spatial-2.x.jar in classpath"
-        : "";
-  }
-
-  public void configure(PlugInContext context) throws Exception {
-    WorkbenchContext wbc = context.getWorkbenchContext();
-
-    // registers the OracleDataStore driver to the system:
-    try {
-      ClassLoader pluginLoader = wbc.getWorkbench().getPlugInManager()
-          .getClassLoader();
-      // check for ojdbc6.jar
-      DriverManager.registerDriver(
-          (Driver)Class.forName(JDBC_CLASS, true, pluginLoader).newInstance());
-
-      // check for gt2-oracle-spatial-2.x.jar
-      Class.forName(GT_SDO_CLASS_NAME, true, pluginLoader)
-          .newInstance();
-      // register the datastore
-      wbc.getRegistry().createEntry(DataStoreDriver.REGISTRY_CLASSIFICATION,
-          new OracleDataStoreDriver());
-    } catch (Exception e) {
-      disabled = true;
-      wbc.getWorkbench()
-          .getFrame()
-          .log(
-              "Oracle Spatial Data Store disabled:\n\t" + e.toString() 
-            + "\n\tOracle JDBC Driver and gt2-oracle-spatial-2.x.jar must 
exist in the classpath !", this.getClass());
-    }
-  }
-
-}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSConnection.java
                           (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSConnection.java
   2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,87 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.datastore.AdhocQuery;
+import com.vividsolutions.jump.datastore.FilterQuery;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import com.vividsolutions.jump.io.FeatureInputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ *
+ * @author nicolas
+ */
+public class MariadbDSConnection extends SpatialDatabasesDSConnection {
+
+    public MariadbDSConnection(Connection con) {
+        super(con); // ?
+        connection = con;
+        this.dbMetadata = new MariadbDSMetadata(this);
+    }
+    
+    @Override
+    public SpatialDatabasesSQLBuilder getSqlBuilder(SpatialReferenceSystemID 
srid, String[] colNames) {
+      return new MariadbSQLBuilder(this.dbMetadata, srid, colNames);
+    }
+
+    /**
+     * Executes a filter query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeFilterQuery(FilterQuery query) throws 
SQLException {
+        SpatialReferenceSystemID srid = 
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
+        String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
+
+        MariadbSQLBuilder builder = 
(MariadbSQLBuilder)this.getSqlBuilder(srid, colNames);
+        String queryString = builder.getSQL(query);
+
+        // [mmichaud 2013-08-07] add a parameter for database primary key name
+        return new MariadbFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
+    }
+    
+    /**
+     * Executes an adhoc query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
+        String queryString = query.getQuery();
+        MariadbFeatureInputStream ifs = new 
MariadbFeatureInputStream(connection, queryString, query.getPrimaryKey());
+        
+        // Nicolas Ribot: getting FeatureSchema here actually runs the query: 
if an error occurs, must trap it here
+        FeatureSchema fs = null;
+        try {
+          fs = ifs.getFeatureSchema();
+        } catch (Exception e) {
+          throw new Exception(
+              
I18N.get(com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                  +".SQL-error") + e.getMessage());
+        }
+        
+        if (fs.getGeometryIndex() < 0) {
+            throw new Exception(I18N.get(
+                
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                +".resultset-must-have-a-geometry-column"));
+        }
+        return ifs;
+        
+    }
+    
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSMetadata.java 
                            (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDSMetadata.java 
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,63 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import com.vividsolutions.jump.datastore.spatialdatabases.*;
+import com.vividsolutions.jump.datastore.GeometryColumn;
+import java.util.List;
+
+public class MariadbDSMetadata extends SpatialDatabasesDSMetadata {
+
+    public MariadbDSMetadata(DataStoreConnection con) {
+        conn = con;
+        // TODO: defaults to database name ?
+        defaultSchemaName = "";
+        // TODO: use bind parameters to avoid SQL injection
+        datasetNameQuery = "select distinct t.TABLE_SCHEMA, t.TABLE_NAME \n" +
+            "from information_schema.TABLES t join information_schema.COLUMNS 
C \n" +
+            "  on t.TABLE_NAME = c.TABLE_NAME and t.TABLE_SCHEMA = 
c.TABLE_SCHEMA\n" +
+            "where t.TABLE_TYPE not in ('SYSTEM VIEW')\n" +
+            "and c.COLUMN_TYPE = 'geometry';";
+        spatialDbName = "MariaDB/MySQL";
+        spatialExtentQuery1 = "select 
st_asBinary(st_envelope(Geomfromtext(concat(concat(\"geometrycollection(\",group_concat(astext(%s))),\")\"))))
 from %s.%s;";
+        // NO metadata => same query is defined.
+        spatialExtentQuery2 = spatialExtentQuery1;
+        geoColumnsQuery = "select c.COLUMN_NAME, 0, 'geometry' \n" +
+            "from information_schema.TABLES t join information_schema.COLUMNS 
C \n" +
+            "  on t.TABLE_NAME = c.TABLE_NAME and t.TABLE_SCHEMA = 
c.TABLE_SCHEMA\n" +
+            "where t.TABLE_TYPE not in ('SYSTEM VIEW')\n" +
+            "and t.TABLE_SCHEMA = '%s' and t.TABLE_NAME = '%s'\n" +
+            "and c.COLUMN_TYPE = 'geometry'";
+        sridQuery = "select case when min(st_srid(%s)) <> max(st_srid(%s)) 
then 0 else min(st_srid(%s)) end as srid\n" +
+                "from %s.%s";
+    }
+
+    @Override
+    public String getSpatialExtentQuery1(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery1, attributeName, schema, 
table);
+    }
+
+    @Override
+    public String getSpatialExtentQuery2(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery2, attributeName, schema, 
table);
+    }
+
+    @Override
+    public String getGeoColumnsQuery(String datasetName) {
+        return String.format(this.geoColumnsQuery, getSchemaName(datasetName), 
getTableName(datasetName));
+    }
+
+    @Override
+    public String getSridQuery(String schemaName, String tableName, String 
colName) {
+        // TODO
+        return String.format(this.sridQuery, colName, colName, colName, 
schemaName, tableName);
+    }
+    
+    @Override
+    public List<GeometryColumn> getGeometryAttributes(String datasetName) {
+        String sql = this.getGeoColumnsQuery(datasetName);
+        // TODO: manage srid by executing 2 SQL queries: one for geo cols, one 
for
+        // srids.
+        return getGeometryAttributes(sql, datasetName);
+    }
+
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreDriver.java
                                (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreDriver.java
        2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,34 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
+import com.vividsolutions.jump.parameter.ParameterList;
+
+/**
+ * A driver for supplying {@link SpatialDatabaseDSConnection}s
+ */
+public class MariadbDataStoreDriver
+    extends SpatialDatabasesDataStoreDriver {
+
+      // TODO: uniformize
+    public final static String JDBC_CLASS = "com.mysql.jdbc.Driver";
+
+    public MariadbDataStoreDriver() {
+        this.driverName = "MariaDB/MySQL";
+        this.jdbcClass = "com.mysql.jdbc.Driver";
+        this.urlPrefix = "jdbc:mysql://";
+    }
+    
+    /**
+     * returns the right type of DataStoreConnection
+     * @param params
+     * @return
+     * @throws Exception 
+     */
+    @Override
+    public DataStoreConnection createConnection(ParameterList params)
+        throws Exception {
+        DataStoreConnection ret = super.createConnection(params);
+        return new MariadbDSConnection(ret.getConnection());
+    }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreExtension.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreExtension.java
                             (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbDataStoreExtension.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,56 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jump.datastore.DataStoreDriver;
+import static 
com.vividsolutions.jump.datastore.mariadb.MariadbDataStoreDriver.JDBC_CLASS;
+
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+import com.vividsolutions.jump.workbench.plugin.Extension;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import java.sql.Driver;
+import java.sql.DriverManager;
+
+/**
+ * 
+ * @author nicolas ribot
+ */
+public class MariadbDataStoreExtension extends Extension {
+  private static boolean disabled = false;
+
+  public String getName() {
+    return "MariaDB/MySQL Spatial Datastore Extension";
+  }
+
+  public String getVersion() {
+    return "0.3 (2015-12-04)";
+  }
+
+  public String getMessage() {
+    return disabled ? "Disabled: Missing mysql-connector-java-<version>.jar in 
classpath"
+        : "";
+  }
+
+  public void configure(PlugInContext context) throws Exception {
+    WorkbenchContext wbc = context.getWorkbenchContext();
+
+    // registers the MariaDBDataStore driver to the system:
+    try {
+      ClassLoader pluginLoader = wbc.getWorkbench().getPlugInManager()
+          .getClassLoader();
+      // check for ojdbc6.jar
+      DriverManager.registerDriver(
+          (Driver)Class.forName(JDBC_CLASS, true, pluginLoader).newInstance());
+
+      // register the datastore
+      wbc.getRegistry().createEntry(DataStoreDriver.REGISTRY_CLASSIFICATION,
+          new MariadbDataStoreDriver());
+    } catch (Exception e) {
+      disabled = true;
+      wbc.getWorkbench()
+          .getFrame()
+          .log(
+              "MariaDB Spatial Data Store disabled:\n\t" + e.toString() 
+            + "\n\tMariaDB JDBC Driver (mysql-connector-java-<version>.jar) 
must exist in the classpath !", this.getClass());
+    }
+  }
+
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbFeatureInputStream.java
                             (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbFeatureInputStream.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,30 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+/**
+ *
+ * @author nicolas Ribot
+ */
+public class MariadbFeatureInputStream extends 
SpatialDatabasesFeatureInputStream {
+    public MariadbFeatureInputStream(Connection conn, String queryString) {
+        super(conn, queryString);
+    }
+
+    public MariadbFeatureInputStream(Connection conn, String queryString, 
String externalIdentifier) {
+        super(conn, queryString, externalIdentifier);
+    }
+    
+    /**
+     * Returns a MariadbResultSetConverter
+     * @param rs
+     * @return 
+     */
+    @Override
+    protected SpatialDatabasesResultSetConverter 
getResultSetConverter(ResultSet rs) {
+      return new MariadbResultSetConverter(conn, rs);
+    }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbResultSetConverter.java
                             (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbResultSetConverter.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,22 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+/**
+ * Implements the mapping between a result set and a {@link FeatureSchema} and
+ * {@link Feature} set.
+ *
+ * This is a transient worker class, whose lifetime should be no longer than 
the
+ * lifetime of the provided ResultSet
+ */
+public class MariadbResultSetConverter extends 
SpatialDatabasesResultSetConverter {
+
+    public MariadbResultSetConverter(Connection conn, ResultSet rs) {
+        super(conn, rs);
+        this.odm = new MariadbValueConverterFactory(conn);
+    }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbSQLBuilder.java 
                            (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbSQLBuilder.java 
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,85 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jump.datastore.FilterQuery;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSMetadata;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+
+
+/**
+ * Creates SQL query strings for a Spatial database.
+ * To be overloaded by classes implementing a spatial database support.
+ */
+public class MariadbSQLBuilder extends SpatialDatabasesSQLBuilder {
+
+  public MariadbSQLBuilder(SpatialDatabasesDSMetadata dsMetadata, 
SpatialReferenceSystemID defaultSRID, String[] colNames) {
+    super(dsMetadata, defaultSRID, colNames);
+  }
+
+  /**
+   * Builds a valid SQL spatial query with the given spatial filter.
+   * @param query
+   * @return a SQL query to get column names
+   */
+  @Override
+  public String getSQL(FilterQuery query) {
+    StringBuilder qs = new StringBuilder();
+    //HACK
+    qs.append("SELECT ");
+    qs.append(getColumnListSpecifier(colNames, 
query.getGeometryAttributeName()));
+    qs.append(" FROM ").append(query.getDatasetName()).append("");
+    qs.append(" t WHERE ");
+    qs.append(buildBoxFilter(query));
+
+    String whereCond = query.getCondition();
+    if (whereCond != null) {
+      qs.append(" AND ");
+      qs.append(whereCond);
+    }
+    int limit = query.getLimit();
+    if (limit != 0 && limit != Integer.MAX_VALUE) {
+      qs.append(" LIMIT ").append(limit);
+    }
+    return qs.toString();
+  };
+
+  /**
+   * Returns the string representing a SQL column definition.
+   * Implementors should take care of column names (case, quotes)
+   * @param colNames
+   * @param geomColName
+   * @return column list
+   */
+  @Override
+  protected String getColumnListSpecifier(String[] colNames, String 
geomColName) {
+    // Added double quotes around each column name in order to read mixed case 
table names
+    // correctly [mmichaud 2007-05-13]
+    StringBuilder buf = new StringBuilder();
+    //buf.append("ST_AsBinary(").append(geomColName).append(") as 
").append(geomColName);
+    // Nicolas Ribot: 12 dec: Native reader supported now
+    buf.append(geomColName);
+    for (String colName : colNames) {
+      if (! geomColName.equalsIgnoreCase(colName)) {
+        buf.append(",").append(colName).append("");
+      }
+    }
+    return buf.toString();
+  }
+
+  @Override
+  protected String buildBoxFilter(FilterQuery query) {
+    Envelope env = query.getFilterGeometry().getEnvelopeInternal();
+
+    // Example of MariaDB SQL: where st_Intersects(b.geom, 
st_polygonFromText('POLYGON((4 4, 5 4, 5 5, 4 5, 4 4))'))
+    StringBuilder buf = new StringBuilder();
+    
buf.append("st_intersects(").append(query.getGeometryAttributeName()).append(", 
st_polygonFromText('POLYGON((");
+    buf.append(env.getMinX()).append(" ").append(env.getMinY()).append(",")
+        .append(env.getMaxX()).append(" ").append(env.getMinY()).append(",")
+        .append(env.getMaxX()).append(" ").append(env.getMaxY()).append(",")
+        .append(env.getMinX()).append(" ").append(env.getMaxY()).append(",")
+        .append(env.getMinX()).append(" ").append(env.getMinY());
+    buf.append("))'))");
+    return buf.toString();
+  }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbValueConverterFactory.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbValueConverterFactory.java
                          (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/mariadb/MariadbValueConverterFactory.java
  2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,128 @@
+package com.vividsolutions.jump.datastore.mariadb;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKBReader;
+import com.vividsolutions.jump.datastore.jdbc.ValueConverter;
+import com.vividsolutions.jump.datastore.jdbc.ValueConverterFactory;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesValueConverterFactory;
+import com.vividsolutions.jump.feature.AttributeType;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+/**
+ *
+ */
+public class MariadbValueConverterFactory extends 
SpatialDatabasesValueConverterFactory {
+
+  protected final ValueConverter MYSQLWKB_GEOMETRY_MAPPER = new 
MariadbValueConverterFactory.MySQLWKBGeometryValueConverter();
+
+  public MariadbValueConverterFactory(Connection conn) {
+    super(conn);
+  }
+
+  @Override
+  public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
+      throws SQLException {
+    String dbTypeName = rsm.getColumnTypeName(columnIndex);
+
+        // manages 2 cases: type retrieved from Database metadata (DataStore 
Panel)
+    // and from direct Adhoc query (type of the column resultset).
+    if ("LONGBLOB".equalsIgnoreCase(dbTypeName) || 
"GEOMETRY".equalsIgnoreCase(dbTypeName)) // WKB is now the normal way to store 
geometry in PostGIS [mmichaud 2007-05-13]
+    {
+      return MYSQLWKB_GEOMETRY_MAPPER;
+    }
+
+    // handle the standard types
+    ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm, 
columnIndex);
+    if (stdConverter != null) {
+      return stdConverter;
+    }
+
+    // default - can always show it as a string!
+    return ValueConverterFactory.STRING_MAPPER;
+  }
+
+  /**
+   * Custom WKB reader for MySQL/MariaDB (cf Jump DB Query plugin source code).
+   * Provides support for both Binary format is blob with 4 empty bytes as the
+   * beginning From Larry Reader code
+   */
+  class MySQLWKBGeometryValueConverter implements ValueConverter {
+
+    public AttributeType getType() {
+      return AttributeType.GEOMETRY;
+    }
+
+    public Object getValue(ResultSet rs, int columnIndex)
+        throws IOException, SQLException, ParseException {
+      byte[] bytes = rs.getBytes(columnIndex);
+
+      Geometry geometry = null;
+      if (bytes == null || bytes.length < 5) {
+        geometry = wktReader.read("GEOMETRYCOLLECTION EMPTY");
+      } else {
+        boolean nativeFormat = appearsToBeNativeFormat(bytes);
+        WKBReader wr = new WKBReader();
+
+        if (nativeFormat) {
+
+                //copy the byte array, removing the first four
+          //zero bytes added by mysql
+          byte[] wkb = new byte[bytes.length - 4];
+          System.arraycopy(bytes, 4, wkb, 0, wkb.length);
+          geometry = wr.read(wkb);
+        } else {
+          // true WKB format as from st_asbinary
+          geometry = wr.read(bytes);
+          }
+      } 
+
+      return geometry;
+    }
+  }
+
+  /**
+   * From Larry Reeder, code to detect MySQL spatial type.
+   * Added detection code for older/strange mysql geometry format beginning 
with 6A 08 00 00 
+   * TODO: make method public static in its package ?
+   * The JUMP DB Query Plugin is Copyright (C) 2007  Larry Reeder
+   *  JUMP is Copyright (C) 2003 Vivid Solutions
+   * 
+   */
+  private boolean appearsToBeNativeFormat(final byte[] geometryAsBytes) {
+      //use a heuristic here.  MySQL seems to store
+    //geometries as WKB with four leading zero bytes
+    //so, the first four should be zero, with the fifth
+    //byte being the byte-order byte, which always seems
+    //to be 0x01 in MySQL
+    int firstFive = geometryAsBytes[0]
+        | geometryAsBytes[1]
+        | geometryAsBytes[2]
+        | geometryAsBytes[3]
+        | geometryAsBytes[4];
+    byte[] ctrl = javax.xml.bind.DatatypeConverter.parseHexBinary("6A080000");
+    byte[] firstFour = new byte[4];
+    System.arraycopy(geometryAsBytes, 0, firstFour, 0, firstFour.length);
+    boolean nativeFormat = false;
+
+    if ((firstFive & 0xFF) == 0x01) {
+          //the next section in WKB is the geometry type.
+      //MySql supports types 1-7
+      if (geometryAsBytes[5] >= 1 && geometryAsBytes[5] <= 7) {
+        nativeFormat = true;
+      }
+
+    } else if (Arrays.equals(ctrl, firstFour)) {
+      // Nicolas Ribot: some geometries begin with: 6A 08 00 00 
+      // TODO: document how/why...
+      nativeFormat = true;
+    }
+    return nativeFormat;
+  }
+
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java 
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java 
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,16 +1,12 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.datastore.AdhocQuery;
 import com.vividsolutions.jump.datastore.FilterQuery;
 import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection;
-import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSMetadata;
-import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+import com.vividsolutions.jump.feature.FeatureSchema;
 import com.vividsolutions.jump.io.FeatureInputStream;
 import java.sql.Connection;
 import java.sql.SQLException;
@@ -44,8 +40,48 @@
      */
     @Override
     public FeatureInputStream executeFilterQuery(FilterQuery query) throws 
SQLException {
-        SpatialDatabasesFeatureInputStream fis = 
(SpatialDatabasesFeatureInputStream)super.executeFilterQuery(query);
-        return new OracleFeatureInputStream(fis.getConnection(), 
fis.getQueryString(), query.getPrimaryKey());
+        SpatialReferenceSystemID srid = 
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
+        String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
+
+        OracleSQLBuilder builder = (OracleSQLBuilder)this.getSqlBuilder(srid, 
colNames);
+        String queryString = builder.getSQL(query);
+
+        // [mmichaud 2013-08-07] add a parameter for database primary key name
+        return new OracleFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
     }
     
+    /**
+     * Executes an adhoc query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
+        String queryString = query.getQuery();
+        OracleFeatureInputStream ifs = new 
OracleFeatureInputStream(connection, queryString, query.getPrimaryKey());
+        
+        // Nicolas Ribot: getting FeatureSchema here actually runs the query: 
if an error occurs, must trap it here
+        FeatureSchema fs = null;
+        try {
+          fs = ifs.getFeatureSchema();
+        } catch (Exception e) {
+          throw new Exception(
+              
I18N.get(com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                  +".SQL-error") + e.getMessage());
+        }
+        
+        if (fs.getGeometryIndex() < 0) {
+            throw new Exception(I18N.get(
+                
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                +".resultset-must-have-a-geometry-column"));
+        }
+        return ifs;
+        
+    }
+    
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
  2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
  2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,13 +1,6 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
-import com.vividsolutions.jump.datastore.DataStoreConnection;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
-import com.vividsolutions.jump.parameter.ParameterList;
 
 /**
  * A driver for supplying {@link SpatialDatabaseDSConnection}s
@@ -19,22 +12,13 @@
     public static final String GT_SDO_CLASS_NAME = 
"org.geotools.data.oracle.sdo.SDO";
 
 
+    /**
+     * Constructor
+     * TODO: static variables for fields
+     */
     public OracleDataStoreDriver() {
         this.driverName = "Oracle Spatial";
         this.jdbcClass = OracleDataStoreDriver.JDBC_CLASS;
         this.urlPrefix = "jdbc:oracle:thin:@//";
     }
-    
-    /**
-     * returns the right type of DataStoreConnection
-     * @param params
-     * @return
-     * @throws Exception 
-     */
-    @Override
-    public DataStoreConnection createConnection(ParameterList params)
-        throws Exception {
-        DataStoreConnection ret = super.createConnection(params);
-        return new OracleDSConnection(ret.getConnection());
-    }
 }

Copied: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreExtension.java
 (from rev 4579, 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java)
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreExtension.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreExtension.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,60 @@
+package com.vividsolutions.jump.datastore.oracle;
+
+import com.vividsolutions.jump.datastore.DataStoreDriver;
+import static 
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.JDBC_CLASS;
+import static 
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.GT_SDO_CLASS_NAME;
+
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+import com.vividsolutions.jump.workbench.plugin.Extension;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import java.sql.Driver;
+import java.sql.DriverManager;
+
+/**
+ * 
+ * @author nicolas ribot
+ */
+public class OracleDataStoreExtension extends Extension {
+  private static boolean disabled = false;
+
+  public String getName() {
+    return "Oracle Spatial Datastore Extension";
+  }
+
+  public String getVersion() {
+    return "0.3 (2015-12-04)";
+  }
+
+  public String getMessage() {
+    return disabled ? "Disabled: Missing either ojdbc6.jar or 
gt2-oracle-spatial-2.x.jar in classpath"
+        : "";
+  }
+
+  public void configure(PlugInContext context) throws Exception {
+    WorkbenchContext wbc = context.getWorkbenchContext();
+
+    // registers the OracleDataStore driver to the system:
+    try {
+      ClassLoader pluginLoader = wbc.getWorkbench().getPlugInManager()
+          .getClassLoader();
+      // check for ojdbc6.jar
+      DriverManager.registerDriver(
+          (Driver)Class.forName(JDBC_CLASS, true, pluginLoader).newInstance());
+
+      // check for gt2-oracle-spatial-2.x.jar
+      Class.forName(GT_SDO_CLASS_NAME, true, pluginLoader)
+          .newInstance();
+      // register the datastore
+      wbc.getRegistry().createEntry(DataStoreDriver.REGISTRY_CLASSIFICATION,
+          new OracleDataStoreDriver());
+    } catch (Exception e) {
+      disabled = true;
+      wbc.getWorkbench()
+          .getFrame()
+          .log(
+              "Oracle Spatial Data Store disabled:\n\t" + e.toString() 
+            + "\n\tOracle JDBC Driver and gt2-oracle-spatial-2.x.jar must 
exist in the classpath !", this.getClass());
+    }
+  }
+
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
       2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
       2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
@@ -21,7 +16,7 @@
 public class OracleResultSetConverter extends 
SpatialDatabasesResultSetConverter {
 
     public OracleResultSetConverter(Connection conn, ResultSet rs) {
-        super(conn, rs);
+        this.rs = rs;
         this.odm = new OracleValueConverterFactory(conn);
     }
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java   
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java   
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
 import com.vividsolutions.jts.geom.Envelope;
@@ -82,7 +77,7 @@
         buf.append(geomColName).append(" as 
").append("\"").append(geomColName).append("\"");
         for (String colName : colNames) {
             if (!geomColName.equalsIgnoreCase(colName)) {
-                buf.append(",\"").append(colName).append("\"");
+                buf.append(", \"").append(colName).append("\"");
             }
         }
         return buf.toString();

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.oracle;
 
 import com.vividsolutions.jts.io.ParseException;
@@ -51,13 +46,6 @@
           .getStatement().getConnection()));
 
       return converterMethod.invoke(converter, 
structClazz.cast(geometryObject));
-
-        //** this is original implementation w/o reflection **// 
-      // org.geotools.data.oracle.sdo.GeometryConverter geometryConverter =
-      // new 
org.geotools.data.oracle.sdo.GeometryConverter((oracle.jdbc.OracleConnection)
-      // rs.getStatement().getConnection());
-      // return geometryConverter.asGeometry((oracle.sql.STRUCT)
-      // geometryObject);
     }
   }
 
@@ -68,9 +56,10 @@
   @Override
   public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
       throws SQLException {
-    String classname = rsm.getColumnClassName(columnIndex);
     String dbTypeName = rsm.getColumnTypeName(columnIndex);
 
+    // manages 2 cases: type retrieved from Database metadata (DataStore Panel)
+    // and from direct Adhoc query (type of the column resultset).
     if (dbTypeName.equalsIgnoreCase("MDSYS.SDO_GEOMETRY")) {
       return ORA_STRUCT_GEOMETRY_MAPPER;
     }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
   2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
   2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,17 +1,16 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.datastore.AdhocQuery;
 import com.vividsolutions.jump.datastore.FilterQuery;
 import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection;
-import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSMetadata;
-import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+import com.vividsolutions.jump.feature.FeatureSchema;
 import com.vividsolutions.jump.io.FeatureInputStream;
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+import com.vividsolutions.jump.workbench.ui.ErrorDialog;
+import com.vividsolutions.jump.workbench.ui.WorkbenchFrame;
 import java.sql.Connection;
 import java.sql.SQLException;
 
@@ -37,6 +36,8 @@
      *
      * The SRID is optional for queries - it will be determined automatically
      * from the table metadata if not supplied.
+     * 13 dec 2015: query is now tested before execution, to prevent adding an 
empty
+     * layer built from invalid WHERE clause, for instance.
      *
      * @param query the query to execute
      * @return the results of the query
@@ -44,8 +45,47 @@
      */
     @Override
     public FeatureInputStream executeFilterQuery(FilterQuery query) throws 
SQLException {
-        SpatialDatabasesFeatureInputStream fis = 
(SpatialDatabasesFeatureInputStream)super.executeFilterQuery(query);
-        return new PostgisFeatureInputStream(fis.getConnection(), 
fis.getQueryString(), query.getPrimaryKey());
+        SpatialReferenceSystemID srid = 
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
+        String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
+
+        PostgisSQLBuilder builder = 
(PostgisSQLBuilder)this.getSqlBuilder(srid, colNames);
+        String queryString = builder.getSQL(query);
+        
+        // [mmichaud 2013-08-07] add a parameter for database primary key name
+        return new PostgisFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
     }
     
+    /**
+     * Executes an adhoc query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
+        String queryString = query.getQuery();
+        PostgisFeatureInputStream ifs = new 
PostgisFeatureInputStream(connection, queryString, query.getPrimaryKey());
+        
+        // Nicolas Ribot: getting FeatureSchema here actually runs the query: 
if an error occurs, must trap it here
+        FeatureSchema fs = null;
+        try {
+          fs = ifs.getFeatureSchema();
+        } catch (Exception e) {
+          throw new Exception(
+            I18N.get(SpatialDatabasesDSConnection.class.getName()              
       
+                +".SQL-error") + e.getMessage());
+        }
+        
+        if (fs.getGeometryIndex() < 0) {
+            throw new 
Exception(I18N.get(SpatialDatabasesDSConnection.class.getName()
+                +".resultset-must-have-a-geometry-column"));
+        }
+        return ifs;
+        
+    }
+    
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java 
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java 
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
 import com.vividsolutions.jump.datastore.spatialdatabases.*;

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
        2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
        2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,13 +1,6 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
-import com.vividsolutions.jump.datastore.DataStoreConnection;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
-import com.vividsolutions.jump.parameter.ParameterList;
 
 /**
  * A driver for supplying {@link SpatialDatabaseDSConnection}s
@@ -15,22 +8,11 @@
 public class PostgisDataStoreDriver
     extends SpatialDatabasesDataStoreDriver {
 
+    public final static String JDBC_CLASS = "org.postgresql.Driver";
+
     public PostgisDataStoreDriver() {
         this.driverName = "PostGIS";
         this.jdbcClass = "org.postgresql.Driver";
         this.urlPrefix = "jdbc:postgresql://";
     }
-    
-    /**
-     * returns the right type of DataStoreConnection
-     * @param params
-     * @return
-     * @throws Exception 
-     */
-    @Override
-    public DataStoreConnection createConnection(ParameterList params)
-        throws Exception {
-        DataStoreConnection ret = super.createConnection(params);
-        return new PostgisDSConnection(ret.getConnection());
-    }
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
     2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,27 +1,34 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
+import com.vividsolutions.jump.workbench.JUMPWorkbench;
 import java.sql.Connection;
 import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  *
- * @author nicolas
+ * @author nicolas Ribot
  */
 public class PostgisFeatureInputStream extends 
SpatialDatabasesFeatureInputStream {
-    public PostgisFeatureInputStream(Connection conn, String queryString) {
-        super(conn, queryString);
+
+  public PostgisFeatureInputStream(Connection conn, String queryString) {
+        this(conn, queryString, null);
     }
 
     public PostgisFeatureInputStream(Connection conn, String queryString, 
String externalIdentifier) {
         super(conn, queryString, externalIdentifier);
+    try {
+      JUMPWorkbench.getInstance().getFrame().log("creating a 
PostgisFeatureInputStream (class:" + this.getClass()
+          + " ) (driver: " + conn.getMetaData().getDriverName() + ") id"
+          + this.hashCode(), this.getClass());
+    } catch (SQLException ex) {
+      
Logger.getLogger(PostgisFeatureInputStream.class.getName()).log(Level.SEVERE, 
null, ex);
     }
+    }
     
     /**
      * Returns a PostgisResultSetConverter

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
     2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
 import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
@@ -20,8 +15,8 @@
  */
 public class PostgisResultSetConverter extends 
SpatialDatabasesResultSetConverter {
 
-    public PostgisResultSetConverter(Connection conn, ResultSet rs) {
-        super(conn, rs);
-        this.odm = new PostgisValueConverterFactory(conn);
-    }
+  public PostgisResultSetConverter(Connection conn, ResultSet rs) {
+    this.rs = rs;
+    this.odm = new PostgisValueConverterFactory(conn);
+  }
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java 
    2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java 
    2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
 import com.vividsolutions.jts.geom.Envelope;

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
  2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
  2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.postgis;
 
 import com.vividsolutions.jump.datastore.jdbc.ValueConverter;
@@ -13,38 +8,35 @@
 import java.sql.SQLException;
 
 /**
- *
+ * Factory to convert Postgis geometric data type.
+ * 
  */
 public class PostgisValueConverterFactory extends 
SpatialDatabasesValueConverterFactory {
 
-    public PostgisValueConverterFactory(Connection conn) {
-        super(conn);
-    }
+  public PostgisValueConverterFactory(Connection conn) {
+    super(conn);
+  }
 
-    @Override
-    public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
-        throws SQLException {
-        String classname = rsm.getColumnClassName(columnIndex);
-        String dbTypeName = rsm.getColumnTypeName(columnIndex);
+  @Override
+  public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
+      throws SQLException {
+    String dbTypeName = rsm.getColumnTypeName(columnIndex);
 
-        // MD - this is slow - is there a better way?
-        if (dbTypeName.equalsIgnoreCase("geometry")) // WKB is now the normal 
way to store geometry in PostGIS [mmichaud 2007-05-13]
-        {
-            return WKB_GEOMETRY_MAPPER;
-        }
+    // manages 2 cases: type retrieved from Database metadata (DataStore Panel)
+    // and from direct Adhoc query (type of the column resultset).
+    if ("bytea".equalsIgnoreCase(dbTypeName) || 
"geometry".equalsIgnoreCase(dbTypeName)) {
+      return WKB_GEOMETRY_MAPPER;
+    } else if (dbTypeName.equalsIgnoreCase("text")) {
+      // TODO: wrong: all text column will be treated as text here...
+      return WKT_GEOMETRY_MAPPER;
+    }
 
-        if (dbTypeName.equalsIgnoreCase("bytea")) {
-            return WKB_GEOMETRY_MAPPER;
-        }
-
-        // handle the standard types
-        ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm, 
columnIndex);
-        if (stdConverter != null) {
-            return stdConverter;
-        }
-
+    // handle the standard types
+    ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm, 
columnIndex);
+    if (stdConverter != null) {
+      return stdConverter;
+    }
         // default - can always show it as a string!
-        return ValueConverterFactory.STRING_MAPPER;
-    }
-
+    return ValueConverterFactory.STRING_MAPPER;
+  }
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
 2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
 2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.spatialdatabases;
 
 import com.vividsolutions.jump.I18N;
@@ -27,9 +22,16 @@
 
     protected SpatialDatabasesDSMetadata dbMetadata;
     protected Connection connection;
-
+    
     public SpatialDatabasesDSConnection(Connection conn) {
-        JUMPWorkbench.getInstance().getFrame().log("creating a 
SpatialDatabasesDSConnection id" + this.hashCode(), this.getClass());
+      
+      try { 
+        JUMPWorkbench.getInstance().getFrame().log("creating a 
SpatialDatabasesDSConnection (class:" + this.getClass() 
+            + " ) (driver: " + conn.getMetaData().getDriverName() + ") id"
+            + this.hashCode(), this.getClass());
+      } catch (SQLException ex) {
+        ex.printStackTrace();
+      }
         connection = conn;
         dbMetadata = new SpatialDatabasesDSMetadata(this);
     }
@@ -74,24 +76,20 @@
      * @throws SQLException
      */
     public FeatureInputStream executeFilterQuery(FilterQuery query) throws 
SQLException {
-
-        SpatialReferenceSystemID srid = 
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
-        String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
-
-        SpatialDatabasesSQLBuilder builder = this.getSqlBuilder(srid, 
colNames);
-        String queryString = builder.getSQL(query);
-
-        // [mmichaud 2013-08-07] add a parameter for database primary key name
-        return new SpatialDatabasesFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
+      throw new UnsupportedOperationException();
     }
 
+    /**
+     * select gid, geom 
+     * from departement
+     * where nom like 'A%'
+     * Executes an adhoc query (direct SQL query)
+     * @param query the query to execute
+     * @return a featureInputStream containing query's features
+     * @throws Exception if no geometric column is found in the query
+     */
     public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
-        String queryString = query.getQuery();
-        SpatialDatabasesFeatureInputStream ifs = new 
SpatialDatabasesFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
-        if (ifs.getFeatureSchema().getGeometryIndex() < 0) {
-            throw new 
Exception(I18N.get(this.getClass().getName()+".resultset-must-have-a-geometry-column"));
-        }
-        return ifs;
+      throw new UnsupportedOperationException();
     }
 
 

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSMetadata.java
   2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSMetadata.java
   2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,8 +1,3 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.spatialdatabases;
 
 import com.vividsolutions.jts.geom.Envelope;
@@ -98,6 +93,9 @@
   }
 
   public SpatialDatabasesDSMetadata(DataStoreConnection conn) {
+    JUMPWorkbench.getInstance().getFrame().log("creating a 
SpatialDatabasesDSMetadata (class:" + this.getClass() 
+        + " ) (con: " + conn.toString() + ") id"
+        + this.hashCode(), this.getClass());
     this.conn = conn;
     // TODO: use bind parameters to avoid SQL injection
     this.datasetNameQuery = "";
@@ -279,7 +277,7 @@
    * @return
    */
   public List<GeometryColumn> getGeometryAttributes(String datasetName) {
-    String sql = this.getGeoColumnsQuery(datasetName);
+    String sql = getGeoColumnsQuery(datasetName);
     return getGeometryAttributes(sql, datasetName);
   }
 

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDataStoreDriver.java
      2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDataStoreDriver.java
      2015-12-13 15:02:36 UTC (rev 4609)
@@ -1,12 +1,11 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
 package com.vividsolutions.jump.datastore.spatialdatabases;
 
 import com.vividsolutions.jump.datastore.DataStoreConnection;
 import com.vividsolutions.jump.datastore.DataStoreDriver;
+import com.vividsolutions.jump.datastore.mariadb.MariadbDSConnection;
+import com.vividsolutions.jump.datastore.oracle.OracleDSConnection;
+import com.vividsolutions.jump.datastore.postgis.PostgisDSConnection;
+import com.vividsolutions.jump.datastore.spatialite.SpatialiteDSConnection;
 import com.vividsolutions.jump.parameter.ParameterList;
 import com.vividsolutions.jump.parameter.ParameterListSchema;
 import java.sql.Connection;
@@ -19,36 +18,43 @@
 public class SpatialDatabasesDataStoreDriver
     implements DataStoreDriver {
 
+  /** TODO: I18N */
   public static final String PARAM_Server = "Server";
   public static final String PARAM_Port = "Port";
   public static final String PARAM_Instance = "Database";
   public static final String PARAM_User = "User";
   public static final String PARAM_Password = "Password";
+  // For Spatialite
+  public static final String PARAM_DB_File = "DB file";
 
   protected String driverName = null;
   protected String jdbcClass = null;
   protected String urlPrefix = null;
 
-  private static final String[] paramNames = new String[]{
-      PARAM_Server,
-      PARAM_Port,
-      PARAM_Instance,
-      PARAM_User,
-      PARAM_Password
-    };
-  private static final Class[] paramClasses = new Class[]{
-      String.class,
-      Integer.class,
-      String.class,
-      String.class,
-      String.class
-    };
-  private final ParameterListSchema schema = new 
ParameterListSchema(paramNames, paramClasses);
+  protected String[] paramNames = null;
+  protected Class[] paramClasses = null;
+  protected ParameterListSchema schema = null;
 
   public SpatialDatabasesDataStoreDriver() {
-//    this.driverName = "";
-//    this.jdbcClass = "";
-//    this.urlPrefix = "";
+    // Nicolas Ribot:
+    //paramNames are no more static now they can be overloaded by child 
classes @link SpatialiteDataStoreDriver for instance
+    paramNames = new String[]{
+        PARAM_Server,
+        PARAM_Port,
+        PARAM_Instance,
+        PARAM_User,
+        PARAM_Password
+      };
+  // Nicolas Ribot: passed protected and not final to allow 
spatialiteDataStoreDriver to overload it
+    paramClasses = new Class[]{
+        String.class,
+        Integer.class,
+        String.class,
+        String.class,
+        String.class
+      };
+    // Nicolas Ribot: passed protected and not final to allow 
spatialiteDataStoreDriver to overload it
+    schema = new ParameterListSchema(paramNames, paramClasses);
   }
 
   public String getDriverName() {
@@ -62,9 +68,19 @@
   public String getUrlPrefix() {
     return urlPrefix;
   }
-  
-  
 
+  public String[] getParamNames() {
+    return paramNames;
+  }
+
+  public Class[] getParamClasses() {
+    return paramClasses;
+  }
+
+  public ParameterListSchema getSchema() {
+    return schema;
+  }
+
   @Override
   public String getName() {
     return driverName;
@@ -108,7 +124,21 @@
     } else {
       System.setProperty("java.net.preferIPv6Addresses", 
savePreferIPv6Addresses);
     }
-    return new SpatialDatabasesDSConnection(conn);
+    //return new SpatialDatabasesDSConnection(conn);
+    // TODO: clean inheritance...
+    if (url.startsWith("jdbc:postgresql")) {
+      return new PostgisDSConnection(conn);
+    } else if (url.startsWith("jdbc:oracle")) {
+      return new OracleDSConnection(conn);
+    } else if (url.startsWith("jdbc:mysql")) {
+      return new MariadbDSConnection(conn);
+    } else if (url.startsWith("jdbc:sqlite")) {
+      return new SpatialiteDSConnection(conn);
+    } else {
+      // TODO: should not pass here
+      System.err.println("ERROR: Returning a SpatialDatabasesDSConnection for 
url: " + url + ". Should not happen...");
+      return new SpatialDatabasesDSConnection(conn);
+    }
   }
 
   @Override

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesFeatureInputStream.java
   2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesFeatureInputStream.java
   2015-12-13 15:02:36 UTC (rev 4609)
@@ -25,20 +25,16 @@
     private ResultSet rs = null;
     private SpatialDatabasesResultSetConverter mapper;
 
-    int geometryColIndex = -1;
     String externalIdentifier = null;  // added on 2013-08-07
 
     public SpatialDatabasesFeatureInputStream(Connection conn, String 
queryString) {
-        this.conn = conn;
-        this.queryString = queryString;
-        //System.out.println("1building new 
SpatialDatabasesFeatureInputStream: " + this.hashCode());
+        this(conn, queryString, null);
     }
 
     public SpatialDatabasesFeatureInputStream(Connection conn, String 
queryString, String externalIdentifier) {
         this.conn = conn;
         this.queryString = queryString;
         this.externalIdentifier = externalIdentifier;
-        //System.out.println("2building new 
SpatialDatabasesFeatureInputStream: " + this.hashCode());
     }
 
     /**
@@ -76,11 +72,11 @@
         stmt = conn.createStatement();
         String parsedQuery = queryString;
         try {
-            rs = stmt.executeQuery(parsedQuery);
+          rs = stmt.executeQuery(parsedQuery);
         } catch (SQLException e) {
-            SQLException sqle = new SQLException("Error : " + parsedQuery);
-            sqle.setNextException(e);
-            throw sqle;
+          // adds SQL query to SQLError
+          e.setNextException(new SQLException("Invalid query: " + 
queryString));
+          throw e;
         }
 //        mapper = new SpatialDatabasesResultSetConverter(conn, rs);
         mapper = getResultSetConverter(rs);
@@ -123,7 +119,7 @@
             String message = ex.getLocalizedMessage();
             Throwable nextT = ex.getNextException();
             if (nextT != null) message = message + "\n" + 
nextT.getLocalizedMessage();
-            throw new Error(message);
+            throw new Error(message, ex);
         }
         if (featureSchema == null) {
             featureSchema = new FeatureSchema();

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesResultSetConverter.java
   2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesResultSetConverter.java
   2015-12-13 15:02:36 UTC (rev 4609)
@@ -27,8 +27,17 @@
   protected SpatialDatabasesValueConverterFactory odm;
   protected boolean isInitialized = false;
 
+  /**
+   * empty ctor
+   * @param conn
+   * @param rs 
+   */
+  public SpatialDatabasesResultSetConverter() {
+  }
+  
   public SpatialDatabasesResultSetConverter(Connection conn, ResultSet rs) {
     this.rs = rs;
+    // try to instantiate the right object type.
     odm = new SpatialDatabasesValueConverterFactory(conn);
   }
 
@@ -57,9 +66,6 @@
 
     ResultSetMetaData rsmd = rs.getMetaData();
     int numberOfColumns = rsmd.getColumnCount();
-    //String[] columnNames = new String[numberOfColumns];
-    //String[] columnTypeNames = new String[numberOfColumns];
-    //int[] columnPositions = new int[numberOfColumns];
     mapper = new ValueConverter[numberOfColumns];
     featureSchema = new FeatureSchema();
 
@@ -70,6 +76,8 @@
       // Convert the first geometry into AttributeType.GEOMETRY and the 
following ones
       // into AttributeType.STRINGs [mmichaud 2007-05-13]
       if (mapper[i].getType() == AttributeType.GEOMETRY) {
+        // Nicolas Ribot: stores geomCol index as it is needed by Adhoc query
+        //geometryColIndex = i+1;
         if (featureSchema.getGeometryIndex() == -1) {
           // fixed by mmichaud using a patch from jaakko [2008-05-21] :
           // use colName instead of "GEOMETRY" for attribute name

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesValueConverterFactory.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesValueConverterFactory.java
        2015-12-13 14:24:16 UTC (rev 4608)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesValueConverterFactory.java
        2015-12-13 15:02:36 UTC (rev 4609)
@@ -7,6 +7,7 @@
 import java.sql.*;
 import com.vividsolutions.jump.datastore.jdbc.*;
 import com.vividsolutions.jump.feature.AttributeType;
+import com.vividsolutions.jump.workbench.JUMPWorkbench;
 import java.io.IOException;
 
 /**
@@ -24,12 +25,27 @@
   protected final Connection conn;
 
   public SpatialDatabasesValueConverterFactory(Connection conn) {
+      try { 
+        JUMPWorkbench.getInstance().getFrame().log("creating a 
SpatialDatabasesValueConverterFactory (class:" + this.getClass() 
+            + " ) (driver: " + conn.getMetaData().getDriverName() + ") id"
+            + this.hashCode(), this.getClass());
+      } catch (SQLException ex) {
+        ex.printStackTrace();
+      }
     this.conn = conn;
   }
 
+  /**
+   * Base class to get converter from factory.
+   * Should never be called !!
+   * @param rsm
+   * @param columnIndex
+   * @return
+   * @throws SQLException 
+   */
   public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
       throws SQLException {
-    return null;
+      throw new UnsupportedOperationException();
   }
 
   class WKTGeometryValueConverter implements ValueConverter {

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometricColumnType.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometricColumnType.java
                                (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometricColumnType.java
        2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,11 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+/**
+ * DB types for geometric columns
+ * Used by spatialite, for other datastore, default to native type.
+ * @author nicolas
+ */
+public enum GeometricColumnType {
+    WKT, WKB, SPATIALITE, NATIVE
+    // All OGC types can be set as column type
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometryColumnsLayout.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometryColumnsLayout.java
                              (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/GeometryColumnsLayout.java
      2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,10 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+/**
+ * An Enum representing Spatialite Geometry_column layout:
+ * either a FDO layout, an OGR OGC layout, and OGR Spatialite layout, or no 
layout (no geometry_column found)
+ * @author nicolas
+ */
+public enum GeometryColumnsLayout {
+    FDO_LAYOUT, OGC_OGR_LAYOUT,OGC_SPATIALITE_LAYOUT, NO_LAYOUT;
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSConnection.java
                             (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSConnection.java
     2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,102 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import com.vividsolutions.jump.I18N;
+import com.vividsolutions.jump.datastore.AdhocQuery;
+import com.vividsolutions.jump.datastore.FilterQuery;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import com.vividsolutions.jump.io.FeatureInputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ *
+ * @author nicolas ribot
+ * TODO: Manage converter to handle all geometry type in the same database.
+ */
+public class SpatialiteDSConnection extends SpatialDatabasesDSConnection {
+
+    public SpatialiteDSConnection(Connection con) {
+        super(con); // ?
+        connection = con;
+        this.dbMetadata = new SpatialiteDSMetadata(this);
+    }
+    
+    /**
+     * Keeps a reference on SpatialiteDSMetadata into the SQL builder, to 
access
+     * Spatialite preferences necessary in order to build proper queries 
according to 
+     * geometric type
+     * @param srid
+     * @param colNames
+     * @return 
+     */
+    @Override
+    public SpatialDatabasesSQLBuilder getSqlBuilder(SpatialReferenceSystemID 
srid, String[] colNames) {
+        SpatialiteSQLBuilder ret = new 
SpatialiteSQLBuilder((SpatialiteDSMetadata)this.dbMetadata, srid, colNames);
+        return ret;
+    }
+
+    /**
+     * Executes a filter query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeFilterQuery(FilterQuery query) throws 
SQLException {
+        SpatialReferenceSystemID srid = 
dbMetadata.getSRID(query.getDatasetName(), query.getGeometryAttributeName());
+        String[] colNames = dbMetadata.getColumnNames(query.getDatasetName());
+
+        SpatialiteSQLBuilder builder = 
(SpatialiteSQLBuilder)this.getSqlBuilder(srid, colNames);
+        String queryString = builder.getSQL(query);
+
+        // [mmichaud 2013-08-07] add a parameter for database primary key name
+        SpatialiteFeatureInputStream fis = new 
SpatialiteFeatureInputStream(connection, queryString, query.getPrimaryKey());
+        // Needed to choose converter according to real geometry type
+        fis.setMetadata((SpatialiteDSMetadata)dbMetadata);
+        return fis;
+    }
+    
+    /**
+     * Executes an adhoc query.
+     *
+     * The SRID is optional for queries - it will be determined automatically
+     * from the table metadata if not supplied.
+     *
+     * @param query the query to execute
+     * @return the results of the query
+     * @throws SQLException
+     */
+    @Override
+    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
+        String queryString = query.getQuery();
+        SpatialiteFeatureInputStream ifs = new 
SpatialiteFeatureInputStream(connection, queryString, query.getPrimaryKey());
+        // Needed to choose converter according to real geometry type
+        ifs.setMetadata((SpatialiteDSMetadata)dbMetadata);
+        
+        // Nicolas Ribot: getting FeatureSchema here actually runs the query: 
if an error occurs, must trap it here
+        FeatureSchema fs = null;
+        try {
+          fs = ifs.getFeatureSchema();
+        } catch (Exception e) {
+          throw new Exception(
+            
I18N.get(com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                +".SQL-error") + e.getMessage());
+        }
+        
+        if (fs.getGeometryIndex() < 0) {
+            throw new Exception(I18N.get(
+                
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDSConnection.class.getName()
+                +".resultset-must-have-a-geometry-column"));
+        }
+        return ifs;
+        
+    }
+    
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSMetadata.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDSMetadata.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,287 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import com.vividsolutions.jump.datastore.spatialdatabases.*;
+import com.vividsolutions.jump.datastore.jdbc.JDBCUtil;
+import com.vividsolutions.jump.datastore.jdbc.ResultSetBlock;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Spatialite connexion metadata. Some extra processing occurs here: telling if
+ * spatialite extension is loaded and what type of geo metatada are present:
+ *
+ * @author nicolas Ribot
+ */
+public class SpatialiteDSMetadata extends SpatialDatabasesDSMetadata {
+
+  public static String GC_COLUMN_NAME = "geometry_columns";
+
+  //TODO= variables for all SQL code + String.format.
+  /**
+   * True if spatialite mod extension loaded
+   */
+  private boolean spatialiteLoaded;
+  /**
+   * spatialite version
+   */
+  private String spatialiteVersion;
+  /**
+   * The geometry_columns table layout for this connection
+   */
+  private GeometryColumnsLayout geometryColumnsLayout;
+
+  /**
+   * The map of geometric columns types (WKB, WKT, SPATIALITE)
+   */
+  private Map<String, GeometricColumnType> geoColTypesdMap = null;
+
+  /**
+   * 
+   * @param con 
+   */
+  public SpatialiteDSMetadata(DataStoreConnection con) {
+    conn = con;
+    this.spatialiteLoaded = false;
+    this.spatialiteVersion = "";
+    this.geometryColumnsLayout = GeometryColumnsLayout.NO_LAYOUT;
+    this.geoColTypesdMap = new HashMap<String, GeometricColumnType>();
+
+    checkSpatialiteLoaded();
+    setGeoColLayout();
+    // done here as every connection needs it
+    getGeoColumnType();
+
+    // TODO: use bind parameters to avoid SQL injection
+    datasetNameQuery = "SELECT DISTINCT '' as f_table_schema, f_table_name 
FROM geometry_columns";
+    defaultSchemaName = "";
+    spatialDbName = isSpatialiteLoaded() ? "Spatialite" : "SQLite";
+    spatialExtentQuery1 = "SELECT %s from %s";
+    spatialExtentQuery2 = "SELECT %s from %s";
+    sridQuery = "SELECT srid FROM geometry_columns where f_table_name = '%s' 
and f_geometry_column = '%s'";
+    // geo column query needs to be built occording to geometryColumnsLayout
+    if (this.geometryColumnsLayout == GeometryColumnsLayout.FDO_LAYOUT) {
+      geoColumnsQuery = "SELECT f_geometry_column, srid, geometry_type FROM 
geometry_columns where f_table_name = '%s'";
+    } else if (this.geometryColumnsLayout == 
GeometryColumnsLayout.OGC_SPATIALITE_LAYOUT) {
+      geoColumnsQuery = "SELECT f_geometry_column, srid, type FROM 
geometry_columns where f_table_name = '%s'";
+    } else if (this.geometryColumnsLayout == 
GeometryColumnsLayout.OGC_OGR_LAYOUT) {
+      geoColumnsQuery = "SELECT f_geometry_column, srid, geometry_type FROM 
geometry_columns where f_table_name = '%s'";
+    } else {
+      geoColumnsQuery = "SELECT '' ";
+    }
+
+  }
+
+  @Override
+  public String getSpatialExtentQuery1(String schema, String table, String 
attributeName) {
+    // No schema in SQLite, schema param not used
+    // must cast the geometric field according to its type, to be able to use 
spatialite functions.
+    //return String.format(spatialExtentQuery1, attributeName, table);
+    String ret = "select 1";
+    
+
+    GeometricColumnType gcType = this.geoColTypesdMap.get(table.toLowerCase() 
+ "." + attributeName.toLowerCase());
+
+    if (gcType == null) {
+      return "select 1";
+    }
+    // TODO: switch case
+    if (this.isSpatialiteLoaded()) {
+      if (gcType == GeometricColumnType.WKB) {
+        ret = String.format("select st_asBinary(extent(st_geomFromWkb(%s))) 
from %s", attributeName, table);
+      } else if (gcType == GeometricColumnType.WKT) {
+        ret = String.format("select st_asBinary(extent(st_geomFromText(%s))) 
from %s", attributeName, table);
+      } else if (gcType == GeometricColumnType.SPATIALITE) {
+        ret = String.format("select st_asBinary(extent(%s)) from %s", 
attributeName, table);
+      } else {
+        // unknown geom type
+        // TODO: log
+        System.out.println("Unknown geo column type for: " + table + "." + 
attributeName + " : " + gcType);
+        ret = "select 1";
+      }
+    } else {
+      // spatialite functions not available: extent cannot be found 
+      ret = "select 1";
+    }
+    return ret;
+  }
+
+  @Override
+  public String getSpatialExtentQuery2(String schema, String table, String 
attributeName) {
+    // only one mechanism to get extent from spatialite
+    return getSpatialExtentQuery1(schema, table, attributeName);
+  }
+
+  /**
+   * No schema in SQLite
+   *
+   * @param datasetName
+   * @return
+   */
+  @Override
+  public String getGeoColumnsQuery(String datasetName) {
+    // No schema in SQLite
+    return String.format(this.geoColumnsQuery, getTableName(datasetName));
+  }
+
+  @Override
+  public String getSridQuery(String schemaName, String tableName, String 
colName) {
+    // no schema in sqlite
+    return String.format(this.sridQuery, tableName, colName);
+  }
+
+  private void checkSpatialiteLoaded() {
+    // tries to load spatialite, assuming it is available on the system's path
+    Statement stmt = null;
+    try {
+      stmt = conn.getConnection().createStatement();
+      stmt.executeUpdate("SELECT load_extension('mod_spatialite')");
+      // ex is thrown if extension cannot be loaded
+      this.spatialiteLoaded = true;
+      ResultSet rs = stmt.executeQuery("select spatialite_version()");
+      rs.next();
+      this.setSpatialiteVersion(rs.getString(1));
+      //TODO: log
+      System.out.println("SpatialDatabasesPlugin: Spatialite extension loaded 
for this connexion, version: " + this.getSpatialiteVersion());
+    } catch (Exception e) {
+      System.out.println("SpatialDatabasesPlugin: Cannot load Spatialite 
Extention (mod_spatialite), reason:" + e.getMessage());
+    } finally {
+      try {
+        stmt.close();
+      } catch (Throwable th) {
+        // TODO: log
+        th.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * Sets the geometry_column layout in this sqlite database: either FDO or
+   * OGC or no layout. Also tries to build the geo col type if geometry_columns
+   * table contains such info TODO: generic mechanism to get geo col type for
+   * Spatialite
+   */
+  private void setGeoColLayout() {
+    DatabaseMetaData dbMd = null;
+    try {
+      dbMd = this.conn.getConnection().getMetaData();
+      ResultSet rs = dbMd.getTables(null, null, 
SpatialiteDSMetadata.GC_COLUMN_NAME, null);
+      if (rs.next()) {
+        // tableName is third column in this metadata resultSet
+        String col = rs.getString(3);
+        boolean isGC = 
SpatialiteDSMetadata.GC_COLUMN_NAME.equalsIgnoreCase(col);
+
+        // gc layout
+        if (isGC) {
+          rs = dbMd.getColumns(null, null, 
SpatialiteDSMetadata.GC_COLUMN_NAME, null);
+          int i = 0;
+          // geometry_columns table may have 2 layouts according to ogr2ogr
+          // options used to create the table:
+          // 1\xB0) the "FDO provider for spatialite 
(https://trac.osgeo.org/fdo/wiki/FDORfc16)", as used in "regular sqlite 
database" (cf.ogr spatialite format doc):
+          //                f_table_name               TEXT    
+          //                f_geometry_column  TEXT    
+          //                geometry_type              INTEGER 
+          //                coord_dimension    INTEGER 
+          //                srid                       INTEGER 
+          //                geometry_format    TEXT
+          // 2\xB0) the "OGC" flavour, as understood by qgis for instance, as 
used in spatialite-enabled sqlite database:
+          //                f_table_name          VARCHAR
+          //                f_geometry_column     VARCHAR
+          //                type                  VARCHAR
+          //                coord_dimension       INTEGER 
+          //                srid                  INTEGER
+          //                spatial_index_enabled INTEGER 
+          i = 0;
+          String geoTypeCol = "";
+          String extraInfoCol = "";
+          while (rs.next()) {
+            // assume columns order is respected when gc table is created.
+            // TODO: enhance this
+            if (i == 2) {
+              geoTypeCol = rs.getString(4);
+            }
+            if (i == 5) {
+              extraInfoCol = rs.getString(4);
+            }
+            i++;
+          }
+          if (geoTypeCol.equalsIgnoreCase("geometry_type") && 
extraInfoCol.equalsIgnoreCase("geometry_format")) {
+            geometryColumnsLayout = GeometryColumnsLayout.FDO_LAYOUT;
+          } else if (geoTypeCol.equalsIgnoreCase("type") && 
extraInfoCol.equalsIgnoreCase("spatial_index_enabled")) {
+            geometryColumnsLayout = 
GeometryColumnsLayout.OGC_SPATIALITE_LAYOUT;
+          } else if (geoTypeCol.equalsIgnoreCase("geometry_type") && 
extraInfoCol.equalsIgnoreCase("spatial_index_enabled")) {
+            geometryColumnsLayout = GeometryColumnsLayout.OGC_OGR_LAYOUT;
+          } else {
+            geometryColumnsLayout = GeometryColumnsLayout.NO_LAYOUT;
+          };
+          rs.close();
+        }
+      }
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      //TODO: logging
+      System.out.println("error getting geometry_column layout: " + 
e.getMessage());
+    }
+  }
+
+  /**
+   * builds the map of geometric columns database type: WKB, WKT, SPATIALITE to
+   * be able to build custom queries for extent and geo type retrieval.
+   * The geometry_format column of the metadata will be queries to find 
geometry type
+   * (column only detected in the FDO_LAYOUT format).
+   * For other layout, will default to SPATIALITE type
+   */
+  private void getGeoColumnType() {
+    // Default query gets a hard-coded value for spatialite type
+    String query = "select f_table_name, f_geometry_column, \"SPATIALITE\" 
from geometry_columns";
+    if (this.getGeometryColumnsLayout() == GeometryColumnsLayout.FDO_LAYOUT) {
+      // MD table contains a geometry_format column: query it
+      query = "select f_table_name, f_geometry_column, geometry_format from 
geometry_columns";
+    } 
+    try {
+      JDBCUtil.execute(
+          conn.getConnection(),
+          query,
+          new ResultSetBlock() {
+            public void yield(ResultSet resultSet) throws SQLException {
+              while (resultSet.next()) {
+                // force lowercase as JDBC metadata and OGC spatialite 
metadata can return
+                // different cases for the same geometric column
+                String table = resultSet.getString(1).toLowerCase();
+                String col = resultSet.getString(2).toLowerCase();
+                GeometricColumnType gcType = 
GeometricColumnType.valueOf(resultSet.getString(3));
+                geoColTypesdMap.put(table + "." + col, gcType);
+              }
+            }
+          });
+    } catch (Exception e) {
+      //TODO...
+    }
+  }
+
+  public boolean isSpatialiteLoaded() {
+    return spatialiteLoaded;
+  }
+
+  public String getSpatialiteVersion() {
+    return spatialiteVersion;
+  }
+
+  public void setSpatialiteVersion(String spatialiteVersion) {
+    this.spatialiteVersion = spatialiteVersion;
+  }
+
+  public GeometryColumnsLayout getGeometryColumnsLayout() {
+    return geometryColumnsLayout;
+  }
+
+  public Map<String, GeometricColumnType> getGeoColTypesdMap() {
+    return geoColTypesdMap;
+  }
+
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreDriver.java
                          (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreDriver.java
  2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,72 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import com.vividsolutions.jump.parameter.ParameterList;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
+import com.vividsolutions.jump.parameter.ParameterListSchema;
+import java.io.File;
+import org.sqlite.SQLiteConfig;
+
+/**
+ * A driver for supplying {@link SpatialDatabaseDSConnection}s
+ */
+public class SpatialiteDataStoreDriver
+    extends SpatialDatabasesDataStoreDriver {
+    
+    public final static String JDBC_CLASS = "org.sqlite.JDBC";
+    
+    public SpatialiteDataStoreDriver() {
+        this.driverName = "Spatialite";
+        this.jdbcClass = "org.sqlite.JDBC";
+        //TODO: prompt for filename
+        this.urlPrefix = "jdbc:sqlite:";
+        
+        // Panel parameters: adds a file chooser for db name
+        paramNames = new String[]{PARAM_DB_File};
+        paramClasses = new Class[]{File.class};
+        schema = new ParameterListSchema(paramNames, paramClasses);
+    }
+    
+    /**
+     * returns a spatialite JDBC connexion with spatialite extension loaded if 
possible
+     * if not, a property will tell so
+     * 
+     * @param params
+     * @return
+     * @throws Exception 
+     */
+  @Override
+  public DataStoreConnection createConnection(ParameterList params)
+      throws Exception {
+    // PARAM_DB_File is a fileChooser: the default mechanism used will store a
+    // DefaultAwtShell on OSX. Do not cast to this internal type but gets its 
toString() method
+    // returning the choosen filename.
+    String database = params.getParameter(PARAM_DB_File).toString();
+    
+    // First checks if the file exists: cannot manage newly created Spatialite 
files yet:
+    // File must exists
+    File sqliteFile = new File(database);
+    if (!sqliteFile.exists() || !sqliteFile.canRead()) {
+      // TODO: I18N
+      throw new Exception("Spatialite file: " + database + " does not exist. 
cannot create connection");
+    }
+    
+    
+    SQLiteConfig config = new SQLiteConfig();
+    // mandatory to load spatialite extension
+    config.enableLoadExtension(true);
+
+    String url
+        = String.valueOf(new StringBuffer(urlPrefix).append(database));
+
+    Driver driver = (Driver) Class.forName(this.getJdbcClass()).newInstance();
+    DriverManager.registerDriver(driver);
+
+    Connection conn = DriverManager.getConnection(url, config.toProperties());
+    
+    return new SpatialiteDSConnection(conn);
+  }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreExtension.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreExtension.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteDataStoreExtension.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,56 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import com.vividsolutions.jump.datastore.DataStoreDriver;
+import static 
com.vividsolutions.jump.datastore.spatialite.SpatialiteDataStoreDriver.JDBC_CLASS;
+
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+import com.vividsolutions.jump.workbench.plugin.Extension;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import java.sql.Driver;
+import java.sql.DriverManager;
+
+/**
+ * 
+ * @author nicolas ribot
+ */
+public class SpatialiteDataStoreExtension extends Extension {
+  private static boolean disabled = false;
+
+  public String getName() {
+    return "Spatialite Spatial Datastore Extension";
+  }
+
+  public String getVersion() {
+    return "0.3 (2015-12-04)";
+  }
+
+  public String getMessage() {
+    return disabled ? "Disabled: Missing sqlite-jdbc-<version>.jar in 
classpath"
+        : "";
+  }
+  // TODO: refactor in a base class.
+  public void configure(PlugInContext context) throws Exception {
+    WorkbenchContext wbc = context.getWorkbenchContext();
+
+    // registers the MariaDBDataStore driver to the system:
+    try {
+      ClassLoader pluginLoader = wbc.getWorkbench().getPlugInManager()
+          .getClassLoader();
+      // check for ojdbc6.jar
+      DriverManager.registerDriver(
+          (Driver)Class.forName(JDBC_CLASS, true, pluginLoader).newInstance());
+
+      // register the datastore
+      wbc.getRegistry().createEntry(DataStoreDriver.REGISTRY_CLASSIFICATION,
+          new SpatialiteDataStoreDriver());
+    } catch (Exception e) {
+      disabled = true;
+      wbc.getWorkbench()
+          .getFrame()
+          .log(
+              "Sqlite/Spatialite Spatial Data Store disabled:\n\t" + 
e.toString() 
+            + "\n\tSqlite JDBC Driver (sqlite-jdbc-<version>.jar) must exist 
in the classpath !", this.getClass());
+    }
+  }
+
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteFeatureInputStream.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteFeatureInputStream.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,45 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+/**
+ *
+ * @author nicolas
+ */
+public class SpatialiteFeatureInputStream extends 
SpatialDatabasesFeatureInputStream {
+
+    /**
+     * propagate the metadata object through Spatialite classes to get access 
to
+     * specific information
+     */
+    private SpatialiteDSMetadata metadata;
+
+    public SpatialiteFeatureInputStream(Connection conn, String queryString) {
+        super(conn, queryString);
+    }
+
+    public SpatialiteFeatureInputStream(Connection conn, String queryString, 
String externalIdentifier) {
+        super(conn, queryString, externalIdentifier);
+    }
+
+    public void setMetadata(SpatialiteDSMetadata metadata) {
+        this.metadata = metadata;
+    }
+
+    /**
+     * Returns a SpatialiteResultSetConverter
+     *
+     * @param rs
+     * @return
+     */
+    @Override
+    protected SpatialDatabasesResultSetConverter 
getResultSetConverter(ResultSet rs) {
+        SpatialiteResultSetConverter ret = new 
SpatialiteResultSetConverter(conn, rs);
+        ret.setMetadata(this.metadata);
+        
+        return ret;
+    }
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteResultSetConverter.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteResultSetConverter.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,37 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+/**
+ * Implements the mapping between a result set and a {@link FeatureSchema} and
+ * {@link Feature} set.
+ *
+ * This is a transient worker class, whose lifetime should be no longer than 
the
+ * lifetime of the provided ResultSet
+ */
+public class SpatialiteResultSetConverter extends 
SpatialDatabasesResultSetConverter {
+    /**
+     * propagate the metadata object through Spatialite classes to get access 
to
+     * specific information
+     */
+    private SpatialiteDSMetadata metadata;
+
+    public SpatialiteResultSetConverter(Connection conn, ResultSet rs) {
+        super(conn, rs);
+        this.odm = new SpatialiteValueConverterFactory(conn);
+    }
+
+    public void setMetadata(SpatialiteDSMetadata metadata) {
+        this.metadata = metadata;
+        //hack: todo: clean inheritance ?
+        if (this.odm != null) {
+            
((SpatialiteValueConverterFactory)this.odm).setMetadata(this.metadata);
+        }
+    }
+    
+    
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteSQLBuilder.java
                               (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialite/SpatialiteSQLBuilder.java
       2015-12-13 15:02:36 UTC (rev 4609)
@@ -0,0 +1,113 @@
+package com.vividsolutions.jump.datastore.spatialite;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jump.datastore.FilterQuery;
+import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesSQLBuilder;
+import com.vividsolutions.jump.workbench.JUMPWorkbench;
+
+/**
+ * Creates SQL query strings for a Spatial database. To be overloaded by 
classes
+ * implementing a spatial database support.
+ */
+public class SpatialiteSQLBuilder extends SpatialDatabasesSQLBuilder {
+
+  private String datasetName;
+
+  public SpatialiteSQLBuilder(SpatialiteDSMetadata dsMetadata, 
SpatialReferenceSystemID defaultSRID, String[] colNames) {
+    super(dsMetadata, defaultSRID, colNames);
+  }
+
+  /**
+   * Builds a valid SQL spatial query with the given spatial filter.
+   *
+   * @param query
+   * @return a SQL query to get column names
+   */
+  @Override
+  public String getSQL(FilterQuery query) {
+    this.datasetName = query.getDatasetName();
+    StringBuilder qs = new StringBuilder();
+    //HACK
+    String ret = "SELECT %s FROM %s WHERE %s AND (%s) %s";
+    String cols = getColumnListSpecifier(colNames, 
query.getGeometryAttributeName());
+    String bbox = buildBoxFilter(query);
+    String and = query.getCondition() == null ? "1" : query.getCondition();
+    String lim = (query.getLimit() != 0 && query.getLimit() != 
Integer.MAX_VALUE) ? " LIMIT " + query.getLimit() : "";
+
+    //System.out.println(qs);
+    String s = String.format(ret, cols, this.datasetName, bbox, and, lim); 
+    JUMPWorkbench.getInstance().getFrame().log(
+        "SQL query to get Spatial table features:\n\t"
+        + s, this.getClass());
+
+    return s;
+  }
+
+  /**
+   * Returns the string representing a SQL column definition. Implementors
+   * should take care of column names (case, quotes)
+   *
+   * @param colNames
+   * @param geomColName
+   * @return column list
+   */
+  @Override
+  protected String getColumnListSpecifier(String[] colNames, String 
geomColName) {
+    // Added double quotes around each column name in order to read mixed case 
table names
+    // correctly [mmichaud 2007-05-13]
+    StringBuilder buf = new StringBuilder();
+    SpatialiteDSMetadata dsm = (SpatialiteDSMetadata)getDbMetadata();
+    GeometricColumnType gcType = 
dsm.getGeoColTypesdMap().get(this.datasetName.toLowerCase() + "." + 
geomColName.toLowerCase());
+    String s = null;
+    switch (gcType) {
+      case SPATIALITE:
+        s = geomColName;
+        break;
+      case WKB:
+        s = String.format("st_geomFromWkb(%s) as %s", geomColName, 
geomColName);
+        break;
+      case WKT:
+        s = String.format("st_geomFromText(%s) as %s", geomColName, 
geomColName);
+        break;
+    }
+    // TODO: use previous code or remove it after check:
+    // geo col should be returned in its default type and handled by the 
converter
+    // according to the geo column type (avoid conversion overhead)
+
+    buf.append("").append(geomColName);
+    for (String colName : colNames) {
+      if (!geomColName.equalsIgnoreCase(colName)) {
+        buf.append(",").append(colName);
+      }
+    }
+    return buf.toString();
+  }
+
+  @Override
+  protected String buildBoxFilter(FilterQuery query) {
+    Envelope env = query.getFilterGeometry().getEnvelopeInternal();
+    String ret = "1";
+        // Example of Spatialite SQL: 
+    // select nom_comm from commune where st_envIntersects(wkt_geometry, 
bbox(516707,6279239,600721,6347851)
+    SpatialiteDSMetadata dsm = (SpatialiteDSMetadata)getDbMetadata();
+    if (dsm.isSpatialiteLoaded()) {
+        GeometricColumnType gcType = dsm.getGeoColTypesdMap().get(
+            query.getDatasetName().toLowerCase() + "." + 
query.getGeometryAttributeName().toLowerCase());
+        if (gcType == GeometricColumnType.SPATIALITE) {
+            ret = String.format("st_envIntersects(%s, %f,%f,%f,%f)", 
query.getGeometryAttributeName(), env.getMinX(),
+                    env.getMinY(), env.getMaxX(), env.getMaxY());
+        } else if (gcType == GeometricColumnType.WKB) {
+            ret = String.format("st_envIntersects(st_geomFromWkb(%s), 
%f,%f,%f,%f)", query.getGeometryAttributeName(), env.getMinX(),
+                    env.getMinY(), env.getMaxX(), env.getMaxY());
+        } else if (gcType == GeometricColumnType.WKT) {

@@ Diff output truncated at 100000 characters. @@

------------------------------------------------------------------------------
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to