PicoAnnotationBuilder.java

  1. package org.jbehave.core.configuration.pico;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import org.jbehave.core.annotations.pico.UsingPico;
  5. import org.jbehave.core.configuration.AnnotationBuilder;
  6. import org.jbehave.core.configuration.AnnotationFinder;
  7. import org.jbehave.core.configuration.AnnotationMonitor;
  8. import org.jbehave.core.configuration.AnnotationRequired;
  9. import org.jbehave.core.configuration.Configuration;
  10. import org.jbehave.core.io.ResourceLoader;
  11. import org.jbehave.core.model.TableTransformers;
  12. import org.jbehave.core.steps.CompositeStepsFactory;
  13. import org.jbehave.core.steps.InjectableStepsFactory;
  14. import org.jbehave.core.steps.ParameterConverters;
  15. import org.jbehave.core.steps.ParameterConverters.ParameterConverter;
  16. import org.jbehave.core.steps.pico.PicoStepsFactory;
  17. import org.picocontainer.MutablePicoContainer;
  18. import org.picocontainer.PicoContainer;
  19. import org.picocontainer.injectors.AbstractInjector.AmbiguousComponentResolutionException;

  20. /**
  21.  * Extends {@link AnnotationBuilder} to provide PicoContainer-based
  22.  * dependency injection if {@link UsingPico} annotation is present.
  23.  *
  24.  * @author Cristiano GaviĆ£o
  25.  * @author Mauro Talevi
  26.  */
  27. public class PicoAnnotationBuilder extends AnnotationBuilder {

  28.     private PicoContainer container;

  29.     public PicoAnnotationBuilder(Class<?> annotatedClass) {
  30.         super(annotatedClass);
  31.     }

  32.     public PicoAnnotationBuilder(Class<?> annotatedClass, AnnotationMonitor annotationMonitor) {
  33.         super(annotatedClass, annotationMonitor);
  34.     }

  35.     @Override
  36.     public Configuration buildConfiguration() throws AnnotationRequired {
  37.         AnnotationFinder finder = annotationFinder();
  38.         if (finder.isAnnotationPresent(UsingPico.class)) {
  39.             @SuppressWarnings("rawtypes")
  40.             List<Class> moduleClasses = finder.getAnnotatedValues(UsingPico.class, Class.class, "modules");
  41.             List<PicoModule> modules = new ArrayList<>();
  42.             for (Class<PicoModule> moduleClass : moduleClasses) {
  43.                 try {
  44.                     modules.add(moduleClass.newInstance());
  45.                 } catch (Exception e) {
  46.                     annotationMonitor().elementCreationFailed(moduleClass, e);
  47.                 }
  48.             }
  49.             if (modules.size() > 0) {
  50.                 container = createPicoContainer(modules);                
  51.             }
  52.         } else {
  53.             annotationMonitor().annotationNotFound(UsingPico.class, annotatedClass());
  54.         }
  55.         return super.buildConfiguration();
  56.     }

  57.     @Override
  58.     public InjectableStepsFactory buildStepsFactory(Configuration configuration) {
  59.         InjectableStepsFactory factoryUsingSteps = super.buildStepsFactory(configuration);
  60.         if (container != null) {
  61.             return new CompositeStepsFactory(new PicoStepsFactory(configuration, container), factoryUsingSteps);
  62.         }
  63.         return factoryUsingSteps;
  64.     }

  65.     @Override
  66.     protected ParameterConverters parameterConverters(AnnotationFinder annotationFinder, ResourceLoader resourceLoader,
  67.             TableTransformers tableTransformers) {
  68.         ParameterConverters converters = super.parameterConverters(annotationFinder, resourceLoader, tableTransformers);
  69.         if (container != null) {
  70.             return converters.addConverters(container.getComponents(ParameterConverter.class));
  71.         }
  72.         return converters;
  73.     }

  74.     @Override
  75.     protected <T, V extends T> T instanceOf(final Class<T> type, final Class<V> ofClass) {
  76.         if (container != null) {
  77.             T instance = null;            
  78.             try {
  79.                 instance = container.getComponent(type);
  80.             } catch (AmbiguousComponentResolutionException e) {
  81.                 instance = container.getComponent(ofClass);
  82.             }
  83.             if (instance != null) {
  84.                 return instance;
  85.             }
  86.         }
  87.         return super.instanceOf(type, ofClass);
  88.     }

  89.     @SuppressWarnings("unchecked")
  90.     protected PicoContainer createPicoContainer(List<PicoModule> modules) {
  91.         if (container != null) {
  92.             return container;
  93.         }
  94.         @SuppressWarnings("rawtypes")
  95.         Class containerClass = annotationFinder().getAnnotatedValue(UsingPico.class, Class.class, "container");
  96.         MutablePicoContainer container = instanceOf(MutablePicoContainer.class, containerClass);
  97.         for (PicoModule module : modules) {
  98.             module.configure(container);
  99.         }
  100.         return container;
  101.     }

  102.     protected PicoContainer picoContainer() {
  103.         return container;
  104.     }

  105. }