Package org.ow2.easybeans.enhancer.lib

Source Code of org.ow2.easybeans.enhancer.lib.AnnotationRecorder

/**
* EasyBeans
* Copyright (C) 2009 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: AnnotationRecorder.java 5369 2010-02-24 14:58:19Z benoitf $
* --------------------------------------------------------------------------
*/

package org.ow2.easybeans.enhancer.lib;

import java.util.LinkedList;
import java.util.List;

import org.ow2.easybeans.asm.AnnotationVisitor;
import org.ow2.easybeans.asm.MethodVisitor;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
* This class is storing annotation information and is able to replay the data collected on a given method.
* @author Florent Benoit
*/
public class AnnotationRecorder implements AnnotationVisitor {

    /**
     * Logger.
     */
    private Log logger = LogFactory.getLog(AnnotationRecorder.class);

    /**
     * Name of this annotation.
     */
    private String name = null;

    /**
     * Desc of this annotation.
     */
    private String desc = null;

    /**
     * Annotation visible or not ?
     */
    private boolean visible = false;

    /**
     * List of primitive values.
     */
    private List<AnnotationPrimitiveValue> primitiveValues = null;

    /**
     * List of enumeration values.
     */
    private List<AnnotationEnumerationValue> enumerationValues = null;

    /**
     * List of nested annotations.
     */
    private List<AnnotationRecorder> nestedValues = null;

    /**
     * List of array of annotations.
     */
    private List<ArrayAnnotationRecorder> arrayValues = null;


    /**
     * Constructor for a given name/visible.
     * @param name the name of the annotation
     * @param visible true if annotation is visible
     */
    public AnnotationRecorder(final String name, final boolean visible) {
        this(name);
        this.visible = visible;
    }

    /**
     * Constructor for a given name/desc.
     * @param name the name of the annotation
     * @param desc the ASM desc value
     */
    public AnnotationRecorder(final String name, final String desc) {
        this(name);
        this.desc = desc;
    }


    /**
     * Default constructor.
     * @param name the given name
     */
    public AnnotationRecorder(final String name) {
        this.name = name;
        this.primitiveValues = new LinkedList<AnnotationPrimitiveValue>();
        this.enumerationValues = new LinkedList<AnnotationEnumerationValue>();
        this.nestedValues = new LinkedList<AnnotationRecorder>();
        this.arrayValues = new LinkedList<ArrayAnnotationRecorder>();
    }


    /**
     * Visits a primitive value of the annotation.
     *
     * @param name the value name.
     * @param value the actual value, whose type must be {@link Byte},
     *        {@link Boolean}, {@link Character}, {@link Short},
     *        {@link Integer}, {@link Long}, {@link Float}, {@link Double},
     *        {@link String} or {@link org.ow2.easybeans.asm.Type}. This value can also be an array
     *        of byte, boolean, short, char, int, long, float or double values
     *        (this is equivalent to using {@link #visitArray visitArray} and
     *        visiting each array element in turn, but is more convenient).
     */
    public void visit(final String name, final Object value) {
        this.primitiveValues.add(new AnnotationPrimitiveValue(name, value));
    }

    /**
     * Visits an enumeration value of the annotation.
     *
     * @param name the value name.
     * @param desc the class descriptor of the enumeration class.
     * @param value the actual enumeration value.
     */
    public void visitEnum(final String name, final String desc, final String value) {
        this.enumerationValues.add(new AnnotationEnumerationValue(name, desc, value));
    }

    /**
     * Visits a nested annotation value of the annotation.
     *
     * @param name the value name.
     * @param desc the class descriptor of the nested annotation class.
     * @return a visitor to visit the actual nested annotation value, or
     *         <tt>null</tt> if this visitor is not interested in visiting
     *         this nested annotation. <i>The nested annotation value must be
     *         fully visited before calling other methods on this annotation
     *         visitor</i>.
     */
    public AnnotationVisitor visitAnnotation(final String name, final String desc) {
        // Add a new recorder for this annotation
        AnnotationRecorder annotationRecorder = new AnnotationRecorder(name, desc);
        this.nestedValues.add(annotationRecorder);
        return annotationRecorder;
    }

    /**
     * Visits an array value of the annotation. Note that arrays of primitive
     * types (such as byte, boolean, short, char, int, long, float or double)
     * can be passed as value to {@link #visit visit}. This is what
     * {@link org.ow2.easybeans.asm.ClassReader} does.
     *
     * @param name the value name.
     * @return a visitor to visit the actual array value elements, or
     *         <tt>null</tt> if this visitor is not interested in visiting
     *         these values. The 'name' parameters passed to the methods of this
     *         visitor are ignored. <i>All the array values must be visited
     *         before calling other methods on this annotation visitor</i>.
     */
    public AnnotationVisitor visitArray(final String name) {
        ArrayAnnotationRecorder arrayAnnotationRecorder = new ArrayAnnotationRecorder(name);
        this.arrayValues.add(arrayAnnotationRecorder);
        return arrayAnnotationRecorder;
    }

    /**
     * Visits the end of the annotation.
     */
    public void visitEnd() {
        // do nothing
    }

    /**
     * Replay the value stored on the given method visitor.
     * @param methodVisitor the given visitor on which annotation are replayed.
     */
    public void replay(final MethodVisitor methodVisitor) {
        // Build a new annotation visitor for the given method
        AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation(this.name, this.visible);
        this.logger.debug("AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation({0}, {1});", this.name,
                Boolean.valueOf(this.visible));

        // Replay
        replayInner(annotationVisitor);

        // End of visit
        annotationVisitor.visitEnd();
        this.logger.debug("annotationVisitor.visitEnd();");
    }

    /**
     * Replay the value stored on the given annotation visitor.
     * @param annotationVisitor the given visitor on which annotation are replayed.
     */
    public void replay(final AnnotationVisitor annotationVisitor) {
        // Build a new inner annotation visitor
        AnnotationVisitor av = annotationVisitor.visitAnnotation(this.name, this.desc);
        this.logger.debug("AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation({0}, {1});", this.name, this.desc);

        // Replay
        replayInner(av);

        // End of visit
        av.visitEnd();
        this.logger.debug("annotationVisitor.visitEnd()");
    }

    /**
     * Common stuff shared by annotationvisitor/methodvisitor replay code.
     * @param annotationVisitor the given visited annotation visitor.
     */
    protected void replayInner(final AnnotationVisitor annotationVisitor) {
        // primitive values
        for (AnnotationPrimitiveValue primitiveValue : this.primitiveValues) {
            primitiveValue.visit(annotationVisitor);
        }

        // Enum values
        for (AnnotationEnumerationValue enumerationValue : this.enumerationValues) {
            enumerationValue.visit(annotationVisitor);
        }

        // Nested values
        for (AnnotationRecorder nestedAnnotation : this.nestedValues) {
            nestedAnnotation.replay(annotationVisitor);
        }

        // Array values
        for (ArrayAnnotationRecorder arrayAnnotationRecorder : this.arrayValues) {
            arrayAnnotationRecorder.replay(annotationVisitor);
        }
    }

    /**
     * @return the given name
     */
    public String getName() {
        return this.name;
    }

    /**
     * @return the visible status
     */
    public boolean getVisible() {
        return this.visible;
    }

    /**
     * @return logger.
     */
    public Log getLogger() {
        return this.logger;
    }
}
TOP

Related Classes of org.ow2.easybeans.enhancer.lib.AnnotationRecorder

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.