SpringAnnotationBuilder.java

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

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

  5. import org.jbehave.core.annotations.spring.UsingSpring;
  6. import org.jbehave.core.configuration.AnnotationBuilder;
  7. import org.jbehave.core.configuration.AnnotationFinder;
  8. import org.jbehave.core.configuration.AnnotationMonitor;
  9. import org.jbehave.core.configuration.AnnotationRequired;
  10. import org.jbehave.core.configuration.Configuration;
  11. import org.jbehave.core.io.ResourceLoader;
  12. import org.jbehave.core.model.TableTransformers;
  13. import org.jbehave.core.steps.CompositeStepsFactory;
  14. import org.jbehave.core.steps.InjectableStepsFactory;
  15. import org.jbehave.core.steps.ParameterConverters;
  16. import org.jbehave.core.steps.ParameterConverters.ParameterConverter;
  17. import org.jbehave.core.steps.spring.SpringApplicationContextFactory;
  18. import org.jbehave.core.steps.spring.SpringStepsFactory;
  19. import org.springframework.context.ApplicationContext;

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

  28.     private ApplicationContext context;

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

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

  35.     @Override
  36.     public Configuration buildConfiguration() throws AnnotationRequired {
  37.         if (annotationFinder().isAnnotationPresent(UsingSpring.class)) {
  38.             List<String> resources = annotationFinder()
  39.                     .getAnnotatedValues(UsingSpring.class, String.class, "resources");
  40.             if (resources.size() > 0) {
  41.                 try {
  42.                     context = createApplicationContext(annotatedClass().getClassLoader(), resources);
  43.                 } catch (Exception e) {
  44.                     annotationMonitor().elementCreationFailed(ApplicationContext.class, e);
  45.                     boolean ignoreContextFailure = annotationFinder().getAnnotatedValue(UsingSpring.class,
  46.                             boolean.class, "ignoreContextFailure");
  47.                     if (!ignoreContextFailure) {
  48.                         throw new InstantiationFailed(annotatedClass(), e);
  49.                     }
  50.                 }
  51.             }
  52.         } else {
  53.             annotationMonitor().annotationNotFound(UsingSpring.class, annotatedClass());
  54.         }
  55.         return super.buildConfiguration();
  56.     }

  57.     @Override
  58.     public InjectableStepsFactory buildStepsFactory(Configuration configuration) {
  59.         InjectableStepsFactory factoryUsingSteps = super.buildStepsFactory(configuration);
  60.         if (context != null) {
  61.             return new CompositeStepsFactory(new SpringStepsFactory(configuration, context), 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 (context != null) {
  70.             return converters.addConverters(getBeansOfType(context, ParameterConverter.class));
  71.         }
  72.         return converters;
  73.     }

  74.     private List<ParameterConverter> getBeansOfType(ApplicationContext context, Class<ParameterConverter> type) {
  75.         Map<String, ParameterConverter> beansOfType = context.getBeansOfType(type);
  76.         List<ParameterConverter> converters = new ArrayList<>();
  77.         for (ParameterConverter converter : beansOfType.values()) {
  78.             converters.add(converter);
  79.         }
  80.         return converters;
  81.     }

  82.     @Override
  83.     protected <T, V extends T> T instanceOf(Class<T> type, Class<V> ofClass) {
  84.         if (context != null) {
  85.             if (!type.equals(Object.class)) {
  86.                 if (context.getBeansOfType(type).size() > 0) {
  87.                     return context.getBeansOfType(type).values().iterator().next();
  88.                 }
  89.             } else {
  90.                 if (context.getBeansOfType(ofClass).size() > 0) {
  91.                     return context.getBeansOfType(ofClass).values().iterator().next();
  92.                 }
  93.             }
  94.         }
  95.         return super.instanceOf(type, ofClass);
  96.     }

  97.     protected ApplicationContext createApplicationContext(ClassLoader classLoader, List<String> resources) {
  98.         if (context != null) {
  99.             return context;
  100.         }
  101.         return new SpringApplicationContextFactory(classLoader, resources.toArray(new String[resources.size()]))
  102.                 .createApplicationContext();
  103.     }

  104.     protected ApplicationContext applicationContext() {
  105.         return context;
  106.     }

  107. }