GuiceStepsFactory.java

  1. package org.jbehave.core.steps.guice;

  2. import java.lang.reflect.Type;
  3. import java.util.ArrayList;
  4. import java.util.List;

  5. import com.google.inject.Binding;
  6. import com.google.inject.Injector;
  7. import com.google.inject.Key;

  8. import org.jbehave.core.configuration.Configuration;
  9. import org.jbehave.core.steps.AbstractStepsFactory;
  10. import org.jbehave.core.steps.InjectableStepsFactory;

  11. /**
  12.  * An {@link InjectableStepsFactory} that uses a Guice {@link Injector} for the
  13.  * composition and instantiation of all components that contain JBehave
  14.  * annotated methods.
  15.  *
  16.  * @author Cristiano GaviĆ£o
  17.  * @author Paul Hammant
  18.  * @author Mauro Talevi
  19.  */
  20. public class GuiceStepsFactory extends AbstractStepsFactory {

  21.     private final Injector injector;

  22.     public GuiceStepsFactory(Configuration configuration, Injector injector) {
  23.         super(configuration);
  24.         this.injector = injector;
  25.     }

  26.     @Override
  27.     protected List<Class<?>> stepsTypes() {
  28.         List<Class<?>> types = new ArrayList<>();
  29.         addTypes(injector, types);
  30.         return types;
  31.     }

  32.     /**
  33.      * Adds steps types from given injector and recursively its parent
  34.      *
  35.      * @param injector the current Inject
  36.      * @param types the List of steps types
  37.      */
  38.     private void addTypes(Injector injector, List<Class<?>> types) {
  39.         for (Binding<?> binding : injector.getBindings().values()) {
  40.             Key<?> key = binding.getKey();
  41.             Type type = key.getTypeLiteral().getType();
  42.             if (hasAnnotatedMethods(type)) {
  43.                 types.add(((Class<?>)type));
  44.             }
  45.         }
  46.         if (injector.getParent() != null) {
  47.             addTypes(injector.getParent(), types);
  48.         }
  49.     }

  50.     @Override
  51.     public Object createInstanceOfType(Class<?> type) {
  52.         List<Object> instances = new ArrayList<>();
  53.         addInstances(injector, type, instances);
  54.         if (!instances.isEmpty()) {
  55.             return instances.iterator().next();
  56.         }
  57.         return new StepsInstanceNotFound(type, this);
  58.     }

  59.     private void addInstances(Injector injector, Class<?> type, List<Object> instances) {
  60.         for (Binding<?> binding : injector.getBindings().values()) {
  61.             Key<?> key = binding.getKey();
  62.             if (type.equals(key.getTypeLiteral().getType())) {
  63.                 instances.add(injector.getInstance(key));
  64.             }
  65.         }
  66.         if (injector.getParent() != null) {
  67.             addInstances(injector.getParent(), type, instances);
  68.         }
  69.     }
  70. }