169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.HashMap;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataInputStream;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ByteArrayOutputStream;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Copier;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Parser;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Renamer;
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.annotation.*;
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>RuntimeInvisibleAnnotations_attribute</code>.
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To obtain an ParameterAnnotationAttribute object, invoke
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>getAttribute(ParameterAnnotationsAttribute.invisibleTag)</code>
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in <code>MethodInfo</code>.
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The obtained attribute is a
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * runtime invisible annotations attribute.
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the parameter is
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>ParameterAnnotationAttribute.visibleTag</code>, then the obtained
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * attribute is a runtime visible one.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ParameterAnnotationsAttribute extends AttributeInfo {
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The name of the <code>RuntimeVisibleParameterAnnotations</code>
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * attribute.
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static final String visibleTag
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        = "RuntimeVisibleParameterAnnotations";
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The name of the <code>RuntimeInvisibleParameterAnnotations</code>
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * attribute.
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static final String invisibleTag
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        = "RuntimeInvisibleParameterAnnotations";
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * a <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cp            constant pool
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param attrname      attribute name (<code>visibleTag</code> or
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      <code>invisibleTag</code>).
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param info          the contents of this attribute.  It does not
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      include <code>attribute_name_index</code> or
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      <code>attribute_length</code>.
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ParameterAnnotationsAttribute(ConstPool cp, String attrname,
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                         byte[] info) {
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(cp, attrname, info);
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs an empty
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * A new annotation can be later added to the created attribute
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * by <code>setAnnotations()</code>.
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cp            constant pool
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param attrname      attribute name (<code>visibleTag</code> or
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      <code>invisibleTag</code>).
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #setAnnotations(Annotation[][])
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ParameterAnnotationsAttribute(ConstPool cp, String attrname) {
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this(cp, attrname, new byte[] { 0 });
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param n     the attribute name.
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    ParameterAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws IOException
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(cp, n, in);
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns <code>num_parameters</code>.
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public int numParameters() {
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return info[0] & 0xff;
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Copies this attribute and returns a new copy.
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public AttributeInfo copy(ConstPool newCp, Map classnames) {
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Copier copier = new Copier(info, constPool, newCp, classnames);
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            copier.parameters();
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new ParameterAnnotationsAttribute(newCp, getName(),
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                                     copier.close());
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (Exception e) {
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e.toString());
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Parses the annotations and returns a data structure representing
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * that parsed annotations.  Note that changes of the node values of the
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returned tree are not reflected on the annotations represented by
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * this object unless the tree is copied back to this object by
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>setAnnotations()</code>.
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return Each element of the returned array represents an array of
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * annotations that are associated with each method parameter.
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #setAnnotations(Annotation[][])
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Annotation[][] getAnnotations() {
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new Parser(info, constPool).parseParameters();
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (Exception e) {
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e.toString());
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Changes the annotations represented by this object according to
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the given array of <code>Annotation</code> objects.
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param params        the data structure representing the
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      new annotations. Every element of this array
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      is an array of <code>Annotation</code> and
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      it represens annotations of each method parameter.
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void setAnnotations(Annotation[][] params) {
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ByteArrayOutputStream output = new ByteArrayOutputStream();
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        AnnotationsWriter writer = new AnnotationsWriter(output, constPool);
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = params.length;
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            writer.numParameters(n);
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; ++i) {
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Annotation[] anno = params[i];
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                writer.numAnnotations(anno.length);
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                for (int j = 0; j < anno.length; ++j)
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    anno[j].write(writer);
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            writer.close();
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (IOException e) {
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e);      // should never reach here.
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        set(output.toByteArray());
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param oldname       a JVM class name.
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param newname       a JVM class name.
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void renameClass(String oldname, String newname) {
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        HashMap map = new HashMap();
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        map.put(oldname, newname);
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        renameClass(map);
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void renameClass(Map classnames) {
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Renamer renamer = new Renamer(info, getConstPool(), classnames);
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            renamer.parameters();
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (Exception e) {
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e);
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void getRefClasses(Map classnames) { renameClass(classnames); }
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns a string representation of this object.
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String toString() {
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Annotation[][] aa = getAnnotations();
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        StringBuilder sbuf = new StringBuilder();
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int k = 0;
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (k < aa.length) {
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Annotation[] a = aa[k++];
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int i = 0;
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            while (i < a.length) {
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                sbuf.append(a[i++].toString());
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (i != a.length)
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    sbuf.append(" ");
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (k != aa.length)
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                sbuf.append(", ");
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return sbuf.toString();
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
215