Skip to content

Commit

Permalink
Resolved cucumber#241
Browse files Browse the repository at this point in the history
Removed child spring context and implemented custom scope for glue code.
cucumber-glue.xml is internal now. All context configuration may be done in cucumber.xml
  • Loading branch information
vladimirkl authored and hutchy2570 committed Mar 21, 2012
1 parent 0825e59 commit 5afbb92
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cucumber.runtime.java.spring;

import java.util.HashMap;
import java.util.Map;

public class GlueCodeContext {
public static final GlueCodeContext INSTANCE = new GlueCodeContext();
private final Map<String, Object> objects = new HashMap<String, Object>();
private final Map<String, Runnable> callbacks = new HashMap<String, Runnable>();
private int counter;

private GlueCodeContext() {
}

public void start () {
cleanUp();
counter++;
}

public String getCounter() {
return "cucumber_glue_"+ counter;
}

public void stop() {
for (Runnable callback : callbacks.values()) {
callback.run();
}
cleanUp();
}

public Object get(String name){
return objects.get(name);
}

public void put(String name, Object object){
objects.put(name, object);
}

public Object remove (String name){
callbacks.remove(name);
return objects.remove(name);
}



private void cleanUp() {
objects.clear();
callbacks.clear();
}


public void registerDestructionCallback(String name, Runnable callback) {
callbacks.put(name, callback);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cucumber.runtime.java.spring;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

public class GlueCodeScope implements Scope {
public static final String NAME = "cucumber-glue";

private final GlueCodeContext context = GlueCodeContext.INSTANCE;

@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Object obj = context.get(name);
if (obj == null) {
obj = objectFactory.getObject();
context.put(name, obj);
}

return obj;
}

@Override
public Object remove(String name) {
return context.remove(name);
}

@Override
public void registerDestructionCallback(String name, Runnable callback) {
context.registerDestructionCallback(name, callback);
}

@Override
public Object resolveContextualObject(String key) {
return null;
}

@Override
public String getConversationId() {
return context.getCounter();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

/**
* Spring based implementation of ObjectFactory.
Expand All @@ -33,50 +33,46 @@ public class SpringFactory implements ObjectFactory {

private static AbstractApplicationContext applicationContext;

private ClassPathXmlApplicationContext stepContext;
private final Collection<Class<?>> stepClasses = new ArrayList<Class<?>>();
private final Collection<Class<?>> stepClasses = new HashSet<Class<?>> ();

public SpringFactory() {
}

static {
applicationContext = new ClassPathXmlApplicationContext(new String[]{"cucumber.xml"});
applicationContext = new ClassPathXmlApplicationContext(
"cucumber/runtime/java/spring/cucumber-glue.xml",
"cucumber.xml");
applicationContext.registerShutdownHook();
}

@Override
public void addClass(final Class<?> clazz) {
stepClasses.add(clazz);

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();
for (Class<?> stepClass : stepClasses) {
registry.registerBeanDefinition(stepClass.getName(),
BeanDefinitionBuilder.genericBeanDefinition(stepClass)
.setScope(GlueCodeScope.NAME)
.getBeanDefinition());
}
}

@Override
public void createInstances() {
createNewStepContext();
populateStepContext();
}

private void createNewStepContext() {
stepContext = new ClassPathXmlApplicationContext(new String[]{"classpath*:cucumber-glue.xml"},
applicationContext);
}

private void populateStepContext() {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) stepContext.getAutowireCapableBeanFactory();
for (Class<?> stepClass : stepClasses) {
registry.registerBeanDefinition(stepClass.getName(),
BeanDefinitionBuilder.genericBeanDefinition(stepClass).getBeanDefinition());
}
GlueCodeContext.INSTANCE.start();
}

@Override
public void disposeInstances() {
stepContext.close();
GlueCodeContext.INSTANCE.stop();
}

@SuppressWarnings("unchecked")
@Override
public <T> T getInstance(final Class<T> type) {
try {
return stepContext.getBean(type);
return applicationContext.getBean(type);
} catch (NoSuchBeanDefinitionException exception) {
throw new CucumberException(exception.getMessage(), exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,16 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="glueCodeScope" class="cucumber.runtime.java.spring.GlueCodeScope">
</bean>

<bean id="customScopeConfigurer" class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="cucumber-glue" value-ref="glueCodeScope"/>
</map>
</property>
</bean>
<context:annotation-config/>

</beans>
9 changes: 9 additions & 0 deletions spring/src/test/resources/applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,13 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="bellyBean" class="cucumber.runtime.java.spring.BellyBean"/>

<bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<props>
<prop key="cukes.test.property">property value</prop>
</props>
</property>
</bean>

</beans>
13 changes: 0 additions & 13 deletions spring/src/test/resources/cucumber-glue.xml

This file was deleted.

0 comments on commit 5afbb92

Please sign in to comment.