HHH-5943 - Make ServiceRegistry mutable
This commit is contained in:
parent
02cf95da33
commit
11d32ba69c
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.connections.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
|
@ -31,6 +32,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.util.ReflectHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
import com.mchange.v2.c3p0.DataSources;
|
||||
|
@ -87,10 +89,23 @@ public class C3P0ConnectionProvider implements ConnectionProvider {
|
|||
conn.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param props
|
||||
* @throws HibernateException
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) ds;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void configure(Properties props) throws HibernateException {
|
||||
String jdbcDriverClass = props.getProperty( Environment.DRIVER );
|
||||
String jdbcUrl = props.getProperty( Environment.URL );
|
||||
|
|
|
@ -22,19 +22,10 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.cfg.internal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Map;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
|
||||
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
|
||||
import org.hibernate.service.internal.ServiceRegistryImpl;
|
||||
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectResolverInitiator;
|
||||
import org.hibernate.service.jmx.internal.JmxServiceInitiator;
|
||||
import org.hibernate.service.jndi.internal.JndiServiceInitiator;
|
||||
import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
|
||||
import org.hibernate.service.spi.ServiceInitiator;
|
||||
import org.hibernate.service.spi.StandardServiceInitiators;
|
||||
|
||||
/**
|
||||
* The standard bootstrap process for Hibernate services
|
||||
|
@ -42,25 +33,7 @@ import org.hibernate.service.spi.ServiceInitiator;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServicesRegistryBootstrap {
|
||||
private List<ServiceInitiator> serviceInitiators = new ArrayList<ServiceInitiator>();
|
||||
|
||||
public ServicesRegistryBootstrap() {
|
||||
serviceInitiators.add( ClassLoaderServiceInitiator.INSTANCE );
|
||||
serviceInitiators.add( JndiServiceInitiator.INSTANCE );
|
||||
serviceInitiators.add( JmxServiceInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
|
||||
serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( JtaPlatformInitiator.INSTANCE );
|
||||
//serviceInitiators.add( TransactionFactoryInitiator.INSTANCE );
|
||||
}
|
||||
|
||||
public ServiceRegistryImpl initiateServicesRegistry(Map configurationValues) {
|
||||
final ServiceRegistryImpl servicesRegistry = new ServiceRegistryImpl( serviceInitiators );
|
||||
servicesRegistry.initialize( configurationValues );
|
||||
return servicesRegistry;
|
||||
return new ServiceRegistryImpl( StandardServiceInitiators.LIST, configurationValues );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -44,15 +45,15 @@ import org.jboss.logging.Logger;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServicesInitializer {
|
||||
public class ServiceInitializer {
|
||||
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ServicesInitializer.class.getName());
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ServiceInitializer.class.getName());
|
||||
|
||||
private final ServiceRegistryImpl servicesRegistry;
|
||||
private final Map<Class,ServiceInitiator> serviceInitiatorMap;
|
||||
private final Map configurationValues;
|
||||
|
||||
public ServicesInitializer(
|
||||
public ServiceInitializer(
|
||||
ServiceRegistryImpl servicesRegistry,
|
||||
List<ServiceInitiator> serviceInitiators,
|
||||
Map configurationValues) {
|
||||
|
@ -64,11 +65,12 @@ public class ServicesInitializer {
|
|||
/**
|
||||
* We convert the incoming list of initiators to a map for 2 reasons:<ul>
|
||||
* <li>to make it easier to look up the initiator we need for a given service role</li>
|
||||
* <li>to make sure there is only one initator for a given service role (last wins)</li>
|
||||
* <li>to make sure there is only one initiator for a given service role (last wins)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param serviceInitiators
|
||||
* @return
|
||||
* @param serviceInitiators The list of individual initiators
|
||||
*
|
||||
* @return The map of initiators keyed by the service rle they initiate.
|
||||
*/
|
||||
private static Map<Class, ServiceInitiator> toMap(List<ServiceInitiator> serviceInitiators) {
|
||||
final Map<Class, ServiceInitiator> result = new HashMap<Class, ServiceInitiator>();
|
||||
|
@ -78,6 +80,13 @@ public class ServicesInitializer {
|
|||
return result;
|
||||
}
|
||||
|
||||
void registerServiceInitiator(ServiceInitiator serviceInitiator) {
|
||||
final Object previous = serviceInitiatorMap.put( serviceInitiator.getServiceInitiated(), serviceInitiator );
|
||||
final boolean overwritten = previous != null;
|
||||
if (overwritten) LOG.debugf("Over-wrote existing service initiator [role=%s]",
|
||||
serviceInitiator.getServiceInitiated().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function of this delegate. Used to initialize the service of a given role.
|
||||
*
|
||||
|
@ -158,7 +167,9 @@ public class ServicesInitializer {
|
|||
dependentServiceRole = injectionMethod.getParameterTypes()[0];
|
||||
}
|
||||
|
||||
final Service dependantService = servicesRegistry.internalGetService( dependentServiceRole );
|
||||
// todo : because of the use of proxies, this is no longer returning null here...
|
||||
|
||||
final Service dependantService = servicesRegistry.getService( dependentServiceRole );
|
||||
if ( dependantService == null ) {
|
||||
if ( injectService.required() ) {
|
||||
throw new ServiceDependencyException(
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal;
|
||||
|
||||
import org.hibernate.service.spi.Service;
|
||||
|
||||
/**
|
||||
* Marker interface for a service proxy which allows mixed-in ability to unproxy.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ServiceProxy extends Service {
|
||||
/**
|
||||
* Get the target service instance represented by this proxy.
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public <T extends Service> T getTargetInstance();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Indicates a problem generating a service proxy
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServiceProxyGenerationException extends HibernateException {
|
||||
public ServiceProxyGenerationException(String string, Throwable root) {
|
||||
super( string, root );
|
||||
}
|
||||
|
||||
public ServiceProxyGenerationException(Throwable root) {
|
||||
super( root );
|
||||
}
|
||||
}
|
|
@ -22,44 +22,53 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.HibernateLogger;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.internal.proxy.javassist.ServiceProxyFactoryFactoryImpl;
|
||||
import org.hibernate.service.spi.Service;
|
||||
import org.hibernate.service.spi.ServiceInitiator;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
import org.hibernate.service.spi.StandardServiceInitiators;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownServiceException;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyFactory;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyTargetSource;
|
||||
import org.hibernate.util.CollectionHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Basic Hibernate implementation of the service registry.
|
||||
* Standard Hibernate implementation of the service registry.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServiceRegistryImpl implements ServiceRegistry {
|
||||
public class ServiceRegistryImpl implements ServiceProxyTargetSource {
|
||||
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ServiceRegistryImpl.class.getName());
|
||||
|
||||
private final List<ServiceInitiator> serviceInitiators;
|
||||
private ServicesInitializer initializer;
|
||||
private final ServiceInitializer initializer;
|
||||
// for now just hardcode the javassist factory
|
||||
private ServiceProxyFactory serviceProxyFactory = new ServiceProxyFactoryFactoryImpl().makeServiceProxyFactory( this );
|
||||
|
||||
private HashMap<Class,Service> serviceMap = new HashMap<Class, Service>();
|
||||
private ConcurrentHashMap<Class,ServiceBinding> serviceBindingMap;
|
||||
// IMPL NOTE : the list used for ordered destruction. Cannot used ordered map above because we need to
|
||||
// iterate it in reverse order which is only available through ListIterator
|
||||
private List<Service> serviceList = new ArrayList<Service>();
|
||||
|
||||
public ServiceRegistryImpl(List<ServiceInitiator> serviceInitiators) {
|
||||
this.serviceInitiators = Collections.unmodifiableList( serviceInitiators );
|
||||
public ServiceRegistryImpl(Map configurationValues) {
|
||||
this( StandardServiceInitiators.LIST, configurationValues );
|
||||
}
|
||||
|
||||
public void initialize(Map configurationValues) {
|
||||
this.initializer = new ServicesInitializer( this, serviceInitiators, ConfigurationHelper.clone( configurationValues ) );
|
||||
public ServiceRegistryImpl(List<ServiceInitiator> serviceInitiators, Map configurationValues) {
|
||||
this.initializer = new ServiceInitializer( this, serviceInitiators, ConfigurationHelper.clone( configurationValues ) );
|
||||
final int anticipatedSize = serviceInitiators.size() + 5; // allow some growth
|
||||
serviceBindingMap = CollectionHelper.concurrentMap( anticipatedSize );
|
||||
serviceList = CollectionHelper.arrayList( anticipatedSize );
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
@ -77,35 +86,84 @@ public class ServiceRegistryImpl implements ServiceRegistry {
|
|||
}
|
||||
serviceList.clear();
|
||||
serviceList = null;
|
||||
serviceMap.clear();
|
||||
serviceMap = null;
|
||||
serviceBindingMap.clear();
|
||||
serviceBindingMap = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <T extends Service> T getService(Class<T> serviceRole) {
|
||||
T service = internalGetService( serviceRole );
|
||||
return locateOrCreateServiceBinding( serviceRole ).getProxy();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private <T extends Service> ServiceBinding<T> locateOrCreateServiceBinding(Class<T> serviceRole) {
|
||||
ServiceBinding<T> serviceBinding = serviceBindingMap.get( serviceRole );
|
||||
if ( serviceBinding == null ) {
|
||||
T proxy = serviceProxyFactory.makeProxy( serviceRole );
|
||||
serviceBinding = new ServiceBinding<T>( proxy );
|
||||
serviceBindingMap.put( serviceRole, serviceBinding );
|
||||
}
|
||||
return serviceBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T extends Service> T getServiceInternal(Class<T> serviceRole) {
|
||||
ServiceBinding<T> serviceBinding = serviceBindingMap.get( serviceRole );
|
||||
if ( serviceBinding == null ) {
|
||||
throw new HibernateException( "Only proxies should invoke #getServiceInternal" );
|
||||
}
|
||||
T service = serviceBinding.getTarget();
|
||||
if ( service == null ) {
|
||||
service = initializer.initializeService( serviceRole );
|
||||
serviceBinding.setTarget( service );
|
||||
}
|
||||
if ( service == null ) {
|
||||
throw new UnknownServiceException( serviceRole );
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private <T extends Service> T locateService(Class<T> serviceRole) {
|
||||
return (T) serviceMap.get( serviceRole );
|
||||
}
|
||||
|
||||
<T extends Service> T internalGetService(Class<T> serviceRole) {
|
||||
T service = locateService( serviceRole );
|
||||
if ( service == null ) {
|
||||
service = initializer.initializeService( serviceRole );
|
||||
@Override
|
||||
public <T extends Service> void registerService(Class<T> serviceRole, T service) {
|
||||
ServiceBinding<T> serviceBinding = locateOrCreateServiceBinding( serviceRole );
|
||||
T priorServiceInstance = serviceBinding.getTarget();
|
||||
serviceBinding.setTarget( service );
|
||||
if ( priorServiceInstance != null ) {
|
||||
serviceList.remove( priorServiceInstance );
|
||||
}
|
||||
return service;
|
||||
serviceList.add( service );
|
||||
}
|
||||
|
||||
<T extends Service> void registerService(Class<T> serviceRole, T service) {
|
||||
serviceList.add( service );
|
||||
serviceMap.put( serviceRole, service );
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public void registerServiceInitiator(ServiceInitiator initiator) {
|
||||
ServiceBinding serviceBinding = serviceBindingMap.get( initiator.getServiceInitiated() );
|
||||
if ( serviceBinding != null ) {
|
||||
serviceBinding.setTarget( null );
|
||||
}
|
||||
initializer.registerServiceInitiator( initiator );
|
||||
}
|
||||
|
||||
private static final class ServiceBinding<T> {
|
||||
private final T proxy;
|
||||
private T target;
|
||||
|
||||
private ServiceBinding(T proxy) {
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
public T getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public T getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(T target) {
|
||||
this.target = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal.proxy.javassist;
|
||||
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyFactory;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyFactoryFactory;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyTargetSource;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServiceProxyFactoryFactoryImpl implements ServiceProxyFactoryFactory {
|
||||
@Override
|
||||
public ServiceProxyFactory makeServiceProxyFactory(ServiceProxyTargetSource registry) {
|
||||
return new ServiceProxyFactoryImpl( registry );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.internal.proxy.javassist;
|
||||
|
||||
import javassist.util.proxy.MethodFilter;
|
||||
import javassist.util.proxy.MethodHandler;
|
||||
import javassist.util.proxy.ProxyFactory;
|
||||
import javassist.util.proxy.ProxyObject;
|
||||
|
||||
import org.hibernate.service.internal.ServiceProxy;
|
||||
import org.hibernate.service.internal.ServiceProxyGenerationException;
|
||||
import org.hibernate.service.spi.Service;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyFactory;
|
||||
import org.hibernate.service.spi.proxy.ServiceProxyTargetSource;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServiceProxyFactoryImpl implements ServiceProxyFactory {
|
||||
private final ServiceProxyTargetSource serviceRegistry;
|
||||
|
||||
public ServiceProxyFactoryImpl(ServiceProxyTargetSource serviceRegistry) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
|
||||
public boolean isHandled(Method m) {
|
||||
// skip finalize methods
|
||||
return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T extends Service> T makeProxy(Class<T> serviceRole) {
|
||||
try {
|
||||
ProxyFactory factory = new ProxyFactory();
|
||||
factory.setFilter( FINALIZE_FILTER );
|
||||
|
||||
Class[] interfaces = new Class[2];
|
||||
interfaces[0] = serviceRole;
|
||||
interfaces[1] = ServiceProxy.class;
|
||||
factory.setInterfaces( interfaces );
|
||||
|
||||
Class proxyClass = factory.createClass();
|
||||
ProxyObject proxyObject = (ProxyObject) proxyClass.newInstance();
|
||||
proxyObject.setHandler( new ServiceProxyMethodInterceptor<T>( (T)proxyObject, serviceRole, serviceRegistry ) );
|
||||
return (T) proxyObject;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ServiceProxyGenerationException( "Unable to make service proxy", e );
|
||||
}
|
||||
}
|
||||
|
||||
private static class ServiceProxyMethodInterceptor<T extends Service> implements MethodHandler {
|
||||
private final T proxy;
|
||||
private final Class<T> serviceRole;
|
||||
private final ServiceProxyTargetSource serviceRegistry;
|
||||
|
||||
private ServiceProxyMethodInterceptor(T proxy, Class<T> serviceRole, ServiceProxyTargetSource serviceRegistry) {
|
||||
this.proxy = proxy;
|
||||
this.serviceRole = serviceRole;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"UnnecessaryBoxing"} )
|
||||
public Object invoke(
|
||||
Object object,
|
||||
Method method,
|
||||
Method method1,
|
||||
Object[] args) throws Exception {
|
||||
String name = method.getName();
|
||||
if ( "toString".equals( name ) ) {
|
||||
return serviceRole.getName() + "_$$_Proxy@" + System.identityHashCode( object );
|
||||
}
|
||||
else if ( "equals".equals( name ) ) {
|
||||
return proxy == object ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
else if ( "hashCode".equals( name ) ) {
|
||||
return Integer.valueOf( System.identityHashCode( object ) );
|
||||
}
|
||||
else if ( "getTargetInstance".equals( name ) && ServiceProxy.class.equals( method.getDeclaringClass() ) ) {
|
||||
return serviceRegistry.getServiceInternal( serviceRole );
|
||||
}
|
||||
else {
|
||||
try {
|
||||
T target = serviceRegistry.getServiceInternal( serviceRole );
|
||||
return method.invoke( target, args );
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw (Exception) e.getTargetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,7 @@ import org.hibernate.service.jndi.spi.JndiService;
|
|||
import org.hibernate.service.spi.Configurable;
|
||||
import org.hibernate.service.spi.InjectService;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
|
||||
/**
|
||||
* A {@link ConnectionProvider} that manages connections from an underlying {@link DataSource}.
|
||||
|
@ -69,6 +70,28 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
|
|||
this.jndiService = jndiService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProvider.class.equals( unwrapType ) ||
|
||||
DatasourceConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ||
|
||||
DataSource.class.isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProvider.class.equals( unwrapType ) ||
|
||||
DatasourceConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) getDataSource();
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
|
|||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.Configurable;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.util.ReflectHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -61,6 +62,24 @@ public class DriverManagerConnectionProviderImpl implements ConnectionProvider,
|
|||
private final ArrayList<Connection> pool = new ArrayList<Connection>();
|
||||
private int checkedOut = 0;
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProvider.class.equals( unwrapType ) ||
|
||||
DriverManagerConnectionProviderImpl.class.isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProvider.class.equals( unwrapType ) ||
|
||||
DriverManagerConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
public void configure(Map configurationValues) {
|
||||
LOG.usingHibernateBuiltInConnectionPool();
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.service.jdbc.connections.internal;
|
|||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link ConnectionProvider} interface that simply throws an exception when a connection
|
||||
|
@ -35,6 +36,24 @@ import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class UserSuppliedConnectionProviderImpl implements ConnectionProvider {
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProvider.class.equals( unwrapType ) ||
|
||||
UserSuppliedConnectionProviderImpl.class.isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProvider.class.equals( unwrapType ) ||
|
||||
UserSuppliedConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.sql.Connection;
|
|||
import java.sql.SQLException;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.service.spi.Service;
|
||||
import org.hibernate.service.spi.Wrapped;
|
||||
|
||||
/**
|
||||
* A contract for obtaining JDBC connections.
|
||||
|
@ -37,7 +38,7 @@ import org.hibernate.service.spi.Service;
|
|||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ConnectionProvider extends Service {
|
||||
public interface ConnectionProvider extends Service, Wrapped {
|
||||
/**
|
||||
* Obtains a connection for Hibernate use according to the underlying strategy of this provider.
|
||||
*
|
||||
|
@ -62,7 +63,7 @@ public interface ConnectionProvider extends Service {
|
|||
* Does this connection provider support aggressive release of JDBC
|
||||
* connections and re-acquistion of those connections (if need be) later?
|
||||
* <p/>
|
||||
* This is used in conjunction with {@link org.hibernate.cfg.Environment.RELEASE_CONNECTIONS}
|
||||
* This is used in conjunction with {@link org.hibernate.cfg.Environment#RELEASE_CONNECTIONS}
|
||||
* to aggressively release JDBC connections. However, the configured ConnectionProvider
|
||||
* must support re-acquisition of the same underlying connection for that semantic to work.
|
||||
* <p/>
|
||||
|
|
|
@ -31,14 +31,30 @@ package org.hibernate.service.spi;
|
|||
*/
|
||||
public interface ServiceRegistry {
|
||||
/**
|
||||
* Retrieve a service by role.
|
||||
* Retrieve a service by role. If service is not found, but a {@link ServiceInitiator} is registered for
|
||||
* this service role, the service will be initialized and returned.
|
||||
*
|
||||
* @param type The service role
|
||||
* @param serviceRole The service role
|
||||
* @param <T> The type of the service
|
||||
*
|
||||
* @return The requested service.
|
||||
*
|
||||
* @throws UnknownServiceException Indicates the service was not known.
|
||||
*/
|
||||
public <T extends Service> T getService(Class<T> type);
|
||||
public <T extends Service> T getService(Class<T> serviceRole);
|
||||
|
||||
/**
|
||||
* Register a service into the registry.
|
||||
*
|
||||
* @param serviceRole The service role.
|
||||
* @param service The service to register
|
||||
*/
|
||||
public <T extends Service> void registerService(Class<T> serviceRole, T service);
|
||||
|
||||
/**
|
||||
* Register a service initiator.
|
||||
*
|
||||
* @param initiator The initiator of a service
|
||||
*/
|
||||
public void registerServiceInitiator(ServiceInitiator initiator);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi;
|
||||
|
||||
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
|
||||
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
|
||||
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectResolverInitiator;
|
||||
import org.hibernate.service.jmx.internal.JmxServiceInitiator;
|
||||
import org.hibernate.service.jndi.internal.JndiServiceInitiator;
|
||||
import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardServiceInitiators {
|
||||
public static List<ServiceInitiator> LIST = buildStandardServiceInitiatorList();
|
||||
|
||||
private static List<ServiceInitiator> buildStandardServiceInitiatorList() {
|
||||
final List<ServiceInitiator> serviceInitiators = new ArrayList<ServiceInitiator>();
|
||||
|
||||
serviceInitiators.add( ClassLoaderServiceInitiator.INSTANCE );
|
||||
serviceInitiators.add( JndiServiceInitiator.INSTANCE );
|
||||
serviceInitiators.add( JmxServiceInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
|
||||
serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( JtaPlatformInitiator.INSTANCE );
|
||||
//serviceInitiators.add( TransactionFactoryInitiator.INSTANCE );
|
||||
|
||||
return serviceInitiators;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class UnknownUnwrapTypeException extends HibernateException {
|
||||
public UnknownUnwrapTypeException(Class unwrapType) {
|
||||
super( "Cannot unwrap to requested type [" + unwrapType.getName() + "]" );
|
||||
}
|
||||
|
||||
public UnknownUnwrapTypeException(Class unwrapType, Throwable root) {
|
||||
this( unwrapType );
|
||||
super.initCause( root );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Wrapped {
|
||||
/**
|
||||
* Can this wrapped service be unwrapped as the indicated type?
|
||||
*
|
||||
* @param unwrapType The type to check.
|
||||
*
|
||||
* @return True/false.
|
||||
*/
|
||||
public boolean isUnwrappableAs(Class unwrapType);
|
||||
|
||||
/**
|
||||
* Unproxy the service proxy
|
||||
*
|
||||
* @param unwrapType The java type as which to unwrap this instance.
|
||||
*
|
||||
* @return The unwrapped reference
|
||||
*/
|
||||
public <T> T unwrap(Class<T> unwrapType);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi.proxy;
|
||||
|
||||
import org.hibernate.service.spi.Service;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ServiceProxyFactory {
|
||||
public <T extends Service> T makeProxy(Class<T> serviceRole);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi.proxy;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ServiceProxyFactoryFactory {
|
||||
public ServiceProxyFactory makeServiceProxyFactory(ServiceProxyTargetSource registry);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 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 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
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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 distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.spi.proxy;
|
||||
|
||||
import org.hibernate.service.spi.Service;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* Additional contract for service proxies. This allows the proxies access to their actual service instances.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ServiceProxyTargetSource extends ServiceRegistry {
|
||||
/**
|
||||
* Retrieve a service by role. Unlike {@link org.hibernate.service.spi.ServiceRegistry#getService}, this version
|
||||
* will never return a proxy.
|
||||
*
|
||||
* @param serviceRole The service role
|
||||
* @param <T> The type of the service
|
||||
*
|
||||
* @return The requested service.
|
||||
*
|
||||
* @throws org.hibernate.service.spi.UnknownServiceException Indicates the service was not known.
|
||||
*/
|
||||
public <T extends Service> T getServiceInternal(Class<T> serviceRole);
|
||||
}
|
|
@ -29,6 +29,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Various help for handling collections.
|
||||
|
@ -92,4 +93,37 @@ public final class CollectionHelper {
|
|||
int actual = ( (int) (numberOfElements / LOAD_FACTOR) ) + 1;
|
||||
return Math.max( actual, MINIMUM_INITIAL_CAPACITY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a properly sized {@link ConcurrentHashMap} based on the given expected number of elements.
|
||||
*
|
||||
* @param expectedNumberOfElements The expected number of elements for the created map
|
||||
* @param <K> The map key type
|
||||
* @param <V> The map value type
|
||||
*
|
||||
* @return The created map.
|
||||
*/
|
||||
public static <K,V> ConcurrentHashMap<K,V> concurrentMap(int expectedNumberOfElements) {
|
||||
return concurrentMap( expectedNumberOfElements, LOAD_FACTOR );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a properly sized {@link ConcurrentHashMap} based on the given expected number of elements and an
|
||||
* explicit load factor
|
||||
*
|
||||
* @param expectedNumberOfElements The expected number of elements for the created map
|
||||
* @param loadFactor The collection load factor
|
||||
* @param <K> The map key type
|
||||
* @param <V> The map value type
|
||||
*
|
||||
* @return The created map.
|
||||
*/
|
||||
public static <K,V> ConcurrentHashMap<K,V> concurrentMap(int expectedNumberOfElements, float loadFactor) {
|
||||
final int size = expectedNumberOfElements + 1 + (int) ( expectedNumberOfElements * loadFactor );
|
||||
return new ConcurrentHashMap<K, V>( size, loadFactor );
|
||||
}
|
||||
|
||||
public static <T> List<T> arrayList(int anticipatedSize) {
|
||||
return new ArrayList<T>( anticipatedSize );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,20 +22,13 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.cfg.internal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Properties;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.engine.jdbc.internal.JdbcServicesInitiator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.service.classloading.internal.ClassLoaderServiceInitiator;
|
||||
import org.hibernate.service.internal.ServiceRegistryImpl;
|
||||
import org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator;
|
||||
import org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectResolverInitiator;
|
||||
import org.hibernate.service.spi.ServiceInitiator;
|
||||
import org.hibernate.test.common.ConnectionProviderBuilder;
|
||||
import org.hibernate.testing.junit.UnitTestCase;
|
||||
|
||||
|
@ -45,47 +38,32 @@ import org.hibernate.testing.junit.UnitTestCase;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ServiceBootstrappingTest extends UnitTestCase {
|
||||
private ServiceRegistryImpl servicesRegistry;
|
||||
|
||||
public ServiceBootstrappingTest(String string) {
|
||||
super( string );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
List<ServiceInitiator> serviceInitiators = new ArrayList<ServiceInitiator>();
|
||||
serviceInitiators.add( ClassLoaderServiceInitiator.INSTANCE );
|
||||
serviceInitiators.add( ConnectionProviderInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
|
||||
serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
|
||||
|
||||
servicesRegistry = new ServiceRegistryImpl( serviceInitiators );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() {
|
||||
servicesRegistry.destroy();
|
||||
}
|
||||
|
||||
public void testBasicBuild() {
|
||||
servicesRegistry.initialize( ConnectionProviderBuilder.getConnectionProviderProperties() );
|
||||
JdbcServices jdbcServices = servicesRegistry.getService( JdbcServices.class );
|
||||
ServiceRegistryImpl serviceRegistry = new ServiceRegistryImpl( ConnectionProviderBuilder.getConnectionProviderProperties() );
|
||||
JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
|
||||
|
||||
assertTrue( jdbcServices.getDialect() instanceof H2Dialect );
|
||||
assertTrue( jdbcServices.getConnectionProvider() instanceof DriverManagerConnectionProviderImpl );
|
||||
assertTrue( jdbcServices.getConnectionProvider().isUnwrappableAs( DriverManagerConnectionProviderImpl.class ) );
|
||||
assertFalse( jdbcServices.getSqlStatementLogger().isLogToStdout() );
|
||||
|
||||
serviceRegistry.destroy();
|
||||
}
|
||||
|
||||
public void testBuildWithLogging() {
|
||||
Properties props = ConnectionProviderBuilder.getConnectionProviderProperties();
|
||||
props.put( Environment.SHOW_SQL, "true" );
|
||||
|
||||
servicesRegistry.initialize( props );
|
||||
JdbcServices jdbcServices = servicesRegistry.getService( JdbcServices.class );
|
||||
ServiceRegistryImpl serviceRegistry = new ServiceRegistryImpl( props );
|
||||
JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
|
||||
|
||||
assertTrue( jdbcServices.getDialect() instanceof H2Dialect );
|
||||
assertTrue( jdbcServices.getConnectionProvider() instanceof DriverManagerConnectionProviderImpl );
|
||||
assertTrue( jdbcServices.getConnectionProvider().isUnwrappableAs( DriverManagerConnectionProviderImpl.class ) );
|
||||
assertTrue( jdbcServices.getSqlStatementLogger().isLogToStdout() );
|
||||
|
||||
serviceRegistry.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Properties;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.test.common.ConnectionProviderBuilder;
|
||||
|
||||
/**
|
||||
|
@ -49,6 +50,28 @@ public class ConnectionProviderImpl implements ConnectionProvider {
|
|||
public void configure(Properties props) throws HibernateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ||
|
||||
ConnectionProvider.class.isAssignableFrom( unwrapType ) ||
|
||||
getActualConnectionProvider().getClass().isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else if ( ConnectionProvider.class.isAssignableFrom( unwrapType ) ||
|
||||
getActualConnectionProvider().getClass().isAssignableFrom( unwrapType ) ) {
|
||||
return (T) getActualConnectionProvider();
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
SimpleJtaTransactionImpl currentTransaction = SimpleJtaTransactionManagerImpl.getInstance().getCurrentTransaction();
|
||||
if ( currentTransaction == null ) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.sql.SQLException;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.test.common.ConnectionProviderBuilder;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,26 @@ public class DualNodeConnectionProviderImpl implements ConnectionProvider {
|
|||
private String nodeId;
|
||||
private boolean isTransactional;
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return DualNodeConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ||
|
||||
ConnectionProvider.class.isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( DualNodeConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else if ( ConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) actualConnectionProvider;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
public static ConnectionProvider getActualConnectionProvider() {
|
||||
return actualConnectionProvider;
|
||||
}
|
||||
|
|
|
@ -26,54 +26,78 @@ import java.util.Properties;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.test.common.ConnectionProviderBuilder;
|
||||
|
||||
/**
|
||||
* XaConnectionProvider.
|
||||
*
|
||||
*
|
||||
* @author Galder Zamarreño
|
||||
* @since 3.5
|
||||
*/
|
||||
public class XaConnectionProvider implements ConnectionProvider {
|
||||
private static ConnectionProvider actualConnectionProvider = ConnectionProviderBuilder.buildConnectionProvider();
|
||||
private boolean isTransactional;
|
||||
private static ConnectionProvider actualConnectionProvider = ConnectionProviderBuilder.buildConnectionProvider();
|
||||
private boolean isTransactional;
|
||||
|
||||
public static ConnectionProvider getActualConnectionProvider() {
|
||||
return actualConnectionProvider;
|
||||
}
|
||||
public static ConnectionProvider getActualConnectionProvider() {
|
||||
return actualConnectionProvider;
|
||||
}
|
||||
|
||||
public void configure(Properties props) throws HibernateException {
|
||||
}
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return XaConnectionProvider.class.isAssignableFrom( unwrapType ) ||
|
||||
ConnectionProvider.class.equals( unwrapType ) ||
|
||||
actualConnectionProvider.getClass().isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
XaTransactionImpl currentTransaction = XaTransactionManagerImpl.getInstance().getCurrentTransaction();
|
||||
if (currentTransaction == null) {
|
||||
isTransactional = false;
|
||||
return actualConnectionProvider.getConnection();
|
||||
} else {
|
||||
isTransactional = true;
|
||||
Connection connection = currentTransaction.getEnlistedConnection();
|
||||
if (connection == null) {
|
||||
connection = actualConnectionProvider.getConnection();
|
||||
currentTransaction.enlistConnection(connection);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( XaConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else if ( ConnectionProvider.class.isAssignableFrom( unwrapType ) ||
|
||||
actualConnectionProvider.getClass().isAssignableFrom( unwrapType ) ) {
|
||||
return (T) getActualConnectionProvider();
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
public void closeConnection(Connection conn) throws SQLException {
|
||||
if (!isTransactional) {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
public void configure(Properties props) throws HibernateException {
|
||||
}
|
||||
|
||||
public void close() throws HibernateException {
|
||||
if ( actualConnectionProvider instanceof Stoppable ) {
|
||||
( ( Stoppable ) actualConnectionProvider ).stop();
|
||||
}
|
||||
}
|
||||
public Connection getConnection() throws SQLException {
|
||||
XaTransactionImpl currentTransaction = XaTransactionManagerImpl.getInstance().getCurrentTransaction();
|
||||
if ( currentTransaction == null ) {
|
||||
isTransactional = false;
|
||||
return actualConnectionProvider.getConnection();
|
||||
}
|
||||
else {
|
||||
isTransactional = true;
|
||||
Connection connection = currentTransaction.getEnlistedConnection();
|
||||
if ( connection == null ) {
|
||||
connection = actualConnectionProvider.getConnection();
|
||||
currentTransaction.enlistConnection( connection );
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return true;
|
||||
}
|
||||
public void closeConnection(Connection conn) throws SQLException {
|
||||
if ( !isTransactional ) {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws HibernateException {
|
||||
if ( actualConnectionProvider instanceof Stoppable ) {
|
||||
((Stoppable) actualConnectionProvider).stop();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.UnknownUnwrapTypeException;
|
||||
import org.hibernate.util.ConfigHelper;
|
||||
import org.hibernate.util.StringHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -79,6 +80,24 @@ public class ProxoolConnectionProvider implements ConnectionProvider {
|
|||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProvider.class.equals( unwrapType ) ||
|
||||
ProxoolConnectionProvider.class.isAssignableFrom( unwrapType );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if ( ConnectionProvider.class.equals( unwrapType ) ||
|
||||
ProxoolConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
|
||||
return (T) this;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException( unwrapType );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of a used connection.
|
||||
* @param conn a JDBC connection
|
||||
|
|
Loading…
Reference in New Issue