diff --git a/engine/src/main/java/org/hibernate/search/engine/cfg/SearchEngineSettings.java b/engine/src/main/java/org/hibernate/search/engine/cfg/SearchEngineSettings.java new file mode 100644 index 00000000000..5e697ce30e1 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/cfg/SearchEngineSettings.java @@ -0,0 +1,51 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.cfg; + +import java.util.Collections; +import java.util.List; + +import org.hibernate.search.engine.environment.bean.BeanReference; +import org.hibernate.search.engine.environment.bean.spi.BeanConfigurer; +import org.hibernate.search.engine.environment.bean.spi.BeanResolver; + +/** + * Configuration properties for the Hibernate Search engine. + */ +public final class SearchEngineSettings { + + private SearchEngineSettings() { + } + + /** + * The {@link BeanConfigurer} instances + * used to pre-define beans. + *

+ * Accepts either: + *

+ */ + public static final String BEAN_CONFIGURERS = "bean_configurers"; + + /** + * Default values for the different settings if no values are given. + */ + public static final class Defaults { + + private Defaults() { + } + + public static final List> BEAN_CONFIGURERS = Collections.emptyList(); + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/common/impl/SearchIntegrationBuilderImpl.java b/engine/src/main/java/org/hibernate/search/engine/common/impl/SearchIntegrationBuilderImpl.java index 2eacd954557..08fd5096f22 100644 --- a/engine/src/main/java/org/hibernate/search/engine/common/impl/SearchIntegrationBuilderImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/common/impl/SearchIntegrationBuilderImpl.java @@ -25,7 +25,7 @@ import org.hibernate.search.engine.common.spi.SearchIntegration; import org.hibernate.search.engine.common.spi.SearchIntegrationBuilder; import org.hibernate.search.engine.environment.bean.BeanProvider; -import org.hibernate.search.engine.environment.bean.impl.BeanProviderImpl; +import org.hibernate.search.engine.environment.bean.impl.ConfiguredBeanProvider; import org.hibernate.search.engine.environment.bean.spi.BeanResolver; import org.hibernate.search.engine.environment.bean.spi.ReflectionBeanResolver; import org.hibernate.search.engine.environment.classpath.spi.ClassResolver; @@ -149,10 +149,6 @@ public SearchIntegration build() { beanResolver = new ReflectionBeanResolver( classResolver ); } - BeanProvider beanProvider = new BeanProviderImpl( classResolver, beanResolver ); - ServiceManager serviceManager = new ServiceManagerImpl( classResolver, resourceResolver, beanProvider ); - RootBuildContext rootBuildContext = new RootBuildContext( serviceManager, failureCollector ); - ConfigurationPropertySource propertySource; if ( !overriddenProperties.isEmpty() ) { propertySource = mainPropertySource.withOverride( @@ -163,6 +159,10 @@ public SearchIntegration build() { propertySource = mainPropertySource; } + BeanProvider beanProvider = new ConfiguredBeanProvider( classResolver, beanResolver, propertySource ); + ServiceManager serviceManager = new ServiceManagerImpl( classResolver, resourceResolver, beanProvider ); + RootBuildContext rootBuildContext = new RootBuildContext( serviceManager, failureCollector ); + indexManagerBuildingStateHolder = new IndexManagerBuildingStateHolder( rootBuildContext, propertySource ); // First phase: collect configuration for all mappings diff --git a/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanResolverOnlyBeanProvider.java b/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanResolverOnlyBeanProvider.java new file mode 100644 index 00000000000..975eb7ca9b8 --- /dev/null +++ b/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanResolverOnlyBeanProvider.java @@ -0,0 +1,37 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.engine.environment.bean.impl; + +import org.hibernate.search.engine.environment.bean.BeanHolder; +import org.hibernate.search.engine.environment.bean.BeanProvider; +import org.hibernate.search.engine.environment.bean.spi.BeanResolver; +import org.hibernate.search.util.impl.common.Contracts; + +/** + * A BeanProvider that ignores the explicitly configured beans. + * Used in the ConfiguredBeanProvider constructor to retrieve bean configurers. + */ +final class BeanResolverOnlyBeanProvider implements BeanProvider { + private final BeanResolver beanResolver; + + BeanResolverOnlyBeanProvider(BeanResolver beanResolver) { + this.beanResolver = beanResolver; + } + + @Override + public BeanHolder getBean(Class typeReference) { + Contracts.assertNotNull( typeReference, "typeReference" ); + return beanResolver.resolve( typeReference ); + } + + @Override + public BeanHolder getBean(Class typeReference, String nameReference) { + Contracts.assertNotNull( typeReference, "typeReference" ); + Contracts.assertNotNullNorEmpty( nameReference, "nameReference" ); + return beanResolver.resolve( typeReference, nameReference ); + } +} diff --git a/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanProviderImpl.java b/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/ConfiguredBeanProvider.java similarity index 70% rename from engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanProviderImpl.java rename to engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/ConfiguredBeanProvider.java index 63edd0f835f..162600e0572 100644 --- a/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/BeanProviderImpl.java +++ b/engine/src/main/java/org/hibernate/search/engine/environment/bean/impl/ConfiguredBeanProvider.java @@ -6,10 +6,16 @@ */ package org.hibernate.search.engine.environment.bean.impl; +import java.util.List; import java.util.Map; +import java.util.regex.Pattern; +import org.hibernate.search.engine.cfg.ConfigurationPropertySource; +import org.hibernate.search.engine.cfg.SearchEngineSettings; +import org.hibernate.search.engine.cfg.spi.ConfigurationProperty; import org.hibernate.search.engine.environment.bean.BeanHolder; import org.hibernate.search.engine.environment.bean.BeanProvider; +import org.hibernate.search.engine.environment.bean.BeanReference; import org.hibernate.search.engine.environment.bean.spi.BeanConfigurer; import org.hibernate.search.engine.environment.bean.spi.BeanCreationContext; import org.hibernate.search.engine.environment.bean.spi.BeanFactory; @@ -18,21 +24,35 @@ import org.hibernate.search.util.SearchException; import org.hibernate.search.util.impl.common.Contracts; -public final class BeanProviderImpl implements BeanProvider { +public final class ConfiguredBeanProvider implements BeanProvider { + + private static final ConfigurationProperty>> BEAN_CONFIGURERS = + ConfigurationProperty.forKey( SearchEngineSettings.BEAN_CONFIGURERS ) + .asBeanReference( BeanConfigurer.class ) + .multivalued( Pattern.compile( "\\s+" ) ) + .withDefault( SearchEngineSettings.Defaults.BEAN_CONFIGURERS ) + .build(); private final BeanResolver beanResolver; private final Map, BeanFactory> explicitlyConfiguredBeans; private final BeanCreationContext beanCreationContext; - public BeanProviderImpl(ClassResolver classResolver, BeanResolver beanResolver) { + public ConfiguredBeanProvider(ClassResolver classResolver, BeanResolver beanResolver, + ConfigurationPropertySource configurationPropertySource) { this.beanResolver = beanResolver; - // TODO maybe also add a way to pass configurer through a configuration property? BeanConfigurationContextImpl configurationContext = new BeanConfigurationContextImpl(); for ( BeanConfigurer beanConfigurer : classResolver.loadJavaServices( BeanConfigurer.class ) ) { beanConfigurer.configure( configurationContext ); } + BeanResolverOnlyBeanProvider beanProviderForConfigurers = new BeanResolverOnlyBeanProvider( beanResolver ); + try ( BeanHolder> beanConfigurersFromConfigurationProperties = + BEAN_CONFIGURERS.getAndTransform( configurationPropertySource, beanProviderForConfigurers::getBeans ) ) { + for ( BeanConfigurer beanConfigurer : beanConfigurersFromConfigurationProperties.get() ) { + beanConfigurer.configure( configurationContext ); + } + } this.explicitlyConfiguredBeans = configurationContext.getConfiguredBeans(); this.beanCreationContext = new BeanCreationContextImpl( this );