KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2006, 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.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import javax.annotation.processing.RoundEnvironment;
22 import javax.lang.model.element.Element;
23 import javax.lang.model.element.TypeElement;
24
25 /**
26  * Manages context during a single round of annotation processing.
27  */

28 public class RoundDispatcher {
29     
30     private final Set JavaDoc<TypeElement> _unclaimedAnnotations;
31     private final RoundEnvironment _roundEnv;
32     private final IProcessorProvider _provider;
33     private boolean _searchForStar = false;
34     private final PrintWriter JavaDoc _traceProcessorInfo;
35     private final PrintWriter JavaDoc _traceRounds;
36     
37     /**
38      * Processors discovered so far. This list may grow during the
39      * course of a round, as additional processors are discovered.
40      */

41     private final List JavaDoc<ProcessorInfo> _processors;
42     
43     /**
44      * @param rootAnnotations a possibly empty but non-null set of annotations on the
45      * root compilation units of this round. A local copy of the set will be made, to
46      * avoid modifying the set passed in.
47      * @param traceProcessorInfo a PrintWriter that processor trace output will be sent
48      * to, or null if tracing is not desired.
49      * @param traceRounds
50      */

51     public RoundDispatcher(
52             IProcessorProvider provider,
53             RoundEnvironment env,
54             Set JavaDoc<TypeElement> rootAnnotations,
55             PrintWriter JavaDoc traceProcessorInfo,
56             PrintWriter JavaDoc traceRounds)
57     {
58         _provider = provider;
59         _processors = provider.getDiscoveredProcessors();
60         _roundEnv = env;
61         _unclaimedAnnotations = new HashSet JavaDoc<TypeElement>(rootAnnotations);
62         _traceProcessorInfo = traceProcessorInfo;
63         _traceRounds = traceRounds;
64     }
65     
66     /**
67      * Handle a complete round, dispatching to all appropriate processors.
68      */

69     public void round()
70     {
71         if (null != _traceRounds) {
72             StringBuilder JavaDoc sbElements = new StringBuilder JavaDoc();
73             sbElements.append("\tinput files: {"); //$NON-NLS-1$
74
Iterator JavaDoc<? extends Element> iElements = _roundEnv.getRootElements().iterator();
75             boolean hasNext = iElements.hasNext();
76             while (hasNext) {
77                 sbElements.append(iElements.next());
78                 hasNext = iElements.hasNext();
79                 if (hasNext) {
80                     sbElements.append(',');
81                 }
82             }
83             sbElements.append('}');
84             _traceRounds.println(sbElements.toString());
85             
86             StringBuilder JavaDoc sbAnnots = new StringBuilder JavaDoc();
87             sbAnnots.append("\tannotations: ["); //$NON-NLS-1$
88
Iterator JavaDoc<TypeElement> iAnnots = _unclaimedAnnotations.iterator();
89             hasNext = iAnnots.hasNext();
90             while (hasNext) {
91                 sbAnnots.append(iAnnots.next());
92                 hasNext = iAnnots.hasNext();
93                 if (hasNext) {
94                     sbAnnots.append(',');
95                 }
96             }
97             sbAnnots.append(']');
98             _traceRounds.println(sbAnnots.toString());
99             
100             _traceRounds.println("\tlast round: " + _roundEnv.processingOver()); //$NON-NLS-1$
101
}
102         
103         // If there are no root annotations, try to find a processor that claims "*"
104
_searchForStar = _unclaimedAnnotations.isEmpty();
105         
106         // Iterate over all the already-found processors, giving each one a chance at the unclaimed
107
// annotations. If a processor is called at all, it is called on every subsequent round
108
// including the final round, but it may be called with an empty set of annotations.
109
for (ProcessorInfo pi : _processors) {
110             handleProcessor(pi);
111         }
112         
113         // If there are any unclaimed annotations, or if there were no root annotations and
114
// we have not yet run into a processor that claimed "*", continue discovery.
115
while (_searchForStar || !_unclaimedAnnotations.isEmpty()) {
116             ProcessorInfo pi = _provider.discoverNextProcessor();
117             if (null == pi) {
118                 // There are no more processors to be discovered.
119
break;
120             }
121             handleProcessor(pi);
122         }
123         
124         // TODO: If !unclaimedAnnos.isEmpty(), issue a warning.
125
}
126     
127     /**
128      * Evaluate a single processor. Depending on the unclaimed annotations,
129      * the annotations this processor supports, and whether it has already been
130      * called in a previous round, possibly call its process() method.
131      */

132     private void handleProcessor(ProcessorInfo pi)
133     {
134         try {
135             Set JavaDoc<TypeElement> annotationsToProcess = new HashSet JavaDoc<TypeElement>();
136             boolean shouldCall = pi.computeSupportedAnnotations(
137                     _unclaimedAnnotations, annotationsToProcess);
138             if (shouldCall) {
139                 boolean claimed = pi._processor.process(annotationsToProcess, _roundEnv);
140                 if (null != _traceProcessorInfo && !_roundEnv.processingOver()) {
141                     StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
142                     sb.append("Processor "); //$NON-NLS-1$
143
sb.append(pi._processor.getClass().getName());
144                     sb.append(" matches ["); //$NON-NLS-1$
145
Iterator JavaDoc<TypeElement> i = annotationsToProcess.iterator();
146                     boolean hasNext = i.hasNext();
147                     while (hasNext) {
148                         sb.append(i.next());
149                         hasNext = i.hasNext();
150                         if (hasNext) {
151                             sb.append(' ');
152                         }
153                     }
154                     sb.append("] and returns "); //$NON-NLS-1$
155
sb.append(claimed);
156                     _traceProcessorInfo.println(sb.toString());
157                 }
158                 if (claimed) {
159                     // The processor claimed its annotations.
160
_unclaimedAnnotations.removeAll(annotationsToProcess);
161                     if (pi.supportsStar()) {
162                         _searchForStar = false;
163                     }
164                 }
165             }
166         } catch (Exception JavaDoc e) {
167             // If a processor throws an exception (as opposed to reporting an error),
168
// report it and abort compilation by throwing AbortCompilation.
169
_provider.reportProcessorException(pi._processor, e);
170         }
171     }
172     
173 }
174
Popular Tags