Revision: 4579
          http://sourceforge.net/p/jump-pilot/code/4579
Author:   elnico
Date:     2015-12-07 17:07:02 +0000 (Mon, 07 Dec 2015)
Log Message:
-----------
Integration of the latest version of spatialDatabases plugin into the core, for 
Postgis and Oracle Spatial support.
Refactored methods: added a base package for spatialdatabases common code, each 
DB provider implementing custom operations.
Uses JDBC Database Metadata information as much as possible (indexes, column 
names, etc.).
Uses Ede introspection code to hide Oracle.* imports at compile time.

Modified Paths:
--------------
    
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
    
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.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

Added Paths:
-----------
    core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/
    
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/SpatialDatabasesSQLBuilder.java
    
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesValueConverterFactory.java

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java  
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/OracleDataStoreExtension.java  
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -7,11 +7,8 @@
 import com.vividsolutions.jump.workbench.WorkbenchContext;
 import com.vividsolutions.jump.workbench.plugin.Extension;
 import com.vividsolutions.jump.workbench.plugin.PlugInContext;
-import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.Statement;
 
 /**
  * 

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java 
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSConnection.java 
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,46 +1,37 @@
+/*
+ * 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.*;
+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.io.FeatureInputStream;
-
 import java.sql.Connection;
 import java.sql.SQLException;
 
 /**
+ *
+ * @author nicolas
  */
-public class OracleDSConnection implements DataStoreConnection {
+public class OracleDSConnection extends SpatialDatabasesDSConnection {
 
-    private OracleDSMetadata dbMetadata;
-    private Connection connection;
-
-    public OracleDSConnection(Connection conn) {
-        connection = conn;
-        dbMetadata = new OracleDSMetadata(this);
+    public OracleDSConnection(Connection con) {
+        super(con); // ?
+        connection = con;
+        this.dbMetadata = new OracleDSMetadata(this);
     }
-
-    public Connection getConnection() {
-        return connection;
+    
+    @Override
+    public SpatialDatabasesSQLBuilder getSqlBuilder(SpatialReferenceSystemID 
srid, String[] colNames) {
+      return new OracleSQLBuilder(this.dbMetadata, srid, colNames);
     }
 
-    public DataStoreMetadata getMetadata() {
-        return dbMetadata;
-    }
-
-    public FeatureInputStream execute(Query query) throws Exception {
-        if (query instanceof FilterQuery) {
-            try {
-                return executeFilterQuery((FilterQuery) query);
-            } catch (SQLException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        if (query instanceof AdhocQuery) {
-            return executeAdhocQuery((AdhocQuery) query);
-        }
-        throw new 
IllegalArgumentException(I18N.get(this.getClass().getName()+".unsupported-query-type"));
-    }
-
     /**
      * Executes a filter query.
      *
@@ -51,40 +42,10 @@
      * @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());
-
-        OracleSQLBuilder builder = new OracleSQLBuilder(srid, colNames, 
dbMetadata.getGeoIndexes());
-        String queryString = builder.getSQL(query);
-
-        return new OracleFeatureInputStream(connection, queryString, 
query.getPrimaryKey());
+        SpatialDatabasesFeatureInputStream fis = 
(SpatialDatabasesFeatureInputStream)super.executeFilterQuery(query);
+        return new OracleFeatureInputStream(fis.getConnection(), 
fis.getQueryString(), query.getPrimaryKey());
     }
-
-    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
-        String queryString = query.getQuery();
-        OracleFeatureInputStream ifs = new 
OracleFeatureInputStream(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;
-    }
-
-
-    public void close() throws DataStoreException {
-        try {
-            connection.close();
-        }
-        catch (Exception ex) { throw new DataStoreException(ex); }
-    }
-
-    public boolean isClosed() throws DataStoreException {
-        try {
-            return connection.isClosed();
-        } catch (SQLException e) {
-            throw new DataStoreException(e);
-        }
-    }
-
-}
\ No newline at end of file
+    
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java   
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDSMetadata.java   
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,383 +1,84 @@
+/*
+ * 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;
-import com.vividsolutions.jts.io.WKBReader;
-import com.vividsolutions.jump.datastore.DataStoreMetadata;
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import com.vividsolutions.jump.datastore.spatialdatabases.*;
 import com.vividsolutions.jump.datastore.GeometryColumn;
-import com.vividsolutions.jump.datastore.PrimaryKeyColumn;
-import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
-import com.vividsolutions.jump.datastore.jdbc.JDBCUtil;
-import com.vividsolutions.jump.datastore.jdbc.ResultSetBlock;
-import com.vividsolutions.jump.workbench.JUMPWorkbench;
-import java.sql.DatabaseMetaData;
-
-import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.*;
+import java.util.List;
 
-public class OracleDSMetadata implements DataStoreMetadata {
-    private static final String SQL_QUERY_LAYERS = "select distinct owner, 
table_name from ALL_SDO_GEOM_METADATA";
+public class OracleDSMetadata extends SpatialDatabasesDSMetadata {
 
-    private final WKBReader reader = new WKBReader();
-
-    private OracleDSConnection conn;
-    // connection username, used a default schema
-    private String userSchema;
-
-    private Map sridMap = new HashMap();
-    
-    // map storing the geo column names and the name of their index 
-    private HashMap<String, String> geoIndexes = new HashMap<String, String>();
-
-    public OracleDSMetadata(OracleDSConnection conn) {
-        this.conn = conn;
-
+    public OracleDSMetadata(DataStoreConnection con) {
+        conn = con;
+        // TODO: use bind parameters to avoid SQL injection
         try {
-            this.userSchema = conn.getConnection().getMetaData().getUserName();
+            this.defaultSchemaName = 
conn.getConnection().getMetaData().getUserName();
         } catch (SQLException ex) {
-            System.out.println(ex.toString());
+            System.err.println(ex.toString());
+            defaultSchemaName = "";
         }
-    }
-
-    public HashMap<String, String> getGeoIndexes() {
-        return geoIndexes;
-    }
-
-    public String[] getDatasetNames() {
-        final List datasetNames = new ArrayList();
-        // Spatial tables only.
-        JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get list of spatial data:\n\t" 
-                + SQL_QUERY_LAYERS, this.getClass());
-
-        JDBCUtil.execute(
-            conn.getConnection(),
-            SQL_QUERY_LAYERS,
-            new ResultSetBlock() {
-                public void yield(ResultSet resultSet) throws SQLException {
-                    while (resultSet.next()) {
-                        String schema = resultSet.getString(1);
-                        String table = resultSet.getString(2);
-                        // on Oracle, user's schema is the default schema
-                        if (!schema.equalsIgnoreCase(userSchema)) {
-                            table = schema + "." + table;
-                        }
-                        datasetNames.add(table);
-                    }
-                }
-            });
-        return (String[]) datasetNames.toArray(new 
String[datasetNames.size()]);
-    }
-
-    // TODO: check
-    public Envelope getExtents(String datasetName, String attributeName) {
-
-        final Envelope[] e = new Envelope[]{null};
-        // extent is taken from layer's metadata
-        String sql1 = "SELECT dim.* FROM ALL_SDO_GEOM_METADATA usgm, 
TABLE(usgm.diminfo) "
-            + "dim WHERE table_name = '" + getTableName(datasetName) + "' and 
owner='" + getSchemaName(datasetName) 
-            + "' and column_name = '" + attributeName + "'";
+        datasetNameQuery = "SELECT distinct asgm.OWNER, asgm.TABLE_NAME FROM 
ALL_SDO_GEOM_METADATA asgm";
+        spatialDbName = "Oracle Spatial";
+        spatialExtentQuery1 = "with tmp as (\n" +
+            "  SELECT dim.*\n" +
+            "  FROM ALL_SDO_GEOM_METADATA asgm, TABLE (asgm.diminfo) dim\n" +
+            "  WHERE owner = '%s' and table_name = '%s' AND 
COLUMN_NAME='%s'\n" +
+            ") select sdo_util.to_wktgeometry(SDO_GEOMETRY(\n" +
+            "    2003,\n" +
+            "    NULL,\n" +
+            "    NULL,\n" +
+            "    SDO_ELEM_INFO_ARRAY(1,1003,1),\n" +
+            "    SDO_ORDINATE_ARRAY((select sdo_lb from tmp where sdo_dimname 
= 'X'),\n" +
+            "                       (select sdo_lb from tmp where sdo_dimname 
= 'Y'), \n" +
+            "                       (select sdo_ub from tmp where sdo_dimname 
= 'X'),\n" +
+            "                       (select sdo_lb from tmp where sdo_dimname 
= 'Y'),\n" +
+            "                       (select sdo_ub from tmp where sdo_dimname 
= 'X'),\n" +
+            "                       (select sdo_ub from tmp where sdo_dimname 
= 'Y'),\n" +
+            "                       (select sdo_ub from tmp where sdo_dimname 
= 'X'),\n" +
+            "                       (select sdo_lb from tmp where sdo_dimname 
= 'Y'),\n" +
+            "                       (select sdo_lb from tmp where sdo_dimname 
= 'X'),\n" +
+            "                       (select sdo_lb from tmp where sdo_dimname 
= 'Y'))\n" +
+            "  )) as geom \n" +
+            "from dual";
         
-        JUMPWorkbench.getInstance().getFrame().log("SQL query to get 
extent:\n\t" + sql1, this.getClass());
-
-        final ResultSetBlock resultSetBlock = new ResultSetBlock() {
-            public void yield(ResultSet resultSet) throws Exception {
-                // looks only for X-Y dimension, though oracle metadata can 
store more
-                double xmin = 0, ymin = 0, xmax = 0, ymax = 0;
-                while (resultSet.next()) {
-                    if ("X".equalsIgnoreCase(resultSet.getString(1))) {
-                        xmin = resultSet.getDouble(2);
-                        xmax = resultSet.getDouble(3);
-                    }
-                    if ("Y".equalsIgnoreCase(resultSet.getString(1))) {
-                        ymin = resultSet.getDouble(2);
-                        ymax = resultSet.getDouble(3);
-                    }
-                }
-                e[0] = new Envelope(xmin, ymin, xmax, ymax);
-            }
-        };
-        try {
-            JDBCUtil.execute(conn.getConnection(), (sql1), resultSetBlock);
-            if (e[0] == null || e[0].isNull()) {
-                JDBCUtil.execute(conn.getConnection(), (sql1), resultSetBlock);
-            }
-        } catch (Exception ex1) {
-            // TODO: 
-            ex1.printStackTrace();
-        }
-        return e[0];
-    }
-
-    /**
-     * Returns the list of geometryColumns for the given name in Oracle,
-     * metadata does not store this info: queries the table to get distinct 
list
-     * of geometries: if several found: geometry type. Also retrieves geom srid
-     * from metadata and stores it in the map
-     *
-     * @param datasetName
-     * @return
-     */
-    public List<GeometryColumn> getGeometryAttributes(final String 
datasetName) {
-        final List<GeometryColumn> geometryAttributes = new 
ArrayList<GeometryColumn>();
-        String sql = "select column_name, srid from ALL_SDO_GEOM_METADATA "
-            + geomColumnMetadataWhereClause("owner", "table_name", 
datasetName);
+        spatialExtentQuery2 = "select 
sdo_util.to_wktgeometry(sdo_aggr_mbr(%s)) as geom from %s.%s";
         
-        JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get geometry attributes from a spatial table:\n\t" 
-                + sql, this.getClass());
-
-        JDBCUtil.execute(
-            conn.getConnection(), sql,
-            new ResultSetBlock() {
-                public void yield(ResultSet resultSet) throws SQLException {
-                    while (resultSet.next()) {
-                        String colName = resultSet.getString(1);
-                        int srid = resultSet.getInt(2);
-                        sridMap.put(datasetName + "#" + colName, new 
SpatialReferenceSystemID(srid));
-                        geometryAttributes.add(new GeometryColumn(
-                                colName,
-                                srid
-                            //              ,resultSet.getString(3)
-                            ));
-                    }
-                }
-            });
-        
-        // TODO: move MD retrieving in a JDBCUtil static method and use JDBC 
metadata
-        // as deep as we can ?
-        geoIndexes = new HashMap<String, String>();
-        try {
-            // gets info in cnx metadata:
-            DatabaseMetaData md = conn.getConnection().getMetaData();
-            ResultSet rs = md.getIndexInfo(null, getSchemaName(datasetName), 
getTableName(datasetName), false, true);
-            StringBuilder b = new StringBuilder();
-            while (rs.next()) {
-                if (rs.getString(6) != null && rs.getString(9) != null) {
-                    geoIndexes.put(rs.getString(9), rs.getString(6));
-                }
-            }
-        } catch (SQLException ex) {
-            // TODO
-        }
-
-        // gets the geometry column type for each geo col
-        for (final GeometryColumn gc : geometryAttributes) {
-            sql = "select distinct t." + gc.getName() + ".sdo_gtype from " + 
datasetName + " t";
-            JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get geometry column type :\n\t" 
-                + sql, this.getClass());
-
-            JDBCUtil.execute(
-                conn.getConnection(), sql,
-                new ResultSetBlock() {
-                    public void yield(ResultSet resultSet) throws SQLException 
{
-                        int gtype = 0;
-                        int i = 0;
-                        String type = "";
-                        while (resultSet.next()) {
-                            gtype = resultSet.getInt(1) % 10;
-                            if (i == 0) {
-                                switch (gtype) {
-                                    case 1:
-                                        type = "POINT";
-                                        break;
-                                    case 2:
-                                        type = "LINESTRING";
-                                        break;
-                                    case 3:
-                                        type = "POLYGON";
-                                        break;
-                                    case 4:
-                                        type = "GEOMETRYCOLLECTION";
-                                        break;
-                                    case 5:
-                                        type = "MULTIPOINT";
-                                        break;
-                                    case 6:
-                                        type = "MULTILINESTRING";
-                                        break;
-                                    case 7:
-                                        type = "MULTIPOLYGON";
-                                        break;
-                                    default:
-                                        type = "GEOMETRY";
-                                }
-                            } else if (i > 0) {
-                                // more than one geo type:
-                                type = "GEOMETRY";
-                                break;
-                            }
-                            i++;
-                        }
-                        gc.setType(type);
-                    }
-                });
-            // also gets info about index is column indexed: useful to avoid 
calling sdo_filter on
-            // a non-indexed column
-            gc.setIndexed(geoIndexes.containsKey(gc.getName()));
-        }
-        return geometryAttributes;
+        geoColumnsQuery = "select t.column_name, t.srid, 'SDO_GEOMETRY' as 
type from ALL_SDO_GEOM_METADATA t "
+            + "where t.owner = '%s' and t.table_name = '%s'";
+        sridQuery = "select t.srid from ALL_SDO_GEOM_METADATA t "
+            + "where t.owner = '%s' and t.table_name = '%s' and t.COLUMN_NAME 
= '%s'";
     }
 
-    /**
-     * Returns PRIMARY KEY columns of dataset names. // TODO: check STATUS PK:
-     * enabled/disabled
-     *
-     * @param datasetName name of the table (optionally prefixed by the schema
-     * name)
-     * @return the list of columns involved in the Primary Key (generally, a
-     * single column)
-     */
-    public List<PrimaryKeyColumn> getPrimaryKeyColumns(String datasetName) {
-        final List<PrimaryKeyColumn> identifierColumns = new 
ArrayList<PrimaryKeyColumn>();
-        // query taken from 
http://www.alberton.info/postgresql_meta_info.html#.UewsFG29b0Q
-        String sql
-            = "SELECT cols.table_name, cols.column_name \n"
-            + "FROM all_constraints cons, all_cons_columns cols \n"
-            + "WHERE cols.table_name = '" + getTableName(datasetName) + "' and 
cols.OWNER = '"
-            + getSchemaName(datasetName) + "' \n"
-            + "AND cons.constraint_type = 'P' \n"
-            + "AND cons.constraint_name = cols.constraint_name \n"
-            + "AND cons.owner = cols.owner \n"
-            + "ORDER BY cols.table_name, cols.position";
-        
-        JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get PK from a spatial table:\n\t" 
-                + sql, this.getClass());
-
-        JDBCUtil.execute(
-            conn.getConnection(), sql,
-            new ResultSetBlock() {
-                public void yield(ResultSet resultSet) throws SQLException {
-                    while (resultSet.next()) {
-                        identifierColumns.add(new PrimaryKeyColumn(
-                                resultSet.getString(1),
-                                resultSet.getString(2)));
-                    }
-                }
-            });
-        return identifierColumns;
+    @Override
+    public String getSpatialExtentQuery1(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery1, schema, table, 
attributeName);
     }
 
-    /**
-     * Fetch only not hidden columns
-     *
-     * @param datasetName
-     * @return
-     */
-    public String[] getColumnNames(String datasetName) {
-        String sql = "SELECT cols.COLUMN_NAME, cols.DATA_TYPE \n"
-            + "FROM ALL_TAB_COLS cols \n"
-            + "WHERE hidden_column = 'NO' and cols.table_name = '" + 
getTableName(datasetName) + "' and cols.OWNER = '"
-            + getSchemaName(datasetName) + "' \n"
-            + "ORDER BY cols.table_name, cols.COLUMN_ID";
-        
-        JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get column names and types from a spatial 
table:\n\t" 
-                + sql, this.getClass());
-
-        ColumnNameBlock block = new ColumnNameBlock();
-        JDBCUtil.execute(conn.getConnection(), sql, block);
-        return block.colName;
+    @Override
+    public String getSpatialExtentQuery2(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery2, attributeName, schema, 
table);
     }
 
-    /**
-     * Returns the schema name based on the given tableName: string before . if
-     * exists, else returns userName
-     *
-     * @param tableName
-     * @return
-     */
-    private String getSchemaName(String tableName) {
-        int dotPos = tableName.indexOf(".");
-        String schema = this.userSchema;
-        if (dotPos != -1) {
-            schema = tableName.substring(0, dotPos);
-        }
-        return schema;
+    @Override
+    public String getGeoColumnsQuery(String datasetName) {
+        return String.format(this.geoColumnsQuery, getSchemaName(datasetName), 
getTableName(datasetName));
     }
 
-    /**
-     * Returns the table name based on the given tableName: string after "." if
-     * exists, else returns userName
-     *
-     * @param tableName
-     * @return
-     */
-    private String getTableName(String tableName) {
-        int dotPos = tableName.indexOf(".");
-        String ret = tableName;
-        if (dotPos != -1) {
-            ret = tableName.substring(0, dotPos);
-        }
-        return ret;
+    @Override
+    public String getSridQuery(String schemaName, String tableName, String 
colName) {
+        // TODO
+        return String.format(this.sridQuery, schemaName, tableName, colName);
     }
-
-    @Deprecated
-    public SpatialReferenceSystemID getSRID(String tableName, String colName)
-        throws SQLException {
-        String key = tableName + "#" + colName;
-        if (!sridMap.containsKey(key)) {
-            // not in cache, so query it
-            String srid = querySRID(tableName, colName);
-            sridMap.put(key, new SpatialReferenceSystemID(srid));
-        }
-        return (SpatialReferenceSystemID) sridMap.get(key);
+    
+    @Override
+    public List<GeometryColumn> getGeometryAttributes(String datasetName) {
+        String sql = this.getGeoColumnsQuery(datasetName);
+        return getGeometryAttributes(sql, datasetName);
     }
 
-    // TODO: should never be called: sridMap should be filled when getting geo 
columns
-    @Deprecated
-    private String querySRID(String tableName, String colName) {
-        final StringBuffer srid = new StringBuffer();
-    // Changed by Michael Michaud 2010-05-26 (throwed exception for empty 
tableName)
-        // String sql = "SELECT getsrid(" + colName + ") FROM " + tableName + 
" LIMIT 1";
-        String[] tokens = tableName.split("\\.", 2);
-        String schema = tokens.length == 2 ? tokens[0] : "public";
-        String table = tokens.length == 2 ? tokens[1] : tableName;
-        String sql = "SELECT srid FROM geometry_columns where (f_table_schema 
= '" + schema + "' and f_table_name = '" + table + "')";
-        
-        JUMPWorkbench.getInstance().getFrame().log(
-            "SQL query to get geometry column SRID:\n\t" 
-                + sql, this.getClass());
-        
-        // End of the fix
-        JDBCUtil.execute(conn.getConnection(), sql, new ResultSetBlock() {
-            public void yield(ResultSet resultSet) throws SQLException {
-                if (resultSet.next()) {
-                    srid.append(resultSet.getString(1));
-                }
-            }
-        });
-
-        return srid.toString();
-    }
-
-    private String geomColumnMetadataWhereClause(String schemaCol, String 
tableCol, String tableName) {
-        // [mmichaud 2011-07-24] Fixed a bug related to tables having common
-        // names in public schema and another schema
-        int dotPos = tableName.indexOf(".");
-        String schema = this.userSchema;
-        String table = tableName;
-        if (dotPos != -1) {
-            schema = tableName.substring(0, dotPos);
-            table = tableName.substring(dotPos + 1);
-        }
-        return "WHERE " + schemaCol + " = '" + schema + "'"
-            + " AND " + tableCol + " = '" + table + "'";
-    }
-
-    private static class ColumnNameBlock implements ResultSetBlock {
-
-        List colList = new ArrayList();
-        String[] colName;
-
-        public void yield(ResultSet resultSet) throws SQLException {
-            while (resultSet.next()) {
-                colList.add(resultSet.getString(1));
-            }
-            colName = (String[]) colList.toArray(new String[colList.size()]);
-        }
-    }
-
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
  2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleDataStoreDriver.java
  2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,110 +1,40 @@
+/*
+ * 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 java.sql.*;
-
-import com.vividsolutions.jump.datastore.*;
-
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
 import com.vividsolutions.jump.parameter.ParameterList;
-import com.vividsolutions.jump.parameter.ParameterListSchema;
-import com.vividsolutions.jump.util.Blackboard;
-import com.vividsolutions.jump.workbench.JUMPWorkbench;
 
 /**
- *  * A driver for supplying {@link OracleDSConnection}s
+ * A driver for supplying {@link SpatialDatabaseDSConnection}s
  */
 public class OracleDataStoreDriver
-    implements DataStoreDriver
-{
-  public static final String DRIVER_NAME = "Oracle Spatial";
-  /** name of the class dealing with SDO geometries from Geotools jar.
-   * Oracle driver needs this class
-   */
-  public static final String GT_SDO_CLASS_NAME = 
"org.geotools.data.oracle.sdo.SDO";
-  public static final String JDBC_CLASS = "oracle.jdbc.driver.OracleDriver";
-  // using new URL style: jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE
-  public static final String URL_PREFIX = "jdbc:oracle:thin:@//";
+    extends SpatialDatabasesDataStoreDriver {
+    // TODO: uniformize
+    public final static String JDBC_CLASS = "oracle.jdbc.driver.OracleDriver";
+    public static final String GT_SDO_CLASS_NAME = 
"org.geotools.data.oracle.sdo.SDO";
 
-  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";
 
-  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);
-  
-  /** The database driver */
-  private Driver driver;
-
-  public OracleDataStoreDriver(Driver driver) {
-    this.driver = driver;
-  }
-
-  public OracleDataStoreDriver() {
-    this(null);
-  }
-
-  public String getName()
-  {
-    return DRIVER_NAME;
-  }
-  public ParameterListSchema getParameterListSchema()
-  {
-    return schema;
-  }
-  public DataStoreConnection createConnection(ParameterList params)
-      throws Exception
-  {
-    String host = params.getParameterString(PARAM_Server);
-    int port = params.getParameterInt(PARAM_Port);
-    String database = params.getParameterString(PARAM_Instance);
-    String user = params.getParameterString(PARAM_User);
-    String password = params.getParameterString(PARAM_Password);
-
-    String url
-        = String.valueOf(new StringBuffer(URL_PREFIX).append
-        (host).append
-        (":").append
-        (port).append
-        ("/").append(database));
-
-    // mmichaud 2013-08-27 workaround for ticket #330
-    String savePreferIPv4Stack = 
System.getProperty("java.net.preferIPv4Stack");
-    String savePreferIPv6Addresses = 
System.getProperty("java.net.preferIPv6Addresses");
-    System.setProperty("java.net.preferIPv4Stack", "true");
-    System.setProperty("java.net.preferIPv6Addresses", "false");
-
-    JUMPWorkbench.getInstance().getFrame().log("Url for oracle: " + url, 
this.getClass());
-    Connection conn = DriverManager.getConnection(url, user, password);
-
-    if (savePreferIPv4Stack == null) {
-        System.getProperties().remove("java.net.preferIPv4Stack");
-    } else {
-        System.setProperty("java.net.preferIPv4Stack", savePreferIPv4Stack);
+    public OracleDataStoreDriver() {
+        this.driverName = "Oracle Spatial";
+        this.jdbcClass = OracleDataStoreDriver.JDBC_CLASS;
+        this.urlPrefix = "jdbc:oracle:thin:@//";
     }
-    if (savePreferIPv6Addresses == null) {
-        System.getProperties().remove("java.net.preferIPv6Addresses");
-    } else {
-        System.setProperty("java.net.preferIPv6Addresses", 
savePreferIPv6Addresses);
+    
+    /**
+     * 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());
     }
-    return new OracleDSConnection(conn);
-  }
-  public boolean isAdHocQuerySupported() {
-      return true;
-  }
-
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
       2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleFeatureInputStream.java
       2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,113 +1,35 @@
+/*
+ * 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.feature.Feature;
-import com.vividsolutions.jump.feature.FeatureSchema;
-import com.vividsolutions.jump.io.BaseFeatureInputStream;
-
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
 import java.sql.Connection;
 import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
 
 /**
- * Reads features from a PostgreSQL/PostGIS database.
+ *
+ * @author nicolas
  */
-public class OracleFeatureInputStream extends BaseFeatureInputStream {
-    
-    private FeatureSchema featureSchema;
-    private Connection conn;
-    private String queryString;
-    private boolean initialized = false;
-    private Exception savedException;
-
-    private Statement stmt = null;
-    private ResultSet rs = null;
-    private OracleResultSetConverter mapper;
-
-    int geometryColIndex = -1;
-    String externalIdentifier = null;  // added on 2013-08-07
-
+public class OracleFeatureInputStream extends 
SpatialDatabasesFeatureInputStream {
     public OracleFeatureInputStream(Connection conn, String queryString) {
-        this.conn = conn;
-        this.queryString = queryString;
+        super(conn, queryString);
     }
 
     public OracleFeatureInputStream(Connection conn, String queryString, 
String externalIdentifier) {
-        this.conn = conn;
-        this.queryString = queryString;
-        this.externalIdentifier = externalIdentifier;
+        super(conn, queryString, externalIdentifier);
     }
-
+    
     /**
-     * @return The underlaying {@link Connection}.
+     * Returns a PostgisResultSetConverter
+     * @param rs
+     * @return 
      */
-    public Connection getConnection(){return conn;}
-  
-    /**
-     * @return The underlaying {@link Statement}.
-     * Useful to cancel the query on the server if the PlugIn is interrupted 
-     */
-    public Statement getStatement(){return stmt;}
-
-    private void init() throws SQLException {
-        if (initialized) {
-            return;
-        }
-        initialized = true;
-    
-        stmt = conn.createStatement();
-        String parsedQuery = queryString;
-        try {
-            rs = stmt.executeQuery(parsedQuery);
-        } catch (SQLException e) {
-            SQLException sqle = new SQLException("Error : " + parsedQuery);
-            sqle.setNextException(e);
-            throw sqle;
-        }
-        mapper = new OracleResultSetConverter(conn, rs);
-        featureSchema = mapper.getFeatureSchema();
-        if (externalIdentifier != null) {
-            
featureSchema.setExternalPrimaryKeyIndex(featureSchema.getAttributeIndex(externalIdentifier));
-        }
+    @Override
+    protected SpatialDatabasesResultSetConverter 
getResultSetConverter(ResultSet rs) {
+      return new OracleResultSetConverter(conn, rs);
     }
-    
-    protected Feature readNext() throws Exception {
-        if (savedException != null) throw savedException;
-        if (! initialized) init();
-        if (rs == null) return null;
-        if (! rs.next()) return null;
-        return getFeature();
-    }
-    
-    private Feature getFeature() throws Exception {
-        return mapper.getFeature();
-    }
-    
-    public void close() throws SQLException {
-        if (rs != null) {
-            rs.close();
-        }
-        if (stmt != null) {
-            stmt.close();
-        }
-    }
-    
-    public FeatureSchema getFeatureSchema() {      
-        if (featureSchema != null) {
-            return featureSchema;
-        }
-        try {
-            init();
-        }
-        catch (SQLException ex) {
-            String message = ex.getLocalizedMessage();
-            Throwable nextT = ex.getNextException();
-            if (nextT != null) message = message + "\n" + 
nextT.getLocalizedMessage();
-            throw new Error(message);
-        }
-        if (featureSchema == null) {
-            featureSchema = new FeatureSchema();
-        }
-        return featureSchema;
-    }
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
       2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleResultSetConverter.java
       2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,94 +1,27 @@
+/*
+ * 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.jdbc.ValueConverter;
-import com.vividsolutions.jump.feature.AttributeType;
-import com.vividsolutions.jump.feature.BasicFeature;
+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;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
 
 /**
- * Implements the mapping between a result set and
- * a {@link FeatureSchema} and {@link Feature} set.
+ * 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
+ * This is a transient worker class, whose lifetime should be no longer than 
the
+ * lifetime of the provided ResultSet
  */
-public class OracleResultSetConverter
-{
-  private ResultSet rs;
-  private FeatureSchema featureSchema;
-  private int geometryColIndex = -1;
-  private ValueConverter[] mapper;
-  private OracleValueConverterFactory odm;
-  private boolean isInitialized = false;
+public class OracleResultSetConverter extends 
SpatialDatabasesResultSetConverter {
 
-  public OracleResultSetConverter(Connection conn, ResultSet rs)
-  {
-    odm = new OracleValueConverterFactory(conn);
-    this.rs = rs;
-  }
-
-  public FeatureSchema getFeatureSchema()
-      throws SQLException
-  {
-    init();
-    return featureSchema;
-  }
-
-  public Feature getFeature()
-      throws Exception
-  {
-    init();
-    Feature f = new BasicFeature(featureSchema);
-    for (int i = 0; i < mapper.length; i++) {
-      f.setAttribute(i, mapper[i].getValue(rs, i + 1));
+    public OracleResultSetConverter(Connection conn, ResultSet rs) {
+        super(conn, rs);
+        this.odm = new OracleValueConverterFactory(conn);
     }
-    return f;
-  }
-
-  private void init()
-    throws SQLException
-  {
-    if (isInitialized) return;
-    isInitialized = true;
-
-    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();
-
-    for (int i = 0; i < numberOfColumns; i++)
-    {
-      mapper[i] = odm.getConverter(rsmd, i + 1);
-      String colName = rsmd.getColumnName(i + 1);
-      // only handles one geometry col for now [MD ?]
-      // Convert the first geometry into AttributeType.GEOMETRY and the 
following ones
-      // into AttributeType.STRINGs [mmichaud 2007-05-13]
-      if (mapper[i].getType() == AttributeType.GEOMETRY) {
-        if (featureSchema.getGeometryIndex() == -1) {
-          // fixed by mmichaud using a patch from jaakko [2008-05-21] :
-          // use colName instead of "GEOMETRY" for attribute name
-          featureSchema.addAttribute(colName, mapper[i].getType());
-        }
-        else {
-            // other oracle geom columns are treated as text:
-          //mapper[i] = odm.;
-          featureSchema.addAttribute(colName, AttributeType.STRING);
-        }
-      }
-      else {
-          featureSchema.addAttribute(colName, mapper[i].getType());
-      }
-    }
-  }
-
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java   
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleSQLBuilder.java   
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,49 +1,52 @@
+/*
+ * 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;
-import com.vividsolutions.jts.geom.Geometry;
 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;
 import com.vividsolutions.jump.workbench.JUMPWorkbench;
-import java.util.Map;
+import java.sql.SQLException;
 
 /**
- * Creates SQL query strings for a PostGIS database
+ * Creates SQL query strings for a Spatial database. To be overloaded by 
classes
+ * implementing a spatial database support.
  */
-public class OracleSQLBuilder {
+public class OracleSQLBuilder extends SpatialDatabasesSQLBuilder {
 
-    private SpatialReferenceSystemID defaultSRID = null;
-    private String[] colNames = null;
-    private Map<String, String> geoIndexes = null;
-
-    public OracleSQLBuilder(SpatialReferenceSystemID defaultSRID, String[] 
colNames) {
-        this.defaultSRID = defaultSRID;
-        this.colNames = colNames;
+    public OracleSQLBuilder(SpatialDatabasesDSMetadata dbMetadata, 
+        SpatialReferenceSystemID defaultSRID, String[] colNames) {
+      
+        super(dbMetadata, defaultSRID, colNames);
+        
     }
 
-    public OracleSQLBuilder(SpatialReferenceSystemID defaultSRID, String[] 
colNames, Map<String, String> geoIndexes) {
-        this(defaultSRID, colNames);
-        this.geoIndexes = geoIndexes;
-    }
-
+    /**
+     * 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) {
-        return buildQueryString(query);
-    }
-
-    private String buildQueryString(FilterQuery query) {
         StringBuilder qs = new StringBuilder();
         //HACK
         // surrond query by a rownum clause, used for limit
-        qs.append("SELECT ").append(getColumnListSpecifier(colNames, 
query.getGeometryAttributeName(), false));
+        qs.append("SELECT ROWNUM, ").append(getColumnListSpecifier(colNames, 
query.getGeometryAttributeName()));
         qs.append(" FROM ( ");
         qs.append("SELECT ");
-        qs.append(getColumnListSpecifier(colNames, 
query.getGeometryAttributeName(), true));
+        qs.append(getColumnListSpecifier(colNames, 
query.getGeometryAttributeName()));
         qs.append(" FROM ");
         // fixed by mmichaud on 2010-05-27 for mixed case dataset names
         qs.append("\"").append(query.getDatasetName().replaceAll("\\.", 
"\".\"")).append("\"");
         qs.append(" t WHERE ");
 
-        qs.append(buildBoxFilter(query.getGeometryAttributeName(), 
query.getSRSName(), query.getFilterGeometry()));
+        qs.append(buildBoxFilter(query));
 
         String whereCond = query.getCondition();
         if (whereCond != null) {
@@ -51,7 +54,7 @@
             qs.append(whereCond);
         }
         qs.append(")");
-        
+
         int limit = query.getLimit();
         if (limit != 0 && limit != Integer.MAX_VALUE) {
             qs.append(" where ROWNUM <= ").append(limit);
@@ -64,59 +67,18 @@
         return qs.toString();
     }
 
-    /**
-     * Buuilds a bbox filter only if geo column is indexed with a valid 
spatial index
-     * @param geometryColName
-     * @param SRID
-     * @param geom
-     * @return 
-     */
-    private String buildBoxFilter(String geometryColName, 
SpatialReferenceSystemID SRID, Geometry geom) {
-        StringBuilder buf = new StringBuilder("1=1");
-        
-        if (this.geoIndexes != null && 
this.geoIndexes.containsKey(geometryColName)) {
-            buf = new StringBuilder();
-            Envelope env = geom.getEnvelopeInternal();
+    ;
 
-            // Example of Postgis SQL: where sdo_filter (geom, 
SDO_geometry(2003,2154,NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(100225,1002375,6549646,6810524)))
 = 'TRUE'
-            String srid = getSRID(SRID) == null ? "null" : getSRID(SRID);
-
-            // fixed by mmichaud on 2010-05-27 for mixed case geometryColName 
names
-            buf.append("sdo_filter(\"").append(geometryColName).append("\" , 
SDO_geometry(");
-            
buf.append("2003,").append(srid).append(",NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(");
-            buf.append(env.getMinX()).append(", 
").append(env.getMinY()).append(", ").append(env.getMaxX()).append(", 
").append(env.getMaxY());
-            buf.append(srid).append(")))='TRUE'");
-
-            JUMPWorkbench.getInstance().getFrame().log(
-                "SQL query fragment to get spatial table BBOX filter:\n\t" 
-                + buf.toString(), this.getClass());
-        }
-
-        return buf.toString();
-    }
-
-    private String getSRID(SpatialReferenceSystemID querySRID) {
-        SpatialReferenceSystemID srid = defaultSRID;
-        if (!querySRID.isNull()) {
-            srid = querySRID;
-        }
-
-        if (srid.isNull() || srid.getString().trim().length() == 0) {
-            return null;
-        } else {
-            return srid.getString();
-        }
-    }
-
-    private String getColumnListSpecifier(String[] colNames, String 
geomColName, boolean addRownum) {
-    // Added double quotes around each column name in order to read mixed case 
table names
-        // correctly [mmichaud 2007-05-13]
+  /**
+   * 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) {
         StringBuilder buf = new StringBuilder();
-    // fixed by mmichaud using a patch from jaakko [2008-05-21]
-        // query geomColName as geomColName instead of geomColName as 
geomColName + "_wkb"
-        if (addRownum) {
-            buf.append("ROWNUM, ");
-        }
         buf.append(geomColName).append(" as 
").append("\"").append(geomColName).append("\"");
         for (String colName : colNames) {
             if (!geomColName.equalsIgnoreCase(colName)) {
@@ -125,4 +87,41 @@
         }
         return buf.toString();
     }
+
+    @Override
+    protected String buildBoxFilter(FilterQuery query) {
+        StringBuilder buf = new StringBuilder("1=1");
+
+        // spatial query in Oracle is only available if geom column is indexed.
+        // This information is found during datastoreDSMetadata init.
+        // todo names can contain dots ?
+        // todo: oracle always have a schema name ?
+      try {
+        if (super.getDbMetadata().isIndexed(query.getDatasetName(), 
query.getGeometryAttributeName())) {
+          buf = new StringBuilder();
+          Envelope env = query.getFilterGeometry().getEnvelopeInternal();
+
+          // Example of Postgis SQL: where sdo_filter (geom, 
SDO_geometry(2003,2154,NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(100225,1002375,6549646,6810524)))
 = 'TRUE'
+          String srid = getSRID(query.getSRSName()) == null ? "null" : 
getSRID(query.getSRSName());
+
+          // fixed by mmichaud on 2010-05-27 for mixed case geometryColName 
names
+          
buf.append("sdo_filter(\"").append(query.getGeometryAttributeName()).append("\" 
, SDO_geometry(");
+          
buf.append("2003,").append(srid).append(",NULL,SDO_elem_info_array(1,1003,3),SDO_ordinate_array(");
+          // force min/max values to avoid a ORA-01426: numeric overflow with 
some extents OJ can generate
+          buf.append(env.getMinX()).append(", 
").append(env.getMinY()).append(", ").append(env.getMaxX()).append(", 
").append(env.getMaxY());
+          buf.append(srid).append(")))='TRUE'");
+          
+          JUMPWorkbench.getInstance().getFrame().log(
+              "SQL query fragment to get spatial table BBOX filter:\n\t" 
+                  + buf.toString(), this.getClass());
+        }
+      } catch (SQLException ex) {
+        JUMPWorkbench.getInstance().getFrame().log(
+            "cannot guess if geo column is indexed, error: "+ ex.getMessage(), 
this.getClass());
+        //TODO: remove ?
+        ex.printStackTrace();
+      }
+        
+        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-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/oracle/OracleValueConverterFactory.java
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,131 +1,88 @@
+/*
+ * 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 static 
com.vividsolutions.jump.datastore.oracle.OracleDataStoreDriver.JDBC_CLASS;
-
-import java.sql.*;
-import java.io.*;
+import com.vividsolutions.jts.io.ParseException;
+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.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
 
-import com.vividsolutions.jump.feature.*;
-import com.vividsolutions.jts.geom.*;
-import com.vividsolutions.jts.io.*;
-import com.vividsolutions.jump.datastore.jdbc.*;
-//import oracle.jdbc.OracleConnection;
-//import oracle.sql.STRUCT;
-//import org.geotools.data.oracle.sdo.GeometryConverter;
-
 /**
  *
  */
-public class OracleValueConverterFactory
-{
-  // should lazily init these
-  private final ValueConverter ORA_STRUCT_GEOMETRY_MAPPER = new 
OracleStructGeometryValueConverter();
-    public final ValueConverter WKB_OBJECT_MAPPER   = new 
OracleValueConverterFactory.WKBObjectValueConverter();
+public class OracleValueConverterFactory extends 
SpatialDatabasesValueConverterFactory {
 
-  private final Connection conn;
-  private final WKBReader wkbReader = new WKBReader();
-  private final WKTReader wktReader = new WKTReader();
+  protected final ValueConverter ORA_STRUCT_GEOMETRY_MAPPER = new 
OracleStructGeometryValueConverter();
 
+  class OracleStructGeometryValueConverter implements ValueConverter {
+
+    public AttributeType getType() {
+      return AttributeType.GEOMETRY;
+    }
+
+    public Object getValue(ResultSet rs, int columnIndex) throws IOException,
+        SQLException, ParseException, ClassNotFoundException,
+        NoSuchMethodException, SecurityException, InstantiationException,
+        IllegalAccessException, IllegalArgumentException,
+        InvocationTargetException {
+      Object geometryObject = rs.getObject(columnIndex);
+      Class converterClazz = Class
+          .forName("org.geotools.data.oracle.sdo.GeometryConverter");
+      Class connectionClazz = Class.forName("oracle.jdbc.OracleConnection");
+      Class structClazz = Class.forName("oracle.sql.STRUCT");
+      Method converterMethod = converterClazz.getMethod("asGeometry",
+          new Class[]{structClazz});
+
+      Constructor constructor = converterClazz
+          .getDeclaredConstructor(connectionClazz);
+      Object converter = constructor.newInstance(connectionClazz.cast(rs
+          .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);
+    }
+  }
+
   public OracleValueConverterFactory(Connection conn) {
-    this.conn = conn;
+    super(conn);
   }
 
+  @Override
   public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
-      throws SQLException
-  {
+      throws SQLException {
     String classname = rsm.getColumnClassName(columnIndex);
     String dbTypeName = rsm.getColumnTypeName(columnIndex);
 
     if (dbTypeName.equalsIgnoreCase("MDSYS.SDO_GEOMETRY")) {
-        // WKB is now the normal way to store geometry in PostGIS [mmichaud 
2007-05-13]
-        return ORA_STRUCT_GEOMETRY_MAPPER;
+      return ORA_STRUCT_GEOMETRY_MAPPER;
     }
 
     // handle the standard types
     ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm, 
columnIndex);
-    if (stdConverter != null)
+    if (stdConverter != null) {
       return stdConverter;
+    }
 
     // default - can always show it as a string!
     return ValueConverterFactory.STRING_MAPPER;
   }
-  
 
-    class OracleStructGeometryValueConverter implements ValueConverter {
-      public AttributeType getType() {
-        return AttributeType.GEOMETRY;
-      }
-  
-      public Object getValue(ResultSet rs, int columnIndex) throws IOException,
-          SQLException, ParseException, ClassNotFoundException,
-          NoSuchMethodException, SecurityException, InstantiationException,
-          IllegalAccessException, IllegalArgumentException,
-          InvocationTargetException 
-      {
-        Object geometryObject = rs.getObject(columnIndex);
-        Class converterClazz = Class
-            .forName("org.geotools.data.oracle.sdo.GeometryConverter");
-        Class connectionClazz = Class.forName("oracle.jdbc.OracleConnection");
-        Class structClazz = Class.forName("oracle.sql.STRUCT");
-        Method converterMethod = converterClazz.getMethod("asGeometry",
-            new Class[] { structClazz });
-
-        Constructor constructor = converterClazz
-            .getDeclaredConstructor(connectionClazz);
-        Object converter = constructor.newInstance(connectionClazz.cast(rs
-            .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);
-      }
-    }
-
-    class WKBObjectValueConverter implements ValueConverter
-    {
-        public AttributeType getType() { return AttributeType.OBJECT; }
-        public Object getValue(ResultSet rs, int columnIndex)
-                throws IOException, SQLException, ParseException
-        {
-            byte[] bytes = rs.getBytes(columnIndex);
-
-            //so rs.getBytes will be one of two things:
-            //1. The actual bytes of the WKB if someone did ST_AsBinary
-            //2. The bytes of hex representation of the WKB.
-
-            //in the case of #1, according to the WKB spec, the byte value
-            //can only be 0 or 1.
-            //in the case of #2, it's a hex string, so values range from ascii 
0-F
-            //use this logic to determine how to process the bytes.
-
-            Geometry geometry = null;
-            if(bytes == null || bytes.length <= 0)
-            {
-                geometry = wktReader.read("GEOMETRYCOLLECTION EMPTY");
-            }
-            else
-            {
-                //assume it's the actual bytes (from ST_AsBinary)
-                byte[] realWkbBytes = bytes;
-                if(bytes[0] >= '0')
-                {
-                    //ok, it's hex, convert hex string to actual bytes
-                    String hexString = new String(bytes);
-                    realWkbBytes = WKBReader.hexToBytes(hexString);
-                }
-
-                geometry = wkbReader.read(realWkbBytes);
-            }
-
-            return geometry;
-        }
-    }
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
   2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSConnection.java
   2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,46 +1,37 @@
+/*
+ * 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.*;
+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.io.FeatureInputStream;
-
 import java.sql.Connection;
 import java.sql.SQLException;
 
 /**
+ *
+ * @author nicolas
  */
-public class PostgisDSConnection implements DataStoreConnection {
+public class PostgisDSConnection extends SpatialDatabasesDSConnection {
 
-    private PostgisDSMetadata dbMetadata;
-    private Connection connection;
-
-    public PostgisDSConnection(Connection conn) {
-        connection = conn;
-        dbMetadata = new PostgisDSMetadata(this);
+    public PostgisDSConnection(Connection con) {
+        super(con); // ?
+        connection = con;
+        this.dbMetadata = new PostgisDSMetadata(this);
     }
-
-    public Connection getConnection() {
-        return connection;
+    
+    @Override
+    public SpatialDatabasesSQLBuilder getSqlBuilder(SpatialReferenceSystemID 
srid, String[] colNames) {
+      return new PostgisSQLBuilder(this.dbMetadata, srid, colNames);
     }
 
-    public DataStoreMetadata getMetadata() {
-        return dbMetadata;
-    }
-
-    public FeatureInputStream execute(Query query) throws Exception {
-        if (query instanceof FilterQuery) {
-            try {
-                return executeFilterQuery((FilterQuery) query);
-            } catch (SQLException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        if (query instanceof AdhocQuery) {
-            return executeAdhocQuery((AdhocQuery) query);
-        }
-        throw new 
IllegalArgumentException(I18N.get(this.getClass().getName()+".unsupported-query-type"));
-    }
-
     /**
      * Executes a filter query.
      *
@@ -51,41 +42,10 @@
      * @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());
-
-        PostgisSQLBuilder builder = new PostgisSQLBuilder(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());
+        SpatialDatabasesFeatureInputStream fis = 
(SpatialDatabasesFeatureInputStream)super.executeFilterQuery(query);
+        return new PostgisFeatureInputStream(fis.getConnection(), 
fis.getQueryString(), query.getPrimaryKey());
     }
-
-    public FeatureInputStream executeAdhocQuery(AdhocQuery query) throws 
Exception {
-        String queryString = query.getQuery();
-        PostgisFeatureInputStream ifs = new 
PostgisFeatureInputStream(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;
-    }
-
-
-    public void close() throws DataStoreException {
-        try {
-            connection.close();
-        }
-        catch (Exception ex) { throw new DataStoreException(ex); }
-    }
-
-    public boolean isClosed() throws DataStoreException {
-        try {
-            return connection.isClosed();
-        } catch (SQLException e) {
-            throw new DataStoreException(e);
-        }
-    }
-
-}
\ No newline at end of file
+    
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java 
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDSMetadata.java 
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,294 +1,54 @@
+/*
+ * 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;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.io.WKBReader;
-import com.vividsolutions.jump.datastore.DataStoreMetadata;
+import com.vividsolutions.jump.datastore.spatialdatabases.*;
+import com.vividsolutions.jump.datastore.DataStoreConnection;
 import com.vividsolutions.jump.datastore.GeometryColumn;
-import com.vividsolutions.jump.datastore.PrimaryKeyColumn;
-import com.vividsolutions.jump.datastore.SpatialReferenceSystemID;
-import com.vividsolutions.jump.datastore.jdbc.JDBCUtil;
-import com.vividsolutions.jump.datastore.jdbc.ResultSetBlock;
+import java.util.List;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.*;
+public class PostgisDSMetadata extends SpatialDatabasesDSMetadata {
 
-public class PostgisDSMetadata implements DataStoreMetadata {
-
-  private final WKBReader reader = new WKBReader();
-
-  private PostgisDSConnection conn;
-
-  private Map sridMap = new HashMap();
-
-  public PostgisDSMetadata( PostgisDSConnection conn ) {
-    this.conn = conn;
-  }
-
-  public String[] getDatasetNames() {
-    final List datasetNames = new ArrayList();
-    // Spatial tables only.
-    try {
-      JDBCUtil.execute(
-          conn.getConnection(),
-        "SELECT DISTINCT f_table_schema, f_table_name FROM geometry_columns 
ORDER BY f_table_schema, f_table_name",
-          new ResultSetBlock() {
-      public void yield( ResultSet resultSet ) throws SQLException {
-        while ( resultSet.next() ) {
-                String schema = resultSet.getString( 1 );
-                String table = resultSet.getString( 2 );
-          if ( !schema.equalsIgnoreCase( "public" ) ) {
-                  table = schema + "." + table;
-                }
-          datasetNames.add( table );
-              }
-            }
-          });
-    } catch (Exception e) {
-      if (! e.getMessage().contains("geometry_columns")) {
-        e.printStackTrace();
-      } else {
-        System.out.println("not a postGIS db or bad search_path");
-      }
+    public PostgisDSMetadata(DataStoreConnection con) {
+        conn = con;
+        // TODO: use bind parameters to avoid SQL injection
+        datasetNameQuery = "SELECT DISTINCT f_table_schema, f_table_name FROM 
geometry_columns";
+        defaultSchemaName = "public";
+        spatialDbName = "PostGIS";
+        spatialExtentQuery1 = "SELECT ST_AsBinary(ST_Estimated_Extent( '%s', 
'%s', '%s' ))";
+        spatialExtentQuery2 = "SELECT ST_AsBinary(ST_Envelope(ST_Extent(%s))) 
FROM %s.%s";
+        geoColumnsQuery = "SELECT f_geometry_column, srid, type FROM 
geometry_columns where f_table_schema='%s' and f_table_name = '%s'";
+        sridQuery = "SELECT srid FROM geometry_columns where f_table_schema = 
'%s' and f_table_name = '%s' and f_geometry_column = '%s'";
     }
-    return (String[]) datasetNames.toArray(new String[datasetNames.size()]);
-  }
 
-  public Envelope getExtents(String datasetName, String attributeName) {
-
-    final Envelope[] e = new Envelope[]{null};
-
-    String schema;
-    String table;
-    if (datasetName.indexOf('.') != -1) {
-      String[] parts = datasetName.split("\\.", 2);
-      schema = parts[0];
-      table = parts[1];
-    } else {
-      schema = "public";
-      table = datasetName;
+    @Override
+    public String getSpatialExtentQuery1(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery1, schema, table, 
attributeName);
     }
-    // There are two methods to compute the extent,
-    // ST_EstimatedExtent is fast but not precise (last entered data may be 
excluded
-    // until the next ANALYZE)
-    // ST_Extent is slow but precise (scan over the whole table)
-    String sql1 = "SELECT ST_AsBinary(ST_Estimated_Extent( '" + schema + "', 
'" + table + "', '" + attributeName + "' ));";
-    String sql2 = "SELECT ST_AsBinary(ST_Envelope(ST_Extent(\"" + 
attributeName + "\"))) FROM \"" + schema + "\".\"" + table + "\";";
 
-    final ResultSetBlock resultSetBlock = new ResultSetBlock() {
-      public void yield(ResultSet resultSet) throws Exception {
-        if (resultSet.next()) {
-          byte[] bytes = (byte[]) resultSet.getObject(1);
-          if (bytes != null) {
-            Geometry geom = reader.read(bytes);
-            if (geom != null) {
-              e[0] = geom.getEnvelopeInternal();
-            }
-          }
-        }
-      }
-    };
-    try {
-      JDBCUtil.execute(conn.getConnection(), (sql1), resultSetBlock);
-      if (e[0] == null || e[0].isNull()) {
-        JDBCUtil.execute(conn.getConnection(), (sql2), resultSetBlock);
-      }
-    } catch (Exception ex1) {
-        // If attributeName is indexed but indexed has not been initialized
-      // (no VACUUM ANALYZE) ST_Estimated_Extent may throw an exception.
-      // In this case, try the second method using ST_Extent
-      JDBCUtil.execute(conn.getConnection(), sql2, resultSetBlock);
+    @Override
+    public String getSpatialExtentQuery2(String schema, String table, String 
attributeName) {
+        return String.format(this.spatialExtentQuery2, attributeName, schema, 
table);
     }
-    return e[0];
-  }
 
-  @Deprecated
-  public SpatialReferenceSystemID getSRID(String tableName, String colName)
-      throws SQLException {
-    String key = tableName + "#" + colName;
-    if (!sridMap.containsKey(key)) {
-      // not in cache, so query it
-      String srid = querySRID(tableName, colName);
-      sridMap.put(key, new SpatialReferenceSystemID(srid));
+    @Override
+    public String getGeoColumnsQuery(String datasetName) {
+        return String.format(this.geoColumnsQuery, getSchemaName(datasetName), 
getTableName(datasetName));
     }
-    return (SpatialReferenceSystemID) sridMap.get(key);
-  }
 
-  @Deprecated
-  private String querySRID(String tableName, String colName) {
-    final StringBuffer srid = new StringBuffer();
-    // Changed by Michael Michaud 2010-05-26 (throwed exception for empty 
tableName)
-    // String sql = "SELECT getsrid(" + colName + ") FROM " + tableName + " 
LIMIT 1";
-    String[] tokens = tableName.split("\\.", 2);
-    String schema = tokens.length == 2 ? tokens[0] : "public";
-    String table = tokens.length == 2 ? tokens[1] : tableName;
-    String sql = "SELECT srid FROM geometry_columns where (f_table_schema = '" 
+ schema + "' and f_table_name = '" + table + "')";
-    // End of the fix
-    JDBCUtil.execute(conn.getConnection(), sql, new ResultSetBlock() {
-      public void yield(ResultSet resultSet) throws SQLException {
-        if (resultSet.next()) {
-          srid.append(resultSet.getString(1));
-        }
-      }
-    });
-
-    return srid.toString();
-  }
-
-  @Deprecated
-  public String[] getGeometryAttributeNames(String datasetName) {
-    final List geometryAttributeNames = new ArrayList();
-    String sql = "SELECT f_geometry_column FROM geometry_columns "
-        + geomColumnMetadataWhereClause("f_table_schema", "f_table_name", 
datasetName);
-    JDBCUtil.execute(
-        conn.getConnection(), sql,
-        new ResultSetBlock() {
-          public void yield(ResultSet resultSet) throws SQLException {
-            while (resultSet.next()) {
-              geometryAttributeNames.add(resultSet.getString(1));
-            }
-          }
-        });
-    return (String[]) geometryAttributeNames.toArray(new 
String[geometryAttributeNames.size()]);
-  }
-
-  public List<GeometryColumn> getGeometryAttributes(String datasetName) {
-    final List<GeometryColumn> geometryAttributes = new 
ArrayList<GeometryColumn>();
-    String sql = "SELECT f_geometry_column, srid, type FROM geometry_columns "
-        + geomColumnMetadataWhereClause("f_table_schema", "f_table_name", 
datasetName);
-    JDBCUtil.execute(
-        conn.getConnection(), sql,
-        new ResultSetBlock() {
-          public void yield(ResultSet resultSet) throws SQLException {
-            while (resultSet.next()) {
-              geometryAttributes.add(new GeometryColumn(
-                      resultSet.getString(1),
-                      resultSet.getInt(2),
-                      resultSet.getString(3)));
-            }
-          }
-        });
-    return geometryAttributes;
-  }
-
-  /**
-   * Returns PRIMARY KEY columns of dataset names.
-   *
-   * @param datasetName name of the table (optionally prefixed by the schema
-   * name)
-   * @return the list of columns involved in the Primary Key (generally, a
-   * single column)
-   */
-  public List<PrimaryKeyColumn> getPrimaryKeyColumns(String datasetName) {
-    final List<PrimaryKeyColumn> identifierColumns = new 
ArrayList<PrimaryKeyColumn>();
-    // query taken from 
http://www.alberton.info/postgresql_meta_info.html#.UewsFG29b0Q
-    String sql
-        = "SELECT kcu.column_name, col.data_type"
-        + " FROM information_schema.table_constraints tc"
-        + " LEFT JOIN information_schema.key_column_usage kcu"
-        + " ON tc.constraint_catalog = kcu.constraint_catalog"
-        + " AND tc.constraint_schema = kcu.constraint_schema"
-        + " AND tc.constraint_name = kcu.constraint_name"
-        + " LEFT JOIN information_schema.referential_constraints rc"
-        + " ON tc.constraint_catalog = rc.constraint_catalog"
-        + " AND tc.constraint_schema = rc.constraint_schema"
-        + " AND tc.constraint_name = rc.constraint_name"
-        + " LEFT JOIN information_schema.constraint_column_usage ccu"
-        + " ON rc.unique_constraint_catalog = ccu.constraint_catalog"
-        + " AND rc.unique_constraint_schema = ccu.constraint_schema"
-        + " AND rc.unique_constraint_name = ccu.constraint_name"
-        + " LEFT JOIN information_schema.columns col"
-        + " ON kcu.table_catalog = col.table_catalog"
-        + " AND kcu.table_schema = col.table_schema"
-        + " AND kcu.table_name = col.table_name"
-        + " AND kcu.column_name = col.column_name "
-        + geomColumnMetadataWhereClause("col.table_schema", "col.table_name", 
datasetName)
-        + " AND tc.constraint_type = 'PRIMARY KEY';";
-    JDBCUtil.execute(
-        conn.getConnection(), sql,
-        new ResultSetBlock() {
-          public void yield(ResultSet resultSet) throws SQLException {
-            while (resultSet.next()) {
-              identifierColumns.add(new PrimaryKeyColumn(
-                      resultSet.getString(1),
-                      resultSet.getString(2)));
-            }
-          }
-        });
-    return identifierColumns;
-  }
-
-  public String[] getColumnNames(String datasetName) {
-    String sql = "SELECT column_name FROM information_schema.columns "
-        + geomColumnMetadataWhereClause("table_schema", "table_name", 
datasetName);
-    ColumnNameBlock block = new ColumnNameBlock();
-    JDBCUtil.execute(conn.getConnection(), sql, block);
-    return block.colName;
-  }
-
-  private String geomColumnMetadataWhereClause(String schemaCol, String 
tableCol, String tableName) {
-    // [mmichaud 2011-07-24] Fixed a bug related to tables having common
-    // names in public schema and another schema
-    int dotPos = tableName.indexOf(".");
-    String schema = "public";
-    String table = tableName;
-    if (dotPos != -1) {
-      schema = tableName.substring(0, dotPos);
-      table = tableName.substring(dotPos + 1);
+    @Override
+    public String getSridQuery(String schemaName, String tableName, String 
colName) {
+        // TODO
+        return String.format(this.sridQuery, schemaName, tableName, colName);
     }
-    return "WHERE " + schemaCol + " = '" + schema + "'"
-        + " AND " + tableCol + " = '" + table + "'";
-  }
-
-  /**
-   * Returns whether column is used by a spatial index (Gist) or not.
-   */
-  public boolean isIndexed(final String schema, final String table,
-      final String column) throws SQLException {
-    String sql = getGeometryIndicesQuery(schema, table, column);
-    return conn.getConnection().createStatement().executeQuery(sql).next();
-  }
-
-  private static class ColumnNameBlock implements ResultSetBlock {
-
-    List colList = new ArrayList();
-    String[] colName;
-
-    public void yield(ResultSet resultSet) throws SQLException {
-      while (resultSet.next()) {
-        colList.add(resultSet.getString(1));
-      }
-      colName = (String[]) colList.toArray(new String[colList.size()]);
+    
+    @Override
+    public List<GeometryColumn> getGeometryAttributes(String datasetName) {
+        String sql = this.getGeoColumnsQuery(datasetName);
+        return getGeometryAttributes(sql, datasetName);
     }
-  }
 
-  /**
-   * Use PostgreSQL metadata to know if schema.table.column is spatially 
indexed
-   * (or involved in a spatial index).
-   *
-   * @deprecated initially thought that statistic used by ST_Estimated_Extent
-   * was depending on whether a spatial index exists or not. Finally, 
statistics
-   * and index seem to be two independant things
-   */
-  @Deprecated
-  public String getGeometryIndicesQuery(String schema, String table, String 
column) {
-    return "SELECT n.nspname, t.relname, a.attname, c.relname\n"
-        + "FROM pg_index i\n"
-        + "-- join indexes in pg_class to filter gist indexes (783 and 4000)\n"
-        + "JOIN pg_class c ON i.indexrelid = c.oid\n"
-        + "-- join tables in pg_class to get the table name\n"
-        + "JOIN pg_class t ON i.indrelid = t.oid\n"
-        + "-- join tables in pg_tables to get the schema name\n"
-        + "JOIN pg_namespace n ON t.relnamespace = n.oid\n"
-        + "-- join attributes to check geometry involved in the index\n"
-        + "JOIN pg_attribute a ON (a.attrelid = t.oid AND a.attnum = 
ANY(i.indkey))\n"
-        + "-- limit the search in pg_class to index objects\n"
-        + "WHERE c.relkind = 'i'\n"
-        + "AND (c.relam = 783 OR c.relam = 4000)\n"
-        + "AND n.nspname = '" + schema + "'\n"
-        + "AND t.relname = '" + table + "'\n"
-        + "AND a.attname = '" + column + "';";
-  }
-
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
        2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisDataStoreDriver.java
        2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,97 +1,36 @@
+/*
+ * 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 java.sql.*;
-
-import com.vividsolutions.jump.datastore.*;
-
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesDataStoreDriver;
 import com.vividsolutions.jump.parameter.ParameterList;
-import com.vividsolutions.jump.parameter.ParameterListSchema;
 
 /**
- * A driver for supplying {@link PostgisDSConnection}s
+ * A driver for supplying {@link SpatialDatabaseDSConnection}s
  */
 public class PostgisDataStoreDriver
-    implements DataStoreDriver
-{
-  public static final String DRIVER_NAME = "PostGIS";
-  public static final String JDBC_CLASS = "org.postgresql.Driver";
-  public static final String URL_PREFIX = "jdbc:postgresql://";
+    extends SpatialDatabasesDataStoreDriver {
 
-  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";
-
-  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);
-
-  public PostgisDataStoreDriver() {
-  }
-
-  public String getName()
-  {
-    return DRIVER_NAME;
-  }
-  public ParameterListSchema getParameterListSchema()
-  {
-    return schema;
-  }
-  public DataStoreConnection createConnection(ParameterList params)
-      throws Exception
-  {
-    String host = params.getParameterString(PARAM_Server);
-    int port = params.getParameterInt(PARAM_Port);
-    String database = params.getParameterString(PARAM_Instance);
-    String user = params.getParameterString(PARAM_User);
-    String password = params.getParameterString(PARAM_Password);
-
-    String url
-        = String.valueOf(new StringBuffer(URL_PREFIX).append
-        (host).append
-        (":").append
-        (port).append
-        ("/").append(database));
-
-    Driver driver = (Driver) Class.forName(JDBC_CLASS).newInstance();
-    DriverManager.registerDriver(driver);
-
-    // mmichaud 2013-08-27 workaround for ticket #330
-    String savePreferIPv4Stack = 
System.getProperty("java.net.preferIPv4Stack");
-    String savePreferIPv6Addresses = 
System.getProperty("java.net.preferIPv6Addresses");
-    System.setProperty("java.net.preferIPv4Stack", "true");
-    System.setProperty("java.net.preferIPv6Addresses", "false");
-
-    Connection conn = DriverManager.getConnection(url, user, password);
-
-    if (savePreferIPv4Stack == null) {
-        System.getProperties().remove("java.net.preferIPv4Stack");
-    } else {
-        System.setProperty("java.net.preferIPv4Stack", savePreferIPv4Stack);
+    public PostgisDataStoreDriver() {
+        this.driverName = "PostGIS";
+        this.jdbcClass = "org.postgresql.Driver";
+        this.urlPrefix = "jdbc:postgresql://";
     }
-    if (savePreferIPv6Addresses == null) {
-        System.getProperties().remove("java.net.preferIPv6Addresses");
-    } else {
-        System.setProperty("java.net.preferIPv6Addresses", 
savePreferIPv6Addresses);
+    
+    /**
+     * 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());
     }
-    return new PostgisDSConnection(conn);
-  }
-  public boolean isAdHocQuerySupported() {
-      return true;
-  }
-
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
     2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisFeatureInputStream.java
     2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,113 +1,35 @@
+/*
+ * 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.feature.Feature;
-import com.vividsolutions.jump.feature.FeatureSchema;
-import com.vividsolutions.jump.io.BaseFeatureInputStream;
-
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesFeatureInputStream;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesResultSetConverter;
 import java.sql.Connection;
 import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
 
 /**
- * Reads features from a PostgreSQL/PostGIS database.
+ *
+ * @author nicolas
  */
-public class PostgisFeatureInputStream extends BaseFeatureInputStream {
-    
-    private FeatureSchema featureSchema;
-    private Connection conn;
-    private String queryString;
-    private boolean initialized = false;
-    private Exception savedException;
-
-    private Statement stmt = null;
-    private ResultSet rs = null;
-    private PostgisResultSetConverter mapper;
-
-    int geometryColIndex = -1;
-    String externalIdentifier = null;  // added on 2013-08-07
-
+public class PostgisFeatureInputStream extends 
SpatialDatabasesFeatureInputStream {
     public PostgisFeatureInputStream(Connection conn, String queryString) {
-        this.conn = conn;
-        this.queryString = queryString;
+        super(conn, queryString);
     }
 
     public PostgisFeatureInputStream(Connection conn, String queryString, 
String externalIdentifier) {
-        this.conn = conn;
-        this.queryString = queryString;
-        this.externalIdentifier = externalIdentifier;
+        super(conn, queryString, externalIdentifier);
     }
-
+    
     /**
-     * @return The underlaying {@link Connection}.
+     * Returns a PostgisResultSetConverter
+     * @param rs
+     * @return 
      */
-    public Connection getConnection(){return conn;}
-  
-    /**
-     * @return The underlaying {@link Statement}.
-     * Useful to cancel the query on the server if the PlugIn is interrupted 
-     */
-    public Statement getStatement(){return stmt;}
-
-    private void init() throws SQLException {
-        if (initialized) {
-            return;
-        }
-        initialized = true;
-    
-        stmt = conn.createStatement();
-        String parsedQuery = queryString;
-        try {
-            rs = stmt.executeQuery(parsedQuery);
-        } catch (SQLException e) {
-            SQLException sqle = new SQLException("Error : " + parsedQuery);
-            sqle.setNextException(e);
-            throw sqle;
-        }
-        mapper = new PostgisResultSetConverter(conn, rs);
-        featureSchema = mapper.getFeatureSchema();
-        if (externalIdentifier != null) {
-            
featureSchema.setExternalPrimaryKeyIndex(featureSchema.getAttributeIndex(externalIdentifier));
-        }
+    @Override
+    protected SpatialDatabasesResultSetConverter 
getResultSetConverter(ResultSet rs) {
+      return new PostgisResultSetConverter(conn, rs);
     }
-    
-    protected Feature readNext() throws Exception {
-        if (savedException != null) throw savedException;
-        if (! initialized) init();
-        if (rs == null) return null;
-        if (! rs.next()) return null;
-        return getFeature();
-    }
-    
-    private Feature getFeature() throws Exception {
-        return mapper.getFeature();
-    }
-    
-    public void close() throws SQLException {
-        if (rs != null) {
-            rs.close();
-        }
-        if (stmt != null) {
-            stmt.close();
-        }
-    }
-    
-    public FeatureSchema getFeatureSchema() {      
-        if (featureSchema != null) {
-            return featureSchema;
-        }
-        try {
-            init();
-        }
-        catch (SQLException ex) {
-            String message = ex.getLocalizedMessage();
-            Throwable nextT = ex.getNextException();
-            if (nextT != null) message = message + "\n" + 
nextT.getLocalizedMessage();
-            throw new Error(message);
-        }
-        if (featureSchema == null) {
-            featureSchema = new FeatureSchema();
-        }
-        return featureSchema;
-    }
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
     2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisResultSetConverter.java
     2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,83 +1,27 @@
+/*
+ * 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;
-import com.vividsolutions.jump.datastore.jdbc.ValueConverterFactory;
-import com.vividsolutions.jump.feature.AttributeType;
-import com.vividsolutions.jump.feature.BasicFeature;
+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;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
 
 /**
- * Implements the mapping between a result set and
- * a {@link FeatureSchema} and {@link Feature} set.
+ * 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
+ * This is a transient worker class, whose lifetime should be no longer than 
the
+ * lifetime of the provided ResultSet
  */
-public class PostgisResultSetConverter {
+public class PostgisResultSetConverter extends 
SpatialDatabasesResultSetConverter {
 
-    private ResultSet rs;
-    private FeatureSchema featureSchema;
-    private int geometryColIndex = -1;
-    private ValueConverter[] mapper;
-    private PostgisValueConverterFactory odm;
-    private boolean isInitialized = false;
-
     public PostgisResultSetConverter(Connection conn, ResultSet rs) {
-        odm = new PostgisValueConverterFactory(conn);
-        this.rs = rs;
+        super(conn, rs);
+        this.odm = new PostgisValueConverterFactory(conn);
     }
-
-    public FeatureSchema getFeatureSchema() throws SQLException {
-        init();
-        return featureSchema;
-    }
-
-    public Feature getFeature() throws Exception {
-        init();
-        Feature f = new BasicFeature(featureSchema);
-        for (int i = 0; i < mapper.length; i++) {
-            f.setAttribute(i, mapper[i].getValue(rs, i + 1));
-        }
-        return f;
-    }
-
-    private void init() throws SQLException {
-        if (isInitialized) return;
-        isInitialized = true;
-
-        ResultSetMetaData rsmd = rs.getMetaData();
-        int numberOfColumns = rsmd.getColumnCount();
-        mapper = new ValueConverter[numberOfColumns];
-        featureSchema = new FeatureSchema();
-
-        for (int i = 0; i < numberOfColumns; i++) {
-            mapper[i] = odm.getConverter(rsmd, i + 1);
-            String colName = rsmd.getColumnName(i + 1);
-            // only handles one geometry col for now [MD ?]
-            // Convert the first geometry into AttributeType.GEOMETRY and the 
following ones
-            // into AttributeType.STRINGs [mmichaud 2007-05-13]
-            if (mapper[i].getType() == AttributeType.GEOMETRY) {
-                if (featureSchema.getGeometryIndex() == -1) {
-                    // fixed by mmichaud using a patch from jaakko 
[2008-05-21] :
-                    // use colName instead of "GEOMETRY" for attribute name
-                    featureSchema.addAttribute(colName, 
AttributeType.GEOMETRY);
-                }
-                else {
-                    mapper[i] = new ValueConverterFactory.ObjectConverter();
-                    featureSchema.addAttribute(colName, AttributeType.OBJECT);
-                }
-            }
-            else {
-                featureSchema.addAttribute(colName, mapper[i].getType());
-            }
-        }
-    }
-
-}
\ No newline at end of file
+}

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java 
    2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisSQLBuilder.java 
    2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,28 +1,36 @@
+/*
+ * 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;
-import com.vividsolutions.jts.geom.Geometry;
 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 PostGIS database
+ * Creates SQL query strings for a Spatial database.
+ * To be overloaded by classes implementing a spatial database support.
  */
-public class PostgisSQLBuilder {
+public class PostgisSQLBuilder extends SpatialDatabasesSQLBuilder {
 
-  private SpatialReferenceSystemID defaultSRID = null;
-  private String[] colNames = null;
-
-  public PostgisSQLBuilder(SpatialReferenceSystemID defaultSRID, String[] 
colNames) {
-    this.defaultSRID = defaultSRID;
-    this.colNames = colNames;
+  public PostgisSQLBuilder(SpatialDatabasesDSMetadata dbMetadata, 
+      SpatialReferenceSystemID defaultSRID, String[] colNames) {
+    super(dbMetadata, defaultSRID, colNames);
   }
 
+  /**
+   * Builds a valid SQL spatial query with the given spatial filter.
+   * @param query
+   * @return a SQL query to get column names
+   * //TODO: refactor like Oracle code: queries as variable placeholders: put 
it in base class.
+   */
+  @Override
   public String getSQL(FilterQuery query) {
-    return buildQueryString(query);
-  }
-
-  private String buildQueryString(FilterQuery query) {
     StringBuilder qs = new StringBuilder();
     //HACK
     qs.append("SELECT ");
@@ -31,7 +39,7 @@
     // fixed by mmichaud on 2010-05-27 for mixed case dataset names
     
qs.append("\"").append(query.getDatasetName().replaceAll("\\.","\".\"")).append("\"");
     qs.append(" t WHERE ");
-    qs.append(buildBoxFilter(query.getGeometryAttributeName(), 
query.getSRSName(), query.getFilterGeometry()));
+    qs.append(buildBoxFilter(query));
 
     String whereCond = query.getCondition();
     if (whereCond != null) {
@@ -44,15 +52,39 @@
     }
     //System.out.println(qs);
     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();
+    // fixed by mmichaud using a patch from jaakko [2008-05-21]
+    // query geomColName as geomColName instead of geomColName as geomColName 
+ "_wkb"
+    buf.append("ST_AsEWKB(\"").append(geomColName).append("\") as 
").append("\"").append(geomColName).append("\"");
+    for (String colName : colNames) {
+      if (! geomColName.equalsIgnoreCase(colName)) {
+        buf.append(",\"").append(colName).append("\"");
+      }
+    }
+    return buf.toString();
   }
 
-  private String buildBoxFilter(String geometryColName, 
SpatialReferenceSystemID SRID, Geometry geom) {
-    Envelope env = geom.getEnvelopeInternal();
+  @Override
+  protected String buildBoxFilter(FilterQuery query) {
+    Envelope env = query.getFilterGeometry().getEnvelopeInternal();
 
     // Example of Postgis SQL: GEOM && SetSRID('BOX3D(191232 243117,191232 
243119)'::box3d,-1);
     StringBuilder buf = new StringBuilder();
     // fixed by mmichaud on 2010-05-27 for mixed case geometryColName names
-    buf.append("\"").append(geometryColName).append("\" && 
ST_SetSRID('BOX3D(");
+    buf.append("\"").append(query.getGeometryAttributeName()).append("\" && 
ST_SetSRID('BOX3D(");
     buf.append(env.getMinX()
                + " " + env.getMinY()
                + "," + env.getMaxX()
@@ -61,35 +93,9 @@
     buf.append(")'::box3d,");
     // [mmichaud 2012-03-14] make windows srid homogeneous with geometry srid
     // in case it is not defined
-    String srid = getSRID(SRID);
-    srid = srid==null? "ST_SRID(\"" + geometryColName + "\")" : srid;
+    String srid = getSRID(query.getSRSName());
+    srid = srid==null? "ST_SRID(\"" + query.getGeometryAttributeName() + "\")" 
: srid;
     buf.append(srid).append(")");
     return buf.toString();
   }
-
-  private String getSRID(SpatialReferenceSystemID querySRID) {
-    SpatialReferenceSystemID srid = defaultSRID;
-    if (! querySRID.isNull())
-      srid = querySRID;
-
-    if (srid.isNull() || srid.getString().trim().length()==0)
-      return null;
-    else
-      return srid.getString();
-  }
-
-  private 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();
-    // fixed by mmichaud using a patch from jaakko [2008-05-21]
-    // query geomColName as geomColName instead of geomColName as geomColName 
+ "_wkb"
-    buf.append("ST_AsEWKB(\"").append(geomColName).append("\") as 
").append("\"").append(geomColName).append("\"");
-    for (String colName : colNames) {
-      if (! geomColName.equalsIgnoreCase(colName)) {
-        buf.append(",\"").append(colName).append("\"");
-      }
-    }
-    return buf.toString();
-  }
 }

Modified: 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
  2015-12-07 07:02:08 UTC (rev 4578)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/postgis/PostgisValueConverterFactory.java
  2015-12-07 17:07:02 UTC (rev 4579)
@@ -1,90 +1,50 @@
+/*
+ * 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 java.sql.*;
-import java.io.*;
-import com.vividsolutions.jump.feature.*;
-import com.vividsolutions.jts.geom.*;
-import com.vividsolutions.jts.io.*;
-import com.vividsolutions.jump.datastore.jdbc.*;
+import com.vividsolutions.jump.datastore.jdbc.ValueConverter;
+import com.vividsolutions.jump.datastore.jdbc.ValueConverterFactory;
+import 
com.vividsolutions.jump.datastore.spatialdatabases.SpatialDatabasesValueConverterFactory;
+import java.sql.Connection;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
 
 /**
  *
  */
-public class PostgisValueConverterFactory {
+public class PostgisValueConverterFactory extends 
SpatialDatabasesValueConverterFactory {
 
-    // should lazily init these
-    private final ValueConverter WKB_GEOMETRY_MAPPER = new 
WKBGeometryValueConverter();
-
-    private final Connection conn;
-    private static final WKBReader wkbReader = new WKBReader();
-    private static final WKTReader wktReader = new WKTReader();
-
     public PostgisValueConverterFactory(Connection conn) {
-    this.conn = conn;
-  }
+        super(conn);
+    }
 
-    public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex) 
throws SQLException {
+    @Override
+    public ValueConverter getConverter(ResultSetMetaData rsm, int columnIndex)
+        throws SQLException {
         String classname = rsm.getColumnClassName(columnIndex);
         String dbTypeName = rsm.getColumnTypeName(columnIndex);
-        ResultSet rs = conn.getMetaData().getColumns(
-                rsm.getCatalogName(columnIndex),
-                rsm.getSchemaName(columnIndex),
-                rsm.getTableName(columnIndex),
-                rsm.getColumnName(columnIndex));
-        String udt = rs.next() ? rs.getString("TYPE_NAME") : "";
-        //System.out.println(dbTypeName + " (" + classname + ") [" + udt + 
"]");
 
-        // A geometry column created with addGeometryColumn has the 
ColumnTypeName = geometry
-        // but if column is created from a statement like "create table2 as 
select * from table1"
-        // its ColumnTypeName is bytea even if its UDT is geometry
-        if ("geometry".equals(dbTypeName) || "geometry".equals(udt))
+        // 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;
+        }
 
+        if (dbTypeName.equalsIgnoreCase("bytea")) {
+            return WKB_GEOMETRY_MAPPER;
+        }
+
         // handle the standard types
         ValueConverter stdConverter = ValueConverterFactory.getConverter(rsm, 
columnIndex);
-        if (stdConverter != null)
+        if (stdConverter != null) {
             return stdConverter;
+        }
 
         // default - can always show it as a string!
         return ValueConverterFactory.STRING_MAPPER;
     }
 
-
-    static class WKBGeometryValueConverter implements ValueConverter {
-
-        public AttributeType getType() {
-            return AttributeType.GEOMETRY;
-        }
-
-        public Object getValue(ResultSet rs, int columnIndex) throws 
IOException, SQLException, ParseException {
-
-            byte[] bytes = rs.getBytes(columnIndex);
-
-            //so rs.getBytes will be one of two things:
-            //1. The actual bytes of the WKB if someone did ST_AsBinary
-            //2. The bytes of hex representation of the WKB.
-
-            //in the case of #1, according to the WKB spec, the byte value can 
only be 0 or 1.
-            //in the case of #2, it's a hex string, so values range from ascii 
0-F
-            //use this logic to determine how to process the bytes.
-
-            Geometry geometry = null;
-            if(bytes == null || bytes.length <= 0) {
-                geometry = wktReader.read("GEOMETRYCOLLECTION EMPTY");
-            }
-            else {
-                //assume it's the actual bytes (from ST_AsBinary)
-                byte[] realWkbBytes = bytes;
-                if(bytes[0] >= '0') {
-                    //ok, it's hex, convert hex string to actual bytes
-                    String hexString = new String(bytes);
-                    realWkbBytes = WKBReader.hexToBytes(hexString);
-                }
-                geometry = wkbReader.read(realWkbBytes);
-            }
-
-            return geometry;
-        }
-    }
-
-}
\ No newline at end of file
+}

Added: 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
===================================================================
--- 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
                         (rev 0)
+++ 
core/trunk/src/com/vividsolutions/jump/datastore/spatialdatabases/SpatialDatabasesDSConnection.java
 2015-12-07 17:07:02 UTC (rev 4579)
@@ -0,0 +1,114 @@
+/*
+ * 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;
+import com.vividsolutions.jump.datastore.AdhocQuery;
+import com.vividsolutions.jump.datastore.DataStoreConnection;
+import com.vividsolutions.jump.datastore.DataStoreException;
+import com.vividsolutions.jump.datastore.DataStoreMetadata;
+import com.vividsolutions.jump.datastore.FilterQuery;

@@ Diff output truncated at 100000 characters. @@

------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to