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 }