001 package org.shiftone.jrat.inject.bytecode.asm;
002
003
004 import org.objectweb.asm.ClassReader;
005 import org.objectweb.asm.ClassVisitor;
006 import org.objectweb.asm.ClassWriter;
007 import org.objectweb.asm.commons.SerialVersionUIDAdder;
008 import org.shiftone.jrat.inject.bytecode.InjectorStrategy;
009 import org.shiftone.jrat.inject.bytecode.TransformerOptions;
010
011
012 public class AsmInjectorStrategy implements InjectorStrategy {
013
014 public byte[] inject(byte[] rawClassData, TransformerOptions options) throws Exception {
015
016 ClassReader reader = new ClassReader(rawClassData);
017 ClassWriter classWriter = new ClassWriter(true);
018 ClassVisitor target = classWriter;
019
020 // target = new DebugClassVisitor(target);
021 ClassInitClassVisitor classInitClassVisitor = new ClassInitClassVisitor(target);
022 SerialVersionUIDAdder serialVersionUIDAdder = new SerialVersionUIDAdder(classInitClassVisitor);
023 InjectClassVisitor injectClassVisitor = new InjectClassVisitor(serialVersionUIDAdder);
024 MethodCriteriaClassVisitor criteriaClassVisitor = new MethodCriteriaClassVisitor(injectClassVisitor,
025 serialVersionUIDAdder);
026 ClassVisitor visitor = new IfInterfaceClassVisitor(target, criteriaClassVisitor);
027
028 criteriaClassVisitor.setCriteria(options.getCriteria());
029
030 // * IfInterfaceClassVisitor delegates to either ClassWriter or
031 // InjectClassVisitor
032 // this causes interface classes to be skipped (not be processed)
033 // * InjectClassVisitor will column a proxy method for each method in
034 // the class
035 // it also adds a "jrat static init" method
036 // * SerialVersionUIDAdder will add a serialVersionUID method if it is
037 // missing
038 // most likely this will cause a static initializer to be added
039 // * ClassInitClassVisitor will add to the static initializer or add on
040 // the result is the class will have one that calls the jrat static init
041 // method
042 reader.accept(visitor, false);
043
044 return classWriter.toByteArray();
045 }
046
047
048 public String toString() {
049 return "ASM";
050 }
051 }