NeedleAnnotationBuilder.java
- package org.jbehave.core.configuration.needle;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
- import org.jbehave.core.annotations.UsingSteps;
- import org.jbehave.core.annotations.needle.UsingNeedle;
- import org.jbehave.core.configuration.AnnotationBuilder;
- import org.jbehave.core.configuration.AnnotationFinder;
- import org.jbehave.core.configuration.AnnotationMonitor;
- import org.jbehave.core.configuration.AnnotationRequired;
- import org.jbehave.core.configuration.Configuration;
- import org.jbehave.core.configuration.PrintStreamAnnotationMonitor;
- import org.jbehave.core.steps.InjectableStepsFactory;
- import org.jbehave.core.steps.needle.NeedleStepsFactory;
- import org.jbehave.core.steps.needle.configuration.CreateInstanceByDefaultConstructor;
- import org.needle4j.injection.InjectionProvider;
- import org.needle4j.injection.InjectionProviderInstancesSupplier;
- /**
- * Extends {@link AnnotationBuilder} to provide Needle-based dependency injection if {@link UsingNeedle} annotation is
- * present.
- *
- * @author Simon Zambrovski (simon.zambrovski@holisticon.de)
- * @author Jan Galinski (jan.galinski@holisticon.de)
- *
- */
- public class NeedleAnnotationBuilder extends AnnotationBuilder {
- private final Set<InjectionProvider<?>> provider = new HashSet<>();
- private final Set<Class<?>> stepsClasses = new HashSet<>();
- private NeedleStepsFactory factory;
- public NeedleAnnotationBuilder(Class<?> annotatedClass, AnnotationMonitor annotationMonitor) {
- super(annotatedClass, annotationMonitor);
- }
- public NeedleAnnotationBuilder(Class<?> annotatedClass) {
- this(annotatedClass, new PrintStreamAnnotationMonitor());
- }
- @Override
- public Configuration buildConfiguration() throws AnnotationRequired {
- final AnnotationFinder finder = annotationFinder();
- if (finder.isAnnotationPresent(UsingSteps.class)) {
- stepsClasses.addAll(finder.getAnnotatedClasses(UsingSteps.class, Object.class, "instances"));
- }
- if (finder.isAnnotationPresent(UsingNeedle.class)) {
- @SuppressWarnings("rawtypes")
- final List<Class> supplierClasses = finder.getAnnotatedValues(UsingNeedle.class, Class.class, "supplier");
- for (Class<InjectionProviderInstancesSupplier> supplierClass : supplierClasses) {
- provider.addAll(CreateInstanceByDefaultConstructor.INSTANCE.apply(supplierClass).get());
- }
- @SuppressWarnings("rawtypes")
- final List<Class> providerClasses = finder.getAnnotatedValues(UsingNeedle.class, Class.class, "provider");
- for (Class<InjectionProvider<?>> providerClass : providerClasses) {
- provider.add(CreateInstanceByDefaultConstructor.INSTANCE.apply(providerClass));
- }
- } else {
- annotationMonitor().annotationNotFound(UsingNeedle.class, annotatedClass());
- }
- return super.buildConfiguration();
- }
- @Override
- public InjectableStepsFactory buildStepsFactory(Configuration configuration) {
- this.factory = new NeedleStepsFactory(configuration, provider, stepsClasses.toArray(new Class<?>[stepsClasses
- .size()]));
- return factory;
- }
- @Override
- @SuppressWarnings("unchecked")
- protected <T, V extends T> T instanceOf(Class<T> type, Class<V> ofClass) {
- /*
- * This allow usage of the factory only after step factory is constructed. Current implementation only supports
- * creation injection into steps. Further improvement will be to provide a needle factory capable of creating
- * configuration parts.
- */
- if (factory != null) {
- return (T) factory.createInstanceOfType(ofClass);
- }
- return super.instanceOf(type, ofClass);
- }
- /**
- * Retrieves the set of injection providers.
- *
- * @return set of providers.
- */
- public Set<InjectionProvider<?>> getProvider() {
- return provider;
- }
- /**
- * Retrieve step classes.
- *
- * @return set of step classes.
- */
- public Set<Class<?>> getStepsClasses() {
- return stepsClasses;
- }
- }