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.instrumentors.DoNotInstrument; 011 import edu.rice.cs.cunit.instrumentors.IInstrumentationStrategy; 012 import edu.rice.cs.cunit.util.Debug; 013 014 import java.util.ArrayList; 015 import java.util.List; 016 017 /** 018 * Decorator to execute several strategies at once. 019 * 020 * @author Mathias Ricken 021 */ 022 public class CompoundStrategy implements IInstrumentationStrategy, IScannerStrategy { 023 /** 024 * Parameters for the instrumentors. 025 */ 026 List<String> _parameters; 027 028 /** 029 * Contained strategies. 030 */ 031 ArrayList<IInstrumentationStrategy> _combined = new ArrayList<IInstrumentationStrategy>(); 032 033 /** 034 * Constructor for an empty compound strategy. 035 * @param parameters parameters for the instrumentors 036 */ 037 public CompoundStrategy(List<String> parameters) { 038 _parameters = parameters; 039 } 040 041 /** 042 * Constructor for a compound strategy. 043 * @param parameters parameters for the instrumentors 044 * @param contained strategies to combine 045 */ 046 public CompoundStrategy(List<String> parameters, IInstrumentationStrategy[] contained) { 047 this(parameters); 048 for (IInstrumentationStrategy is: contained) { 049 _combined.add(is); 050 } 051 } 052 053 /** 054 * Returns the list of combined strategies. 055 * @return list of combined strategies. 056 */ 057 public List<IInstrumentationStrategy> getCombined() { 058 return _combined; 059 } 060 061 /** 062 * Instrument the class. 063 * 064 * @param cf class file info 065 */ 066 public void instrument(ClassFile cf) { 067 String[] doNotInstrumentPatterns = new String[0]; 068 AAttributeInfo attr = cf.getAttribute(RuntimeInvisibleAnnotationsAttributeInfo.getAttributeName()); 069 if (null!=attr) { 070 RuntimeInvisibleAnnotationsAttributeInfo ann = (RuntimeInvisibleAnnotationsAttributeInfo)attr; 071 for (AAnnotationsAttributeInfo.Annotation a: ann.getAnnotations()) { 072 String typeString = ClassFileTools.getTypeString(a.getType(), ""); 073 if (typeString.substring(0,typeString.length()-1).equals(DoNotInstrument.class.getName())) { 074 for (AAnnotationsAttributeInfo.Annotation.NameValuePair nvp: a.getPairs()) { 075 if (nvp.getName().toString().equals("instrumentors")) { 076 AAnnotationsAttributeInfo.Annotation.ConstantMemberValue c = nvp.getValue().execute( 077 AAnnotationsAttributeInfo.Annotation.CheckConstantMemberVisitor.singleton(), null); 078 AUTFPoolInfo patternString = c.getConstValue().execute(CheckUTFVisitor.singleton(), null); 079 doNotInstrumentPatterns = patternString.toString().split(";"); 080 break; 081 } 082 } 083 break; 084 } 085 } 086 } 087 // apply all instrumentors 088 for(IInstrumentationStrategy itor : _combined) { 089 if (!ClassFileTools.classNameMatches(itor.getClass().getName(),doNotInstrumentPatterns)) { 090 itor.instrument(cf); 091 } 092 else { 093 Debug.out.println("Class "+cf.getThisClassName()+" not instrumented with "+ 094 itor.getClass().getName()+" because it matched @DoNotInstrument instrumentors"); 095 } 096 } 097 } 098 099 /** 100 * Returns the combined list of all scan results. 101 * @return combined list of usage locations 102 */ 103 public List<IScanResult> getScanResults() { 104 List<IScanResult> results = new ArrayList<IScanResult>(); 105 for(IInstrumentationStrategy is: _combined) { 106 if (is instanceof IScannerStrategy) { 107 results.addAll(((IScannerStrategy)is).getScanResults()); 108 } 109 } 110 return results; 111 } 112 113 /** 114 * Instrumentation of all classes is done. 115 */ 116 public void done() { 117 // apply all instrumentors 118 for(IInstrumentationStrategy itor : _combined) { 119 itor.done(); 120 } 121 } 122 }