Package com.onpositive.instrumentation.processors

Source Code of com.onpositive.instrumentation.processors.ClassProcessor

package com.onpositive.instrumentation.processors;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.GeneratorAdapter;

/**
*
* @author Pavel Petrochenko
*
*
*/
public class ClassProcessor {

  ArrayList participants = new ArrayList();

  public void addParticipant(ClassProcessingParticipant participant) {
    participants.add(participant);
  }

  public void removeParticipant(ClassProcessingParticipant participant) {
    participants.remove(participant);
  }

  public byte[] processClass(byte[] stream) throws IOException {
    ClassReader reader = new ClassReader(stream);
    ClassProcessingParticipant[] subjectOfInterest = isSubjectOfInterest(reader);
    if (subjectOfInterest != null) {
      return transform(reader, subjectOfInterest);
    }
    return null;
  }

  protected byte[] transform(final ClassReader reader,
      final ClassProcessingParticipant[] subjectOfInterest) {
    ClassWriter cv = new ClassWriter(ClassWriter.COMPUTE_FRAMES
        | ClassWriter.COMPUTE_MAXS);
    reader.accept(new ClassAdapter(cv) {

     
      public void visit(int version, int access, String name,
          String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces);
      }

     
      public FieldVisitor visitField(int access, String name,
          String desc, String signature, Object value) {
        for (int a = 0; a < subjectOfInterest.length; a++) {
          ClassProcessingParticipant p = subjectOfInterest[a];
          p.visitField(access,name,desc,signature,value);
        }
        return super.visitField(access, name, desc, signature, value);
      }

      public MethodVisitor visitMethod(int access, String name,
          String desc, String signature, String[] exceptions) {
        final ArrayList contributors = new ArrayList();
        MethodVisitor visitMethod = super.visitMethod(access, name,
            desc, signature, exceptions);
        GeneratorAdapter ma = new GeneratorAdapter(visitMethod, access,
            name, desc) {

          public AnnotationVisitor visitAnnotation(String desc,
              boolean visible) {

            return super.visitAnnotation(desc, visible);
          }

          public AnnotationVisitor visitAnnotationDefault() {
            return super.visitAnnotationDefault();
          }

          public void visitAttribute(Attribute attr) {
            super.visitAttribute(attr);
          }

          public void visitCode() {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitCode();
            }
            super.visitCode();
          }

          public void visitEnd() {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitEnd();
            }
            super.visitEnd();
          }

          public void visitFieldInsn(int opcode, String owner,
              String name, String desc) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitFieldInsn(opcode, owner, name, desc);
            }
            super.visitFieldInsn(opcode, owner, name, desc);
          }

          public void visitInsn(int opcode) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitInsn(opcode);
            }
            super.visitInsn(opcode);
          }

          public void visitIntInsn(int opcode, int operand) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitIntInsn(opcode, operand);
            }
            super.visitIntInsn(opcode, operand);
          }

          public void visitJumpInsn(int opcode, Label label) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitJumpInsn(opcode, label);
            }
            super.visitJumpInsn(opcode, label);
          }

          public void visitLabel(Label label) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitLabel(label);
            }
            super.visitLabel(label);
          }

          public void visitLdcInsn(Object cst) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitLdcInsn(cst);
            }
            super.visitLdcInsn(cst);
          }

          public void visitLookupSwitchInsn(Label dflt, int[] keys,
              Label[] labels) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitLookupSwitchInsn(dflt, keys, labels);
            }
            super.visitLookupSwitchInsn(dflt, keys, labels);
          }

          public void visitMethodInsn(int opcode, String owner,
              String name, String desc) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitMethodInsn(opcode, owner, name, desc);
            }
            super.visitMethodInsn(opcode, owner, name, desc);
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.afterVisitMethodInsn(opcode, owner, name, desc);
            }           
          }

          public void visitMultiANewArrayInsn(String desc, int dims) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitMultiANewArrayInsn(desc, dims);
            }
            super.visitMultiANewArrayInsn(desc, dims);
          }

          public AnnotationVisitor visitParameterAnnotation(
              int parameter, String desc, boolean visible) {
            return super.visitParameterAnnotation(parameter, desc,
                visible);
          }

          public void visitTableSwitchInsn(int min, int max,
              Label dflt, Label[] labels) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitTableSwitchInsn(min, max, dflt, labels);
            }
            super.visitTableSwitchInsn(min, max, dflt, labels);
          }

          public void visitTryCatchBlock(Label start, Label end,
              Label handler, String type) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitTryCatchBlock(start, end, handler, type);
            }
            super.visitTryCatchBlock(start, end, handler, type);
          }

          public void visitTypeInsn(int opcode, String type) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitTypeInsn(opcode, type);
            }
            super.visitTypeInsn(opcode, type);
          }

          public void visitLineNumber(int line, Label start) {
            int size = contributors.size();
            for (int a = 0; a < size; a++) {
              InstrumentationContributor c = (InstrumentationContributor) contributors
                  .get(a);
              c.visitLineNumber(line, start);
            }
            super.visitLineNumber(line, start);
          }

        };
        for (int a = 0; a < subjectOfInterest.length; a++) {
          ClassProcessingParticipant p = subjectOfInterest[a];
          InstrumentationContributor instrumentationContributor = p
              .getInstrumentationContributor(access, name, desc,
                  signature, exceptions, ma);
          if (instrumentationContributor != null) {
            instrumentationContributor.visitMethod(reader, name, desc);
            contributors.add(instrumentationContributor);
          }
        }
        return ma;
      }

    }, ClassReader.EXPAND_FRAMES);
    byte[] byteArray = cv.toByteArray();
    return byteArray;
  }

  protected ClassProcessingParticipant[] isSubjectOfInterest(
      ClassReader reader) {
    int size = participants.size();
    ArrayList result = null;
    for (int a = 0; a < size; a++) {
      ClassProcessingParticipant p = (ClassProcessingParticipant) participants
          .get(a);
      if (p.isInterestedIn(reader)) {
        if (result == null) {
          result = new ArrayList();
        }
        result.add(p);
      }
    }
    return (ClassProcessingParticipant[]) (result == null ? null : result
        .toArray(new ClassProcessingParticipant[result.size()]));
  }

 

}
TOP

Related Classes of com.onpositive.instrumentation.processors.ClassProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.