All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cucumber.runtime.java.needle.NeedleFactory Maven / Gradle / Ivy

There is a newer version: 6.11.0
Show newest version
package cucumber.runtime.java.needle;

import cucumber.api.java.ObjectFactory;
import cucumber.runtime.java.needle.config.CollectInjectionProvidersFromStepsInstance;
import cucumber.runtime.java.needle.config.CreateInstanceByDefaultConstructor;
import cucumber.runtime.java.needle.config.CucumberNeedleConfiguration;
import de.akquinet.jbosscc.needle.NeedleTestcase;
import de.akquinet.jbosscc.needle.injection.InjectionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.Map;

import static cucumber.runtime.java.needle.config.CucumberNeedleConfiguration.RESOURCE_CUCUMBER_NEEDLE;
import static java.lang.String.format;

/**
 * Needle factory for object resolution inside of cucumber tests.
 */
public class NeedleFactory extends NeedleTestcase implements ObjectFactory {

    private final Map, Object> cachedStepsInstances = new LinkedHashMap, Object>();
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final CreateInstanceByDefaultConstructor createInstanceByDefaultConstructor = CreateInstanceByDefaultConstructor.INSTANCE;
    private final CollectInjectionProvidersFromStepsInstance collectInjectionProvidersFromStepsInstance = CollectInjectionProvidersFromStepsInstance.INSTANCE;

    public NeedleFactory() {
        super(setUpInjectionProviders(RESOURCE_CUCUMBER_NEEDLE));
    }

    @Override
    public  T getInstance(final Class type) {
        logger.trace("getInstance: " + type.getCanonicalName());
        assertTypeHasBeenAdded(type);
        return nullSafeGetInstance(type);
    }

    @Override
    public void start() {
        logger.trace("start()");
        try {
            // First create all instances
            for (final Class stepDefinitionType : cachedStepsInstances.keySet()) {
                cachedStepsInstances.put(stepDefinitionType, createStepsInstance(stepDefinitionType));
            }
            // Then collect injection providers from all instances
            for (Object stepsInstance : cachedStepsInstances.values()) {
                addInjectionProvider(collectInjectionProvidersFromStepsInstance.apply(stepsInstance));
            }
            // Now init all instances, having the injection providers from all other instances available
            for (Object stepsInstance : cachedStepsInstances.values()) {
                initTestcase(stepsInstance);
            }
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public void stop() {
        logger.trace("stop()");
        for (final Class stepDefinitionType : cachedStepsInstances.keySet()) {
            cachedStepsInstances.put(stepDefinitionType, null);
        }
    }

    @Override
    public boolean addClass(final Class type) {
        logger.trace("addClass(): " + type.getCanonicalName());

        // build up cache keys ...
        if (!cachedStepsInstances.containsKey(type)) {
            cachedStepsInstances.put(type, null);
        }
        return true;
    }

    private void assertTypeHasBeenAdded(final Class type) {
        if (!cachedStepsInstances.containsKey(type)) {
            throw new IllegalStateException(format("%s was not added during addClass()", type.getSimpleName()));
        }
    }

    @SuppressWarnings("unchecked")
    private  T nullSafeGetInstance(final Class type) {
        final Object instance = cachedStepsInstances.get(type);
        if (instance == null) {
            throw new IllegalStateException(format("instance of type %s has not been initialized in start()!",
                type.getSimpleName()));
        }
        return (T) instance;
    }

    private  T createStepsInstance(final Class type) throws Exception {
        logger.trace("createInstance(): " + type.getCanonicalName());
        return createInstanceByDefaultConstructor.apply(type);
    }

    static InjectionProvider[] setUpInjectionProviders(final String resourceName) {
        return new CucumberNeedleConfiguration(resourceName).getInjectionProviders();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy