1 26 27 package net.sourceforge.groboutils.codecoverage.v2.compiler; 28 29 import org.apache.bcel.classfile.JavaClass; 30 import org.apache.bcel.classfile.Method; 31 import org.apache.bcel.generic.InstructionList; 32 import org.apache.bcel.generic.MethodGen; 33 34 42 public class ModifiedMethod 43 { 44 private static final org.apache.log4j.Logger LOG = 45 org.apache.log4j.Logger.getLogger( ModifiedMethod.class ); 46 private JavaClass origClass; 47 private Method origMethod; 48 private MethodGen modMethGen; 49 private Method modMeth; 50 private boolean closed = false; 51 private ModifiedInstructionList modInstructions; 52 53 56 private int classSigPoolIndex; 57 58 61 private int staticMethodPoolIndex; 62 63 66 private long checksum; 67 68 71 private final short methodIndex; 72 73 77 ModifiedMethod( short methodIndex, int classSigPoolIndex, 78 int staticMethodPoolIndex, JavaClass origC, Method origM, 79 MethodGen mg ) 80 { 81 if (mg == null || origC == null || origM == null) 82 { 83 throw new IllegalArgumentException ("no null args"); 84 } 85 this.methodIndex = methodIndex; 86 this.classSigPoolIndex = classSigPoolIndex; 87 this.staticMethodPoolIndex = staticMethodPoolIndex; 88 89 this.modMethGen = mg; 90 this.origClass = origC; 91 this.origMethod = origM; 92 } 93 94 95 public short getMethodIndex() 96 { 97 return this.methodIndex; 98 } 99 100 101 public String getMethodName() 102 { 103 return this.origMethod.getName() + this.origMethod.getSignature(); 104 } 105 106 107 110 public ModifiedInstructionList getInstructionList() 111 { 112 checkClose(); 113 if (this.modInstructions == null && canAddMarks()) 114 { 115 createInstructionList(); 116 117 } 120 return this.modInstructions; 121 } 122 123 124 public JavaClass getOriginalClass() 125 { 126 return this.origClass; 127 } 128 129 130 public Method getOriginalMethod() 131 { 132 return this.origMethod; 133 } 134 135 136 141 public boolean canAddMarks() 142 { 143 return ModifiedClass.isMarkable( this.origMethod ); 144 } 145 146 147 149 150 153 MethodGen getModifiedMethodGen() 154 { 155 checkClose(); 156 return this.modMethGen; 157 } 158 159 160 163 Method getNewMethod() 164 { 165 if (!this.closed || this.modMeth == null) 166 { 167 throw new IllegalStateException ( 168 "ModifiedMethod has not been closed." ); 169 } 170 return this.modMeth; 171 } 172 173 174 void close() 175 { 176 checkClose(); 177 178 this.closed = true; 179 if (this.modInstructions != null) 180 { 181 LOG.debug( "Setting the modified instruction list." ); 182 this.modInstructions.updateInstructionList(); 183 this.modMethGen.setMaxLocals(); 184 this.modMethGen.setMaxStack(); 185 this.modMeth = this.modMethGen.getMethod(); 186 this.modInstructions.close(); 187 this.modInstructions = null; 188 189 195 this.modMethGen = null; 196 } 197 else 198 if (this.modMeth == null) 199 { 200 this.modMeth = this.modMethGen.getMethod(); 201 202 208 this.modMethGen = null; 209 } 210 } 211 212 213 215 216 220 private void createInstructionList() 221 { 222 InstructionList list = getModifiedMethodGen().getInstructionList(); 223 if (ModifiedInstructionList.isValidInstructionList( list )) 224 { 225 this.modInstructions = new ModifiedInstructionList( 226 this.methodIndex, this.classSigPoolIndex, 227 this.staticMethodPoolIndex, list, 228 new ModifiedTargeters( this.modMethGen ) ); 229 } 230 else 231 { 232 LOG.warn( "Instruction list for method ["+getMethodName()+ 233 "] in class ["+getOriginalClass().getClassName()+ 234 "] is invalid." ); 235 } 236 } 238 239 240 private void checkClose() 241 { 242 if (this.closed) 243 { 244 throw new IllegalStateException ("Method has been closed."); 245 } 246 } 247 } 248 249 | Popular Tags |