001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 BEA Systems, Inc.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * tyeung@bea.com - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.apt.core.internal.declaration;
011:
012: import java.lang.annotation.Annotation;
013: import java.lang.reflect.Proxy;
014: import java.util.ArrayList;
015: import java.util.Collection;
016: import java.util.Collections;
017: import java.util.List;
018:
019: import org.eclipse.core.resources.IFile;
020: import org.eclipse.jdt.apt.core.internal.env.AnnotationInvocationHandler;
021: import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
022: import org.eclipse.jdt.apt.core.internal.util.Factory;
023: import org.eclipse.jdt.core.dom.ASTNode;
024: import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
025: import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
026: import org.eclipse.jdt.core.dom.BodyDeclaration;
027: import org.eclipse.jdt.core.dom.CompilationUnit;
028: import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
029: import org.eclipse.jdt.core.dom.FieldDeclaration;
030: import org.eclipse.jdt.core.dom.IAnnotationBinding;
031: import org.eclipse.jdt.core.dom.ITypeBinding;
032: import org.eclipse.jdt.core.dom.Javadoc;
033: import org.eclipse.jdt.core.dom.MethodDeclaration;
034: import org.eclipse.jdt.core.dom.SimpleName;
035: import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
036: import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
037:
038: import com.sun.mirror.declaration.AnnotationMirror;
039: import com.sun.mirror.declaration.Declaration;
040: import com.sun.mirror.util.DeclarationVisitor;
041:
042: public abstract class EclipseDeclarationImpl implements Declaration,
043: EclipseMirrorObject {
044: final BaseProcessorEnv _env;
045:
046: EclipseDeclarationImpl(final BaseProcessorEnv env) {
047: assert env != null : "missing environment"; //$NON-NLS-1$
048: _env = env;
049: }
050:
051: public void accept(DeclarationVisitor visitor) {
052: visitor.visitDeclaration(this );
053: }
054:
055: @SuppressWarnings("unchecked")
056: <A extends Annotation> A _getAnnotation(Class<A> annotationClass,
057: IAnnotationBinding[] annoInstances) {
058: if (annoInstances == null || annoInstances.length == 0
059: || annotationClass == null)
060: return null;
061:
062: String annoTypeName = annotationClass.getName();
063: if (annoTypeName == null)
064: return null;
065: annoTypeName = annoTypeName.replace('$', '.');
066: for (IAnnotationBinding annoInstance : annoInstances) {
067: if (annoInstance == null)
068: continue;
069: final ITypeBinding binding = annoInstance
070: .getAnnotationType();
071: if (binding != null && binding.isAnnotation()) {
072: final String curTypeName = binding.getQualifiedName();
073: if (annoTypeName.equals(curTypeName)) {
074: final AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) Factory
075: .createAnnotationMirror(annoInstance, this ,
076: _env);
077: final AnnotationInvocationHandler handler = new AnnotationInvocationHandler(
078: annoMirror, annotationClass);
079: return (A) Proxy.newProxyInstance(annotationClass
080: .getClassLoader(),
081: new Class[] { annotationClass }, handler);
082: }
083: }
084: }
085: return null;
086: }
087:
088: Collection<AnnotationMirror> _getAnnotationMirrors(
089: IAnnotationBinding[] annoInstances) {
090: if (annoInstances == null || annoInstances.length == 0)
091: return Collections.emptyList();
092: final List<AnnotationMirror> result = new ArrayList<AnnotationMirror>(
093: annoInstances.length);
094: for (IAnnotationBinding annoInstance : annoInstances) {
095: if (annoInstance != null) {
096: final AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) Factory
097: .createAnnotationMirror(annoInstance, this ,
098: _env);
099: result.add(annoMirror);
100: }
101: }
102: return result;
103: }
104:
105: Collection<AnnotationMirror> _getAnnotationMirrors(
106: List<org.eclipse.jdt.core.dom.Annotation> annoInstances) {
107: if (annoInstances == null || annoInstances.size() == 0)
108: return Collections.emptyList();
109: final List<AnnotationMirror> result = new ArrayList<AnnotationMirror>(
110: annoInstances.size());
111: for (org.eclipse.jdt.core.dom.Annotation annoInstance : annoInstances) {
112: if (annoInstance != null) {
113: final AnnotationMirrorImpl annoMirror = (AnnotationMirrorImpl) Factory
114: .createAnnotationMirror(annoInstance
115: .resolveAnnotationBinding(), this , _env);
116: result.add(annoMirror);
117: }
118: }
119: return result;
120: }
121:
122: /**
123: * @return the ast node that corresponding to this declaration,
124: * or null if this declaration came from binary.
125: * @see #isFromSource()
126: */
127: abstract ASTNode getAstNode();
128:
129: /**
130: * @return the compilation unit that the ast node of this declaration came from
131: * Return null if this declaration came from binary.
132: * @see #isFromSource()
133: */
134: abstract CompilationUnit getCompilationUnit();
135:
136: /**
137: * @return the resource of this declaration if the declaration is from source.
138: */
139: abstract public IFile getResource();
140:
141: /**
142: * @return true iff this declaration came from a source file.
143: * Return false otherwise.
144: */
145: public abstract boolean isFromSource();
146:
147: public abstract boolean isBindingBased();
148:
149: public BaseProcessorEnv getEnvironment() {
150: return _env;
151: }
152:
153: /**
154: * @return the ast node that holds the range of this member declaration in source.
155: * The default is to find the name of the node and if that fails, return the
156: * node with the smallest range that contains the declaration.
157: */
158: protected ASTNode getRangeNode() {
159: final ASTNode node = getAstNode();
160: if (node == null)
161: return null;
162: SimpleName name = null;
163: switch (node.getNodeType()) {
164: case ASTNode.TYPE_DECLARATION:
165: case ASTNode.ANNOTATION_TYPE_DECLARATION:
166: case ASTNode.ENUM_DECLARATION:
167: name = ((AbstractTypeDeclaration) node).getName();
168: break;
169: case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
170: name = ((AnnotationTypeMemberDeclaration) node).getName();
171: break;
172: case ASTNode.METHOD_DECLARATION:
173: name = ((MethodDeclaration) node).getName();
174: break;
175: case ASTNode.SINGLE_VARIABLE_DECLARATION:
176: name = ((SingleVariableDeclaration) node).getName();
177: break;
178: case ASTNode.FIELD_DECLARATION:
179: final String declName = getSimpleName();
180: if (declName == null)
181: return node;
182: for (Object obj : ((FieldDeclaration) node).fragments()) {
183: VariableDeclarationFragment frag = (VariableDeclarationFragment) obj;
184: if (declName.equals(frag.getName())) {
185: name = frag.getName();
186: break;
187: }
188: }
189: break;
190: case ASTNode.ENUM_CONSTANT_DECLARATION:
191: name = ((EnumConstantDeclaration) node).getName();
192: break;
193: default:
194: return node;
195: }
196: if (name == null)
197: return node;
198: return name;
199: }
200:
201: protected String getDocComment(final BodyDeclaration decl) {
202: final Javadoc javaDoc = decl.getJavadoc();
203: if (javaDoc == null)
204: return ""; //$NON-NLS-1$
205: return javaDoc.toString();
206: }
207: }
|