KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > apt > core > internal > declaration > AnnotationMirrorImpl


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 BEA Systems, Inc.
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  * tyeung@bea.com - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.apt.core.internal.declaration;
13
14 import java.util.Collections JavaDoc;
15 import java.util.LinkedHashMap JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
21 import org.eclipse.jdt.apt.core.internal.util.Factory;
22 import org.eclipse.jdt.apt.core.internal.util.SourcePositionImpl;
23 import org.eclipse.jdt.core.dom.ASTNode;
24 import org.eclipse.jdt.core.dom.Annotation;
25 import org.eclipse.jdt.core.dom.CompilationUnit;
26 import org.eclipse.jdt.core.dom.IMethodBinding;
27 import org.eclipse.jdt.core.dom.IAnnotationBinding;
28 import org.eclipse.jdt.core.dom.IMemberValuePairBinding;
29 import org.eclipse.jdt.core.dom.ITypeBinding;
30 import org.eclipse.jdt.core.dom.IVariableBinding;
31 import org.eclipse.jdt.core.dom.MemberValuePair;
32 import org.eclipse.jdt.core.dom.Name;
33 import org.eclipse.jdt.core.dom.NormalAnnotation;
34 import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
35
36 import com.sun.mirror.declaration.AnnotationMirror;
37 import com.sun.mirror.declaration.AnnotationTypeElementDeclaration;
38 import com.sun.mirror.declaration.AnnotationValue;
39 import com.sun.mirror.type.AnnotationType;
40 import com.sun.mirror.util.SourcePosition;
41
42 /**
43  * Annotation instance from source.
44  */

45 public class AnnotationMirrorImpl implements AnnotationMirror, EclipseMirrorObject
46 {
47     /**The ast node that correspond to the annotation.*/
48     private final IAnnotationBinding _domAnnotation;
49     private final BaseProcessorEnv _env;
50     /** the declaration that is annotated by this annotation or the annotation element declaration
51      * if this is (part of) a default value*/

52     private final EclipseDeclarationImpl _annotated;
53     
54     public AnnotationMirrorImpl(IAnnotationBinding annotationAstNode, EclipseDeclarationImpl decl, BaseProcessorEnv env)
55     {
56         _domAnnotation = annotationAstNode;
57         _env = env;
58         _annotated = decl;
59         assert _domAnnotation != null : "annotation node missing."; //$NON-NLS-1$
60
assert _annotated != null : "missing the declaration that is annotated with this annotation."; //$NON-NLS-1$
61
}
62     
63     public AnnotationType getAnnotationType()
64     {
65         final ITypeBinding binding = _domAnnotation.getAnnotationType();
66         if( binding == null ){
67             final ASTNode node = _annotated.getCompilationUnit().findDeclaringNode(_domAnnotation);
68             String JavaDoc name = ""; //$NON-NLS-1$
69
if( node != null && node instanceof Annotation ){
70                 final Name typeNameNode = ((Annotation)node).getTypeName();
71                 if( typeNameNode != null )
72                     name = typeNameNode.toString();
73             }
74             return Factory.createErrorAnnotationType(name);
75         }
76         else
77             return (AnnotationType)Factory.createReferenceType(binding, _env);
78     }
79
80     public Map JavaDoc<AnnotationTypeElementDeclaration, AnnotationValue> getElementValues()
81     {
82         final IMemberValuePairBinding[] pairs = _domAnnotation.getDeclaredMemberValuePairs();
83         if (pairs.length == 0) {
84             return Collections.emptyMap();
85         }
86         
87         final Map JavaDoc<AnnotationTypeElementDeclaration, AnnotationValue> result =
88             new LinkedHashMap JavaDoc<AnnotationTypeElementDeclaration, AnnotationValue>(pairs.length * 4 / 3 + 1 );
89         for( IMemberValuePairBinding pair : pairs ){
90              final String JavaDoc name = pair.getName();
91              if( name == null ) continue;
92              IMethodBinding elementMethod = pair.getMethodBinding();
93              if( elementMethod != null ){
94                  final EclipseDeclarationImpl mirrorDecl = Factory.createDeclaration(elementMethod, _env);
95                  if( mirrorDecl != null && mirrorDecl.kind() == EclipseMirrorObject.MirrorKind.ANNOTATION_ELEMENT )
96                  {
97                      final AnnotationTypeElementDeclaration elementDecl =
98                          (AnnotationTypeElementDeclaration)mirrorDecl;
99                      final AnnotationValue annoValue =
100                          Factory.createAnnotationMemberValue(pair.getValue(), name, this, _env, elementDecl.getReturnType());
101                      if( annoValue != null )
102                          result.put( elementDecl, annoValue);
103                  }
104              }
105         }
106         return result;
107     }
108
109     public SourcePosition getPosition()
110     {
111         if( isFromSource() ){
112             final CompilationUnit unit = _annotated.getCompilationUnit();
113             final org.eclipse.jdt.core.dom.Annotation annotation = getAstNode();
114             if( annotation == null ) return null;
115             org.eclipse.jdt.core.dom.ASTNode astNode = annotation.getTypeName();
116             if( astNode == null )
117                 astNode = annotation;
118             
119             final int offset = astNode.getStartPosition();
120             return new SourcePositionImpl(astNode.getStartPosition(),
121                                           astNode.getLength(),
122                                           unit.getLineNumber(offset),
123                                           unit.getColumnNumber(offset),
124                                           _annotated);
125         }
126         return null;
127     }
128
129     public String JavaDoc toString()
130     {
131         return _domAnnotation.toString();
132     }
133
134     /**
135      * @return the type(s) of the member value named <code>membername</code>.
136      * If the value is a class literal, then return the type binding corresponding to the type requested.
137      * Otherwise, return the type of the expression.
138      * If the value is an array initialization, then the type of each of the initialization expresion will
139      * be returned. Return null if no match is found.
140      */

141     public ITypeBinding[] getMemberValueTypeBinding(String JavaDoc membername)
142     {
143         if( membername == null ) return null;
144         final IMemberValuePairBinding[] declaredPairs = _domAnnotation.getDeclaredMemberValuePairs();
145         for( IMemberValuePairBinding pair : declaredPairs ){
146             if( membername.equals(pair.getName()) ){
147                 final Object JavaDoc value = pair.getValue();
148                 return getValueTypeBinding(value, pair.getMethodBinding().getReturnType());
149             }
150         }
151       
152         // didn't find it in the ast, check the default values.
153
final IMethodBinding binding = getMethodBinding(membername);
154         if(binding == null ) return null;
155         final Object JavaDoc defaultValue = binding.getDefaultValue();
156         if( defaultValue != null )
157             return getValueTypeBinding(defaultValue, binding.getReturnType() );
158         else
159             return null;
160     }
161     
162     private ITypeBinding[] getValueTypeBinding(Object JavaDoc value, final ITypeBinding resolvedType)
163     {
164         if( value == null ) return null;
165         if( resolvedType.isPrimitive() || resolvedType.isAnnotation() || value instanceof String JavaDoc )
166             return new ITypeBinding[]{ resolvedType };
167         else if( resolvedType.isArray() ){
168             final Object JavaDoc[] elements = (Object JavaDoc[])value;
169             final ITypeBinding[] result = new ITypeBinding[elements.length];
170             final ITypeBinding leafType = resolvedType.getElementType();
171             for(int i=0, len = elements.length; i<len; i++ ){
172                 final ITypeBinding[] t = getValueTypeBinding(elements[i], leafType);
173                 result[i] = t == null ? null : t[0];
174             }
175             return result;
176         }
177         else if( value instanceof IVariableBinding )
178             return new ITypeBinding[]{ ( (IVariableBinding)value ).getDeclaringClass() };
179         else if( value instanceof ITypeBinding )
180             return new ITypeBinding[]{ (ITypeBinding)value };
181         else
182             throw new IllegalStateException JavaDoc("value = " + value + " resolvedType = " + resolvedType ); //$NON-NLS-1$ //$NON-NLS-2$
183

184     }
185
186     /**
187      * @param memberName the name of the member
188      * @return the value of the given member
189      */

190     public Object JavaDoc getValue(final String JavaDoc memberName)
191     {
192         if( memberName == null ) return null;
193         final IMemberValuePairBinding[] declaredPairs = _domAnnotation.getDeclaredMemberValuePairs();
194         for( IMemberValuePairBinding pair : declaredPairs ){
195             if( memberName.equals(pair.getName()) ){
196                 return pair.getValue();
197             }
198         }
199       
200         // didn't find it in the ast, check the default values.
201
final IMethodBinding binding = getMethodBinding(memberName);
202         if(binding == null ) return null;
203         return binding.getDefaultValue();
204     }
205
206     /**
207      * @return the method binding that matches the given name from the annotation type
208      * referenced by this annotation.
209      */

210     public IMethodBinding getMethodBinding(final String JavaDoc memberName)
211     {
212         if( memberName == null ) return null;
213         final ITypeBinding typeBinding = _domAnnotation.getAnnotationType();
214         if( typeBinding == null ) return null;
215         final IMethodBinding[] methods = typeBinding.getDeclaredMethods();
216         for( IMethodBinding method : methods ){
217             if( memberName.equals(method.getName()) )
218                 return method;
219         }
220         return null;
221     }
222     
223     public IAnnotationBinding getResolvedAnnotaion(){return _domAnnotation; }
224
225     
226
227     public MirrorKind kind(){ return MirrorKind.ANNOTATION_MIRROR; }
228
229     boolean isFromSource()
230     {
231         return _annotated.isFromSource();
232     }
233
234     org.eclipse.jdt.core.dom.Annotation getAstNode()
235     {
236         if( isFromSource() ){
237             final CompilationUnit unit = _annotated.getCompilationUnit();
238             final ASTNode node = unit.findDeclaringNode(_domAnnotation);
239             if( node instanceof org.eclipse.jdt.core.dom.Annotation )
240                 return (org.eclipse.jdt.core.dom.Annotation)node;
241         }
242         return null;
243     }
244     
245     @SuppressWarnings JavaDoc("unchecked")
246     ASTNode getASTNodeForElement(String JavaDoc name)
247     {
248         if( name == null ) return null;
249         final org.eclipse.jdt.core.dom.Annotation anno = getAstNode();
250         if( anno != null ){
251             if( anno.isSingleMemberAnnotation() ){
252                 if( "value".equals(name) ) //$NON-NLS-1$
253
return ((SingleMemberAnnotation)anno).getValue();
254             }
255             else if( anno.isNormalAnnotation() ){
256                 final List JavaDoc<MemberValuePair> pairs = ((NormalAnnotation)anno).values();
257                 for( MemberValuePair pair : pairs )
258                 {
259                     final String JavaDoc pairName = pair.getName() == null ? null : pair.getName().toString();
260                     if( name.equals(pairName) )
261                         return pair.getValue();
262                 }
263             }
264         }
265         // marker annotation or no match.
266
return null;
267     }
268
269     CompilationUnit getCompilationUnit() { return _annotated.getCompilationUnit(); }
270
271     public BaseProcessorEnv getEnvironment(){ return _env; }
272     
273     public IFile getResource()
274     { return _annotated.getResource(); }
275     
276     public EclipseDeclarationImpl getAnnotatedDeclaration(){ return _annotated; }
277
278     public boolean equals(Object JavaDoc obj){
279         if( obj instanceof AnnotationMirrorImpl ){
280             return ((AnnotationMirrorImpl)obj)._domAnnotation == _domAnnotation;
281         }
282         return false;
283     }
284
285     public int hashCode(){
286         return _domAnnotation.hashCode();
287     }
288 }
289
Popular Tags