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 field. The methods of this class must be called in
034 * the following order: ( <tt>visitAnnotation</tt> |
035 * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
036 * 
037 * @author Eric Bruneton
038 */
039public abstract class FieldVisitor {
040
041    /**
042     * The ASM API version implemented by this visitor. The value of this field
043     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
044     */
045    protected final int api;
046
047    /**
048     * The field visitor to which this visitor must delegate method calls. May
049     * be null.
050     */
051    protected FieldVisitor fv;
052
053    /**
054     * Constructs a new {@link FieldVisitor}.
055     * 
056     * @param api
057     *            the ASM API version implemented by this visitor. Must be one
058     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
059     */
060    public FieldVisitor(final int api) {
061        this(api, null);
062    }
063
064    /**
065     * Constructs a new {@link FieldVisitor}.
066     * 
067     * @param api
068     *            the ASM API version implemented by this visitor. Must be one
069     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
070     * @param fv
071     *            the field visitor to which this visitor must delegate method
072     *            calls. May be null.
073     */
074    public FieldVisitor(final int api, final FieldVisitor fv) {
075        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
076            throw new IllegalArgumentException();
077        }
078        this.api = api;
079        this.fv = fv;
080    }
081
082    /**
083     * Visits an annotation of the field.
084     * 
085     * @param desc
086     *            the class descriptor of the annotation class.
087     * @param visible
088     *            <tt>true</tt> if the annotation is visible at runtime.
089     * @return a visitor to visit the annotation values, or <tt>null</tt> if
090     *         this visitor is not interested in visiting this annotation.
091     */
092    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
093        if (fv != null) {
094            return fv.visitAnnotation(desc, visible);
095        }
096        return null;
097    }
098
099    /**
100     * Visits an annotation on the type of the field.
101     * 
102     * @param typeRef
103     *            a reference to the annotated type. The sort of this type
104     *            reference must be {@link TypeReference#FIELD FIELD}. See
105     *            {@link TypeReference}.
106     * @param typePath
107     *            the path to the annotated type argument, wildcard bound, array
108     *            element type, or static inner type within 'typeRef'. May be
109     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
110     * @param desc
111     *            the class descriptor of the annotation class.
112     * @param visible
113     *            <tt>true</tt> if the annotation is visible at runtime.
114     * @return a visitor to visit the annotation values, or <tt>null</tt> if
115     *         this visitor is not interested in visiting this annotation.
116     */
117    public AnnotationVisitor visitTypeAnnotation(int typeRef,
118            TypePath typePath, String desc, boolean visible) {
119                /* SPRING PATCH: REMOVED FOR COMPATIBILITY WITH CGLIB 3.1
120        if (api < Opcodes.ASM5) {
121            throw new RuntimeException();
122        }
123        */
124        if (fv != null) {
125            return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
126        }
127        return null;
128    }
129
130    /**
131     * Visits a non standard attribute of the field.
132     * 
133     * @param attr
134     *            an attribute.
135     */
136    public void visitAttribute(Attribute attr) {
137        if (fv != null) {
138            fv.visitAttribute(attr);
139        }
140    }
141
142    /**
143     * Visits the end of the field. This method, which is the last one to be
144     * called, is used to inform the visitor that all the annotations and
145     * attributes of the field have been visited.
146     */
147    public void visitEnd() {
148        if (fv != null) {
149            fv.visitEnd();
150        }
151    }
152}