Coverage Report - org.jbehave.core.steps.spring.SpringStepsFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
SpringStepsFactory
94%
18/19
93%
15/16
3
 
 1  
 package org.jbehave.core.steps.spring;
 2  
 
 3  
 import java.lang.reflect.Modifier;
 4  
 import java.util.ArrayList;
 5  
 import java.util.HashSet;
 6  
 import java.util.List;
 7  
 import java.util.Set;
 8  
 
 9  
 import org.jbehave.core.configuration.Configuration;
 10  
 import org.jbehave.core.steps.AbstractStepsFactory;
 11  
 import org.jbehave.core.steps.InjectableStepsFactory;
 12  
 import org.springframework.aop.framework.AopProxyUtils;
 13  
 import org.springframework.context.ApplicationContext;
 14  
 import org.springframework.util.ClassUtils;
 15  
 
 16  
 /**
 17  
  * An {@link InjectableStepsFactory} that uses Spring's
 18  
  * {@link ApplicationContext} for the composition and instantiation of all
 19  
  * components that contain JBehave annotated methods.
 20  
  * 
 21  
  * @author Paul Hammant
 22  
  * @author Mauro Talevi
 23  
  */
 24  
 public class SpringStepsFactory extends AbstractStepsFactory {
 25  
 
 26  
         private final ApplicationContext context;
 27  
 
 28  
         public SpringStepsFactory(Configuration configuration,
 29  
                         ApplicationContext context) {
 30  9
                 super(configuration);
 31  9
                 this.context = context;
 32  9
         }
 33  
 
 34  
         @Override
 35  
         protected List<Class<?>> stepsTypes() {
 36  
                 // Using set because in some cases (eg: scoped proxies),
 37  
                 // there may be two actual beans for each defined bean).
 38  9
                 Set<Class<?>> types = new HashSet<Class<?>>();
 39  65
                 for (String name : context.getBeanDefinitionNames()) {
 40  56
                         Class<?> type = beanType(name);
 41  56
                         if (isAllowed(type) && hasAnnotatedMethods(type)) {
 42  9
                                 types.add(type);
 43  
                         }
 44  
                 }
 45  9
                 return new ArrayList<Class<?>>(types);
 46  
         }
 47  
 
 48  
         /**
 49  
          * Checks if type returned from context is allowed, i.e. not null and not
 50  
          * abstract.
 51  
          * 
 52  
          * @param type
 53  
          *            the Class of the bean
 54  
          * @return A boolean, <code>true</code> if allowed
 55  
          */
 56  
         protected boolean isAllowed(Class<?> type) {
 57  56
                 return type != null && !Modifier.isAbstract(type.getModifiers());
 58  
         }
 59  
 
 60  
         public Object createInstanceOfType(Class<?> type) {
 61  69
                 for (String name : context.getBeanDefinitionNames()) {
 62  69
                         Class<?> beanType = beanType(name);
 63  69
                         if (type.equals(beanType)) {
 64  12
                                 return context.getBean(name);
 65  
                         }
 66  
                 }
 67  0
                 throw new StepsInstanceNotFound(type, this);
 68  
         }
 69  
 
 70  
         /**
 71  
          * Return the bean type, untangling the proxy if needed
 72  
          * 
 73  
          * @param name
 74  
          *            the bean name
 75  
          * @return The Class of the bean
 76  
          */
 77  
         private Class<?> beanType(String name) {
 78  125
                 Class<?> type = context.getType(name);
 79  125
                 if (ClassUtils.isCglibProxyClass(type)) {
 80  9
                         return AopProxyUtils.ultimateTargetClass(context.getBean(name));
 81  
                 }
 82  116
                 return type;
 83  
         }
 84  
 
 85  
 }