GroovyContext.java

  1. package org.jbehave.core.configuration.groovy;

  2. import static java.text.MessageFormat.format;

  3. import java.io.File;
  4. import java.util.ArrayList;
  5. import java.util.List;

  6. import groovy.lang.GroovyClassLoader;
  7. import groovy.lang.GroovyCodeSource;

  8. public class GroovyContext {

  9.     private final GroovyClassLoader classLoader;
  10.     private final List<String> resources;
  11.     private List<Object> instances;

  12.     public GroovyContext() {
  13.         this(new GroovyResourceFinder());
  14.     }

  15.     public GroovyContext(GroovyResourceFinder resourceFinder) {
  16.         this(resourceFinder.findResources());
  17.     }

  18.     public GroovyContext(List<String> resources) {
  19.         this(new BytecodeGroovyClassLoader(), resources);
  20.     }

  21.     public GroovyContext(GroovyClassLoader classLoader, GroovyResourceFinder resourceFinder) {
  22.         this(classLoader, resourceFinder.findResources());
  23.     }

  24.     public GroovyContext(GroovyClassLoader classLoader, List<String> resources) {
  25.         this.classLoader = classLoader;
  26.         this.resources = resources;
  27.         this.instances = createGroovyInstances();
  28.     }

  29.     public List<Object> getInstances() {
  30.         return instances;
  31.     }

  32.     @SuppressWarnings("unchecked")
  33.     public <T> T getInstanceOfType(Class<T> type) {
  34.         for (Object instance : instances) {
  35.             if (type.isAssignableFrom(instance.getClass())) {
  36.                 return (T) instance;
  37.             }
  38.         }
  39.         throw new GroovyInstanceNotFound(type);
  40.     }

  41.     /**
  42.      * Creates an object instance from the Groovy resource
  43.      *
  44.      * @param resource the Groovy resource to parse
  45.      * @return An Object instance
  46.      */
  47.     public Object newInstance(String resource) {
  48.         try {
  49.             String name = resource.startsWith("/") ? resource : "/" + resource;
  50.             File file = new File(this.getClass().getResource(name).toURI());
  51.             return newInstance(classLoader.parseClass(new GroovyCodeSource(file), true));
  52.         } catch (Exception e) {
  53.             throw new GroovyClassInstantiationFailed(classLoader, resource, e);
  54.         }
  55.     }

  56.     /**
  57.      * Creates an instance from the parsed Groovy class. This method can be
  58.      * overriden to do some dependency injection on Groovy classes.
  59.      *
  60.      * @param parsedClass the parsed Class to instantiate
  61.      * @return An Object instance of the parsed Class
  62.      * @throws Exception if instantiation or injection fails
  63.      */
  64.     public Object newInstance(Class<?> parsedClass) throws Exception {
  65.         return parsedClass.newInstance();
  66.     }

  67.     private List<Object> createGroovyInstances() {
  68.         List<Object> instances = new ArrayList<>();
  69.         for (String resource : resources) {
  70.             instances.add(newInstance(resource));
  71.         }
  72.         return instances;
  73.     }

  74.     @SuppressWarnings("serial")
  75.     public static final class GroovyClassInstantiationFailed extends RuntimeException {

  76.         public GroovyClassInstantiationFailed(GroovyClassLoader classLoader, String resource, Exception cause) {
  77.             super(format("Failed to create new instance of class from resource {0} using Groovy class loader {1}",
  78.                     resource, classLoader), cause);
  79.         }

  80.     }

  81.     @SuppressWarnings("serial")
  82.     public static final class GroovyInstanceNotFound extends RuntimeException {

  83.         public GroovyInstanceNotFound(Class<?> type) {
  84.             super(type.toString());
  85.         }

  86.     }

  87. }