/* * 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 <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.engine.service.beanresolver.impl; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.hibernate.search.annotations.Factory; import org.hibernate.search.engine.service.beanresolver.spi.BeanResolver; import org.hibernate.search.exception.SearchException; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.search.util.logging.impl.LoggerFactory; /** * A bean resolver that uses reflection to instantiate beans. * <p> * The class passed as an argument must expose a public, no-arg constructor, * or this resolver will fail with a {@link SearchException}. * <p> * If the class passed as an argument contains a method annotated * with {@code @Factory}, the class will be considered as a factory * and the returned bean will be fetched from this factory method instead. */ public class ReflectionBeanResolver implements BeanResolver { private static final Log log = LoggerFactory.make(); @Override public <T> T resolve(Class<?> classOrFactoryClass, Class<T> expectedClass) { Object instance; try { instance = classOrFactoryClass.newInstance(); } catch (InstantiationException e) { throw log.noPublicNoArgConstructor( classOrFactoryClass.getName() ); } catch (IllegalAccessException e) { throw log.unableToAccessClass( classOrFactoryClass.getName() ); } // check for a factory annotation int numberOfFactoryMethodsFound = 0; for ( Method method : classOrFactoryClass.getMethods() ) { if ( method.isAnnotationPresent( Factory.class ) ) { if ( numberOfFactoryMethodsFound == 1 ) { throw log.multipleFactoryMethodsInClass( classOrFactoryClass.getName() ); } if ( method.getReturnType() == void.class ) { throw log.factoryMethodsMustReturnAnObject( classOrFactoryClass.getName(), method.getName() ); } try { instance = method.invoke( instance ); } catch (IllegalAccessException e) { throw log.unableToAccessMethod( classOrFactoryClass.getName(), method.getName() ); } catch (InvocationTargetException e) { throw log.exceptionDuringFactoryMethodExecution( e, classOrFactoryClass.getName(), method.getName() ); } numberOfFactoryMethodsFound++; } } return expectedClass.cast( instance ); } }