001/***
002 * ASM: a very small and fast Java bytecode manipulation framework
003 * Copyright (c) 2000-2011 INRIA, France Telecom
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 * 1. Redistributions of source code must retain the above copyright
010 *    notice, this list of conditions and the following disclaimer.
011 * 2. Redistributions in binary form must reproduce the above copyright
012 *    notice, this list of conditions and the following disclaimer in the
013 *    documentation and/or other materials provided with the distribution.
014 * 3. Neither the name of the copyright holders nor the names of its
015 *    contributors may be used to endorse or promote products derived from
016 *    this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028 * THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.springframework.asm;
031
032/**
033 * A visitor to visit a Java annotation. The methods of this class must be
034 * called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> |
035 * <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>.
036 * 
037 * @author Eric Bruneton
038 * @author Eugene Kuleshov
039 */
040public abstract class AnnotationVisitor {
041
042    /**
043     * The ASM API version implemented by this visitor. The value of this field
044     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
045     */
046    protected final int api;
047
048    /**
049     * The annotation visitor to which this visitor must delegate method calls.
050     * May be null.
051     */
052    protected AnnotationVisitor av;
053
054    /**
055     * Constructs a new {@link AnnotationVisitor}.
056     * 
057     * @param api
058     *            the ASM API version implemented by this visitor. Must be one
059     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
060     */
061    public AnnotationVisitor(final int api) {
062        this(api, null);
063    }
064
065    /**
066     * Constructs a new {@link AnnotationVisitor}.
067     * 
068     * @param api
069     *            the ASM API version implemented by this visitor. Must be one
070     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
071     * @param av
072     *            the annotation visitor to which this visitor must delegate
073     *            method calls. May be null.
074     */
075    public AnnotationVisitor(final int api, final AnnotationVisitor av) {
076        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
077            throw new IllegalArgumentException();
078        }
079        this.api = api;
080        this.av = av;
081    }
082
083    /**
084     * Visits a primitive value of the annotation.
085     * 
086     * @param name
087     *            the value name.
088     * @param value
089     *            the actual value, whose type must be {@link Byte},
090     *            {@link Boolean}, {@link Character}, {@link Short},
091     *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
092     *            {@link String} or {@link Type} of OBJECT or ARRAY sort. This
093     *            value can also be an array of byte, boolean, short, char, int,
094     *            long, float or double values (this is equivalent to using
095     *            {@link #visitArray visitArray} and visiting each array element
096     *            in turn, but is more convenient).
097     */
098    public void visit(String name, Object value) {
099        if (av != null) {
100            av.visit(name, value);
101        }
102    }
103
104    /**
105     * Visits an enumeration value of the annotation.
106     * 
107     * @param name
108     *            the value name.
109     * @param desc
110     *            the class descriptor of the enumeration class.
111     * @param value
112     *            the actual enumeration value.
113     */
114    public void visitEnum(String name, String desc, String value) {
115        if (av != null) {
116            av.visitEnum(name, desc, value);
117        }
118    }
119
120    /**
121     * Visits a nested annotation value of the annotation.
122     * 
123     * @param name
124     *            the value name.
125     * @param desc
126     *            the class descriptor of the nested annotation class.
127     * @return a visitor to visit the actual nested annotation value, or
128     *         <tt>null</tt> if this visitor is not interested in visiting this
129     *         nested annotation. <i>The nested annotation value must be fully
130     *         visited before calling other methods on this annotation
131     *         visitor</i>.
132     */
133    public AnnotationVisitor visitAnnotation(String name, String desc) {
134        if (av != null) {
135            return av.visitAnnotation(name, desc);
136        }
137        return null;
138    }
139
140    /**
141     * Visits an array value of the annotation. Note that arrays of primitive
142     * types (such as byte, boolean, short, char, int, long, float or double)
143     * can be passed as value to {@link #visit visit}. This is what
144     * {@link ClassReader} does.
145     * 
146     * @param name
147     *            the value name.
148     * @return a visitor to visit the actual array value elements, or
149     *         <tt>null</tt> if this visitor is not interested in visiting these
150     *         values. The 'name' parameters passed to the methods of this
151     *         visitor are ignored. <i>All the array values must be visited
152     *         before calling other methods on this annotation visitor</i>.
153     */
154    public AnnotationVisitor visitArray(String name) {
155        if (av != null) {
156            return av.visitArray(name);
157        }
158        return null;
159    }
160
161    /**
162     * Visits the end of the annotation.
163     */
164    public void visitEnd() {
165        if (av != null) {
166            av.visitEnd();
167        }
168    }
169}