001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.bytecode;
017:
018: import java.util.Map;
019: import java.io.IOException;
020: import java.io.DataInputStream;
021: import java.io.ByteArrayOutputStream;
022:
023: import javassist.bytecode.AnnotationsAttribute.Copier;
024: import javassist.bytecode.AnnotationsAttribute.Parser;
025: import javassist.bytecode.annotation.*;
026:
027: /**
028: * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and
029: * <code>RuntimeInvisibleAnnotations_attribute</code>.
030: *
031: * <p>To obtain an ParameterAnnotationAttribute object, invoke
032: * <code>getAttribute(ParameterAnnotationsAttribute.invisibleTag)</code>
033: * in <code>MethodInfo</code>.
034: * The obtained attribute is a
035: * runtime invisible annotations attribute.
036: * If the parameter is
037: * <code>ParameterAnnotationAttribute.visibleTag</code>, then the obtained
038: * attribute is a runtime visible one.
039: */
040: public class ParameterAnnotationsAttribute extends AttributeInfo {
041: /**
042: * The name of the <code>RuntimeVisibleParameterAnnotations</code>
043: * attribute.
044: */
045: public static final String visibleTag = "RuntimeVisibleParameterAnnotations";
046:
047: /**
048: * The name of the <code>RuntimeInvisibleParameterAnnotations</code>
049: * attribute.
050: */
051: public static final String invisibleTag = "RuntimeInvisibleParameterAnnotations";
052:
053: /**
054: * Constructs
055: * a <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>.
056: *
057: * @param cp constant pool
058: * @param attrname attribute name (<code>visibleTag</code> or
059: * <code>invisibleTag</code>).
060: * @param info the contents of this attribute. It does not
061: * include <code>attribute_name_index</code> or
062: * <code>attribute_length</code>.
063: */
064: public ParameterAnnotationsAttribute(ConstPool cp, String attrname,
065: byte[] info) {
066: super (cp, attrname, info);
067: }
068:
069: /**
070: * Constructs an empty
071: * <code>Runtime(In)VisisbleParameterAnnotations_attribute</code>.
072: * A new annotation can be later added to the created attribute
073: * by <code>setAnnotations()</code>.
074: *
075: * @param cp constant pool
076: * @param attrname attribute name (<code>visibleTag</code> or
077: * <code>invisibleTag</code>).
078: * @see #setAnnotations(Annotation[][])
079: */
080: public ParameterAnnotationsAttribute(ConstPool cp, String attrname) {
081: this (cp, attrname, new byte[] { 0 });
082: }
083:
084: /**
085: * @param n the attribute name.
086: */
087: ParameterAnnotationsAttribute(ConstPool cp, int n,
088: DataInputStream in) throws IOException {
089: super (cp, n, in);
090: }
091:
092: /**
093: * Returns <code>num_parameters</code>.
094: */
095: public int numParameters() {
096: return info[0] & 0xff;
097: }
098:
099: /**
100: * Copies this attribute and returns a new copy.
101: */
102: public AttributeInfo copy(ConstPool newCp, Map classnames) {
103: Copier copier = new Copier(info, constPool, newCp, classnames);
104: try {
105: copier.parameters();
106: return new ParameterAnnotationsAttribute(newCp, getName(),
107: copier.close());
108: } catch (Exception e) {
109: throw new RuntimeException(e.toString());
110: }
111: }
112:
113: /**
114: * Parses the annotations and returns a data structure representing
115: * that parsed annotations. Note that changes of the node values of the
116: * returned tree are not reflected on the annotations represented by
117: * this object unless the tree is copied back to this object by
118: * <code>setAnnotations()</code>.
119: *
120: * @return Each element of the returned array represents an array of
121: * annotations that are associated with each method parameter.
122: *
123: * @see #setAnnotations(Annotation[][])
124: */
125: public Annotation[][] getAnnotations() {
126: try {
127: return new Parser(info, constPool).parseParameters();
128: } catch (Exception e) {
129: throw new RuntimeException(e.toString());
130: }
131: }
132:
133: /**
134: * Changes the annotations represented by this object according to
135: * the given array of <code>Annotation</code> objects.
136: *
137: * @param params the data structure representing the
138: * new annotations. Every element of this array
139: * is an array of <code>Annotation</code> and
140: * it represens annotations of each method parameter.
141: */
142: public void setAnnotations(Annotation[][] params) {
143: ByteArrayOutputStream output = new ByteArrayOutputStream();
144: AnnotationsWriter writer = new AnnotationsWriter(output,
145: constPool);
146: try {
147: int n = params.length;
148: writer.numParameters(n);
149: for (int i = 0; i < n; ++i) {
150: Annotation[] anno = params[i];
151: writer.numAnnotations(anno.length);
152: for (int j = 0; j < anno.length; ++j)
153: anno[j].write(writer);
154: }
155:
156: writer.close();
157: } catch (IOException e) {
158: throw new RuntimeException(e); // should never reach here.
159: }
160:
161: set(output.toByteArray());
162: }
163: }
|