001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2003-2007 University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.classfile.analysis;
021:
022: import java.util.HashMap;
023: import java.util.LinkedList;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.objectweb.asm.AnnotationVisitor;
028:
029: import edu.umd.cs.findbugs.classfile.ClassDescriptor;
030: import edu.umd.cs.findbugs.classfile.DescriptorFactory;
031:
032: /**
033: * The "raw" version of an annotation appearing in a class file.
034: *
035: * @author William Pugh
036: */
037: public class AnnotationValue {
038: private final ClassDescriptor annotationClass;
039: private Map<String, Object> valueMap = new HashMap<String, Object>();
040: private Map<String, Object> typeMap = new HashMap<String, Object>();
041:
042: /**
043: * Constructor.
044: *
045: * @param annotationClass the annotation class
046: */
047: public AnnotationValue(ClassDescriptor annotationClass) {
048: this .annotationClass = annotationClass;
049: }
050:
051: /**
052: * Constructor.
053: *
054: * @param annotationClass JVM signature of the annotation class
055: */
056: public AnnotationValue(String annotationClass) {
057: this .annotationClass = DescriptorFactory
058: .createClassDescriptorFromSignature(annotationClass);
059: }
060:
061: /**
062: * @return ClassDescriptor referring to the annotation class
063: */
064: public ClassDescriptor getAnnotationClass() {
065: return annotationClass;
066: }
067:
068: /**
069: * Get the value of given annotation element.
070: * See <a href="http://asm.objectweb.org/current/doc/javadoc/user/org/objectweb/asm/AnnotationVisitor.html">AnnotationVisitor Javadoc</a>
071: * for information on what the object returned could be.
072: *
073: * @param name name of annotation element
074: * @return the element value (primitive value, String value, enum value, Type, or array of one of the previous)
075: */
076: public Object getValue(String name) {
077: return valueMap.get(name);
078: }
079:
080: /**
081: * Get a descriptor specifying the type of an annotation element.
082: *
083: * @param name name of annotation element
084: * @return descriptor specifying the type of the annotation element
085: */
086: public Object getDesc(String name) {
087: return typeMap.get(name);
088: }
089:
090: @Override
091: public String toString() {
092: return annotationClass + ":" + valueMap.toString();
093: }
094:
095: /**
096: * Get an AnnotationVisitor which can populate this AnnotationValue object.
097: */
098: public AnnotationVisitor getAnnotationVisitor() {
099: return new AnnotationVisitor() {
100: public void visit(String name, Object value) {
101: valueMap.put(name, value);
102: }
103:
104: /*
105: * (non-Javadoc)
106: *
107: * @see org.objectweb.asm.AnnotationVisitor#visitAnnotation(java.lang.String,
108: * java.lang.String)
109: */
110: public AnnotationVisitor visitAnnotation(String name,
111: String desc) {
112: AnnotationValue newValue = new AnnotationValue(desc);
113: valueMap.put(name, newValue);
114: typeMap.put(name, desc);
115: return newValue.getAnnotationVisitor();
116: }
117:
118: /*
119: * (non-Javadoc)
120: *
121: * @see org.objectweb.asm.AnnotationVisitor#visitArray(java.lang.String)
122: */
123: public AnnotationVisitor visitArray(final String name) {
124: return new AnnotationArrayVisitor(name);
125: }
126:
127: /*
128: * (non-Javadoc)
129: *
130: * @see org.objectweb.asm.AnnotationVisitor#visitEnd()
131: */
132: public void visitEnd() {
133:
134: }
135:
136: /*
137: * (non-Javadoc)
138: *
139: * @see org.objectweb.asm.AnnotationVisitor#visitEnum(java.lang.String,
140: * java.lang.String, java.lang.String)
141: */
142: public void visitEnum(String name, String desc, String value) {
143: valueMap.put(name, new EnumValue(desc, value));
144: typeMap.put(name, desc);
145:
146: }
147: };
148: }
149:
150: private final class AnnotationArrayVisitor implements
151: AnnotationVisitor {
152: /**
153: *
154: */
155: private final String name;
156:
157: private final List<Object> outerList;
158:
159: /**
160: *
161: */
162: private final List<Object> result = new LinkedList<Object>();
163:
164: /**
165: * @param name
166: * @param result
167: */
168: private AnnotationArrayVisitor(String name) {
169: this .name = name;
170: this .outerList = null;
171: }
172:
173: private AnnotationArrayVisitor(List<Object> outerList) {
174: this .name = null;
175: this .outerList = outerList;
176: }
177:
178: public void visit(String name, Object value) {
179: result.add(value);
180: }
181:
182: public AnnotationVisitor visitAnnotation(String name,
183: String desc) {
184: AnnotationValue newValue = new AnnotationValue(desc);
185: result.add(newValue);
186: return newValue.getAnnotationVisitor();
187: }
188:
189: public AnnotationVisitor visitArray(String name) {
190: return new AnnotationArrayVisitor(result);
191: }
192:
193: public void visitEnd() {
194: if (name != null)
195: valueMap.put(name, result.toArray());
196: else
197: outerList.add(result.toArray());
198: }
199:
200: public void visitEnum(String name, String desc, String value) {
201: result.add(new EnumValue(desc, value));
202:
203: }
204: }
205:
206: }
|