Coverage Report - org.jbehave.core.configuration.groovy.BytecodeGroovyClassLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
BytecodeGroovyClassLoader
87%
7/8
50%
1/2
1.4
BytecodeGroovyClassLoader$1
100%
2/2
N/A
1.4
BytecodeGroovyClassLoader$BytecodeClassCollector
100%
5/5
N/A
1.4
 
 1  
 package org.jbehave.core.configuration.groovy;
 2  
 
 3  
 import groovy.lang.GroovyClassLoader;
 4  
 import groovyjarjarasm.asm.ClassWriter;
 5  
 import org.codehaus.groovy.ast.ClassNode;
 6  
 import org.codehaus.groovy.control.CompilationUnit;
 7  
 import org.codehaus.groovy.control.SourceUnit;
 8  
 
 9  
 import java.io.ByteArrayInputStream;
 10  
 import java.io.InputStream;
 11  
 import java.security.AccessController;
 12  
 import java.security.PrivilegedAction;
 13  
 import java.util.HashMap;
 14  
 import java.util.Map;
 15  
 
 16  
 /**
 17  
  * Groovy does not cache the bytecode sequences for generated classes.
 18  
  * BytecodeReadingParanamer needs these to get paramater names from classes The
 19  
  * Groovy compiler does create the debug tables, and they are the same as the
 20  
  * ones made for a native Java class, so this derived GroovyClassLoader fills in
 21  
  * for the missing functionality from the base GroovyClassLoader.
 22  
  * 
 23  
  * Groovy allows a mechanism via a system property to force the dump of bytecode
 24  
  * to a (temp) directory, but caching the bytecode avoids having to clean up
 25  
  * temp directories after the run.
 26  
  */
 27  5
 public class BytecodeGroovyClassLoader extends GroovyClassLoader {
 28  
 
 29  5
     private Map<String, byte[]> classBytes = new HashMap<String, byte[]>();
 30  
 
 31  
     @Override
 32  
     public InputStream getResourceAsStream(String name) {
 33  1
         if (classBytes.containsKey(name)) {
 34  1
             return new ByteArrayInputStream(classBytes.get(name));
 35  
         }
 36  0
         return super.getResourceAsStream(name);
 37  
     }
 38  
 
 39  
     @Override
 40  
     protected ClassCollector createCollector(CompilationUnit unit, SourceUnit su) {
 41  
         // These six lines copied from Groovy itself, with the intention to
 42  
         // return a subclass
 43  12
         InnerLoader loader = AccessController.doPrivileged(new PrivilegedAction<InnerLoader>() {
 44  
             public InnerLoader run() {
 45  6
                 return new InnerLoader(BytecodeGroovyClassLoader.this);
 46  
             }
 47  
         });
 48  6
         return new BytecodeClassCollector(classBytes, loader, unit, su);
 49  
     }
 50  
 
 51  5
     public static class BytecodeClassCollector extends ClassCollector {
 52  
         private final Map<String, byte[]> classBytes;
 53  
 
 54  
         public BytecodeClassCollector(Map<String, byte[]> classBytes, InnerLoader loader, CompilationUnit unit,
 55  
                 SourceUnit su) {
 56  6
             super(loader, unit, su);
 57  6
             this.classBytes = classBytes;
 58  6
         }
 59  
 
 60  
         @Override
 61  
         protected Class<?> onClassNode(ClassWriter classWriter, ClassNode classNode) {
 62  6
             classBytes.put(classNode.getName() + ".class", classWriter.toByteArray());
 63  6
             return super.onClassNode(classWriter, classNode);
 64  
         }
 65  
     }
 66  
 
 67  
 }