/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* 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.ogm.options.navigation.impl;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.ogm.options.navigation.source.impl.OptionValueSource;
import org.hibernate.ogm.options.navigation.source.impl.OptionValueSources;
import org.hibernate.ogm.options.spi.OptionsContext;
import org.hibernate.ogm.options.spi.OptionsService;
import org.hibernate.ogm.util.configurationreader.impl.ConfigurationPropertyReader;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
/**
* Provides read access to option contexts maintained at the session factory and session level.
*
* @author Emmanuel Bernard <emmanuel@hibernate.org>
* @author Gunnar Morling
*/
public class OptionsServiceImpl implements OptionsService, Configurable, ServiceRegistryAwareService {
private OptionsServiceContext sessionFactoryOptions;
private ServiceRegistryImplementor registry;
@Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
this.registry = serviceRegistry;
}
@Override
public void configure(Map configurationValues) {
ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
ConfigurationPropertyReader propertyReader = new ConfigurationPropertyReader( configurationValues, classLoaderService );
sessionFactoryOptions = new OptionsServiceContextImpl( OptionValueSources.getDefaultSources( propertyReader ) );
}
@Override
public OptionsServiceContext context() {
return sessionFactoryOptions;
}
@Override
public OptionsServiceContext context(SessionImplementor session) {
throw new UnsupportedOperationException( "OGM-343 Session specific options are not currently supported" );
}
private static class OptionsServiceContextImpl implements OptionsServiceContext {
private final List<OptionValueSource> sources;
private final OptionsContext globalOptions;
private final ConcurrentMap<Class<?>, OptionsContext> entityContexts;
private final ConcurrentMap<PropertyKey, OptionsContext> propertyContexts;
public OptionsServiceContextImpl(List<OptionValueSource> sources) {
this.sources = sources;
globalOptions = OptionsContextImpl.forGlobal( sources );
entityContexts = new ConcurrentHashMap<Class<?>, OptionsContext>();
propertyContexts = new ConcurrentHashMap<PropertyKey, OptionsContext>();
}
@Override
public OptionsContext getGlobalOptions() {
return globalOptions;
}
@Override
public OptionsContext getEntityOptions(Class<?> entityType) {
OptionsContext entityOptions = entityContexts.get( entityType );
if ( entityOptions == null ) {
entityOptions = getAndCacheEntityOptions( entityType );
}
return entityOptions;
}
@Override
public OptionsContext getPropertyOptions(Class<?> entityType, String propertyName) {
PropertyKey key = new PropertyKey( entityType, propertyName );
OptionsContext propertyOptions = propertyContexts.get( key );
if ( propertyOptions == null ) {
propertyOptions = getAndCachePropertyOptions( key );
}
return propertyOptions;
}
private OptionsContext getAndCacheEntityOptions(Class<?> entityType) {
OptionsContext entityOptions = OptionsContextImpl.forEntity( sources, entityType );
OptionsContext cachedOptions = entityContexts.putIfAbsent( entityType, entityOptions );
if ( cachedOptions != null ) {
entityOptions = cachedOptions;
}
return entityOptions;
}
private OptionsContext getAndCachePropertyOptions(PropertyKey key) {
OptionsContext propertyOptions = OptionsContextImpl.forProperty( sources, key.getEntity(), key.getProperty() );
OptionsContext cachedOptions = propertyContexts.putIfAbsent( key, propertyOptions );
if ( cachedOptions != null ) {
propertyOptions = cachedOptions;
}
return propertyOptions;
}
}
}