GroovyContext.java
package org.jbehave.core.configuration.groovy;
import static java.text.MessageFormat.format;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
public class GroovyContext {
private final GroovyClassLoader classLoader;
private final List<String> resources;
private List<Object> instances;
public GroovyContext() {
this(new GroovyResourceFinder());
}
public GroovyContext(GroovyResourceFinder resourceFinder) {
this(resourceFinder.findResources());
}
public GroovyContext(List<String> resources) {
this(new BytecodeGroovyClassLoader(), resources);
}
public GroovyContext(GroovyClassLoader classLoader, GroovyResourceFinder resourceFinder) {
this(classLoader, resourceFinder.findResources());
}
public GroovyContext(GroovyClassLoader classLoader, List<String> resources) {
this.classLoader = classLoader;
this.resources = resources;
this.instances = createGroovyInstances();
}
public List<Object> getInstances() {
return instances;
}
@SuppressWarnings("unchecked")
public <T> T getInstanceOfType(Class<T> type) {
for (Object instance : instances) {
if (type.isAssignableFrom(instance.getClass())) {
return (T) instance;
}
}
throw new GroovyInstanceNotFound(type);
}
/**
* Creates an object instance from the Groovy resource
*
* @param resource the Groovy resource to parse
* @return An Object instance
*/
public Object newInstance(String resource) {
try {
String name = resource.startsWith("/") ? resource : "/" + resource;
File file = new File(this.getClass().getResource(name).toURI());
return newInstance(classLoader.parseClass(new GroovyCodeSource(file), true));
} catch (Exception e) {
throw new GroovyClassInstantiationFailed(classLoader, resource, e);
}
}
/**
* Creates an instance from the parsed Groovy class. This method can be
* overriden to do some dependency injection on Groovy classes.
*
* @param parsedClass the parsed Class to instantiate
* @return An Object instance of the parsed Class
* @throws Exception if instantiation or injection fails
*/
public Object newInstance(Class<?> parsedClass) throws Exception {
return parsedClass.newInstance();
}
private List<Object> createGroovyInstances() {
List<Object> instances = new ArrayList<>();
for (String resource : resources) {
instances.add(newInstance(resource));
}
return instances;
}
@SuppressWarnings("serial")
public static final class GroovyClassInstantiationFailed extends RuntimeException {
public GroovyClassInstantiationFailed(GroovyClassLoader classLoader, String resource, Exception cause) {
super(format("Failed to create new instance of class from resource {0} using Groovy class loader {1}",
resource, classLoader), cause);
}
}
@SuppressWarnings("serial")
public static final class GroovyInstanceNotFound extends RuntimeException {
public GroovyInstanceNotFound(Class<?> type) {
super(type.toString());
}
}
}