KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > apt > pluggable > core > dispatch > IdeAnnotationProcessorManager


1 /*******************************************************************************
2  * Copyright (c) 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  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.internal.apt.pluggable.core.dispatch;
14
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Map.Entry;
18
19 import javax.annotation.processing.Processor;
20
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader;
24 import org.eclipse.jdt.apt.core.internal.IServiceFactory;
25 import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
26 import org.eclipse.jdt.apt.core.internal.util.FactoryPath.Attributes;
27 import org.eclipse.jdt.core.IJavaProject;
28 import org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin;
29 import org.eclipse.jdt.internal.compiler.Compiler;
30 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager;
31 import org.eclipse.jdt.internal.compiler.apt.dispatch.ProcessorInfo;
32 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
33 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
34 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
35 import org.eclipse.jdt.internal.core.CompilationUnitProblemFinder;
36 import org.eclipse.jdt.internal.core.builder.ICompilationUnitLocator;
37
38 /**
39  * Java 6 annotation processor manager used when compiling within the IDE.
40  * @see org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager
41  */

42 public class IdeAnnotationProcessorManager extends BaseAnnotationProcessorManager {
43     
44     private IJavaProject _javaProject;
45     private ICompilationUnitLocator _cuLocator;
46     private Map JavaDoc<IServiceFactory, FactoryPath.Attributes> _processorFactories;
47     private Iterator JavaDoc<Entry<IServiceFactory, Attributes>> _processorIter;
48
49     /**
50      * Initialize the processor manager for a particular project. It is an error
51      * to initialize a manager more than once.
52      *
53      * @param abstractImageBuilder must be an instanceof AbstractImageBuilder.
54      * (But it can't be prototyped that way because the abstract base class must
55      * compile without Eclipse platform code.)
56      *
57      * @param javaProject must be an instanceof IJavaProject. (But it can't be
58      * prototyped that way because the abstract base class must compile without
59      * Eclipse platform code.)
60      */

61     @Override JavaDoc
62     public void configureFromPlatform(Compiler JavaDoc compiler, Object JavaDoc compilationUnitLocator, Object JavaDoc javaProject) {
63         _javaProject = (IJavaProject) javaProject;
64         _cuLocator = (ICompilationUnitLocator) compilationUnitLocator;
65         if (null != _processingEnv) {
66             throw new IllegalStateException JavaDoc(
67                     "Calling configure() more than once on an AnnotationProcessorManager is not supported"); //$NON-NLS-1$
68
}
69         // If it's a CompilationUnitProblemFinder, we're in reconcile phase. Else it's build.
70
if (compiler instanceof CompilationUnitProblemFinder) {
71             _processingEnv = new IdeReconcileProcessingEnvImpl(this, _javaProject, compiler);
72         } else {
73             _processingEnv = new IdeBuildProcessingEnvImpl(this, _javaProject, compiler);
74         }
75         if (Apt6Plugin.DEBUG) {
76             Apt6Plugin.trace("Java 6 annotation processor manager initialized for compiler " +
77                     compiler.toString() + " on project " + _javaProject.getElementName());
78         }
79     }
80
81     /**
82      * If this project has a ProcessorPath defined, use it. Else, construct
83      * one from the classpath.
84      */

85     @Override JavaDoc
86     public ProcessorInfo discoverNextProcessor() {
87         // _processorIter gets initialized the first time through processAnnotations()
88
if (_processorIter.hasNext()) {
89             Entry<IServiceFactory, Attributes> entry = _processorIter.next();
90             Processor p;
91             try {
92                 p = (Processor)entry.getKey().newInstance();
93                 p.init(_processingEnv);
94                 ProcessorInfo pi = new ProcessorInfo(p);
95                 if (Apt6Plugin.DEBUG) {
96                     Apt6Plugin.trace("Discovered processor " + p.toString());
97                 }
98                 _processors.add(pi);
99                 return pi;
100             } catch (CoreException e) {
101                 Apt6Plugin.log(e, "Unable to create instance of annotation processor " + entry.getKey()); //$NON-NLS-1$
102
}
103         }
104         return null;
105     }
106
107     @Override JavaDoc
108     public void reportProcessorException(Processor p, Exception JavaDoc e) {
109         Apt6Plugin.log(e, "Exception thrown by Java annotation processor " + p); //$NON-NLS-1$
110
}
111
112     /**
113      * @return an ICompilationUnit corresponding to the specified file. In IDE mode this
114      * will be backed by an org.eclipse.jdt.internal.core.builder.SourceFile.
115      */

116     public ICompilationUnit findCompilationUnit(IFile file) {
117         return _cuLocator.fromIFile(file);
118     }
119
120     /**
121      * In IDE mode, we are able to determine whether there are no processors. If that's the case,
122      * then we can avoid doing the work of walking the ASTs to search for annotations. We still
123      * need to clean up no-longer-generated files when the factory path is changed, but the best
124      * way to do that is to force a clean build.
125      * @see BaseAnnotationProcessorManager#processAnnotations(CompilationUnitDeclaration[], boolean)
126      */

127     @Override JavaDoc
128     public void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound) {
129         if (null == _processorFactories ) {
130             _processorFactories = AnnotationProcessorFactoryLoader.getLoader().getJava6FactoriesAndAttributesForProject(_javaProject);
131             _processorIter = _processorFactories.entrySet().iterator();
132         }
133         if (!_processorFactories.isEmpty()) {
134             super.processAnnotations(units, referenceBindings, isLastRound);
135         }
136     }
137
138 }
139
Popular Tags