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 }