Coverage Report - org.jbehave.core.steps.ScanningStepsFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ScanningStepsFactory
95%
44/46
100%
10/10
1.875
 
 1  
 package org.jbehave.core.steps;
 2  
 
 3  
 import java.lang.annotation.Annotation;
 4  
 import java.lang.reflect.Method;
 5  
 import java.util.ArrayList;
 6  
 import java.util.HashSet;
 7  
 import java.util.List;
 8  
 import java.util.Set;
 9  
 
 10  
 import org.jbehave.core.annotations.AfterScenario;
 11  
 import org.jbehave.core.annotations.AfterStories;
 12  
 import org.jbehave.core.annotations.AfterStory;
 13  
 import org.jbehave.core.annotations.BeforeScenario;
 14  
 import org.jbehave.core.annotations.BeforeStories;
 15  
 import org.jbehave.core.annotations.BeforeStory;
 16  
 import org.jbehave.core.annotations.Given;
 17  
 import org.jbehave.core.annotations.Then;
 18  
 import org.jbehave.core.annotations.When;
 19  
 import org.jbehave.core.configuration.Configuration;
 20  
 import org.junit.After;
 21  
 import org.junit.Before;
 22  
 import org.reflections.Reflections;
 23  
 import org.reflections.scanners.MethodAnnotationsScanner;
 24  
 
 25  
 /**
 26  
  * An {@link InjectableStepsFactory} that scans for classes in the classpath.
 27  
  * The constructors allows the specification of the package names to scan or the
 28  
  * root class from which the package name is derived. All classes that include
 29  
  * any step method annotation ({@link Given}, {@link When}, {@link Then},
 30  
  * {@link Before}, {@link After}, etc ... ) will be collected in the scan.
 31  
  * Additional regex filters on the class names are provided via the
 32  
  * {@link #matchingNames(String)} and {@link #notMatchingNames(String)} methods,
 33  
  * which by default match all names.
 34  
  */
 35  
 public class ScanningStepsFactory extends AbstractStepsFactory {
 36  
 
 37  6
         private final Set<Class<?>> types = new HashSet<Class<?>>();
 38  6
         private String matchingRegex = ".*";
 39  6
         private String notMatchingRegex = "";
 40  
 
 41  
         public ScanningStepsFactory(Configuration configuration, Class<?> root) {
 42  1
                 this(configuration, root.getPackage().getName());
 43  1
         }
 44  
 
 45  
         public ScanningStepsFactory(Configuration configuration,
 46  
                         String... packageNames) {
 47  6
                 super(configuration);
 48  13
                 for (String packageName : packageNames) {
 49  7
                         types.addAll(scanTypes(packageName));
 50  
                 }
 51  6
         }
 52  
 
 53  
         public ScanningStepsFactory matchingNames(String matchingRegex) {
 54  2
                 this.matchingRegex = matchingRegex;
 55  2
                 return this;
 56  
         }
 57  
 
 58  
         public ScanningStepsFactory notMatchingNames(String notMatchingRegex) {
 59  2
                 this.notMatchingRegex = notMatchingRegex;
 60  2
                 return this;
 61  
         }
 62  
 
 63  
         private Set<Class<?>> scanTypes(String packageName) {
 64  7
                 Reflections reflections = new Reflections(packageName,
 65  
                                 new MethodAnnotationsScanner());
 66  7
                 Set<Class<?>> types = new HashSet<Class<?>>();
 67  7
                 types.addAll(typesAnnotatedWith(reflections, Given.class));
 68  7
                 types.addAll(typesAnnotatedWith(reflections, When.class));
 69  7
                 types.addAll(typesAnnotatedWith(reflections, Then.class));
 70  7
                 types.addAll(typesAnnotatedWith(reflections, Before.class));
 71  7
                 types.addAll(typesAnnotatedWith(reflections, After.class));
 72  7
                 types.addAll(typesAnnotatedWith(reflections, BeforeScenario.class));
 73  7
                 types.addAll(typesAnnotatedWith(reflections, AfterScenario.class));
 74  7
                 types.addAll(typesAnnotatedWith(reflections, BeforeStory.class));
 75  7
                 types.addAll(typesAnnotatedWith(reflections, AfterStory.class));
 76  7
                 types.addAll(typesAnnotatedWith(reflections, BeforeStories.class));
 77  7
                 types.addAll(typesAnnotatedWith(reflections, AfterStories.class));
 78  7
                 return types;
 79  
         }
 80  
 
 81  
         private Set<Class<?>> typesAnnotatedWith(Reflections reflections,
 82  
                         Class<? extends Annotation> annotation) {
 83  77
                 Set<Class<?>> types = new HashSet<Class<?>>();
 84  77
                 Set<Method> methodsAnnotatedWith = reflections
 85  77
                                 .getMethodsAnnotatedWith(annotation);
 86  77
                 for (Method method : methodsAnnotatedWith) {
 87  106
                         types.add(method.getDeclaringClass());
 88  106
                 }
 89  77
                 return types;
 90  
         }
 91  
 
 92  
         @Override
 93  
         protected List<Class<?>> stepsTypes() {
 94  6
                 List<Class<?>> matchingTypes = new ArrayList<Class<?>>();
 95  6
                 for (Class<?> type : types) {
 96  40
                         String name = type.getName();
 97  40
                         if (name.matches(matchingRegex) && !name.matches(notMatchingRegex)) {
 98  38
                                 matchingTypes.add(type);
 99  
                         }
 100  40
                 }
 101  6
                 return matchingTypes;
 102  
         }
 103  
 
 104  
         public Object createInstanceOfType(Class<?> type) {
 105  
                 Object instance;
 106  
                 try {
 107  9
                         instance = type.newInstance();
 108  0
                 } catch (Exception e) {
 109  0
                         throw new StepsInstanceNotFound(type, this);
 110  9
                 }
 111  9
                 return instance;
 112  
         }
 113  
 
 114  
 }