001 package org.shiftone.jrat.inject.bytecode.asm; 002 003 004 import org.objectweb.asm.ClassAdapter; 005 import org.objectweb.asm.ClassVisitor; 006 import org.objectweb.asm.MethodVisitor; 007 import org.objectweb.asm.Opcodes; 008 import org.shiftone.jrat.inject.bytecode.Modifier; 009 import org.shiftone.jrat.util.log.Logger; 010 011 012 /** 013 * @author jeff@shiftone.org (Jeff Drost) 014 */ 015 public class ClassInitClassVisitor extends ClassAdapter implements Constants, Opcodes { 016 017 private static final Logger LOG = Logger.getLogger(ClassInitClassVisitor.class); 018 private boolean clinitVisited = false; 019 private String className; 020 021 public ClassInitClassVisitor(final ClassVisitor cv) { 022 super(cv); 023 } 024 025 026 public void visit(final int version, final int access, final String name, final String signature, 027 final String superName, final String[] interfaces) { 028 029 clinitVisited = false; 030 className = name; 031 032 super.visit(version, access, name, signature, superName, interfaces); 033 } 034 035 036 public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, 037 final String[] exceptions) { 038 039 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions); 040 041 if (classInitName.equals(name)) { 042 clinitVisited = true; 043 visitor = new ClassInitMethodVisitor(className, visitor); 044 } 045 046 return visitor; 047 } 048 049 050 public void visitEnd() { 051 052 if (!clinitVisited) { 053 054 // LOG.info("adding new <clinit> method to " + className); 055 MethodVisitor clinit = visitMethod(Modifier.PRIVATE_STATIC, classInitName, classInitDesc, null, null); 056 057 clinit.visitCode(); 058 clinit.visitInsn(RETURN); 059 clinit.visitEnd(); 060 } else { 061 062 // LOG.info("class already had <clinit> method " + className); 063 } 064 065 super.visitEnd(); 066 } 067 }