Package org.jbehave.core.steps

Source Code of org.jbehave.core.steps.ScanningStepsFactory

package org.jbehave.core.steps;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.jbehave.core.annotations.AfterScenario;
import org.jbehave.core.annotations.AfterStories;
import org.jbehave.core.annotations.AfterStory;
import org.jbehave.core.annotations.BeforeScenario;
import org.jbehave.core.annotations.BeforeStories;
import org.jbehave.core.annotations.BeforeStory;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.jbehave.core.configuration.Configuration;
import org.junit.After;
import org.junit.Before;
import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;

/**
* An {@link InjectableStepsFactory} that scans for classes in the classpath.
* The constructors allows the specification of the package names to scan or the
* root class from which the package name is derived. All classes that include
* any step method annotation ({@link Given}, {@link When}, {@link Then},
* {@link Before}, {@link After}, etc ... ) will be collected in the scan.
* Additional regex filters on the class names are provided via the
* {@link #matchingNames(String)} and {@link #notMatchingNames(String)} methods,
* which by default match all names.
*/
public class ScanningStepsFactory extends AbstractStepsFactory {

  private final Set<Class<?>> types = new HashSet<Class<?>>();
  private String matchingRegex = ".*";
  private String notMatchingRegex = "";

  public ScanningStepsFactory(Configuration configuration, Class<?> root) {
    this(configuration, root.getPackage().getName());
  }

  public ScanningStepsFactory(Configuration configuration,
      String... packageNames) {
    super(configuration);
    for (String packageName : packageNames) {
      types.addAll(scanTypes(packageName));
    }
  }

  public ScanningStepsFactory matchingNames(String matchingRegex) {
    this.matchingRegex = matchingRegex;
    return this;
  }

  public ScanningStepsFactory notMatchingNames(String notMatchingRegex) {
    this.notMatchingRegex = notMatchingRegex;
    return this;
  }

  private Set<Class<?>> scanTypes(String packageName) {
    Reflections reflections = new Reflections(packageName,
        new MethodAnnotationsScanner());
    Set<Class<?>> types = new HashSet<Class<?>>();
    types.addAll(typesAnnotatedWith(reflections, Given.class));
    types.addAll(typesAnnotatedWith(reflections, When.class));
    types.addAll(typesAnnotatedWith(reflections, Then.class));
    types.addAll(typesAnnotatedWith(reflections, Before.class));
    types.addAll(typesAnnotatedWith(reflections, After.class));
    types.addAll(typesAnnotatedWith(reflections, BeforeScenario.class));
    types.addAll(typesAnnotatedWith(reflections, AfterScenario.class));
    types.addAll(typesAnnotatedWith(reflections, BeforeStory.class));
    types.addAll(typesAnnotatedWith(reflections, AfterStory.class));
    types.addAll(typesAnnotatedWith(reflections, BeforeStories.class));
    types.addAll(typesAnnotatedWith(reflections, AfterStories.class));
    return types;
  }

  private Set<Class<?>> typesAnnotatedWith(Reflections reflections,
      Class<? extends Annotation> annotation) {
    Set<Class<?>> types = new HashSet<Class<?>>();
    Set<Method> methodsAnnotatedWith = reflections
        .getMethodsAnnotatedWith(annotation);
    for (Method method : methodsAnnotatedWith) {
      types.add(method.getDeclaringClass());
    }
    return types;
  }

  @Override
  protected List<Class<?>> stepsTypes() {
    List<Class<?>> matchingTypes = new ArrayList<Class<?>>();
    for (Class<?> type : types) {
      String name = type.getName();
      if (name.matches(matchingRegex) && !name.matches(notMatchingRegex)) {
        matchingTypes.add(type);
      }
    }
    return matchingTypes;
  }

  public Object createInstanceOfType(Class<?> type) {
    Object instance;
    try {
      instance = type.newInstance();
    } catch (Exception e) {
      throw new StepsInstanceNotFound(type, this);
    }
    return instance;
  }

}
TOP

Related Classes of org.jbehave.core.steps.ScanningStepsFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.