Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions h2/src/main/org/h2/api/IGeometry.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ public interface IGeometry extends Comparable<IGeometry>, Cloneable, Wrapper{
* @return the bounding box
*/
public IEnvelope getEnvelope();

@Override
public boolean isWrapperFor(Class<?> iface);

@Override
public <T> T unwrap(Class<T> iface);

/**
* @return Internal object returned when user call {@link java.sql.ResultSet#getObject(int)}
*/
public Object getJDBCJavaObject();
}
14 changes: 14 additions & 0 deletions h2/src/main/org/h2/api/IGeometryFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,25 @@ 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.
*
* @param envelope the envelope
* @return a new {@link IGeometry} instance
*/
public IGeometry toGeometry(IEnvelope envelope);

/**
* @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(Class<?> geomClass);
}
25 changes: 12 additions & 13 deletions h2/src/main/org/h2/jts/H2Geometry.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -38,24 +36,25 @@ 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());
}

/**
* @see org.h2.value.IGeometry#getString()
@Override
public Object getJDBCJavaObject() {
return geometry;
}

/**
* @see org.h2.api.IGeometry#getString()
*/
@Override
public String getString() {
return new WKTWriter(3).write(geometry);
}

/**
* @see org.h2.value.IGeometry#getBytes()
* @see org.h2.api.IGeometry#getBytes()
*/
@Override
public byte[] getBytes() {
Expand All @@ -72,15 +71,15 @@ private static int getDimensionCount(Geometry geometry) {
}

/**
* @see org.h2.value.IGeometry#clone()
* @see org.h2.api.IGeometry#clone()
*/
@Override
public IGeometry clone() {
return new H2Geometry((Geometry) geometry.clone());
}

/**
* @see org.h2.value.IGeometry#getEnvelope()
* @see org.h2.api.IGeometry#getEnvelope()
*/
@Override
public IEnvelope getEnvelope() {
Expand Down
22 changes: 18 additions & 4 deletions h2/src/main/org/h2/jts/H2GeometryFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -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 {
Expand All @@ -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) {
Expand All @@ -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(Class geomClass) {
return Geometry.class.isAssignableFrom(geomClass);
}
}
2 changes: 1 addition & 1 deletion h2/src/main/org/h2/res/help.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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","
Expand Down
23 changes: 16 additions & 7 deletions h2/src/main/org/h2/value/DataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -919,7 +918,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;
Expand All @@ -940,7 +939,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);
Expand Down Expand Up @@ -1015,8 +1019,13 @@ 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())){
ValueGeometry value = ValueGeometry.tryGet(x);
if(value != null) {
return value;
} else {
return ValueNull.INSTANCE;
}
} else {
return ValueJavaObject.getNoCopy(x, null, session.getDataHandler());
}
Expand Down
33 changes: 30 additions & 3 deletions h2/src/main/org/h2/value/ValueGeometry.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class ValueGeometry extends Value {
private static final IGeometryFactory GEOMETRY_FACTORY;

static {
ServiceLoader<IGeometryFactory> geometryFactories = ServiceLoader.load(IGeometryFactory.class);
ServiceLoader<IGeometryFactory> geometryFactories = ServiceLoader.load(IGeometryFactory.class, ValueGeometry.class.getClassLoader());
Iterator<IGeometryFactory> geometryFactoryIterator = geometryFactories.iterator();
GEOMETRY_FACTORY = geometryFactoryIterator.hasNext() ? geometryFactories.iterator().next() : null;
}
Expand Down Expand Up @@ -110,6 +110,33 @@ 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(object instanceof IGeometry) {
return ValueGeometry.get((IGeometry) object);
}
if(isInitialized()) {
try {
if(GEOMETRY_FACTORY.isAssignableFrom(object.getClass())) {
return ValueGeometry.get(GEOMETRY_FACTORY.assignFrom(object));
} else {
return null;
}
} catch (GeometryParseException ex) {
return null;
}
} else {
return null;
}
}

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.
*
Expand Down Expand Up @@ -202,7 +229,7 @@ public int hashCode() {

@Override
public Object getObject() {
return getGeometry();
return getGeometry().getJDBCJavaObject();
}

@Override
Expand Down Expand Up @@ -244,7 +271,7 @@ public Value convertTo(int targetType) {
}
return super.convertTo(targetType);
}

/**
* Returns <code>true</code> if a IGeometryFactory is available and initialized.
* @return
Expand Down
22 changes: 12 additions & 10 deletions h2/src/test/org/h2/test/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down
Loading