KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > dispatch > BaseAnnotationProcessorManager


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.compiler.apt.dispatch;
14
15 import java.io.PrintWriter JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
20 import org.eclipse.jdt.internal.compiler.Compiler;
21 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
22 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
23 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
24
25 /**
26  * This class is the central dispatch point for Java 6 annotation processing.
27  * This is created and configured by the JDT core; specifics depend on how
28  * compilation is being performed, ie from the command line, via the Tool
29  * interface, or within the IDE. This class manages the discovery of annotation
30  * processors and other information spanning multiple rounds of processing;
31  * context that is valid only within a single round is managed by
32  * {@link RoundDispatcher}. There may be multiple instances of this class;
33  * there is in general one of these for every Compiler that has annotation
34  * processing enabled. Within the IDE there will typically be one for every
35  * Java project, because each project potentially has a separate processor path.
36  *
37  * TODO: do something useful with _supportedOptions and _supportedAnnotationTypes.
38  */

39 public abstract class BaseAnnotationProcessorManager extends AbstractAnnotationProcessorManager
40         implements IProcessorProvider
41 {
42
43     protected PrintWriter JavaDoc _out;
44     protected PrintWriter JavaDoc _err;
45     protected BaseProcessingEnvImpl _processingEnv;
46     protected boolean _isFirstRound = true;
47     
48     /**
49      * The list of processors that have been loaded so far. A processor on this
50      * list has been initialized, but may not yet have been called to process().
51      */

52     protected List JavaDoc<ProcessorInfo> _processors = new ArrayList JavaDoc<ProcessorInfo>();
53     
54     // Tracing
55
protected boolean _printProcessorInfo = false;
56     protected boolean _printRounds = false;
57     protected int _round;
58     
59     /* (non-Javadoc)
60      * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#configure(org.eclipse.jdt.internal.compiler.batch.Main, java.lang.String[])
61      */

62     @Override JavaDoc
63     public void configure(Object JavaDoc batchCompiler, String JavaDoc[] options) {
64         // Implemented by BatchAnnotationProcessorManager.
65
throw new UnsupportedOperationException JavaDoc();
66     }
67
68     /* (non-Javadoc)
69      * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#configureFromPlatform(org.eclipse.jdt.internal.compiler.Compiler, java.lang.Object)
70      */

71     @Override JavaDoc
72     public void configureFromPlatform(Compiler JavaDoc compiler, Object JavaDoc compilationUnitLocator, Object JavaDoc javaProject) {
73         // Implemented by IdeAnnotationProcessorManager.
74
throw new UnsupportedOperationException JavaDoc();
75     }
76
77     @Override JavaDoc
78     public List JavaDoc<ProcessorInfo> getDiscoveredProcessors() {
79         return _processors;
80     }
81
82     @Override JavaDoc
83     public ICompilationUnit[] getDeletedUnits() {
84         return _processingEnv.getDeletedUnits();
85     }
86
87     @Override JavaDoc
88     public ICompilationUnit[] getNewUnits() {
89         return _processingEnv.getNewUnits();
90     }
91
92     @Override JavaDoc
93     public ReferenceBinding[] getNewClassFiles() {
94         return _processingEnv.getNewClassFiles();
95     }
96
97     @Override JavaDoc
98     public void reset() {
99         _processingEnv.reset();
100     }
101
102     /* (non-Javadoc)
103      * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setErr(java.io.PrintWriter)
104      */

105     @Override JavaDoc
106     public void setErr(PrintWriter JavaDoc err) {
107         _err = err;
108     }
109
110     /* (non-Javadoc)
111      * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setOut(java.io.PrintWriter)
112      */

113     @Override JavaDoc
114     public void setOut(PrintWriter JavaDoc out) {
115         _out = out;
116     }
117
118     /* (non-Javadoc)
119      * @see org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager#setProcessors(java.lang.Object[])
120      */

121     @Override JavaDoc
122     public void setProcessors(Object JavaDoc[] processors) {
123         // Only meaningful in batch mode.
124
throw new UnsupportedOperationException JavaDoc();
125     }
126
127     /**
128      * A single "round" of processing, in the sense implied in
129      * {@link javax.lang.annotation.processing.Processor}.
130      * <p>
131      * The Java 6 Processor spec contains ambiguities about how processors that support "*" are
132      * handled. Eclipse tries to match Sun's implementation in javac. What that actually does is
133      * analogous to inspecting the set of annotions found in the root units and adding an
134      * "imaginary" annotation if the set is empty. Processors are then called in order of discovery;
135      * for each processor, the intersection between the set of root annotations and the set of
136      * annotations the processor supports is calculated, and if it is non-empty, the processor is
137      * called. If the processor returns <code>true</code> then the intersection (including the
138      * imaginary annotation if one exists) is removed from the set of root annotations and the loop
139      * continues, until the set is empty. Of course, the imaginary annotation is not actually
140      * included in the set of annotations passed in to the processor. A processor's process() method
141      * is not called until its intersection set is non-empty, but thereafter it is called on every
142      * round. Note that even if a processor is not called in the first round, if it is called in
143      * subsequent rounds, it will be called in the order in which the processors were discovered,
144      * rather than being added to the end of the list.
145      */

146     @Override JavaDoc
147     public void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound) {
148         RoundEnvImpl roundEnv = new RoundEnvImpl(units, referenceBindings, isLastRound, _processingEnv);
149         if (_isFirstRound) {
150             _isFirstRound = false;
151         }
152         PrintWriter JavaDoc traceProcessorInfo = _printProcessorInfo ? _out : null;
153         PrintWriter JavaDoc traceRounds = _printRounds ? _out : null;
154         if (traceRounds != null) {
155             traceRounds.println("Round " + ++_round + ':'); //$NON-NLS-1$
156
}
157         RoundDispatcher dispatcher = new RoundDispatcher(
158                 this, roundEnv, roundEnv.getRootAnnotations(), traceProcessorInfo, traceRounds);
159         dispatcher.round();
160     }
161
162 }
163
Popular Tags