package cuke4duke.internal.jvmclass; import com.google.inject.*; import cuke4duke.StepMother; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.lang.reflect.Modifier; public class GuiceFactory implements ObjectFactory { private static final String CONFIG_GUICE_MODULE = "cuke4duke.guiceModule"; private final List<Module> modules = new ArrayList<Module>(); private final List<Class<?>> classes = new ArrayList<Class<?>>(); private final Map<Class<?>, Object> instances = new HashMap<Class<?>, Object>(); public GuiceFactory() throws Throwable { this(System.getProperty(CONFIG_GUICE_MODULE, null)); } public GuiceFactory(String moduleClassName) throws Throwable { modules.add((Module) Class.forName(moduleClassName).newInstance()); } public boolean canHandle(Class<?> clazz) { return Modifier.isStatic(clazz.getModifiers()) || clazz.getEnclosingClass() == null; } public void addClass(Class<?> clazz) { classes.add(clazz); } public void addStepMother(StepMother stepMother) { modules.add(new StepMotherModule(stepMother)); } public void createObjects() { Injector injector = Guice.createInjector(modules); for (Class<?> clazz : classes) { try { instances.put(clazz, injector.getInstance(clazz)); } catch (ConfigurationException e) { System.err.println("WARNING: Cuke4Duke/Guice could not create instance for " + clazz.getCanonicalName() + ":\n" + e.getLocalizedMessage()); } } } public void disposeObjects() { instances.clear(); } @SuppressWarnings("unchecked") public <T> T getComponent(Class<T> clazz) { return (T) instances.get(clazz); } public List<Class<?>> getClasses() { return classes; } class StepMotherModule extends AbstractModule { private Provider<? extends StepMother> stepMotherProvider; public StepMotherModule(StepMother stepMother) { stepMotherProvider = new StepMotherProvider(stepMother); } @Override protected void configure() { bind(StepMother.class).toProvider(stepMotherProvider); } } class StepMotherProvider implements Provider<StepMother> { private StepMother stepMother; public StepMotherProvider(StepMother stepMother) { this.stepMother = stepMother; } public StepMother get() { return stepMother; } } }