HHH-7552 - New StrategySelectorService : initial auto-detection
This commit is contained in:
parent
98ad44e75d
commit
ab64f5c3be
|
@ -26,6 +26,8 @@ package org.hibernate.boot.registry;
|
|||
import java.util.LinkedHashSet;
|
||||
|
||||
import org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl;
|
||||
import org.hibernate.boot.registry.selector.Availability;
|
||||
import org.hibernate.boot.registry.selector.AvailabilityAnnouncer;
|
||||
import org.hibernate.integrator.internal.IntegratorServiceImpl;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
|
||||
|
@ -120,7 +122,24 @@ public class BootstrapServiceRegistryBuilder {
|
|||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public <T> BootstrapServiceRegistryBuilder withStrategySelector(Class<T> strategy, String name, Class<? extends T> implementation) {
|
||||
this.strategySelectorBuilder.addCustomRegistration( strategy, name, implementation );
|
||||
this.strategySelectorBuilder.addExplicitAvailability( strategy, implementation, name );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies one or more strategy selectors announced as available by the passed announcer.
|
||||
*
|
||||
* @param availabilityAnnouncer An announcer for one or more available selectors
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @see org.hibernate.boot.registry.selector.spi.StrategySelector#registerStrategyImplementor(Class, String, Class)
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public <T> BootstrapServiceRegistryBuilder withStrategySelectors(AvailabilityAnnouncer availabilityAnnouncer) {
|
||||
for ( Availability availability : availabilityAnnouncer.getAvailabilities() ) {
|
||||
this.strategySelectorBuilder.addExplicitAvailability( availability );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.boot.registry.selector;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Availability {
|
||||
public Class getStrategyRole();
|
||||
public Iterable<String> getSelectorNames();
|
||||
public Class getStrategyImplementation();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.boot.registry.selector;
|
||||
|
||||
/**
|
||||
* Responsible for announcing the availability of strategy selector(s). Can be registered directly with the
|
||||
* {@link org.hibernate.boot.registry.BootstrapServiceRegistry} or located via discovery
|
||||
*
|
||||
* todo : better name?
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AvailabilityAnnouncer {
|
||||
public Iterable<Availability> getAvailabilities();
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.boot.registry.selector;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SimpleAvailabilityImpl implements Availability {
|
||||
private final Class strategyRole;
|
||||
private final Class strategyImplementation;
|
||||
private final Iterable<String> selectorNames;
|
||||
|
||||
public SimpleAvailabilityImpl(
|
||||
Class strategyRole,
|
||||
Class strategyImplementation,
|
||||
Iterable<String> selectorNames) {
|
||||
this.strategyRole = strategyRole;
|
||||
this.strategyImplementation = strategyImplementation;
|
||||
this.selectorNames = selectorNames;
|
||||
}
|
||||
|
||||
public SimpleAvailabilityImpl(
|
||||
Class strategyRole,
|
||||
Class strategyImplementation,
|
||||
String... selectorNames) {
|
||||
this( strategyRole, strategyImplementation, Arrays.asList( selectorNames ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getStrategyRole() {
|
||||
return strategyRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getSelectorNames() {
|
||||
return selectorNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getStrategyImplementation() {
|
||||
return strategyImplementation;
|
||||
}
|
||||
}
|
|
@ -29,6 +29,9 @@ import java.util.List;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
|
||||
import org.hibernate.boot.registry.selector.Availability;
|
||||
import org.hibernate.boot.registry.selector.AvailabilityAnnouncer;
|
||||
import org.hibernate.boot.registry.selector.SimpleAvailabilityImpl;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelectionException;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.dialect.CUBRIDDialect;
|
||||
|
@ -98,38 +101,27 @@ import org.hibernate.engine.transaction.spi.TransactionFactory;
|
|||
public class StrategySelectorBuilder {
|
||||
private static final Logger log = Logger.getLogger( StrategySelectorBuilder.class );
|
||||
|
||||
private static class CustomRegistration<T> {
|
||||
private final Class<T> strategy;
|
||||
private final String name;
|
||||
private final Class<? extends T> implementation;
|
||||
|
||||
private CustomRegistration(Class<T> strategy, String name, Class<? extends T> implementation) {
|
||||
this.strategy = strategy;
|
||||
this.name = name;
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public void registerWith(StrategySelectorImpl strategySelector) {
|
||||
strategySelector.registerStrategyImplementor( strategy, name, implementation );
|
||||
}
|
||||
}
|
||||
|
||||
private final List<CustomRegistration> customRegistrations = new ArrayList<CustomRegistration>();
|
||||
private final List<Availability> explicitAvailabilities = new ArrayList<Availability>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void addCustomRegistration(Class<T> strategy, String name, Class<? extends T> implementation) {
|
||||
if ( !strategy.isInterface() ) {
|
||||
// not good form...
|
||||
log.debug( "Registering non-interface strategy implementation : " + strategy.getName() );
|
||||
public <T> void addExplicitAvailability(Class<T> strategy, Class<? extends T> implementation, String name) {
|
||||
addExplicitAvailability( new SimpleAvailabilityImpl( strategy, implementation, name ) );
|
||||
}
|
||||
|
||||
if ( ! strategy.isAssignableFrom( implementation ) ) {
|
||||
public void addExplicitAvailability(Availability availability) {
|
||||
if ( !availability.getStrategyRole().isInterface() ) {
|
||||
// not good form...
|
||||
log.debug( "Registering non-interface strategy implementation : " + availability.getStrategyRole().getName() );
|
||||
}
|
||||
|
||||
if ( ! availability.getStrategyRole().isAssignableFrom( availability.getStrategyImplementation() ) ) {
|
||||
throw new StrategySelectionException(
|
||||
"Implementation class [" + implementation.getName() + "] does not implement strategy interface ["
|
||||
+ strategy.getName() + "]"
|
||||
"Implementation class [" + availability.getStrategyImplementation().getName()
|
||||
+ "] does not implement strategy interface ["
|
||||
+ availability.getStrategyRole().getName() + "]"
|
||||
);
|
||||
}
|
||||
customRegistrations.add( new CustomRegistration( strategy, name, implementation ) );
|
||||
explicitAvailabilities.add( availability );
|
||||
}
|
||||
|
||||
public StrategySelector buildSelector(ClassLoaderServiceImpl classLoaderService) {
|
||||
|
@ -140,16 +132,32 @@ public class StrategySelectorBuilder {
|
|||
addJtaPlatforms( strategySelector );
|
||||
addTransactionFactories( strategySelector );
|
||||
|
||||
// todo : apply auto-discovered registrations
|
||||
// apply auto-discovered registrations
|
||||
for ( AvailabilityAnnouncer announcer : classLoaderService.loadJavaServices( AvailabilityAnnouncer.class ) ) {
|
||||
for ( Availability discoveredAvailability : announcer.getAvailabilities() ) {
|
||||
applyFromAvailability( strategySelector, discoveredAvailability );
|
||||
}
|
||||
}
|
||||
|
||||
// apply customizations
|
||||
for ( CustomRegistration customRegistration : customRegistrations ) {
|
||||
customRegistration.registerWith( strategySelector );
|
||||
for ( Availability explicitAvailability : explicitAvailabilities ) {
|
||||
applyFromAvailability( strategySelector, explicitAvailability );
|
||||
}
|
||||
|
||||
return strategySelector;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void applyFromAvailability(StrategySelectorImpl strategySelector, Availability availability) {
|
||||
for ( String name : availability.getSelectorNames() ) {
|
||||
strategySelector.registerStrategyImplementor(
|
||||
availability.getStrategyRole(),
|
||||
name,
|
||||
availability.getStrategyImplementation()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void addDialects(StrategySelectorImpl strategySelector) {
|
||||
addDialect( strategySelector, Cache71Dialect.class );
|
||||
addDialect( strategySelector, CUBRIDDialect.class );
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.hibernate.cfg.Settings;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NoCachingRegionFactory implements RegionFactory {
|
||||
public static final NoCachingRegionFactory INSTANCE = new NoCachingRegionFactory();
|
||||
|
||||
public NoCachingRegionFactory() {
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.cache.internal;
|
|||
import java.util.Map;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.service.spi.ServiceException;
|
||||
|
@ -52,32 +53,37 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
|
|||
@Override
|
||||
@SuppressWarnings( { "unchecked" })
|
||||
public RegionFactory initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||
final Object impl = configurationValues.get( IMPL_NAME );
|
||||
if ( impl == null ) {
|
||||
return new NoCachingRegionFactory();
|
||||
}
|
||||
|
||||
if ( getServiceInitiated().isInstance( impl ) ) {
|
||||
return (RegionFactory) impl;
|
||||
}
|
||||
|
||||
Class<? extends RegionFactory> customImplClass = null;
|
||||
if ( Class.class.isInstance( impl ) ) {
|
||||
customImplClass = (Class<? extends RegionFactory>) impl;
|
||||
}
|
||||
else {
|
||||
customImplClass = registry.getService( ClassLoaderService.class )
|
||||
.classForName( mapLegacyNames( impl.toString() ) );
|
||||
}
|
||||
|
||||
try {
|
||||
return customImplClass.newInstance();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new ServiceException(
|
||||
"Could not initialize custom RegionFactory impl [" + customImplClass.getName() + "]", e
|
||||
final Object setting = configurationValues.get( IMPL_NAME );
|
||||
return registry.getService( StrategySelector.class ).resolveDefaultableStrategy(
|
||||
RegionFactory.class,
|
||||
setting,
|
||||
NoCachingRegionFactory.INSTANCE
|
||||
);
|
||||
}
|
||||
// if ( setting == null ) {
|
||||
// return new NoCachingRegionFactory();
|
||||
// }
|
||||
//
|
||||
// if ( getServiceInitiated().isInstance( setting ) ) {
|
||||
// return (RegionFactory) setting;
|
||||
// }
|
||||
//
|
||||
// Class<? extends RegionFactory> customImplClass = null;
|
||||
// if ( Class.class.isInstance( setting ) ) {
|
||||
// customImplClass = (Class<? extends RegionFactory>) setting;
|
||||
// }
|
||||
// else {
|
||||
// customImplClass = registry.getService( ClassLoaderService.class )
|
||||
// .classForName( mapLegacyNames( setting.toString() ) );
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// return customImplClass.newInstance();
|
||||
// }
|
||||
// catch ( Exception e ) {
|
||||
// throw new ServiceException(
|
||||
// "Could not initialize custom RegionFactory impl [" + customImplClass.getName() + "]", e
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
// todo this shouldn't be public (nor really static):
|
||||
|
|
68
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/AvailabilityAnnouncerImpl.java
vendored
Normal file
68
hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/AvailabilityAnnouncerImpl.java
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.cache.ehcache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.boot.registry.selector.Availability;
|
||||
import org.hibernate.boot.registry.selector.AvailabilityAnnouncer;
|
||||
import org.hibernate.boot.registry.selector.SimpleAvailabilityImpl;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
|
||||
/**
|
||||
* Makes the 2 contained region factory implementations available to the Hibernate
|
||||
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AvailabilityAnnouncerImpl implements AvailabilityAnnouncer {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterable<Availability> getAvailabilities() {
|
||||
final List<Availability> availabilities = new ArrayList<Availability>();
|
||||
|
||||
availabilities.add(
|
||||
new SimpleAvailabilityImpl(
|
||||
RegionFactory.class,
|
||||
EhCacheRegionFactory.class,
|
||||
"ehcache",
|
||||
EhCacheRegionFactory.class.getSimpleName(),
|
||||
"org.hibernate.cache.EhCacheRegionFactory" // legacy impl class name
|
||||
)
|
||||
);
|
||||
|
||||
availabilities.add(
|
||||
new SimpleAvailabilityImpl(
|
||||
RegionFactory.class,
|
||||
SingletonEhCacheRegionFactory.class,
|
||||
"ehcache-singleton",
|
||||
SingletonEhCacheRegionFactory.class.getSimpleName(),
|
||||
"org.hibernate.cache.SingletonEhCacheRegionFactory" // legacy impl class name
|
||||
)
|
||||
);
|
||||
|
||||
return availabilities;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.hibernate.cache.ehcache.AvailabilityAnnouncerImpl
|
65
hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/AvailabilityAnnouncerImpl.java
vendored
Normal file
65
hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/AvailabilityAnnouncerImpl.java
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, 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.cache.infinispan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.boot.registry.selector.Availability;
|
||||
import org.hibernate.boot.registry.selector.AvailabilityAnnouncer;
|
||||
import org.hibernate.boot.registry.selector.SimpleAvailabilityImpl;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
|
||||
/**
|
||||
* Makes the 2 contained region factory implementations available to the Hibernate
|
||||
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AvailabilityAnnouncerImpl implements AvailabilityAnnouncer {
|
||||
@Override
|
||||
public Iterable<Availability> getAvailabilities() {
|
||||
final List<Availability> availabilities = new ArrayList<Availability>();
|
||||
|
||||
availabilities.add(
|
||||
new SimpleAvailabilityImpl(
|
||||
RegionFactory.class,
|
||||
InfinispanRegionFactory.class,
|
||||
"infinispan",
|
||||
InfinispanRegionFactory.class.getSimpleName()
|
||||
)
|
||||
);
|
||||
|
||||
availabilities.add(
|
||||
new SimpleAvailabilityImpl(
|
||||
RegionFactory.class,
|
||||
JndiInfinispanRegionFactory.class,
|
||||
"infinispan-jndi",
|
||||
JndiInfinispanRegionFactory.class.getSimpleName()
|
||||
)
|
||||
);
|
||||
|
||||
return availabilities;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue