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    }