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    }