Rev 242 | Rev 245 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/** $Id: AbstractExpectationsFactory.java 244 2010-10-01 20:55:56Z maesenka $** This file is part of Hibernate Spatial, an extension to the* hibernate ORM solution for geographic data.** Copyright © 2007-2010 Geovise BVBA** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA** For more information, visit: http://www.hibernatespatial.org/*/package org.hibernatespatial.test;import com.vividsolutions.jts.geom.Geometry;import com.vividsolutions.jts.geom.Polygon;import com.vividsolutions.jts.io.ParseException;import com.vividsolutions.jts.io.WKTReader;import java.sql.*;import java.util.HashMap;import java.util.Map;/*** An <code>AbstractExpectationsFactory</code> provides the expected* values to be used in the unit tests of the spatial functions* provided by specific providers.* <p/>* The expected values are returned as a map of (identifier, expected value) pairs.** @author Karel Maesen, Geovise BVBA* @see TestSpatialFunctions*/public abstract class AbstractExpectationsFactory {public final static int INTEGER = 1;public final static int DOUBLE = 2;public final static int GEOMETRY = 3;public final static int STRING = 4;public final static int BOOLEAN = 5;public final static int OBJECT = -1;private final static int TEST_SRID = 4326;private final DataSourceUtils dataSourceUtils;private static final int MAX_BYTE_LEN = 1024;public AbstractExpectationsFactory(String propertiesFile, SQLExpressionTemplate sqlExpressionTemplate) {this.dataSourceUtils = new DataSourceUtils(propertiesFile, sqlExpressionTemplate);}protected DataSourceUtils getDataSourceUtils() {return this.dataSourceUtils;}/*** Returns the SRID in which all tests are conducted. This is for now 4326;** @return*/public int getTestSrid() {return TEST_SRID;}/*** Returns the expected dimensions of all testsuite-suite geometries.** @return map of identifier, dimension* @throws SQLException*/public Map<Integer, Integer> getDimension() throws SQLException {return retrieveExpected(createNativeDimensionSQL(), INTEGER);}/*** Returns the expected WKT of all testsuite-suite geometries.** @return map of identifier, WKT-string* @throws SQLException*/public Map<Integer, String> getAsText() throws SQLException {return retrieveExpected(createNativeAsTextStatement(), STRING);}/*** Returns the expected WKB representations of all testsuite-suite geometries** @return map of identifier, WKB representation* @throws SQLException*/public Map<Integer, byte[]> getAsBinary() throws SQLException {return retrieveExpected(createNativeAsBinaryStatement(), OBJECT);}/*** Returns the expected type names of all testsuite-suite geometries** @return map of identifier, type name* @throws SQLException*/public Map<Integer, String> getGeometryType() throws SQLException {return retrieveExpected(createNativeGeometryTypeStatement(), STRING);}/*** Returns the expected SRID codes of all testsuite-suite geometries** @return map of identifier, SRID* @throws SQLException*/public Map<Integer, Integer> getSrid() throws SQLException {return retrieveExpected(createNativeSridStatement(), INTEGER);}/*** Returns whether the testsuite-suite geometries are simple** @return map of identifier and whether testsuite-suite geometry is simple* @throws SQLException*/public Map<Integer, Boolean> getIsSimple() throws SQLException {return retrieveExpected(createNativeIsSimpleStatement(), BOOLEAN);}/*** Returns whether the testsuite-suite geometries are empty** @return map of identifier and whether testsuite-suite geometry is empty* @throws SQLException*/public Map<Integer, Boolean> getIsEmpty() throws SQLException {return retrieveExpected(createNativeIsEmptyStatement(), BOOLEAN);}/*** Returns the expected boundaries of all testsuite-suite geometries** @return map of identifier and boundary geometry* @throws SQLException*/public Map<Integer, Geometry> getBoundary() throws SQLException {return retrieveExpected(createNativeBoundaryStatement(), GEOMETRY);}/*** Returns the expected envelopes of all testsuite-suite geometries** @return map of identifier and envelope* @throws SQLException*/public Map<Integer, Geometry> getEnvelope() throws SQLException {return retrieveExpected(createNativeEnvelopeStatement(), GEOMETRY);}/*** Returns the expected results of the within operator** @param geom testsuite-suite geometry* @return* @throws SQLException*/public Map<Integer, Boolean> getWithin(Geometry geom) throws SQLException {return retrieveExpected(createNativeWithinStatement(geom), BOOLEAN);}/*** Returns the expected results of the equals operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getEquals(Geometry geom) throws SQLException {return retrieveExpected(createNativeEqualsStatement(geom), BOOLEAN);}/*** Returns the expected results of the crosses operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getCrosses(Geometry geom) throws SQLException {return retrieveExpected(createNativeCrossesStatement(geom), BOOLEAN);}/*** Returns the expected results of the contains operator*/public Map<Integer, Boolean> getContains(Geometry geom) throws SQLException {return retrieveExpected(createNativeContainsStatement(geom), BOOLEAN);}/*** Returns the expected results of the disjoint operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getDisjoint(Geometry geom) throws SQLException {return retrieveExpected(createNativeDisjointStatement(geom), BOOLEAN);}/*** Returns the expected results of the intersects operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getIntersects(Geometry geom) throws SQLException {return retrieveExpected(createNativeIntersectsStatement(geom), BOOLEAN);}/*** Returns the expected results of the touches operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getTouches(Geometry geom) throws SQLException {return retrieveExpected(createNativeTouchesStatement(geom), BOOLEAN);}/*** Returns the expected results of the overlaps operator** @param geom* @return* @throws SQLException*/public Map<Integer, Boolean> getOverlaps(Geometry geom) throws SQLException {return retrieveExpected(createNativeOverlapsStatement(geom), BOOLEAN);}/*** Returns the expected results of the relate operator** @param geom* @param matrix* @return* @throws SQLException*/public Map<Integer, Boolean> getRelate(Geometry geom, String matrix) throws SQLException {return retrieveExpected(createNativeRelateStatement(geom, matrix), BOOLEAN);}/*** Returns the expected results for the geometry filter** @param geom filter Geometry* @return*/public Map<Integer, Boolean> getFilter(Geometry geom) throws SQLException {return retrieveExpected(createNativeFilterStatement(geom), BOOLEAN);}/*** Returns the expected results of the distance function** @param geom geometry parameter to distance function* @return* @throws SQLException*/public Map<Integer, Double> getDistance(Geometry geom) throws SQLException {return retrieveExpected(createNativeDistanceStatement(geom), DOUBLE);}/*** Returns the expected results of the buffering function** @param distance distance parameter to the buffer function* @return* @throws SQLException*/public Map<Integer, Geometry> getBuffer(Double distance) throws SQLException {return retrieveExpected(createNativeBufferStatement(distance), GEOMETRY);}/*** Returns the expected results of the convexhull function** @param geom geometry with which each testsuite-suite geometry is unioned before convexhull calculation* @return* @throws SQLException*/public Map<Integer, Geometry> getConvexHull(Geometry geom) throws SQLException {return retrieveExpected(createNativeConvexHullStatement(geom), GEOMETRY);}/*** Returns the expected results of the intersection function** @param geom parameter to the intersection function* @return* @throws SQLException*/public Map<Integer, Geometry> getIntersection(Geometry geom) throws SQLException {return retrieveExpected(createNativeIntersectionStatement(geom), GEOMETRY);}/*** Returns the expected results of the difference function** @param geom parameter to the difference function* @return* @throws SQLException*/public Map<Integer, Geometry> getDifference(Geometry geom) throws SQLException {return retrieveExpected(createNativeDifferenceStatement(geom), GEOMETRY);}/*** Returns the expected results of the symdifference function** @param geom parameter to the symdifference function* @return* @throws SQLException*/public Map<Integer, Geometry> getSymDifference(Geometry geom) throws SQLException {return retrieveExpected(createNativeSymDifferenceStatement(geom), GEOMETRY);}/*** Returns the expected results of the geomunion function** @param geom parameter to the geomunion function* @return* @throws SQLException*/public Map<Integer, Geometry> getGeomUnion(Geometry geom) throws SQLException {return retrieveExpected(createNativeGeomUnionStatement(geom), GEOMETRY);}/*** Returns a statement corresponding to the HQL statement:* "SELECT id, touches(geom, :filter) from GeomEntity where touches(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeTouchesStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, overlaps(geom, :filter) from GeomEntity where overlaps(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeOverlapsStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, relate(geom, :filter, :matrix) from GeomEntity where relate(geom, :filter, :matrix) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @param matrix the string corresponding to the ':matrix' query parameter* @return*/protected abstract NativeSQLStatement createNativeRelateStatement(Geometry geom, String matrix);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, intersects(geom, :filter) from GeomEntity where intersects(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeIntersectsStatement(Geometry geom);/*** Returns the statement corresponding to the SpatialRestrictions.filter() method.** @param geom filter geometry* @return*/protected abstract NativeSQLStatement createNativeFilterStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, distance(geom, :filter) from GeomEntity where srid(geom) = 4326"** @param geom* @return*/protected abstract NativeSQLStatement createNativeDistanceStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "select id, dimension(geom) from GeomEntity".** @return the SQL String*/protected abstract NativeSQLStatement createNativeDimensionSQL();/*** Returns a statement corresponding to the HQL statement:* "SELECT id, buffer(geom, :distance) from GeomEntity where srid(geom) = 4326"** @param distance parameter corresponding to the ':distance' query parameter* @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeBufferStatement(Double distance);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, convexhull(geomunion(geom, :polygon)) from GeomEntity where srid(geom) = 4326"** @param geom parameter corresponding to the ':polygon' query parameter* @return*/protected abstract NativeSQLStatement createNativeConvexHullStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, intersection(geom, :polygon) from GeomEntity where srid(geom) = 4326"** @param geom parameter corresponding to the ':polygon' query parameter* @return*/protected abstract NativeSQLStatement createNativeIntersectionStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, difference(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"** @param geom parameter corresponding to the ':polygon' query parameter* @return*/protected abstract NativeSQLStatement createNativeDifferenceStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, symdifference(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"** @param geom parameter corresponding to the ':polygon' query parameter* @return*/protected abstract NativeSQLStatement createNativeSymDifferenceStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, geomunion(geom, :polygon) from GeomEntity where srid(geom) = 4326"26"** @param geom parameter corresponding to the ':polygon' query parameter* @return*/protected abstract NativeSQLStatement createNativeGeomUnionStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "select id, astext(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeAsTextStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, srid(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeSridStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, issimple(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeIsSimpleStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, isempty(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeIsEmptyStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, boundary(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeBoundaryStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, envelope(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeEnvelopeStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, asbinary(geom) from GeomEntity".** @return the native SQL Statement*/protected abstract NativeSQLStatement createNativeAsBinaryStatement();/*** Returns a statement corresponding to the HQL statement:* "select id, geometrytype(geom) from GeomEntity".** @return the SQL String*/protected abstract NativeSQLStatement createNativeGeometryTypeStatement();/*** Returns a statement corresponding to the HQL statement* "SELECT id, within(geom, :filter) from GeomEntity where within(geom, :filter) = true and srid(geom) = 4326"** @param testPolygon the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeWithinStatement(Geometry testPolygon);/*** Returns a statement corresponding to the HQL statement* "SELECT id, equals(geom, :filter) from GeomEntity where equals(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeEqualsStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement* "SELECT id, crosses(geom, :filter) from GeomEntity where crosses(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeCrossesStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement:* "SELECT id, contains(geom, :filter) from GeomEntity where contains(geom, :geom) = true and srid(geom) = 4326";** @param geom* @return*/protected abstract NativeSQLStatement createNativeContainsStatement(Geometry geom);/*** Returns a statement corresponding to the HQL statement* "SELECT id, disjoint(geom, :filter) from GeomEntity where disjoint(geom, :filter) = true and srid(geom) = 4326"** @param geom the geometry corresponding to the ':filter' query parameter* @return*/protected abstract NativeSQLStatement createNativeDisjointStatement(Geometry geom);/*** Creates a connection to the database** @return a Connection* @throws SQLException*/protected Connection createConnection() throws SQLException {return this.dataSourceUtils.createConnection();}/*** Decodes a native database object to a JTS <code>Geometry</code> instance** @param o native database object* @return decoded geometry*/protected abstract Geometry decode(Object o);/*** Return a testsuite-suite polygon (filter, ...)** @return a testsuite-suite polygon*/public Polygon getTestPolygon() {WKTReader reader = new WKTReader();try {Polygon polygon = (Polygon) reader.read(dataSourceUtils.TEST_POLYGON_WKT);polygon.setSRID(getTestSrid());return polygon;} catch (ParseException e) {throw new RuntimeException(e);}}protected <T> Map<Integer, T> retrieveExpected(NativeSQLStatement nativeSQLStatement, int type) throws SQLException {PreparedStatement preparedStatement = null;Connection cn = null;Map<Integer, T> expected = new HashMap<Integer, T>();try {cn = createConnection();preparedStatement = nativeSQLStatement.prepare(cn);ResultSet results = preparedStatement.executeQuery();while (results.next()) {int id = results.getInt(1);switch (type) {case GEOMETRY:expected.put(id, (T) decode(results.getObject(2)));break;case STRING:expected.put(id, (T) results.getString(2));break;case INTEGER:expected.put(id, (T) Long.valueOf(results.getLong(2)));break;case DOUBLE:Double value = Double.valueOf(results.getDouble(2));if (results.wasNull())value = null; //this is required because SQL Server converts automatically null to 0.0expected.put(id, (T) value);break;case BOOLEAN:expected.put(id, (T) Boolean.valueOf(results.getBoolean(2)));break;default:T val = (T) results.getObject(2);//this code is a hack to deal with Oracle Spatial that returns Blob's for asWKB() function//TODO -- clean upif (val instanceof Blob) {val = (T) ((Blob) val).getBytes(1, MAX_BYTE_LEN);}expected.put(id, val);}}return expected;} finally {if (preparedStatement != null) preparedStatement.close();if (cn != null) cn.close();}}protected NativeSQLStatement createNativeSQLStatement(final String sql) {return new NativeSQLStatement() {public PreparedStatement prepare(Connection connection) throws SQLException {return connection.prepareStatement(sql);}};}protected NativeSQLStatement createNativeSQLStatementAllWKTParams(final String sql, final String wkt) {return new NativeSQLStatement() {public PreparedStatement prepare(Connection connection) throws SQLException {PreparedStatement pstmt = connection.prepareStatement(sql);for (int i = 1; i <= numPlaceHoldersInSQL(sql); i++) {pstmt.setString(i, wkt);}return pstmt;}};}protected NativeSQLStatement createNativeSQLStatement(final String sql, final Object[] params) {return new NativeSQLStatement() {public PreparedStatement prepare(Connection connection) throws SQLException {PreparedStatement pstmt = connection.prepareStatement(sql);int i = 1;for (Object param : params) {pstmt.setObject(i++, param);}return pstmt;}};}protected int numPlaceHoldersInSQL(String sql) {return sql.replaceAll("[^?]", "").length();}}