Package org.codehaus.aspectwerkz.annotation.instrumentation.asm

Source Code of org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper$NullCodeVisitor

/**************************************************************************************

* Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved.                 *

* http://aspectwerkz.codehaus.org                                                    *

* ---------------------------------------------------------------------------------- *

* The software in this package is published under the terms of the LGPL license      *

* a copy of which has been included with this distribution in the license.txt file.  *

**************************************************************************************/

package org.codehaus.aspectwerkz.annotation.instrumentation.asm;



import org.objectweb.asm.ClassVisitor;

import org.objectweb.asm.Attribute;

import org.objectweb.asm.CodeVisitor;

import org.objectweb.asm.Label;

import org.objectweb.asm.attrs.RuntimeInvisibleAnnotations;

import org.objectweb.asm.attrs.Annotation;

import org.objectweb.asm.attrs.RuntimeVisibleAnnotations;

import org.codehaus.aspectwerkz.annotation.AnnotationInfo;

import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;



import java.util.List;

import java.util.Iterator;



/**

* Helper visitor to extract Annotations.

* The visitors are not writing any bytecode and using a Null ClassVisitor / Code Visitor as a target instead.

*

* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>

*/

public class AsmAnnotationHelper {



    private final static String INIT_METHOD_NAME = "<init>";



    public final static ClassVisitor NULL_CLASS_VISITOR = new NullClassVisitor();



    public static final Attribute[] ANNOTATIONS_ATTRIBUTES = new Attribute[]{

        new RuntimeInvisibleAnnotations(),

        new RuntimeVisibleAnnotations()

    };



    /**

     * Generic extractor

     */

    private static class AnnotationExtractor extends NullClassVisitor {



        /**

         * The list where encountered annotation will be put

         */

        protected List m_annotations;



        /**

         * This classloader will be used to instantiate the proxy instance for Custom Annotation support (1.3/1.4).

         * See CustomAttribute that wraps in a RuntimeInvisibleAnnotation the user custom annotations.

         * <br/>Note: no weak reference is used since the visitor is created for a one shot usage.

         */

        protected ClassLoader m_loader;



        /**

         * Generic extractor

         *

         * @param annotations list where to put annotations

         * @param loader classLoader used to instantiate proxy of custom annotations

         */

        private AnnotationExtractor(List annotations, final ClassLoader loader) {

            m_annotations = annotations;

            m_loader = loader;

        }

    }



    /**

     * Extracts class level annotations

     */

    public static class ClassAnnotationExtractor extends AnnotationExtractor {



        public ClassAnnotationExtractor(List annotations, final ClassLoader loader) {

            super(annotations, loader);

        }



        public void visitAttribute(final Attribute attribute) {

            m_annotations = extractAnnotations(m_annotations, attribute, m_loader);

            super.visitAttribute(attribute);

        }

    }



    /**

     * Generic extractor for member (ctor, method, field) annotations extraction

     */

    private static class MemberAnnotationExtractor extends AnnotationExtractor {



        /**

         * Member name (method name, "<init>", field name

         */

        protected String m_name;



        /**

         * Member descriptor (as in visitMethod/visitField ASM methods)

         */

        protected String m_desc;



        /**

         * Method annotation extractor

         * @param annotations

         * @param name of the member for which we want the annotations

         * @param desc of the member for which we want the annotations

         * @param loader

         */

        private MemberAnnotationExtractor(List annotations, String name, String desc, final ClassLoader loader) {

            super(annotations, loader);

            m_name = name;

            m_desc = desc;

        }

    }



    /**

     * Method annotations extractor

     */

    public static class MethodAnnotationExtractor extends MemberAnnotationExtractor {



        public MethodAnnotationExtractor(List annotations, String name, String desc, final ClassLoader loader) {

            super(annotations, name, desc, loader);

        }



        public CodeVisitor visitMethod(final int access,

                                       final String name,

                                       final String desc,

                                       final String[] exceptions,

                                       final Attribute attrs) {

            if (name.equals(m_name) && desc.equals(m_desc)) {

                m_annotations = extractAnnotations(m_annotations, attrs, m_loader);

            }

            return super.visitMethod(access, name, desc, exceptions, attrs);

        }

    }



    /**

     * Constructor annotations extractor

     */

    public static class ConstructorAnnotationExtractor extends MethodAnnotationExtractor {



        public ConstructorAnnotationExtractor(List annotations, String desc, final ClassLoader loader) {

            super(annotations, INIT_METHOD_NAME, desc, loader);

        }

    }



    /**

     * Field annotations extractor

     */

    public static class FieldAnnotationExtractor extends MemberAnnotationExtractor {



        public FieldAnnotationExtractor(List annotations, String name, final ClassLoader loader) {

            super(annotations, name, null, loader);

        }



        public void visitField (final int access,

          final String name,

          final String desc,

          final Object value,

          final Attribute attrs) {

            // no match on desc

            if (name.equals(m_name)) {

                m_annotations = extractAnnotations(m_annotations, attrs, m_loader);

            }

            super.visitField(access, name, desc, value, attrs);

        }

    }



    /**

     * A NullClassVisitor that does nothing.

     * Can be used to speed up ASM and avoid unecessary bytecode writing thru a regular ClassWriter when this is not

     * needed (read only purpose).

     */

    private static class NullClassVisitor implements ClassVisitor {



        public void visit(int i, int i1, String s, String s1, String[] strings, String s2) {

        }



        public void visitInnerClass(String s, String s1, String s2, int i) {

        }



        public void visitField(int i, String s, String s1, Object o, Attribute attribute) {

        }



        public CodeVisitor visitMethod(int i, String s, String s1, String[] strings, Attribute attribute) {

            return NullCodeVisitor.NULL_CODE_VISITOR;

        }



        public void visitAttribute(Attribute attribute) {

        }



        public void visitEnd() {

        }

    }



    /**

     * A NullCodeVisitor that does nothing.

     * Can be used to speed up ASM and avoid unecessary bytecode writing thru a regular CodeWriter when this is not

     * needed (read only purpose)

     */

    private static class NullCodeVisitor implements CodeVisitor {



        private final static CodeVisitor NULL_CODE_VISITOR = new NullCodeVisitor();



        public void visitInsn(int opcode) {

        }



        public void visitIntInsn(int opcode, int operand) {

        }



        public void visitVarInsn(int opcode, int var) {

        }



        public void visitTypeInsn(int opcode, String desc) {

        }



        public void visitFieldInsn(int opcode, String owner, String name, String desc) {

        }



        public void visitMethodInsn(int opcode, String owner, String name, String desc) {

        }



        public void visitJumpInsn(int opcode, Label label) {

        }



        public void visitLabel(Label label) {

        }



        public void visitLdcInsn(Object cst) {

        }



        public void visitIincInsn(int var, int increment) {

        }



        public void visitTableSwitchInsn(int min, int max, Label dflt, Label labels[]) {

        }



        public void visitLookupSwitchInsn(Label dflt, int keys[], Label labels[]) {

        }



        public void visitMultiANewArrayInsn(String desc, int dims) {

        }



        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {

        }



        public void visitMaxs(int maxStack, int maxLocals) {

        }



        public void visitLocalVariable(String name, String desc, Label start, Label end, int index) {

        }



        public void visitLineNumber(int line, Label start) {

        }



        public void visitAttribute(Attribute attr) {

        }

    }



    /**

     * Helper method to extract Runtime(In)VisibleAnnotations and unwrap custom annotation proxies

     *

     * @param annotations

     * @param attribute

     * @param loader

     * @return annotations list populated

     */

    public static List extractAnnotations(List annotations, final Attribute attribute, final ClassLoader loader) {

        for (Attribute current = attribute; current != null; current = current.next) {

            if (current instanceof RuntimeInvisibleAnnotations) {

                for (Iterator it = ((RuntimeInvisibleAnnotations) current).annotations.iterator(); it.hasNext();) {

                    Annotation annotation = (Annotation) it.next();

                    if (CustomAttribute.TYPE.equals(annotation.type)) {

                        annotations.add(CustomAttributeHelper.extractCustomAnnotation(annotation));

                    } else {

                        AnnotationInfo annotationInfo = AsmClassInfo.getAnnotationInfo(

                                annotation,

                                loader

                        );

                        annotations.add(annotationInfo);

                    }

                }

            } else if (current instanceof RuntimeVisibleAnnotations) {

                for (Iterator it = ((RuntimeVisibleAnnotations) current).annotations.iterator(); it.hasNext();) {

                    Annotation annotation = (Annotation) it.next();

                    AnnotationInfo annotationInfo = AsmClassInfo.getAnnotationInfo(

                            annotation,

                            loader

                    );

                    annotations.add(annotationInfo);

                }

            }

        }

        return annotations;

    }

}

TOP

Related Classes of org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper$NullCodeVisitor

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.