KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > model > AnnotationValueImpl


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.apt.model;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.List JavaDoc;
16
17 import javax.lang.model.element.AnnotationMirror;
18 import javax.lang.model.element.AnnotationValue;
19 import javax.lang.model.element.AnnotationValueVisitor;
20 import javax.lang.model.element.VariableElement;
21 import javax.lang.model.type.TypeMirror;
22
23 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
24 import org.eclipse.jdt.internal.compiler.impl.Constant;
25 import org.eclipse.jdt.internal.compiler.impl.DoubleConstant;
26 import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
27 import org.eclipse.jdt.internal.compiler.impl.LongConstant;
28 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
29 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
30 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
31 import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
32 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
33 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
34 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
35 import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
36
37 public class AnnotationValueImpl implements AnnotationValue, TypeIds {
38     
39     /*
40      * Additions to T_* constants in TypeIds.
41      */

42     private static final int T_AnnotationMirror = -1;
43     private static final int T_EnumConstant = -2;
44     private static final int T_ClassObject = -3;
45     private static final int T_ArrayType = -4;
46     
47     private final BaseProcessingEnvImpl _env;
48     
49     /**
50      * The annotation value, as it would be returned by
51      * {@link #getValue()}. For instance, an Integer (for an int
52      * constant), a VariableElement (for an enum constant), or
53      * a List<AnnotationValueImpl> containing multiple such (for an array type).
54      */

55     private final Object JavaDoc _value;
56     
57     /**
58      * The type stored in _value, represented as a T_* value from {@link TypeIds}
59      * or one of the additional T_* values defined in this class.
60      */

61     private final int _kind;
62
63     /**
64      * @param value
65      * The JDT representation of a compile-time constant. See
66      * {@link ElementValuePair#getValue()} for possible object types:
67      * <ul>
68      * <li>{@link org.eclipse.jdt.internal.compiler.impl.Constant} for member
69      * of primitive type or String</li>
70      * <li>{@link TypeBinding} for a member value of type
71      * {@link java.lang.Class}</li>
72      * <li>{@link FieldBinding} for an enum constant</li>
73      * <li>{@link AnnotationBinding} for an annotation instance</li>
74      * <li><code>Object[]</code> for a member value of array type, where the
75      * array entries are one of the above</li>
76      * </ul>
77      * @param type
78      * The JDT representation of the type of the constant, as determined
79      * by the return type of the element. This is needed because the type
80      * of the value may have been widened (e.g., byte to int) by the compiler
81      * and we need to call the proper visitor. This is used only for base types.
82      * If it is null or not a BaseTypeBinding, it is ignored and the type is
83      * determined from the type of the value.
84      */

85     public AnnotationValueImpl(BaseProcessingEnvImpl env, Object JavaDoc value, TypeBinding type) {
86         _env = env;
87         int kind[] = new int[1];
88         if (type == null) {
89             _value = convertToMirrorType(value, type, kind);
90             _kind = kind[0];
91         } else if (type.isArrayType()) {
92             List JavaDoc<AnnotationValue> convertedValues = null;
93             TypeBinding valueType = ((ArrayBinding)type).elementsType();
94             if (value instanceof Object JavaDoc[]) {
95                 Object JavaDoc[] values = (Object JavaDoc[])value;
96                 convertedValues = new ArrayList JavaDoc<AnnotationValue>(values.length);
97                 for (Object JavaDoc oneValue : values) {
98                     convertedValues.add(new AnnotationValueImpl(_env, oneValue, valueType));
99                 }
100             } else {
101                 convertedValues = new ArrayList JavaDoc<AnnotationValue>(1);
102                 convertedValues.add(new AnnotationValueImpl(_env, value, valueType));
103             }
104             _value = Collections.unmodifiableList(convertedValues);
105             _kind = T_ArrayType;
106         } else {
107             _value = convertToMirrorType(value, type, kind);
108             _kind = kind[0];
109         }
110     }
111     
112     /**
113      * Convert the JDT representation of a single constant into its javax.lang.model
114      * representation. For instance, convert a StringConstant into a String, or
115      * a FieldBinding into a VariableElement. This does not handle the case where
116      * value is an Object[].
117      * @param value the JDT object
118      * @param type the return type of the annotation member. If null or not a
119      * BaseTypeBinding, this is ignored and the value is inspected to determine type.
120      * @param kind an int array whose first element will be set to the type of the
121      * converted object, represented with T_* values from TypeIds or from this class.
122      * @return
123      */

124     private Object JavaDoc convertToMirrorType(Object JavaDoc value, TypeBinding type, int kind[]) {
125         if (type == null) {
126             kind[0] = TypeIds.T_JavaLangString;
127             return "<error>"; //$NON-NLS-1$
128
} else if (type instanceof BaseTypeBinding || type.id == TypeIds.T_JavaLangString) {
129             if (value == null) {
130                 if (type instanceof BaseTypeBinding
131                         || type.id == TypeIds.T_JavaLangString) {
132                     // return a string with error in it to reflect a value that could not be resolved
133
kind[0] = TypeIds.T_JavaLangString;
134                     return "<error>"; //$NON-NLS-1$
135
} else if (type.isAnnotationType()) {
136                     kind[0] = T_AnnotationMirror;
137                     return _env.getFactory().newAnnotationMirror(null);
138                 }
139             } else if (value instanceof Constant) {
140                 if (type instanceof BaseTypeBinding) {
141                     kind[0] = ((BaseTypeBinding)type).id;
142                 }
143                 else if (type.id == TypeIds.T_JavaLangString) {
144                     kind[0] = ((Constant)value).typeID();
145                 } else {
146                     // error case
147
kind[0] = TypeIds.T_JavaLangString;
148                     return "<error>"; //$NON-NLS-1$
149
}
150                 switch (kind[0]) {
151                 case T_boolean:
152                     return ((Constant)value).booleanValue();
153                 case T_byte:
154                     return ((Constant)value).byteValue();
155                 case T_char:
156                     return ((Constant)value).charValue();
157                 case T_double:
158                     return ((Constant)value).doubleValue();
159                 case T_float:
160                     return ((Constant)value).floatValue();
161                 case T_int:
162                     try {
163                         if (value instanceof LongConstant
164                                 || value instanceof DoubleConstant
165                                 || value instanceof FloatConstant) {
166                             // error case
167
kind[0] = TypeIds.T_JavaLangString;
168                             return "<error>"; //$NON-NLS-1$
169
}
170                         return ((Constant)value).intValue();
171                     } catch (ShouldNotImplement e) {
172                         kind[0] = TypeIds.T_JavaLangString;
173                         return "<error>"; //$NON-NLS-1$
174
}
175                 case T_JavaLangString:
176                     return ((Constant)value).stringValue();
177                 case T_long:
178                     return ((Constant)value).longValue();
179                 case T_short:
180                     return ((Constant)value).shortValue();
181                 }
182             }
183         } else if (type.isEnum()) {
184             if (value instanceof FieldBinding) {
185                 kind[0] = T_EnumConstant;
186                 return (VariableElement) _env.getFactory().newElement((FieldBinding) value);
187             } else {
188                 kind[0] = TypeIds.T_JavaLangString;
189                 return "<error>"; //$NON-NLS-1$
190
}
191         } else if (type.isAnnotationType()) {
192             if (value instanceof AnnotationBinding) {
193                 kind[0] = T_AnnotationMirror;
194                 return _env.getFactory().newAnnotationMirror((AnnotationBinding) value);
195             }
196         } else if (value instanceof TypeBinding) {
197             kind[0] = T_ClassObject;
198             return _env.getFactory().newTypeMirror((TypeBinding) value);
199         }
200         // error case
201
kind[0] = TypeIds.T_JavaLangString;
202         return "<error>"; //$NON-NLS-1$
203
}
204
205     @SuppressWarnings JavaDoc("unchecked") // Need to cast Object _value to a List<AnnotationValue>
206
@Override JavaDoc
207     public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
208         switch (_kind) {
209         case TypeIds.T_boolean:
210             return v.visitBoolean((Boolean JavaDoc)_value, p);
211         case TypeIds.T_byte:
212             return v.visitByte((Byte JavaDoc)_value, p);
213         case TypeIds.T_char:
214             return v.visitChar((Character JavaDoc)_value, p);
215         case TypeIds.T_double:
216             return v.visitDouble((Double JavaDoc)_value, p);
217         case TypeIds.T_float:
218             return v.visitFloat((Float JavaDoc)_value, p);
219         case TypeIds.T_int:
220             return v.visitInt((Integer JavaDoc)_value, p);
221         case TypeIds.T_JavaLangString:
222             return v.visitString((String JavaDoc)_value, p);
223         case TypeIds.T_long:
224             return v.visitLong((Long JavaDoc)_value, p);
225         case TypeIds.T_short:
226             return v.visitShort((Short JavaDoc)_value, p);
227         case T_EnumConstant:
228             return v.visitEnumConstant((VariableElement)_value, p);
229         case T_ClassObject:
230             return v.visitType((TypeMirror)_value, p);
231         case T_AnnotationMirror:
232             return v.visitAnnotation((AnnotationMirror)_value, p);
233         case T_ArrayType:
234             return v.visitArray((List JavaDoc<AnnotationValue>)_value, p);
235         default:
236             return null;
237         }
238     }
239
240     @Override JavaDoc
241     public Object JavaDoc getValue() {
242         return _value;
243     }
244
245     @Override JavaDoc
246     public boolean equals(Object JavaDoc obj) {
247         if (obj instanceof AnnotationValueImpl) {
248             return this._value.equals(((AnnotationValueImpl) obj)._value);
249         }
250         return false;
251     }
252
253     @Override JavaDoc
254     public int hashCode() {
255         return this._value.hashCode() + this._kind;
256     }
257
258     @Override JavaDoc
259     public String JavaDoc toString() {
260         if (null == _value) {
261             return "null"; //$NON-NLS-1$
262
}
263         return _value.toString();
264     }
265 }
266
Popular Tags