View Javadoc
1 /*** 2 * ClassLoader 3 * 4 * This is a superclass for all instrumenting class loaders. 5 */ 6 7 package junit.quilt.cover.generic; 8 9 import org.apache.commons.graph.Graph; 10 11 import org.apache.bcel.Constants; 12 13 import org.apache.bcel.generic.*; 14 import org.apache.bcel.classfile.*; 15 16 import java.lang.reflect.Field; 17 18 import java.net.URL; 19 import java.net.URLClassLoader; 20 import java.lang.ClassLoader; 21 22 import java.io.File; 23 import java.io.InputStream; 24 25 import java.util.Enumeration; 26 import java.util.Iterator; 27 import java.util.Map; 28 import java.util.HashMap; 29 import java.util.List; 30 import java.util.ArrayList; 31 32 public class QuiltClassLoader 33 extends URLClassLoader 34 { 35 private String packages[] = null; 36 37 publicQuiltClassLoader( String packages[],/index.html"> QuiltClassLoader( String packages[], 38 URL path[] ) { 39 super( path ); 40 this.packages = packages; 41 } 42 43 publicQuiltClassLoader( String packages[],/index.html"> QuiltClassLoader( String packages[], 44 URL path[], 45 ClassLoader parent ) { 46 super( path, parent ); 47 this.packages = packages; 48 } 49 50 private Map addedStaticFields = new HashMap(); 51 // CLASS X LIST( AddedStaticField ) 52 53 private Map loadedClasses = new HashMap(); 54 // CLASS_NAME X JAVA_CLASS 55 56 private static int lastField = 0; 57 58 /*** 59 * AddedStaticField 60 * 61 * This class just keeps the field name that was generated, 62 * and the data that is supposed to go in there together. 63 */ 64 private class AddedStaticField 65 { 66 public String fieldName = null; 67 public Object initData = null; 68 69 public AddedStaticField( String fieldName, 70 Object initData ) 71 { 72 this.fieldName = fieldName; 73 this.initData = initData; 74 } 75 } 76 77 /*** 78 * makeUniqueFieldName 79 * 80 * This method will create a unique field name for adding 81 * data to a class. 82 */ 83 private String makeUniqueFieldName() { 84 String RC = "junit_quilt_Field_" + lastField; 85 lastField++; 86 return RC; 87 } 88 89 /*** 90 * addStaticField 91 * 92 * This creates a unique static field on the class, and returns 93 * a field reference which is valid in the current ConstantPool. 94 * 95 * The name is autogenerated. 96 */ 97 protected int addStaticField( InstContext context, 98 Type type, 99 Object initData) 100 { 101 ClassGen clazz = context.getClassGen(); 102 ConstantPoolGen pool = context.getConstantPoolGen(); 103 104 String fieldName = makeUniqueFieldName(); 105 List fields = (List) addedStaticFields.get( clazz.getClassName() ); 106 if (fields == null) { 107 fields = new ArrayList(); 108 addedStaticFields.put( clazz.getClassName(), fields ); 109 } 110 111 fields.add( new AddedStaticField( fieldName, 112 initData )); 113 FieldGen field = 114 new FieldGen( Constants.ACC_PUBLIC | 115 Constants.ACC_STATIC, 116 type, 117 fieldName, 118 pool ); 119 clazz.addField( field.getField() ); 120 return pool.addFieldref( clazz.getClassName(), 121 fieldName, 122 type.getSignature()); 123 124 } 125 126 private boolean skip( String className ) { 127 for (int i = 0; i < packages.length; i++) { 128 if (className.startsWith( packages[i] )) 129 return false; 130 } 131 return true; 132 } 133 134 protected JavaClass modifyClass( JavaClass clazz ) { 135 return clazz; 136 } 137 138 private JavaClass makeJavaClass( String className ) 139 throws ClassNotFoundException 140 { 141 try { 142 String classFile = className.replace('.', File.separatorChar) 143 + ".class"; 144 URL bytecodeURL = getResource( classFile ); 145 InputStream bytecodeIS = bytecodeURL.openStream(); 146 147 return new ClassParser( bytecodeIS, className ).parse(); 148 } catch (Exception e) { 149 e.printStackTrace(); 150 throw new ClassNotFoundException( e.toString() ); 151 } 152 } 153 154 public Class findClass( String className ) 155 throws ClassNotFoundException 156 { 157 if (skip( className )) 158 return super.findClass( className ) ; 159 160 JavaClass clazz = null; 161 162 if (loadedClasses.containsKey( className )) { 163 clazz = (JavaClass) loadedClasses.get( className ); 164 } else { 165 clazz = makeJavaClass( className ); 166 clazz = modifyClass( clazz ); 167 } 168 169 byte bytecode[] = clazz.getBytes(); 170 Class RC = defineClass( className, 171 bytecode, 0, 172 bytecode.length); 173 174 if (addedStaticFields.containsKey( className )) { 175 Iterator addedFields = 176 ((List) addedStaticFields.get( className )).iterator(); 177 while (addedFields.hasNext()) { 178 AddedStaticField af = (AddedStaticField) addedFields.next(); 179 try { 180 java.lang.reflect.Field field = 181 RC.getField( af.fieldName ); 182 field.set( null, af.initData ); 183 } catch (Exception e) { 184 System.err.println("Warning: Field " + af.fieldName + 185 " not initialized."); 186 } 187 } 188 } 189 return RC; 190 } 191 // /*** 192 // * This loads the class specified by the Class Name. 193 // * 194 // * After it is loaded, it will initialize all of the static 195 // * values which have been added to the system by the instrumentors. 196 // */ 197 // public synchronized Class loadClass( String className ) 198 // throws ClassNotFoundException 199 // { 200 // addedStaticFields.put( className, new ArrayList() ); 201 202 // Class RC = super.loadClass( className ); 203 204 // try { 205 // List fields = (List) addedStaticFields.get( className ); 206 // if (fields != null) { 207 // Iterator f = fields.iterator(); 208 209 // while (f.hasNext()) { 210 // AddedStaticField asf = (AddedStaticField) f.next(); 211 // java.lang.reflect.Field field 212 // = RC.getField( asf.fieldName ); 213 // field.set( null, asf.initData ); 214 // } 215 // } 216 // } catch (Exception e) { 217 // System.err.println("Warning: Coverage fields not initialized."); 218 // System.err.println("Class: " + className ); 219 // e.printStackTrace(); 220 // } 221 222 // return RC; 223 // } 224 225 } 226 227 228 229 230 231 232 233 234 235 236

This page was automatically generated by Maven