From 041ae127f3d6b9bb1105ae81d7289c880b6226a7 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 11:01:36 +0100 Subject: [PATCH 1/8] Fix test source code --- h2/src/test/org/h2/test/unit/TestValueMemory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h2/src/test/org/h2/test/unit/TestValueMemory.java b/h2/src/test/org/h2/test/unit/TestValueMemory.java index 46bcb7c65..c95559b19 100644 --- a/h2/src/test/org/h2/test/unit/TestValueMemory.java +++ b/h2/src/test/org/h2/test/unit/TestValueMemory.java @@ -195,7 +195,7 @@ private Value create(int type) throws SQLException { case Value.STRING_FIXED: return ValueStringFixed.get(randomString(random.nextInt(100))); case Value.GEOMETRY: - if (DataType.GEOMETRY_CLASS == null) { + if (!ValueGeometry.isInitialized()) { return ValueNull.INSTANCE; } return ValueGeometry.get("POINT (" + random.nextInt(100) + " " + From 0fdea3aa0df399034f17d39ea015b5326c9ed5d0 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 12:51:17 +0100 Subject: [PATCH 2/8] Change cast geometry base type --- h2/src/main/org/h2/api/IGeometryFactory.java | 15 +++++++++++++ h2/src/main/org/h2/jts/H2GeometryFactory.java | 22 +++++++++++++++---- h2/src/main/org/h2/value/DataType.java | 7 +++++- h2/src/main/org/h2/value/ValueGeometry.java | 20 +++++++++++++++++ h2/src/test/org/h2/test/db/TestSpatial.java | 4 ++-- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/h2/src/main/org/h2/api/IGeometryFactory.java b/h2/src/main/org/h2/api/IGeometryFactory.java index 7f7b1dddd..fb51225fc 100644 --- a/h2/src/main/org/h2/api/IGeometryFactory.java +++ b/h2/src/main/org/h2/api/IGeometryFactory.java @@ -41,6 +41,14 @@ public interface IGeometryFactory { */ public IGeometry toGeometry(byte[] bytes) throws GeometryParseException; + /** + * Create IGeometry instance from provided object + * @param object Object assignable using this factory {@link #isAssignableFrom(Object)} + * @return IGeometry instance + * @throws GeometryParseException If object cast failed + */ + public IGeometry assignFrom(Object object) throws GeometryParseException; + /** * Creates a {@link IGeometry} instance by using the given parameters. * @@ -48,4 +56,11 @@ public interface IGeometryFactory { * @return a new {@link IGeometry} instance */ public IGeometry toGeometry(IEnvelope envelope); + + /** + * @param object Object that could be wrapped by this factory. + * @return True if this object can be used as an argument of {@link #toGeometry(Object)} + */ + public boolean isAssignableFrom(Object object); + } diff --git a/h2/src/main/org/h2/jts/H2GeometryFactory.java b/h2/src/main/org/h2/jts/H2GeometryFactory.java index e2af36624..c029b92dc 100644 --- a/h2/src/main/org/h2/jts/H2GeometryFactory.java +++ b/h2/src/main/org/h2/jts/H2GeometryFactory.java @@ -20,7 +20,7 @@ */ public class H2GeometryFactory implements IGeometryFactory { /** - * @see org.h2.value.IGeometryFactory#toGeometry(java.lang.String) + * @see org.h2.api.IGeometryFactory#toGeometry(java.lang.String) */ @Override public IGeometry toGeometry(String s) throws GeometryParseException { @@ -32,7 +32,7 @@ public IGeometry toGeometry(String s) throws GeometryParseException { } /** - * @see org.h2.value.IGeometryFactory#toGeometry(java.lang.String, int) + * @see org.h2.api.IGeometryFactory#toGeometry(java.lang.String, int) */ @Override public IGeometry toGeometry(String s, int srid) @@ -49,7 +49,7 @@ public IGeometry toGeometry(String s, int srid) } /** - * @see org.h2.value.IGeometryFactory#toGeometry(byte[]) + * @see org.h2.api.IGeometryFactory#toGeometry(byte[]) */ @Override public IGeometry toGeometry(byte[] bytes) throws GeometryParseException { @@ -61,7 +61,7 @@ public IGeometry toGeometry(byte[] bytes) throws GeometryParseException { } /** - * @see org.h2.value.IGeometryFactory#toGeometry(org.h2.value.IEnvelope) + * @see org.h2.api.IGeometryFactory#toGeometry(org.h2.api.IEnvelope) */ @Override public IGeometry toGeometry(IEnvelope envelope) { @@ -73,4 +73,18 @@ public IGeometry toGeometry(IEnvelope envelope) { return new H2Geometry( geometryFactory.toGeometry(envelope.unwrap(Envelope.class))); } + + @Override + public IGeometry assignFrom(Object object) throws GeometryParseException { + try { + return new H2Geometry((Geometry)object); + } catch (ClassCastException ex) { + throw new GeometryParseException(ex); + } + } + + @Override + public boolean isAssignableFrom(Object object) { + return object instanceof Geometry; + } } diff --git a/h2/src/main/org/h2/value/DataType.java b/h2/src/main/org/h2/value/DataType.java index b05a1e65a..b6425b21c 100644 --- a/h2/src/main/org/h2/value/DataType.java +++ b/h2/src/main/org/h2/value/DataType.java @@ -940,7 +940,12 @@ public static Value convertToValue(SessionInterface session, Object x, return ValueNull.INSTANCE; } if (type == Value.JAVA_OBJECT) { - return ValueJavaObject.getNoCopy(x, null, session.getDataHandler()); + ValueGeometry geom = ValueGeometry.tryGet(x); + if (geom != null) { + return geom; + } else { + return ValueJavaObject.getNoCopy(x, null, session.getDataHandler()); + } } if (x instanceof String) { return ValueString.get((String) x); diff --git a/h2/src/main/org/h2/value/ValueGeometry.java b/h2/src/main/org/h2/value/ValueGeometry.java index bce9cd5f4..dd3ed7be7 100644 --- a/h2/src/main/org/h2/value/ValueGeometry.java +++ b/h2/src/main/org/h2/value/ValueGeometry.java @@ -110,6 +110,26 @@ public static ValueGeometry get(String s, int srid) { } } + /** + * @param object Any object + * @return ValueGeometry instance if the argument is a Geometry, null otherwise + */ + public static ValueGeometry tryGet(Object object) { + if(isInitialized()) { + try { + if(GEOMETRY_FACTORY.isAssignableFrom(object)) { + return ValueGeometry.get(GEOMETRY_FACTORY.assignFrom(object)); + } else { + return null; + } + } catch (GeometryParseException ex) { + return null; + } + } else { + return null; + } + } + /** * Get or create a geometry value for the given geometry. * diff --git a/h2/src/test/org/h2/test/db/TestSpatial.java b/h2/src/test/org/h2/test/db/TestSpatial.java index fce0ff1eb..e92db2ed0 100644 --- a/h2/src/test/org/h2/test/db/TestSpatial.java +++ b/h2/src/test/org/h2/test/db/TestSpatial.java @@ -576,12 +576,12 @@ public void reset() throws SQLException { * @param srid the projection id * @return Geometry object */ - public static IGeometry geomFromText(String text, int srid) throws SQLException { + public static Geometry geomFromText(String text, int srid) throws SQLException { WKTReader wktReader = new WKTReader(); try { Geometry geom = wktReader.read(text); geom.setSRID(srid); - return new H2Geometry(geom); + return geom; } catch (ParseException ex) { throw new SQLException(ex); } From b2d5e6afc6ee4be17dd8e60d8ee087e80168cc0e Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 13:11:25 +0100 Subject: [PATCH 3/8] Remove IGeometry from rs.getObject() --- h2/src/main/org/h2/api/IGeometry.java | 2 ++ h2/src/main/org/h2/jts/H2Geometry.java | 7 ++++- h2/src/main/org/h2/value/ValueGeometry.java | 2 +- h2/src/test/org/h2/test/TestBase.java | 22 ++++++++------ h2/src/test/org/h2/test/db/TestSpatial.java | 32 +++++++++++--------- h2/src/test/org/h2/test/jaqu/UpdateTest.java | 6 ++-- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/h2/src/main/org/h2/api/IGeometry.java b/h2/src/main/org/h2/api/IGeometry.java index 7f0ea6f0a..fe3f00758 100644 --- a/h2/src/main/org/h2/api/IGeometry.java +++ b/h2/src/main/org/h2/api/IGeometry.java @@ -47,4 +47,6 @@ public interface IGeometry extends Comparable, Cloneable, Wrapper{ @Override public T unwrap(Class iface); + + public Object getJDBCJavaObject(); } diff --git a/h2/src/main/org/h2/jts/H2Geometry.java b/h2/src/main/org/h2/jts/H2Geometry.java index e7d3ac220..577dd6ef2 100644 --- a/h2/src/main/org/h2/jts/H2Geometry.java +++ b/h2/src/main/org/h2/jts/H2Geometry.java @@ -46,7 +46,12 @@ public int compareTo(IGeometry g) throws AssertionError { return geometry.compareTo(g.unwrap(Geometry.class)); } - /** + @Override + public Object getJDBCJavaObject() { + return geometry; + } + + /** * @see org.h2.value.IGeometry#getString() */ @Override diff --git a/h2/src/main/org/h2/value/ValueGeometry.java b/h2/src/main/org/h2/value/ValueGeometry.java index dd3ed7be7..448e0fbbd 100644 --- a/h2/src/main/org/h2/value/ValueGeometry.java +++ b/h2/src/main/org/h2/value/ValueGeometry.java @@ -222,7 +222,7 @@ public int hashCode() { @Override public Object getObject() { - return getGeometry(); + return getGeometry().getJDBCJavaObject(); } @Override diff --git a/h2/src/test/org/h2/test/TestBase.java b/h2/src/test/org/h2/test/TestBase.java index 43cfd4aba..e7dca40e2 100644 --- a/h2/src/test/org/h2/test/TestBase.java +++ b/h2/src/test/org/h2/test/TestBase.java @@ -727,26 +727,28 @@ protected void assertEqualStreams(InputStream expected, InputStream actual, * @param actual the actual value * @throws AssertionError if the values are not equal */ - protected void assertEquals(String message, String expected, String actual) { + protected void assertEquals(String message, Object expected, Object actual) { if (expected == null && actual == null) { return; } else if (expected == null || actual == null) { fail("Expected: " + expected + " Actual: " + actual + " " + message); } else if (!expected.equals(actual)) { - int al = expected.length(); - int bl = actual.length(); - for (int i = 0; i < expected.length(); i++) { - String s = expected.substring(0, i); - if (!actual.startsWith(s)) { - expected = expected.substring(0, i) + "<*>" + expected.substring(i); + String expectedString = expected.toString(); + String actualString = actual.toString(); + int al = expectedString.length(); + int bl = actualString.length(); + for (int i = 0; i < expectedString.length(); i++) { + String s = expectedString.substring(0, i); + if (!actualString.startsWith(s)) { + expected = expectedString.substring(0, i) + "<*>" + expectedString.substring(i); break; } } if (al > 4000) { - expected = expected.substring(0, 4000); + expected = expectedString.substring(0, 4000); } if (bl > 4000) { - actual = actual.substring(0, 4000); + actual = actualString.substring(0, 4000); } fail("Expected: " + expected + " (" + al + ") actual: " + actual + " (" + bl + ") " + message); @@ -760,7 +762,7 @@ protected void assertEquals(String message, String expected, String actual) { * @param actual the actual value * @throws AssertionError if the values are not equal */ - protected void assertEquals(String expected, String actual) { + protected void assertEquals(Object expected, Object actual) { assertEquals("", expected, actual); } diff --git a/h2/src/test/org/h2/test/db/TestSpatial.java b/h2/src/test/org/h2/test/db/TestSpatial.java index e92db2ed0..cb33d170b 100644 --- a/h2/src/test/org/h2/test/db/TestSpatial.java +++ b/h2/src/test/org/h2/test/db/TestSpatial.java @@ -130,7 +130,7 @@ private void testSpatialValues() throws SQLException { new Coordinate(2, 2), new Coordinate(1, 1) }); - assertTrue(new H2Geometry(polygon).equals(rs.getObject(2))); + assertTrue(polygon.equals(rs.getObject(2))); rs = stat.executeQuery("select * from test where polygon = " + "'POLYGON ((1 1, 1 2, 2 2, 1 1))'"); @@ -723,9 +723,8 @@ private void testAggregateWithGeometry() throws SQLException { assertEquals("geometry", rs.getMetaData(). getColumnTypeName(1).toLowerCase()); assertTrue(rs.next()); - assertTrue(rs.getObject(1) instanceof IGeometry); - assertTrue(new Envelope(1, 10, 1, 5).equals( - ((IGeometry) rs.getObject(1)).getEnvelope().unwrap(Envelope.class))); + assertTrue(rs.getObject(1) instanceof Geometry); + assertEquals(new Envelope(1, 10, 1, 5), ((Geometry) rs.getObject(1)).getEnvelopeInternal()); assertFalse(rs.next()); } finally { conn.close(); @@ -737,7 +736,7 @@ private void testAggregateWithGeometry() throws SQLException { * An aggregate function that calculates the envelope. */ public static class TableEnvelope implements Aggregate { - private Envelope tableEnvelope; + private Envelope tableEnvelope = new Envelope(); @Override public int getInternalType(int[] inputTypes) throws SQLException { @@ -756,18 +755,22 @@ public void init(Connection conn) throws SQLException { @Override public void add(Object value) throws SQLException { - if (value instanceof IGeometry) { + if (value instanceof Geometry) { if (tableEnvelope == null) { - tableEnvelope = ((IGeometry) value).getEnvelope().unwrap(Envelope.class); + tableEnvelope = ((Geometry) value).getEnvelopeInternal(); } else { - tableEnvelope.expandToInclude(((IGeometry) value).getEnvelope().unwrap(Envelope.class)); + tableEnvelope.expandToInclude(((Geometry) value).getEnvelopeInternal()); } + } else { + + throw new SQLException("TableEnvelope accepts only Geometry values. Input: " + + value.getClass().getSimpleName()); } } @Override public Object getResult() throws SQLException { - return new H2Geometry(new GeometryFactory().toGeometry(tableEnvelope)); + return new GeometryFactory().toGeometry(tableEnvelope); } } @@ -816,9 +819,8 @@ private void testValueGeometryScript() throws SQLException { "SELECT " + valueGeometry.getSQL()); assertTrue(rs.next()); Object obj = rs.getObject(1); - assertTrue(obj instanceof IGeometry); - ValueGeometry g = ValueGeometry.get((IGeometry) obj); - assertTrue("got: " + g + " exp: " + valueGeometry, valueGeometry.equals(g)); + assertTrue(obj instanceof Geometry); + assertEquals(valueGeometry.getObject(), obj); } finally { conn.close(); } @@ -835,15 +837,15 @@ private void testInPlaceUpdate() throws SQLException { "SELECT 'POINT(1 1)'::geometry"); assertTrue(rs.next()); // Mutate the geometry - ((IGeometry) rs.getObject(1)).unwrap(Geometry.class).apply(new AffineTransformation(1, 0, + ((Geometry) rs.getObject(1)).apply(new AffineTransformation(1, 0, 1, 1, 0, 1)); rs.close(); rs = conn.createStatement().executeQuery( "SELECT 'POINT(1 1)'::geometry"); assertTrue(rs.next()); // Check if the geometry is the one requested - assertEquals(1, ((IGeometry) rs.getObject(1)).unwrap(Point.class).getX()); - assertEquals(1, ((IGeometry) rs.getObject(1)).unwrap(Point.class).getY()); + assertEquals(1, ((Point) rs.getObject(1)).getX()); + assertEquals(1, ((Point) rs.getObject(1)).getY()); rs.close(); } finally { conn.close(); diff --git a/h2/src/test/org/h2/test/jaqu/UpdateTest.java b/h2/src/test/org/h2/test/jaqu/UpdateTest.java index f1773879d..7cc5eb00b 100644 --- a/h2/src/test/org/h2/test/jaqu/UpdateTest.java +++ b/h2/src/test/org/h2/test/jaqu/UpdateTest.java @@ -58,7 +58,7 @@ private void testSimpleUpdate() { Product p2 = new Product(); Product pChang2 = db.from(p2).where(p2.productName).is("Chang") .selectFirst(); - assertEquals(19.5, pChang2.unitPrice); + assertEquals(19.5, pChang2.unitPrice.doubleValue()); assertEquals(16, pChang2.unitsInStock.intValue()); // undo update @@ -96,7 +96,7 @@ private void testSimpleMerge() { Product p2 = new Product(); Product pChang2 = db.from(p2).where(p2.productName).is("Chang") .selectFirst(); - assertEquals(19.5, pChang2.unitPrice); + assertEquals(19.5, pChang2.unitPrice.doubleValue()); assertEquals(16, pChang2.unitsInStock.intValue()); // undo update @@ -137,7 +137,7 @@ private void testSetColumns() { // confirm the data was properly updated Product revised = db.from(p).where(p.productId).is(1).selectFirst(); assertEquals("updated", revised.productName); - assertEquals(original.unitPrice + 3.14, revised.unitPrice); + assertEquals(original.unitPrice + 3.14, revised.unitPrice.doubleValue()); assertEquals(original.unitsInStock + 2, revised.unitsInStock.intValue()); // restore the data From 044826873d4a316d51add021981391892dbb7203 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 13:57:25 +0100 Subject: [PATCH 4/8] Fix more cast errors, unit test ok --- h2/src/main/org/h2/api/IGeometryFactory.java | 7 +++---- h2/src/main/org/h2/jts/H2Geometry.java | 2 -- h2/src/main/org/h2/jts/H2GeometryFactory.java | 4 ++-- h2/src/main/org/h2/value/DataType.java | 6 +++--- h2/src/main/org/h2/value/ValueGeometry.java | 11 +++++++++-- h2/src/test/org/h2/test/db/TestSpatial.java | 11 +++-------- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/h2/src/main/org/h2/api/IGeometryFactory.java b/h2/src/main/org/h2/api/IGeometryFactory.java index fb51225fc..f575735c4 100644 --- a/h2/src/main/org/h2/api/IGeometryFactory.java +++ b/h2/src/main/org/h2/api/IGeometryFactory.java @@ -58,9 +58,8 @@ public interface IGeometryFactory { public IGeometry toGeometry(IEnvelope envelope); /** - * @param object Object that could be wrapped by this factory. - * @return True if this object can be used as an argument of {@link #toGeometry(Object)} + * @param geomClass Object that could be wrapped by this factory. + * @return True if this object can be used as an argument of {@link #assignFrom(Object)} */ - public boolean isAssignableFrom(Object object); - + public boolean isAssignableFrom(Class geomClass); } diff --git a/h2/src/main/org/h2/jts/H2Geometry.java b/h2/src/main/org/h2/jts/H2Geometry.java index 577dd6ef2..271679e2b 100644 --- a/h2/src/main/org/h2/jts/H2Geometry.java +++ b/h2/src/main/org/h2/jts/H2Geometry.java @@ -1,7 +1,5 @@ package org.h2.jts; -import java.sql.SQLException; - import org.h2.api.IEnvelope; import org.h2.api.IGeometry; import org.h2.message.DbException; diff --git a/h2/src/main/org/h2/jts/H2GeometryFactory.java b/h2/src/main/org/h2/jts/H2GeometryFactory.java index c029b92dc..f1bfa3ea5 100644 --- a/h2/src/main/org/h2/jts/H2GeometryFactory.java +++ b/h2/src/main/org/h2/jts/H2GeometryFactory.java @@ -84,7 +84,7 @@ public IGeometry assignFrom(Object object) throws GeometryParseException { } @Override - public boolean isAssignableFrom(Object object) { - return object instanceof Geometry; + public boolean isAssignableFrom(Class geomClass) { + return Geometry.class.isAssignableFrom(geomClass); } } diff --git a/h2/src/main/org/h2/value/DataType.java b/h2/src/main/org/h2/value/DataType.java index b6425b21c..f6d6d57d4 100644 --- a/h2/src/main/org/h2/value/DataType.java +++ b/h2/src/main/org/h2/value/DataType.java @@ -919,7 +919,7 @@ public static int getTypeFromClass(Class x) { } else if (Object[].class.isAssignableFrom(x)) { // this includes String[] and so on return Value.ARRAY; - } else if (IGeometry.class.isAssignableFrom(x)) { + } else if (IGeometry.class.isAssignableFrom(x) || ValueGeometry.isGeometryClass(x)) { return Value.GEOMETRY; } else { return Value.JAVA_OBJECT; @@ -1020,8 +1020,8 @@ public static Value convertToValue(SessionInterface session, Object x, return ValueArray.get(x.getClass().getComponentType(), v); } else if (x instanceof Character) { return ValueStringFixed.get(((Character) x).toString()); - } else if (x instanceof IGeometry) { - return ValueGeometry.get((IGeometry) x); + } else if (ValueGeometry.isGeometryClass(x.getClass())){ + return ValueGeometry.tryGet(x); } else { return ValueJavaObject.getNoCopy(x, null, session.getDataHandler()); } diff --git a/h2/src/main/org/h2/value/ValueGeometry.java b/h2/src/main/org/h2/value/ValueGeometry.java index 448e0fbbd..c1f0f1bcf 100644 --- a/h2/src/main/org/h2/value/ValueGeometry.java +++ b/h2/src/main/org/h2/value/ValueGeometry.java @@ -115,9 +115,12 @@ public static ValueGeometry get(String s, int srid) { * @return ValueGeometry instance if the argument is a Geometry, null otherwise */ public static ValueGeometry tryGet(Object object) { + if(object instanceof IGeometry) { + return ValueGeometry.get((IGeometry) object); + } if(isInitialized()) { try { - if(GEOMETRY_FACTORY.isAssignableFrom(object)) { + if(GEOMETRY_FACTORY.isAssignableFrom(object.getClass())) { return ValueGeometry.get(GEOMETRY_FACTORY.assignFrom(object)); } else { return null; @@ -130,6 +133,10 @@ public static ValueGeometry tryGet(Object object) { } } + public static boolean isGeometryClass(Class classArg) { + return isInitialized() && (GEOMETRY_FACTORY.isAssignableFrom(classArg) || IGeometry.class.isAssignableFrom(classArg)); + } + /** * Get or create a geometry value for the given geometry. * @@ -264,7 +271,7 @@ public Value convertTo(int targetType) { } return super.convertTo(targetType); } - + /** * Returns true if a IGeometryFactory is available and initialized. * @return diff --git a/h2/src/test/org/h2/test/db/TestSpatial.java b/h2/src/test/org/h2/test/db/TestSpatial.java index cb33d170b..8d9a6e8fd 100644 --- a/h2/src/test/org/h2/test/db/TestSpatial.java +++ b/h2/src/test/org/h2/test/db/TestSpatial.java @@ -18,11 +18,6 @@ import com.vividsolutions.jts.geom.util.AffineTransformation; import org.h2.api.Aggregate; -import org.h2.api.IEnvelope; -import org.h2.api.IGeometry; -import org.h2.jts.H2Envelope; -import org.h2.jts.H2Geometry; -import org.h2.jts.H2GeometryFactory; import org.h2.test.TestBase; import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleRowSource; @@ -589,7 +584,7 @@ public static Geometry geomFromText(String text, int srid) throws SQLException { private void testGeometryDataType() { GeometryFactory geometryFactory = new GeometryFactory(); - H2Geometry geometry = new H2Geometry(geometryFactory.createPoint(new Coordinate(0, 0))); + Geometry geometry = geometryFactory.createPoint(new Coordinate(0, 0)); assertEquals(Value.GEOMETRY, DataType.getTypeFromClass(geometry.getClass())); } @@ -656,11 +651,11 @@ private void testEquals() { geometry.setSRID(27572); ValueGeometry valueGeometry = - ValueGeometry.get(new H2Geometry(geometry)); + ValueGeometry.tryGet(geometry); Geometry geometry2 = geometryFactory.createPoint(new Coordinate(0, 0)); geometry2.setSRID(5326); ValueGeometry valueGeometry2 = - ValueGeometry.get(new H2Geometry(geometry2)); + ValueGeometry.tryGet(geometry2); assertFalse(valueGeometry.equals(valueGeometry2)); // Check illegal geometry (no WKB representation) try { From 1681c385939a94648bb2b6d22775573722d06cc6 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 14:04:58 +0100 Subject: [PATCH 5/8] javadoc --- h2/src/main/org/h2/api/IGeometry.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/h2/src/main/org/h2/api/IGeometry.java b/h2/src/main/org/h2/api/IGeometry.java index fe3f00758..a3f6eefcf 100644 --- a/h2/src/main/org/h2/api/IGeometry.java +++ b/h2/src/main/org/h2/api/IGeometry.java @@ -41,12 +41,9 @@ public interface IGeometry extends Comparable, Cloneable, Wrapper{ * @return the bounding box */ public IEnvelope getEnvelope(); - - @Override - public boolean isWrapperFor(Class iface); - - @Override - public T unwrap(Class iface); + /** + * @return Internal object returned when user call {@link java.sql.ResultSet#getObject(int)} + */ public Object getJDBCJavaObject(); } From d5d8a7c477511cb2efd23f98b111547b965dd15d Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 14:34:14 +0100 Subject: [PATCH 6/8] fix exception error --- h2/src/main/org/h2/jts/H2Geometry.java | 16 ++++++---------- h2/src/main/org/h2/value/DataType.java | 7 ++++++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/h2/src/main/org/h2/jts/H2Geometry.java b/h2/src/main/org/h2/jts/H2Geometry.java index 271679e2b..5ee078076 100644 --- a/h2/src/main/org/h2/jts/H2Geometry.java +++ b/h2/src/main/org/h2/jts/H2Geometry.java @@ -36,12 +36,8 @@ public H2Geometry(Geometry geometry) { * if the unwrap of {@link Geometry} is not possible. */ @Override - public int compareTo(IGeometry g) throws AssertionError { - if (!g.isWrapperFor(Geometry.class)) - throw new AssertionError( - "Comparision isn't supported if 'com.vividsolutions.jts.geom.Geometry' can't be unwrapped!"); - - return geometry.compareTo(g.unwrap(Geometry.class)); + public int compareTo(IGeometry g) { + return geometry.compareTo(g.getJDBCJavaObject()); } @Override @@ -50,7 +46,7 @@ public Object getJDBCJavaObject() { } /** - * @see org.h2.value.IGeometry#getString() + * @see org.h2.api.IGeometry#getString() */ @Override public String getString() { @@ -58,7 +54,7 @@ public String getString() { } /** - * @see org.h2.value.IGeometry#getBytes() + * @see org.h2.api.IGeometry#getBytes() */ @Override public byte[] getBytes() { @@ -75,7 +71,7 @@ private static int getDimensionCount(Geometry geometry) { } /** - * @see org.h2.value.IGeometry#clone() + * @see org.h2.api.IGeometry#clone() */ @Override public IGeometry clone() { @@ -83,7 +79,7 @@ public IGeometry clone() { } /** - * @see org.h2.value.IGeometry#getEnvelope() + * @see org.h2.api.IGeometry#getEnvelope() */ @Override public IEnvelope getEnvelope() { diff --git a/h2/src/main/org/h2/value/DataType.java b/h2/src/main/org/h2/value/DataType.java index f6d6d57d4..97697fe01 100644 --- a/h2/src/main/org/h2/value/DataType.java +++ b/h2/src/main/org/h2/value/DataType.java @@ -1021,7 +1021,12 @@ public static Value convertToValue(SessionInterface session, Object x, } else if (x instanceof Character) { return ValueStringFixed.get(((Character) x).toString()); } else if (ValueGeometry.isGeometryClass(x.getClass())){ - return ValueGeometry.tryGet(x); + ValueGeometry value = ValueGeometry.tryGet(x); + if(value != null) { + return value; + } else { + return ValueNull.INSTANCE; + } } else { return ValueJavaObject.getNoCopy(x, null, session.getDataHandler()); } From 737c27d432a70ce4fd1a718511da39af94d249de Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Mon, 16 Mar 2015 15:53:30 +0100 Subject: [PATCH 7/8] Fix user resultset with geometry --- h2/src/main/org/h2/res/help.csv | 2 +- h2/src/main/org/h2/value/DataType.java | 5 ++--- h2/src/test/org/h2/test/db/TestSpatial.java | 9 +++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/h2/src/main/org/h2/res/help.csv b/h2/src/main/org/h2/res/help.csv index 3fdefe9f5..0b4e440f4 100644 --- a/h2/src/main/org/h2/res/help.csv +++ b/h2/src/main/org/h2/res/help.csv @@ -210,7 +210,7 @@ Creates a new table." "Commands (DDL)","CREATE TRIGGER"," CREATE TRIGGER [ IF NOT EXISTS ] newTriggerName { BEFORE | AFTER | INSTEAD OF } { INSERT | UPDATE | DELETE | SELECT | ROLLBACK } [,...] ON tableName [ FOR EACH ROW ] -[ QUEUE int ] [ NOWAIT ] CALL triggeredClassName +[ QUEUE int ] [ NOWAIT ] { CALL triggeredClassName | AS sourceCodeString } "," Creates a new trigger." "Commands (DDL)","CREATE USER"," diff --git a/h2/src/main/org/h2/value/DataType.java b/h2/src/main/org/h2/value/DataType.java index 97697fe01..b672e3e0f 100644 --- a/h2/src/main/org/h2/value/DataType.java +++ b/h2/src/main/org/h2/value/DataType.java @@ -637,11 +637,10 @@ public static Value readValue(SessionInterface session, ResultSet rs, } case Value.GEOMETRY: { Object x = rs.getObject(columnIndex); - if (x == null || !(x instanceof IGeometry)) { + if (x == null || !(ValueGeometry.isGeometryClass(x.getClass()))) { return ValueNull.INSTANCE; } - - return ValueGeometry.get((IGeometry) x); + return ValueGeometry.tryGet(x); } default: throw DbException.throwInternalError("type="+type); diff --git a/h2/src/test/org/h2/test/db/TestSpatial.java b/h2/src/test/org/h2/test/db/TestSpatial.java index 8d9a6e8fd..8b88297ee 100644 --- a/h2/src/test/org/h2/test/db/TestSpatial.java +++ b/h2/src/test/org/h2/test/db/TestSpatial.java @@ -684,6 +684,15 @@ private void testTableFunctionGeometry() throws SQLException { assertEquals("geometry", columnMeta.getString("TYPE_NAME").toLowerCase()); assertFalse(columnMeta.next()); + ResultSet testData = stat.executeQuery("SELECT * FROM test"); + try { + assertTrue(testData.next()); + assertTrue(testData.getObject(1) instanceof Geometry); + assertEquals(1, ((Point) testData.getObject(1)).getX()); + assertEquals(1, ((Point)testData.getObject(1)).getY()); + } finally { + testData.close(); + } } finally { conn.close(); } From 61baf64e53e53dd88c3ecb82dcfcae5eaa3fca51 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Tue, 17 Mar 2015 09:10:07 +0100 Subject: [PATCH 8/8] Fix OSGi error by using ValueGeometry classloader instead of Thread classloader --- h2/src/main/org/h2/value/ValueGeometry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h2/src/main/org/h2/value/ValueGeometry.java b/h2/src/main/org/h2/value/ValueGeometry.java index c1f0f1bcf..ab30d472d 100644 --- a/h2/src/main/org/h2/value/ValueGeometry.java +++ b/h2/src/main/org/h2/value/ValueGeometry.java @@ -33,7 +33,7 @@ public class ValueGeometry extends Value { private static final IGeometryFactory GEOMETRY_FACTORY; static { - ServiceLoader geometryFactories = ServiceLoader.load(IGeometryFactory.class); + ServiceLoader geometryFactories = ServiceLoader.load(IGeometryFactory.class, ValueGeometry.class.getClassLoader()); Iterator geometryFactoryIterator = geometryFactories.iterator(); GEOMETRY_FACTORY = geometryFactoryIterator.hasNext() ? geometryFactories.iterator().next() : null; }