001 package edu.rice.cs.cunit.instrumentors.util; 002 003 import edu.rice.cs.cunit.classFile.ClassFile; 004 import edu.rice.cs.cunit.classFile.ClassFileTools; 005 import edu.rice.cs.cunit.classFile.attributes.AAnnotationsAttributeInfo; 006 import edu.rice.cs.cunit.classFile.attributes.AAttributeInfo; 007 import edu.rice.cs.cunit.classFile.attributes.RuntimeInvisibleAnnotationsAttributeInfo; 008 import edu.rice.cs.cunit.classFile.constantPool.AUTFPoolInfo; 009 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckUTFVisitor; 010 import edu.rice.cs.cunit.util.Debug; 011 import edu.rice.cs.cunit.instrumentors.IInstrumentationStrategy; 012 import edu.rice.cs.cunit.instrumentors.DoNotInstrument; 013 014 /** 015 * Decorator to conditionally execute a decorated strategy. 016 * 017 * @author Mathias Ricken 018 */ 019 public abstract class ConditionalStrategy implements IInstrumentationStrategy { 020 /** 021 * Decorated strategy; 022 */ 023 IInstrumentationStrategy _decoree; 024 025 public ConditionalStrategy(IInstrumentationStrategy decoree) { 026 _decoree = decoree; 027 } 028 029 /** 030 * Instrument the class. 031 * 032 * @param cf class file info 033 */ 034 public void instrument(ClassFile cf) { 035 String[] doNotInstrumentPatterns = new String[0]; 036 AAttributeInfo attr = cf.getAttribute(RuntimeInvisibleAnnotationsAttributeInfo.getAttributeName()); 037 if (null!=attr) { 038 RuntimeInvisibleAnnotationsAttributeInfo ann = (RuntimeInvisibleAnnotationsAttributeInfo)attr; 039 for (AAnnotationsAttributeInfo.Annotation a: ann.getAnnotations()) { 040 String typeString = ClassFileTools.getTypeString(a.getType(), ""); 041 if (typeString.substring(0,typeString.length()-1).equals(DoNotInstrument.class.getName())) { 042 for (AAnnotationsAttributeInfo.Annotation.NameValuePair nvp: a.getPairs()) { 043 if (nvp.getName().toString().equals("instrumentors")) { 044 AAnnotationsAttributeInfo.Annotation.ConstantMemberValue c = nvp.getValue().execute( 045 AAnnotationsAttributeInfo.Annotation.CheckConstantMemberVisitor.singleton(), null); 046 AUTFPoolInfo patternString = c.getConstValue().execute(CheckUTFVisitor.singleton(), null); 047 doNotInstrumentPatterns = patternString.toString().split(";"); 048 break; 049 } 050 } 051 break; 052 } 053 } 054 } 055 if (apply(cf)) { 056 if (!ClassFileTools.classNameMatches(_decoree.getClass().getName(),doNotInstrumentPatterns)) { 057 _decoree.instrument(cf); 058 } 059 else { 060 Debug.out.println("Class "+cf.getThisClassName()+" not instrumented with "+ 061 _decoree.getClass().getName()+" because it matched @DoNotInstrument instrumentors"); 062 } 063 } 064 } 065 066 /** 067 * Return true if the decoree should be applied to this class. 068 * 069 * @return true if decoree should be applied. 070 */ 071 public abstract boolean apply(ClassFile cf); 072 073 /** 074 * Instrumentation of all classes is done. 075 */ 076 public void done() { 077 _decoree.done(); 078 } 079 }