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 */
030
031package org.springframework.asm;
032
033/**
034 * A reference to a field or a method.
035 * 
036 * @author Remi Forax
037 * @author Eric Bruneton
038 */
039public final class Handle {
040
041    /**
042     * The kind of field or method designated by this Handle. Should be
043     * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
044     * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
045     * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
046     * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
047     * {@link Opcodes#H_INVOKEINTERFACE}.
048     */
049    final int tag;
050
051    /**
052     * The internal name of the class that owns the field or method designated
053     * by this handle.
054     */
055    final String owner;
056
057    /**
058     * The name of the field or method designated by this handle.
059     */
060    final String name;
061
062    /**
063     * The descriptor of the field or method designated by this handle.
064     */
065    final String desc;
066
067
068    /**
069     * Indicate if the owner is an interface or not.
070     */
071    final boolean itf;
072
073    /**
074     * Constructs a new field or method handle.
075     * 
076     * @param tag
077     *            the kind of field or method designated by this Handle. Must be
078     *            {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
079     *            {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
080     *            {@link Opcodes#H_INVOKEVIRTUAL},
081     *            {@link Opcodes#H_INVOKESTATIC},
082     *            {@link Opcodes#H_INVOKESPECIAL},
083     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
084     *            {@link Opcodes#H_INVOKEINTERFACE}.
085     * @param owner
086     *            the internal name of the class that owns the field or method
087     *            designated by this handle.
088     * @param name
089     *            the name of the field or method designated by this handle.
090     * @param desc
091     *            the descriptor of the field or method designated by this
092     *            handle.
093     *
094     * @deprecated this constructor has been superseded
095     *             by {@link #Handle(int, String, String, String, boolean)}.
096     */
097    @Deprecated
098    public Handle(int tag, String owner, String name, String desc) {
099        this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
100    }
101
102    /**
103     * Constructs a new field or method handle.
104     *
105     * @param tag
106     *            the kind of field or method designated by this Handle. Must be
107     *            {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
108     *            {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
109     *            {@link Opcodes#H_INVOKEVIRTUAL},
110     *            {@link Opcodes#H_INVOKESTATIC},
111     *            {@link Opcodes#H_INVOKESPECIAL},
112     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
113     *            {@link Opcodes#H_INVOKEINTERFACE}.
114     * @param owner
115     *            the internal name of the class that owns the field or method
116     *            designated by this handle.
117     * @param name
118     *            the name of the field or method designated by this handle.
119     * @param desc
120     *            the descriptor of the field or method designated by this
121     *            handle.
122     * @param itf
123     *            true if the owner is an interface.
124     */
125    public Handle(int tag, String owner, String name, String desc, boolean itf) {
126        this.tag = tag;
127        this.owner = owner;
128        this.name = name;
129        this.desc = desc;
130        this.itf = itf;
131    }
132
133    /**
134     * Returns the kind of field or method designated by this handle.
135     * 
136     * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
137     *         {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
138     *         {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
139     *         {@link Opcodes#H_INVOKESPECIAL},
140     *         {@link Opcodes#H_NEWINVOKESPECIAL} or
141     *         {@link Opcodes#H_INVOKEINTERFACE}.
142     */
143    public int getTag() {
144        return tag;
145    }
146
147    /**
148     * Returns the internal name of the class that owns the field or method
149     * designated by this handle.
150     * 
151     * @return the internal name of the class that owns the field or method
152     *         designated by this handle.
153     */
154    public String getOwner() {
155        return owner;
156    }
157
158    /**
159     * Returns the name of the field or method designated by this handle.
160     * 
161     * @return the name of the field or method designated by this handle.
162     */
163    public String getName() {
164        return name;
165    }
166
167    /**
168     * Returns the descriptor of the field or method designated by this handle.
169     * 
170     * @return the descriptor of the field or method designated by this handle.
171     */
172    public String getDesc() {
173        return desc;
174    }
175
176    /**
177     * Returns true if the owner of the field or method designated
178     * by this handle is an interface.
179     *
180     * @return true if the owner of the field or method designated
181     *         by this handle is an interface.
182     */
183    public boolean isInterface() {
184        return itf;
185    }
186
187    @Override
188    public boolean equals(Object obj) {
189        if (obj == this) {
190            return true;
191        }
192        if (!(obj instanceof Handle)) {
193            return false;
194        }
195        Handle h = (Handle) obj;
196        return tag == h.tag && itf == h.itf && owner.equals(h.owner)
197                && name.equals(h.name) && desc.equals(h.desc);
198    }
199
200    @Override
201    public int hashCode() {
202        return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
203    }
204
205    /**
206     * Returns the textual representation of this handle. The textual
207     * representation is:
208     * 
209     * <pre>
210     * for a reference to a class:
211     * owner '.' name desc ' ' '(' tag ')'
212     * for a reference to an interface:
213     * owner '.' name desc ' ' '(' tag ' ' itf ')'
214     * </pre>
215     * 
216     * . As this format is unambiguous, it can be parsed if necessary.
217     */
218    @Override
219    public String toString() {
220        return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')';
221    }
222}