org.hibernate.search.engine.environment.bean.BeanResolver Maven / Gradle / Ivy
Show all versions of hibernate-search-engine Show documentation
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.search.engine.environment.bean;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.hibernate.search.engine.environment.bean.spi.BeanProvider;
import org.hibernate.search.util.common.SearchException;
import org.hibernate.search.util.common.impl.Contracts;
import org.hibernate.search.util.common.impl.SuppressingCloser;
/**
* The main entry point for components looking to resolve a bean reference into a (usually user-provided) bean.
*
* Depending on the integration, beans may be instantiated using reflection (expecting a no-argument constructor),
* or provided by a more advanced dependency injection context (CDI, Spring DI).
*
* Regardless of the underlying implementation, this interface is used to resolve beans,
* referenced either
* {@link #resolve(Class, BeanRetrieval)} by their type},
* or {@link #resolve(Class, String, BeanRetrieval) by their type and name}.
*
* It also offers ways to {@link #allConfiguredForRole(Class) get references to configured beans of a given type}.
*
* This interface is API,
* but should only be implemented by Hibernate Search itself;
* if you are looking to provide beans from a different source,
* you should implement {@link BeanProvider} instead.
*/
public interface BeanResolver {
/**
* Resolve a bean by its type.
* @param The expected return type.
* @param typeReference The type used as a reference to the bean to resolve. Must be non-null.
* @param retrieval How to retrieve the bean. See {@link BeanRetrieval}.
* @return A {@link BeanHolder} containing the resolved bean.
* @throws SearchException if the reference is invalid (null) or the bean cannot be resolved.
*/
BeanHolder resolve(Class typeReference, BeanRetrieval retrieval);
/**
* Resolve a bean by its name.
* @param The expected return type.
* @param typeReference The type used as a reference to the bean to resolve. Must be non-null.
* @param nameReference The name used as a reference to the bean to resolve. Must be non-null and non-empty.
* @param retrieval How to retrieve the bean. See {@link BeanRetrieval}.
* @return A {@link BeanHolder} containing the resolved bean.
* @throws SearchException if a reference is invalid (null or empty) or the bean cannot be resolved.
*/
BeanHolder resolve(Class typeReference, String nameReference, BeanRetrieval retrieval);
/**
* Resolve a {@link BeanReference}.
*
* This method is just syntactic sugar to allow writing {@code bridgeProvider::resolve}
* and getting a {@code Function, T>} that can be used in {@link java.util.Optional#map(Function)}
* for instance.
*
* @param The expected return type.
* @param reference The reference to the bean to resolve. Must be non-null.
* @return A {@link BeanHolder} containing the resolved bean.
* @throws SearchException if the reference is invalid (null or empty) or the bean cannot be resolved.
*/
default BeanHolder resolve(BeanReference reference) {
Contracts.assertNotNull( reference, "reference" );
return reference.resolve( this );
}
/**
* Resolve a list of {@link BeanReference}s.
*
* The main advantage of calling this method over looping and calling {@link #resolve(BeanReference)} repeatedly
* is that errors are handled correctly: if a bean was already instantiated, and getting the next one fails,
* then the first bean will be properly {@link BeanHolder#close() closed} before the exception is propagated.
* Also, this method returns a {@code BeanHolder>} instead of a {@code List>},
* so its result is easier to use in a try-with-resources.
*
* This method is also syntactic sugar to allow writing {@code bridgeProvider::resolve}
* and getting a {@code Function, T>} that can be used in {@link java.util.Optional#map(Function)}
* for instance.
*
* @param The expected bean type.
* @param references The references to the beans to retrieve. Must be non-null.
* @return A {@link BeanHolder} containing a {@link List} containing the resolved beans,
* in the same order as the {@code references}.
* @throws SearchException if one reference is invalid (null or empty) or the corresponding bean cannot be resolved.
*/
default BeanHolder> resolve(List extends BeanReference extends T>> references) {
List> beanHolders = new ArrayList<>();
try {
for ( BeanReference extends T> reference : references ) {
beanHolders.add( reference.resolve( this ) );
}
return BeanHolder.of( beanHolders );
}
catch (RuntimeException e) {
new SuppressingCloser( e ).pushAll( BeanHolder::close, beanHolders );
throw e;
}
}
/**
* Return all the bean references configured for the given role.
*
* WARNING: this does not just return references to all the beans that implement {@code role}.
* Only beans registered during
* {@link org.hibernate.search.engine.environment.bean.spi.BeanConfigurer bean configuration}
* are taken into account.
*
* @param The expected bean type.
* @param role The role that must have been assigned to the retrieved beans. Must be non-null and non-empty.
* @return A {@link List} of bean references, possibly empty.
*/
List> allConfiguredForRole(Class role);
/**
* Return named bean references configured for the given role.
*
* WARNING: this does not just return references to all the beans that implement {@code role}.
* Only beans registered during
* {@link org.hibernate.search.engine.environment.bean.spi.BeanConfigurer bean configuration}
* are taken into account.
*
* @param The expected bean type.
* @param role The role that must have been assigned to the retrieved beans. Must be non-null and non-empty.
* @return A {@link Map} from name to bean reference, possibly empty.
*/
Map> namedConfiguredForRole(Class role);
}