/*
* Copyright (c) 2015 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.io.jdbc.spatialite.internal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.sqlite.SQLiteConnection;
import com.vividsolutions.jts.geom.Geometry;
import de.fhg.igd.slf4jplus.ALogger;
import de.fhg.igd.slf4jplus.ALoggerFactory;
/**
* Base implementation of {@link SpatiaLiteSupport} interface.
*
* @author Stefano Costa, GeoSolutions
*/
public abstract class AbstractSpatiaLiteSupport implements SpatiaLiteSupport {
private static final ALogger log = ALoggerFactory.getLogger(AbstractSpatiaLiteSupport.class);
/**
* @see eu.esdihumboldt.hale.io.jdbc.spatialite.internal.SpatiaLiteSupport#getGeometryTypeMetadata(org.sqlite.SQLiteConnection,
* java.lang.String, java.lang.String)
*/
@Override
public GeometryTypeMetadata getGeometryTypeMetadata(SQLiteConnection conn, String tableName,
String columnName) {
GeometryTypeMetadata meta = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = getGeometryTypeMetadataSQL();
stmt = conn.prepareStatement(sql);
stmt.setString(1, tableName);
stmt.setString(2, columnName);
rs = stmt.executeQuery();
if (rs.next()) {
int srid = rs.getInt("srid");
Object type = rs.getObject("type");
Object coordDim = rs.getObject("coord_dimension");
meta = new GeometryTypeMetadata(srid, getGeometryType(type),
getCoordDimensionAsInt(coordDim));
}
} catch (SQLException e) {
String errMsg = String.format(
"Error extracting metadata for geometry column \"%s\" in table \"%s\"",
columnName, tableName);
log.error(errMsg, e);
} finally {
closeFinally(stmt, rs);
}
return meta;
}
@Override
public SrsMetadata getSrsMetadata(SQLiteConnection conn, int srid) {
SrsMetadata meta = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// String sqlMeta =
// "SELECT auth_srid, auth_name, srs_wkt AS srtext FROM spatial_ref_sys WHERE srid = ?";
String sqlMeta = getSrsMetadataSQL();
stmt = conn.prepareStatement(sqlMeta);
stmt.setInt(1, srid);
rs = stmt.executeQuery();
if (rs.next()) {
int authSrid = rs.getInt("auth_srid");
String authName = rs.getString("auth_name");
String srText = rs.getString("srtext");
meta = new SrsMetadata(srText, authSrid, authName, srid);
}
} catch (SQLException e) {
String errMsg = String.format("Error extracting SRS metadata for SRID: %d", srid);
log.error(errMsg, e);
} finally {
closeFinally(stmt, rs);
}
return meta;
}
@Override
public SrsMetadata getSrsMetadata(SQLiteConnection conn, String auth, int code) {
SrsMetadata meta = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sqlMeta = getSrsMetadataFromAuthSQL();
stmt = conn.prepareStatement(sqlMeta);
stmt.setString(1, auth);
stmt.setInt(2, code);
rs = stmt.executeQuery();
if (rs.next()) {
int authSrid = rs.getInt("auth_srid");
String authName = rs.getString("auth_name");
String srText = rs.getString("srtext");
int srid = rs.getInt("srid");
meta = new SrsMetadata(srText, authSrid, authName, srid);
}
} catch (SQLException e) {
String errMsg = String.format("Error extracting SRS metadata for SRS: %s:%d", auth,
code);
log.error(errMsg, e);
} finally {
closeFinally(stmt, rs);
}
return meta;
}
/**
* Return a SpatiaLite version dependent SQL query selecting at least three
* columns: <code>srid</code> (integer), <code>type</code> (any type) and
* <code>coord_dimension</code> (any type).
* <p>
* Template method, implementation is provided by subclasses.
* </p>
*
* @return SQL statement to extract geometry type metadata from the
* <code>geometry_columns</code> metadata table
*/
protected abstract String getGeometryTypeMetadataSQL();
/**
* Convert the retrieved <code>coord_dimension</code> column value to an
* integer.
* <p>
* Template method, implementation is provided by subclasses.
* </p>
*
* @param coordDimension the value of the <code>coord_dimension</code>
* column
* @return the dimensionality of the geometry coordinates (either 2, 3, 4 or
* -1 in case of error)
*/
protected abstract int getCoordDimensionAsInt(Object coordDimension);
/**
* Map the retrieved <code>type</code> column value to a subclass of
* {@link Geometry}.
* <p>
* Template method, implementation is provided by subclasses.
* </p>
*
* @param type the value of the <code>type</code> column
* @return the corresponding JTS {@link Geometry} subclass
*/
protected abstract Class<? extends Geometry> getGeometryType(Object type);
/**
* Return a SpatiaLite version dependent SQL query selecting at least three
* columns: <code>auth_srid</code> (integer), <code>auth_name</code>
* (string) and <code>srtext</code> (string).
* <p>
* Template method, implementation is provided by subclasses.
* </p>
*
* @return SQL statement to extract SRS metadata from the
* <code>spatial_ref_sys</code> metadata table
*/
protected abstract String getSrsMetadataSQL();
/**
* Return a SpatiaLite version dependent SQL query selecting at least three
* columns: <code>auth_srid</code> (integer), <code>auth_name</code>
* (string), <code>srtext</code> (string) and <code>srid</code> (integer).
* <p>
* Template method, implementation is provided by subclasses.
* </p>
*
* @return SQL statement to extract SRS metadata from the
* <code>spatial_ref_sys</code> metadata table
*/
protected abstract String getSrsMetadataFromAuthSQL();
/**
* Utility method to close a {@link ResultSet} and a {@link Statement}
* instance.
*
* @param stmt the {@link Statement} to close
* @param rs the {@link ResultSet} to close
*/
protected void closeFinally(Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// ignore
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// ignore
}
}
}
}