HHH-14800 Use FunctionContributor interface to register spatial functions

This commit is contained in:
Karel Maesen 2021-07-24 17:48:20 +02:00
parent 0b9de79a7d
commit f5f0ccfdd3
18 changed files with 153 additions and 56 deletions

View File

@ -41,7 +41,10 @@ public interface HSMessageLogger extends BasicLogger {
void connectionFinder(String className);
@LogMessage(level = INFO) //maybe should be DEBUG?
@Message(value = "hibernate-spatial using type contributions from : %s", id = 80000003)
@Message(value = "hibernate-spatial adding type contributions from : %s", id = 80000003)
void typeContributions(String source);
@LogMessage(level = INFO) //maybe should be DEBUG?
@Message(value = "hibernate-spatial adding function contributions from : %s", id = 80000004)
void functionContributions(String source);
}

View File

@ -5,23 +5,26 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.type;
package org.hibernate.spatial.contributor;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.TypeContributor;
import org.hibernate.service.ServiceRegistry;
/**
* Internal contract for TypeContributor
*/
abstract class SpatialTypeContributorImplementor {
abstract class ContributorImplementor {
private final ServiceRegistry serviceRegistryegistry;
SpatialTypeContributorImplementor(ServiceRegistry serviceRegistry) {
ContributorImplementor(ServiceRegistry serviceRegistry) {
this.serviceRegistryegistry = serviceRegistry;
}
abstract void contribute(TypeContributions typeContributions);
abstract void contributeTypes(TypeContributions typeContributions);
abstract void contributeFunctions(FunctionContributions functionContributions);
ServiceRegistry getServiceRegistryegistry() {
return serviceRegistryegistry;

View File

@ -0,0 +1,44 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.contributor;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.service.ServiceRegistry;
class ContributorResolver {
private final static Map<Class<? extends Dialect>,
Function<ServiceRegistry, ContributorImplementor>> ContributorMap = new HashMap<>();
static {
//TypeContributorImplementor
ContributorMap.put( PostgreSQLDialect.class, PostgreSQLDialectContributor::new );
}
private ContributorResolver() {
}
static ContributorImplementor resolveSpatialtypeContributorImplementor(ServiceRegistry serviceRegistry) {
JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
Dialect dialect = jdbcServices.getDialect();
for ( Class<?> dialectClass : ContributorMap.keySet() ) {
if ( dialectClass.isAssignableFrom( dialect.getClass() ) ) {
return ContributorMap.get( dialectClass ).apply( serviceRegistry );
}
}
return null;
}
}

View File

@ -12,9 +12,13 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.type;
package org.hibernate.spatial.contributor;
import java.util.Map;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
import org.hibernate.spatial.GeolatteGeometryType;
@ -22,14 +26,15 @@ import org.hibernate.spatial.HSMessageLogger;
import org.hibernate.spatial.JTSGeometryJavaTypeDescriptor;
import org.hibernate.spatial.JTSGeometryType;
import org.hibernate.spatial.dialect.postgis.PGGeometryTypeDescriptor;
import org.hibernate.spatial.dialect.postgis.PostgisFunctions;
public class PostgreSQLDialectTypeContributor extends SpatialTypeContributorImplementor{
public class PostgreSQLDialectContributor extends ContributorImplementor {
PostgreSQLDialectTypeContributor(ServiceRegistry serviceRegistry) {
PostgreSQLDialectContributor(ServiceRegistry serviceRegistry) {
super( serviceRegistry );
}
public void contribute(TypeContributions typeContributions) {
public void contributeTypes(TypeContributions typeContributions) {
HSMessageLogger.LOGGER.typeContributions( this.getClass().getCanonicalName() );
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) );
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) );
@ -38,4 +43,13 @@ public class PostgreSQLDialectTypeContributor extends SpatialTypeContributorImpl
typeContributions.contributeJavaTypeDescriptor( GeolatteGeometryJavaTypeDescriptor.INSTANCE );
typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE );
}
@Override
void contributeFunctions(FunctionContributions functionContributions) {
HSMessageLogger.LOGGER.functionContributions( this.getClass().getCanonicalName() );
PostgisFunctions functions = new PostgisFunctions();
for( Map.Entry<String, SqmFunctionDescriptor> kv: functions) {
functionContributions.contributeFunction( kv.getKey(), kv.getValue() );
}
}
}

View File

@ -0,0 +1,26 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.contributor;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.FunctionContributor;
import org.hibernate.service.ServiceRegistry;
public class SpatialFunctionContributor implements FunctionContributor {
@Override
public void contributeTypes(
FunctionContributions functionContributions, ServiceRegistry serviceRegistry) {
ContributorImplementor contributorImplementor = ContributorResolver.resolveSpatialtypeContributorImplementor(
serviceRegistry );
if ( contributorImplementor != null ) {
contributorImplementor.contributeFunctions( functionContributions );
}
}
}

View File

@ -5,7 +5,7 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.type;
package org.hibernate.spatial.contributor;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.TypeContributor;
@ -15,10 +15,10 @@ public class SpatialTypeContributor implements TypeContributor {
@Override
public void contribute(
TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
SpatialTypeContributorImplementor contributorImplementor = TypeContributorResolver.resolve( serviceRegistry );
ContributorImplementor contributorImplementor = ContributorResolver.resolveSpatialtypeContributorImplementor( serviceRegistry );
if (contributorImplementor != null) {
contributorImplementor.contribute( typeContributions );
contributorImplementor.contributeTypes( typeContributions );
}
}

View File

@ -11,6 +11,7 @@ import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
@ -76,6 +77,8 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
return decoder.decode( pgValue );
}
@Override
public int getJdbcType() {
return 5432;
@ -103,9 +106,20 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
st.setObject( name, obj );
}
//this and the next override is ONLY necessary as long as the distinction between SQLType and JDBC Type is not resolved
@Override
protected void doBindNull(PreparedStatement st, int index, WrapperOptions options) throws SQLException {
st.setNull( index, Types.OTHER );
}
@Override
protected void doBindNull(CallableStatement st, String name, WrapperOptions options) throws SQLException {
st.setNull( name, Types.OTHER );
}
private PGobject toPGobject(X value, WrapperOptions options) throws SQLException {
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 );
final Geometry geometry = getJavaTypeDescriptor().unwrap( value, Geometry.class, options );
final Geometry<?> geometry = getJavaTypeDescriptor().unwrap( value, Geometry.class, options );
final String hexString = encoder.encode( geometry, ByteOrder.NDR ).toString();
final PGobject obj = new PGobject();
obj.setType( "geometry" );

View File

@ -1,29 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.type;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.service.ServiceRegistry;
class TypeContributorResolver {
private TypeContributorResolver() {
}
static SpatialTypeContributorImplementor resolve(ServiceRegistry serviceRegistry) {
JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
Dialect dialect = jdbcServices.getDialect();
if ( dialect.getClass().isAssignableFrom( PostgreSQLDialect.class ) ) {
return new PostgreSQLDialectTypeContributor( serviceRegistry );
}
return null;
}
}

View File

@ -0,0 +1,8 @@
#
# Hibernate, Relational Persistence for Idiomatic Java
#
# License: GNU Lesser General Public License (LGPL), version 2.1 or later.
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
#
org.hibernate.spatial.contributor.SpatialFunctionContributor

View File

@ -5,4 +5,4 @@
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
#
org.hibernate.spatial.type.SpatialTypeContributor
org.hibernate.spatial.contributor.SpatialTypeContributor

View File

@ -12,5 +12,9 @@
<bean id="serviceContributor" class="org.hibernate.spatial.integration.SpatialInitializer"/>
<service ref="serviceContributor" interface="org.hibernate.service.spi.ServiceContributor"/>
<bean id="spatialTypeContributor" class="org.hibernate.spatial.contributor.SpatialTypeContributor"/>
<service ref="spatialTypeContributor" interface="org.hibernate.boot.model.TypeContributor"/>
<bean id="spatialFunctionContributor" class="org.hibernate.spatial.contributor.SpatialFunctionContributor"/>
<service ref="spatialFunctionContributor" interface="org.hibernate.boot.model.FunctionContributor"/>
</blueprint>

View File

@ -40,6 +40,7 @@ import static org.junit.Assert.fail;
*/
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
@SkipForDialect(value = HANASpatialDialect.class, comment = "The HANA dialect is tested via org.hibernate.spatial.dialect.hana.TestHANASpatialFunctions", jiraKey = "HHH-12426")
@Deprecated
public class TestGeolatteSpatialPredicates extends SpatialFunctionalTestCase {
private static final HSMessageLogger LOG = Logger.getMessageLogger(

View File

@ -36,6 +36,7 @@ import static org.junit.Assert.fail;
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
@SkipForDialect(value = HANASpatialDialect.class, comment = "The HANA dialect is tested via org.hibernate.spatial.dialect.hana.TestHANASpatialFunctions", jiraKey = "HHH-12426")
@Deprecated
public class TestJTSSpatialPredicates extends SpatialFunctionalTestCase {
private static final HSMessageLogger LOG = Logger.getMessageLogger(

View File

@ -36,7 +36,7 @@ import static java.lang.String.format;
/**
* @author Karel Maesen, Geovise BVBA
*/
@Skip(condition = SpatialDialectMatcher.class, message = "No Spatial Dialect")
@Deprecated
public class TestSpatialFunctions extends SpatialFunctionalTestCase {
private static final HSMessageLogger LOG = Logger.getMessageLogger(

View File

@ -19,6 +19,7 @@ import javax.persistence.Query;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect;
@ -34,7 +35,7 @@ import org.locationtech.jts.geom.Point;
import static org.junit.Assert.assertEquals;
@TestForIssue(jiraKey = "HHH-14523")
@RequiresDialect(PostgisPG95Dialect.class)
@RequiresDialect(PostgreSQLDialect.class)
public class DirtyCheckingTest extends BaseEntityManagerFunctionalTestCase {
private GeometryFactory gfact = new GeometryFactory();

View File

@ -15,7 +15,10 @@ import org.hibernate.testing.Skip;
/**
* @author Karel Maesen, Geovise BVBA
* creation-date: 1/13/12
*
* @deprecated Since we no longer require SpatialDialects
*/
@Deprecated
public class SpatialDialectMatcher implements Skip.Matcher {
@Override
public boolean isMatch() {

View File

@ -165,7 +165,7 @@ public abstract class SpatialFunctionalTestCase extends BaseCoreFunctionalTestCa
*/
public boolean isSupportedByDialect(SpatialFunction spatialFunction) {
Dialect dialect = getDialect();
throw new NotYetImplementedException();
return true;
}

View File

@ -6,17 +6,21 @@
# See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
#
# Default unit/integration test config.
hibernate.dialect @db.dialect@
hibernate.connection.driver_class @jdbc.driver@
hibernate.connection.url @jdbc.url@
hibernate.connection.username @jdbc.user@
hibernate.connection.password @jdbc.pass@
hibernate.show_sql=true
hibernate.max_fetch_depth=5
hibernate.dialect=@db.dialect@
hibernate.connection.driver_class=@jdbc.driver@
hibernate.connection.url=@jdbc.url@
hibernate.connection.username=@jdbc.user@
hibernate.connection.password=@jdbc.pass@
hibernate.connection.init_sql @connection.init_sql@
#hibernate.cache.region_prefix hibernate.test
#hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory
hibernate.connection.pool_size 5
hibernate.show_sql false
hibernate.format_sql true
hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory
#
## NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
#hibernate.jdbc.batch_versioned_data true