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

io.cucumber.guice.GuiceFactory Maven / Gradle / Ivy

There is a newer version: 7.20.1
Show newest version
package io.cucumber.guice;

import com.google.inject.Injector;
import io.cucumber.core.backend.CucumberBackendException;
import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.core.options.CucumberProperties;
import io.cucumber.core.resource.ClasspathSupport;
import org.apiguardian.api.API;

import java.util.Collection;
import java.util.HashSet;

import static io.cucumber.guice.InjectorSourceFactory.createDefaultScenarioModuleInjectorSource;
import static io.cucumber.guice.InjectorSourceFactory.instantiateUserSpecifiedInjectorSource;
import static io.cucumber.guice.InjectorSourceFactory.loadInjectorSourceFromProperties;
import static java.lang.String.format;

/**
 * Guice implementation of the
 * io.cucumber.core.backend.ObjectFactory.
 */
@API(status = API.Status.STABLE)
public final class GuiceFactory implements ObjectFactory {

    private Injector injector;

    private final Collection> stepClasses = new HashSet<>();
    private final Class injectorSourceFromProperty;
    private Class withInjectorSource;
    private ScenarioScope scenarioScope;

    public GuiceFactory() {
        this.injectorSourceFromProperty = loadInjectorSourceFromProperties(CucumberProperties.create());
        // Eager init to allow for static binding prior to before all hooks
        if (this.injectorSourceFromProperty != null) {
            injector = instantiateUserSpecifiedInjectorSource(this.injectorSourceFromProperty).getInjector();
        }
    }

    @Override
    public boolean addClass(final Class stepClass) {
        if (stepClasses.contains(stepClass)) {
            return true;
        }
        if (injectorSourceFromProperty == null) {
            if (hasInjectorSource(stepClass)) {
                checkOnlyOneClassHasInjectorSource(stepClass);
                withInjectorSource = stepClass;
                // Eager init to allow for static binding prior to before all
                // hooks
                injector = instantiateUserSpecifiedInjectorSource(withInjectorSource).getInjector();
            }
        }
        stepClasses.add(stepClass);
        return true;
    }

    private boolean hasInjectorSource(Class stepClass) {
        return InjectorSource.class.isAssignableFrom(stepClass);
    }

    private void checkOnlyOneClassHasInjectorSource(Class stepClass) {
        if (withInjectorSource != null) {
            throw new CucumberBackendException(format("" +
                    "Glue class %1$s and %2$s are both implementing io.cucumber.guice.InjectorSource.\n" +
                    "Please ensure only one class configures the Guice context\n" +
                    "\n" +
                    "By default Cucumber scans the entire classpath for context configuration.\n" +
                    "You can restrict this by configuring the glue path.\n" +
                    ClasspathSupport.configurationExamples(),
                stepClass,
                withInjectorSource));
        }
    }

    void setInjector(Injector injector) {
        this.injector = injector;
    }

    public void start() {
        // Last minute init. Neither properties not annotations provided an
        // injector source.
        if (injector == null) {
            injector = createDefaultScenarioModuleInjectorSource().getInjector();
        }
        scenarioScope = injector.getInstance(ScenarioScope.class);
        scenarioScope.enterScope();
    }

    public void stop() {
        if (scenarioScope != null) {
            scenarioScope.exitScope();
            scenarioScope = null;
        }
    }

    public  T getInstance(Class clazz) {
        return injector.getInstance(clazz);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy