HHH-6144 - Introduce ServiceRegistryBuilder

This commit is contained in:
Steve Ebersole 2011-04-23 16:12:37 -05:00
parent 7d82752fb0
commit 85094bddbf
8 changed files with 148 additions and 60 deletions

View File

@ -190,24 +190,22 @@ public final class Environment implements AvailableSettings {
/**
* Issues warnings to the user when any obsolete or renamed property names are used.
*
* @param props The specified properties.
* @param configurationValues The specified properties.
*/
public static void verifyProperties(Properties props) {
Iterator iter = props.keySet().iterator();
Map propertiesToAdd = new HashMap();
while ( iter.hasNext() ) {
final Object propertyName = iter.next();
Object newPropertyName = OBSOLETE_PROPERTIES.get( propertyName );
if (newPropertyName != null) LOG.unsupportedProperty(propertyName, newPropertyName);
newPropertyName = RENAMED_PROPERTIES.get( propertyName );
if ( newPropertyName != null ) {
LOG.renamedProperty(propertyName, newPropertyName);
if ( ! props.containsKey( newPropertyName ) ) {
propertiesToAdd.put( newPropertyName, props.get( propertyName ) );
}
public static void verifyProperties(Map<?,?> configurationValues) {
final Map propertiesToAdd = new HashMap();
for ( Map.Entry entry : configurationValues.entrySet() ) {
final Object replacementKey = OBSOLETE_PROPERTIES.get( entry.getKey() );
if ( replacementKey != null ) {
LOG.unsupportedProperty( entry.getKey(), replacementKey );
}
final Object renamedKey = RENAMED_PROPERTIES.get( entry.getKey() );
if ( renamedKey != null ) {
LOG.renamedProperty( entry.getKey(), renamedKey );
propertiesToAdd.put( renamedKey, entry.getValue() );
}
}
props.putAll(propertiesToAdd);
configurationValues.putAll( propertiesToAdd );
}
static {

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.internal.util.config;
@ -298,10 +297,10 @@ public final class ConfigurationHelper {
/**
* Handles interpolation processing for all entries in a properties object.
*
* @param properties The properties object.
* @param configurationValues The configuration map.
*/
public static void resolvePlaceHolders(Properties properties) {
Iterator itr = properties.entrySet().iterator();
public static void resolvePlaceHolders(Map<?,?> configurationValues) {
Iterator itr = configurationValues.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
final Object value = entry.getValue();

View File

@ -50,13 +50,4 @@ public interface ServiceRegistry {
* @throws UnknownServiceException Indicates the service was not known.
*/
public <R extends Service> R getService(Class<R> serviceRole);
/**
* Register a service into the registry.
*
* @param serviceRole The service role.
* @param service The service to register
* @param <R> The service role type
*/
public <R extends Service> void registerService(Class<R> serviceRole, R service);
}

View File

@ -28,24 +28,38 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.service.internal.ProvidedService;
import org.hibernate.service.spi.BasicServiceInitiator;
/**
* Builder for basic service registry instances.
*
* @author Steve Ebersole
*/
public class ServiceRegistryBuilder {
private final Map configurationValues;
private final List<BasicServiceInitiator> initiators = standardInitiatorList();
private final List<ProvidedService> services = new ArrayList<ProvidedService>();
public static final String DEFAULT_CFG_RESOURCE_NAME = "hibernate.cfg.xml";
private final Map settings;
private final List<BasicServiceInitiator> initiators = standardInitiatorList();
private final List<ProvidedService> providedServices = new ArrayList<ProvidedService>();
/**
* Create a default builder
*/
public ServiceRegistryBuilder() {
this( new HashMap() );
this( Environment.getProperties() );
}
public ServiceRegistryBuilder(Map configurationValues) {
this.configurationValues = configurationValues;
/**
* Create a builder with the specified settings
*
* @param settings The initial set of settings to use.
*/
public ServiceRegistryBuilder(Map settings) {
this.settings = settings;
}
private static List<BasicServiceInitiator> standardInitiatorList() {
@ -54,18 +68,104 @@ public class ServiceRegistryBuilder {
return initiators;
}
/**
* Read setting information from the standard resource location
*
* @return this, for method chaining
*
* @see #DEFAULT_CFG_RESOURCE_NAME
*/
public ServiceRegistryBuilder configure() {
return configure( DEFAULT_CFG_RESOURCE_NAME );
}
/**
* Read setting information from the named resource location
*
* @param resourceName The named resource
*
* @return this, for method chaining
*/
public ServiceRegistryBuilder configure(String resourceName) {
// todo : parse and apply XML
// we run into a chicken-egg problem here, in that we need the service registry in order to know how to do this
// resource lookup (ClassLoaderService)
return this;
}
/**
* Apply a setting value
*
* @param settingName The name of the setting
* @param value The value to use.
*
* @return this, for method chaining
*/
@SuppressWarnings( {"unchecked", "UnusedDeclaration"})
public ServiceRegistryBuilder applySetting(String settingName, Object value) {
settings.put( settingName, value );
return this;
}
/**
* Apply a groups of setting values
*
* @param settings The incoming settings to apply
*
* @return this, for method chaining
*/
@SuppressWarnings( {"unchecked", "UnusedDeclaration"})
public ServiceRegistryBuilder applySettings(Map settings) {
this.settings.putAll( settings );
return this;
}
/**
* Adds a service initiator.
*
* @param initiator The initiator to be added
*
* @return this, for method chaining
*/
@SuppressWarnings( {"UnusedDeclaration"})
public ServiceRegistryBuilder addInitiator(BasicServiceInitiator initiator) {
initiators.add( initiator );
return this;
}
/**
* Adds a user-provided service
*
* @param serviceRole The role of the service being added
* @param service The service implementation
*
* @return this, for method chaining
*/
@SuppressWarnings( {"unchecked"})
public ServiceRegistryBuilder addService(final Class serviceRole, final Service service) {
services.add( new ProvidedService( serviceRole, service ) );
providedServices.add( new ProvidedService( serviceRole, service ) );
return this;
}
/**
* Build the service registry accounting for all settings and service initiators and services.
*
* @return The built service registry
*/
public BasicServiceRegistry buildServiceRegistry() {
return new BasicServiceRegistryImpl( initiators, services, configurationValues );
Map<?,?> settingsCopy = new HashMap();
settingsCopy.putAll( settings );
Environment.verifyProperties( settingsCopy );
ConfigurationHelper.resolvePlaceHolders( settingsCopy );
return new BasicServiceRegistryImpl( initiators, providedServices, settingsCopy );
}
/**
* Destroy a service registry. Applications should only destroy registries they have explicitly created.
*
* @param serviceRegistry The registry to be closed.
*/
public static void destroy(BasicServiceRegistry serviceRegistry) {
( (BasicServiceRegistryImpl) serviceRegistry ).destroy();
}
}

View File

@ -116,8 +116,7 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
return serviceBinding;
}
@Override
public <R extends Service> void registerService(Class<R> serviceRole, R service) {
protected <R extends Service> void registerService(Class<R> serviceRole, R service) {
ServiceBinding<R> serviceBinding = locateOrCreateServiceBinding( serviceRole, false );
R priorServiceInstance = serviceBinding.getTarget();
serviceBinding.setTarget( service );

View File

@ -24,11 +24,11 @@ import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
@ -42,14 +42,15 @@ public class PersisterClassProviderTest extends BaseUnitTestCase {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass( Gate.class );
ServiceRegistry serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
BasicServiceRegistry serviceRegistry = new ServiceRegistryBuilder( cfg.getProperties() ).buildServiceRegistry();
//no exception as the GoofyPersisterClassProvider is not set
SessionFactory sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();
ServiceRegistryBuilder.destroy( serviceRegistry );
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() );
serviceRegistry = new ServiceRegistryBuilder( cfg.getProperties() )
.addService( PersisterClassResolver.class, new GoofyPersisterClassProvider() )
.buildServiceRegistry();
cfg = new Configuration();
cfg.addAnnotatedClass( Gate.class );
try {
@ -70,8 +71,9 @@ public class PersisterClassProviderTest extends BaseUnitTestCase {
cfg = new Configuration();
cfg.addAnnotatedClass( Portal.class );
cfg.addAnnotatedClass( Window.class );
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( cfg.getProperties() );
serviceRegistry.registerService( PersisterClassResolver.class, new GoofyPersisterClassProvider() );
serviceRegistry = new ServiceRegistryBuilder( cfg.getProperties() )
.addService( PersisterClassResolver.class, new GoofyPersisterClassProvider() )
.buildServiceRegistry();
try {
sessionFactory = cfg.buildSessionFactory( serviceRegistry );
sessionFactory.close();

View File

@ -77,15 +77,20 @@ public class ServiceBootstrappingTest extends BaseUnitTestCase {
@Test
public void testBuildWithServiceOverride() {
Properties props = ConnectionProviderBuilder.getConnectionProviderProperties();
BasicServiceRegistryImpl serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder( props ).buildServiceRegistry();
BasicServiceRegistryImpl serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder( ConnectionProviderBuilder.getConnectionProviderProperties() )
.buildServiceRegistry();
JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
assertTrue( jdbcServices.getDialect() instanceof H2Dialect );
assertTrue( jdbcServices.getConnectionProvider().isUnwrappableAs( DriverManagerConnectionProviderImpl.class ) );
serviceRegistry.registerService( ConnectionProvider.class, new UserSuppliedConnectionProviderImpl() );
Properties props = ConnectionProviderBuilder.getConnectionProviderProperties();
props.setProperty( Environment.DIALECT, H2Dialect.class.getName() );
serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder( props )
.addService( ConnectionProvider.class, new UserSuppliedConnectionProviderImpl() )
.buildServiceRegistry();
jdbcServices = serviceRegistry.getService( JdbcServices.class );
assertTrue( jdbcServices.getDialect() instanceof H2Dialect );
assertTrue( jdbcServices.getConnectionProvider().isUnwrappableAs( UserSuppliedConnectionProviderImpl.class ) );

View File

@ -23,14 +23,12 @@
*/
package org.hibernate.testing;
import java.util.Map;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
import java.util.Map;
import java.util.Properties;
/**
* @author Steve Ebersole
*/
@ -40,11 +38,7 @@ public class ServiceRegistryBuilder {
}
public static BasicServiceRegistryImpl buildServiceRegistry(Map serviceRegistryConfig) {
Properties properties = new Properties();
properties.putAll( serviceRegistryConfig );
Environment.verifyProperties( properties );
ConfigurationHelper.resolvePlaceHolders( properties );
return (BasicServiceRegistryImpl) new org.hibernate.service.ServiceRegistryBuilder( properties ).buildServiceRegistry();
return (BasicServiceRegistryImpl) new org.hibernate.service.ServiceRegistryBuilder( serviceRegistryConfig ).buildServiceRegistry();
}
public static void destroy(ServiceRegistry serviceRegistry) {