SpringStepsFactory.java
- package org.jbehave.core.steps.spring;
- import java.lang.reflect.Modifier;
- import java.util.ArrayList;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
- import org.jbehave.core.configuration.Configuration;
- import org.jbehave.core.steps.AbstractStepsFactory;
- import org.jbehave.core.steps.InjectableStepsFactory;
- import org.springframework.aop.framework.AopProxyUtils;
- import org.springframework.context.ApplicationContext;
- import org.springframework.util.ClassUtils;
- /**
- * An {@link InjectableStepsFactory} that uses Spring's
- * {@link ApplicationContext} for the composition and instantiation of all
- * components that contain JBehave annotated methods.
- *
- * @author Paul Hammant
- * @author Mauro Talevi
- */
- public class SpringStepsFactory extends AbstractStepsFactory {
- private final ApplicationContext context;
- public SpringStepsFactory(Configuration configuration,
- ApplicationContext context) {
- super(configuration);
- this.context = context;
- }
- @Override
- protected List<Class<?>> stepsTypes() {
- // Using set because in some cases (eg: scoped proxies),
- // there may be two actual beans for each defined bean).
- Set<Class<?>> types = new HashSet<>();
- for (String name : context.getBeanDefinitionNames()) {
- Class<?> type = beanType(name);
- if (isAllowed(type) && hasAnnotatedMethods(type)) {
- types.add(type);
- }
- }
- return new ArrayList<>(types);
- }
- /**
- * Checks if type returned from context is allowed, i.e. not null and not
- * abstract.
- *
- * @param type
- * the Class of the bean
- * @return A boolean, <code>true</code> if allowed
- */
- protected boolean isAllowed(Class<?> type) {
- return type != null && !Modifier.isAbstract(type.getModifiers());
- }
- @Override
- public Object createInstanceOfType(Class<?> type) {
- for (String name : context.getBeanDefinitionNames()) {
- Class<?> beanType = beanType(name);
- if (type.equals(beanType)) {
- return context.getBean(name);
- }
- }
- throw new StepsInstanceNotFound(type, this);
- }
- /**
- * Return the bean type, untangling the proxy if needed
- *
- * @param name
- * the bean name
- * @return The Class of the bean
- */
- private Class<?> beanType(String name) {
- Class<?> type = context.getType(name);
- if (ClassUtils.isCglibProxyClass(type)) {
- return AopProxyUtils.ultimateTargetClass(context.getBean(name));
- }
- return type;
- }
- }