KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > controls > runtime > generator > apt > TwoPhaseAnnotationProcessor


1 package org.apache.beehive.controls.runtime.generator.apt;
2
3 /*
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * $Header:$
19  */

20
21 import java.util.*;
22 import java.text.MessageFormat JavaDoc;
23
24 import com.sun.mirror.apt.AnnotationProcessor;
25 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
26 import com.sun.mirror.declaration.AnnotationTypeDeclaration;
27 import com.sun.mirror.declaration.Declaration;
28
29 import org.apache.beehive.controls.runtime.generator.CodeGenerationException;
30
31 /**
32  * The TwoPhaseAnnotationProcessor class is an abstract class that implements the APT
33  * AnnotationProcessor interface. It breaks the work of the process() method of the
34  * AnnotationProcessor down into two distinct phases, represented as abstract method
35  * of TwoPhaseAnnotationProcessor that are to be implemented by concrete subclasses.
36  * <p>
37  * The two phases of processing are:
38  * <ul>
39  * <li>The <b>check</b> phase is used to validate input Declarations that have been
40  * annotated with annotations claimed by the processor to ensure that it
41  * is semantically valid. If the presence of the input Declaration implies the need
42  * to add new files, and those files need to be visible during the check phase for
43  * other Declarations, then the AnnotationProcessorEnvironment's Filer API should be
44  * used to add those files in this phase. The adding of such files at this point
45  * should typically not result in their emission to persistent storage (i.e. disk),
46  * but rather be kept in memory to be referenced by the check phase of other
47  * Declarations.
48  * <li>The <b>generate</b> phase will actually emit any source, binary, or class files
49  * that are derived from the input Declaration, including files added via the Filer
50  * API during the check phase. The Filer API may also be used in this phase to add
51  * new files, however, such additions will not be visible during the check phase of
52  * any Declarations.
53  * </ul>
54  * <p>
55  * The benefits of breaking process() down into check() and generate() phases are:
56  * <ol>
57  * <li>Makes it possible to perform the semantic validation of Declarations without
58  * necessarily resulting in code generation.
59  * <li>Provides a clearer association between input Declarations and generator output.
60  * </ol>
61  * TwoPhaseAnnotationProcessor is intended provide a uniform mechanism for writing
62  * AnnotationProcessor implementations that can be used in tooling environments more
63  * sophisticated than command-line tools (that may not do all their work on source
64  * in a single pass). Such environments will typically also provide implementations
65  * of the AnnotationProcessorEnvironment and associated interfaces (Messager,
66  * Filer etc).
67  */

68 abstract public class TwoPhaseAnnotationProcessor
69         extends Diagnostics
70         implements AnnotationProcessor
71 {
72     public TwoPhaseAnnotationProcessor(Set<AnnotationTypeDeclaration> atds,
73                                        AnnotationProcessorEnvironment env)
74     {
75         super( env );
76         _atds = atds;
77         _locale = Locale.getDefault();
78     }
79
80     /**
81      * Implements AnnotationProcessor.process() as two phases, "check" and "generate".
82      * "generate" will not be called if "check" emitted any errors (via printError()).
83      */

84     public void process()
85     {
86         check();
87
88         // Do not call generate if check resulted in errors.
89
if ( !hasErrors() )
90             generate();
91     }
92
93     /**
94      * Performs semantic validation of input Declarations that are annotated with
95      * annotations claimed by this AnnotationProcessor.
96      */

97     public void check()
98     {
99         for (AnnotationTypeDeclaration atd : _atds)
100         {
101             Collection<Declaration> decls = getAnnotationProcessorEnvironment().getDeclarationsAnnotatedWith(atd);
102             for (Declaration decl : decls)
103             {
104                 check(decl);
105             }
106         }
107     }
108
109     /**
110      * Emits additional artifacts for input Declarations that are annotated with
111      * annotations claimed by this AnnotationProcessor.
112      */

113     public void generate() throws CodeGenerationException
114     {
115         for (AnnotationTypeDeclaration atd : _atds)
116         {
117             Collection<Declaration> decls = getAnnotationProcessorEnvironment().getDeclarationsAnnotatedWith(atd);
118             for (Declaration decl : decls)
119             {
120                 generate(decl);
121             }
122         }
123     }
124     
125     /**
126      * The check method is responsible for all semantic validation of the input Declaration.
127      * <p>
128      * All semantic errors/warnings associated with the input Declaration should
129      * be output during check via the {@link #printError} and
130      * {@link #printWarning} methods. If an implementation
131      * bypasses printError, it must override {@link #hasErrors()} to ensure correct behaviour.
132      * <p>
133      * If the presence of the input Declaration implies the need to add new files,
134      * and those files need to be visible during the check phase for
135      * other Declarations, then the AnnotationProcessorEnvironment's Filer API should be
136      * used to add those files in this phase. The adding of such files at this point
137      * should typically not result in their emission to persistent storage (i.e. disk),
138      * but rather be kept in memory to be referenced by the check phase of other
139      * Declarations.
140      */

141     abstract public void check(Declaration decl);
142
143     /**
144      * The generate method is responsible for the generation of any additional artifacts
145      * (source, class, or binary) that are derived from the input Declaration.
146      */

147     abstract public void generate(Declaration decl);
148
149     //
150
// Helper functions for handling diagnostics
151
//
152

153     /**
154      * Report an error detected during the "check" phase. The presence of errors
155      * will suppress execution of the "generate" phase.
156      */

157     public void printError( Declaration d, String JavaDoc id, Object JavaDoc... args )
158     {
159         addError( d, id, args );
160     }
161
162     /**
163      * Report a warning detected during the "check" phase. The presence of warnings
164      * will not affect execution of the "generate" phase.
165      */

166     public void printWarning( Declaration d, String JavaDoc id, Object JavaDoc... args )
167     {
168         addWarning( d, id, args );
169     }
170
171     protected String JavaDoc getResourceString( String JavaDoc id, Object JavaDoc... args )
172     {
173         ResourceBundle rb = ResourceBundle.getBundle(
174             this.getClass().getPackage().getName() + ".strings", _locale );
175         String JavaDoc pattern = rb.getString(id);
176         return MessageFormat.format(pattern, args);
177     }
178
179     Set<AnnotationTypeDeclaration> _atds;
180     Locale _locale;
181 }
182
Popular Tags