KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > compiler > processor > TwoPhaseAnnotationProcessor


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

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

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

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

101     public void check()
102         throws FatalCompileTimeException
103     {
104         HashSet declsToCheck = new HashSet();
105         
106         //
107
// First, build up the Set of declarations to check. We don't want any duplicates.
108
//
109
for ( int i = 0; i < _atds.length; ++i )
110         {
111             AnnotationTypeDeclaration atd = _atds[i];
112             Declaration[] decls = getAnnotationProcessorEnvironment().getDeclarationsAnnotatedWith( atd );
113             for ( int j = 0; j < decls.length; j++ )
114             {
115                 declsToCheck.add( decls[j] );
116             }
117         }
118         
119         //
120
// Now, check the declarations.
121
//
122
for ( Iterator i = declsToCheck.iterator(); i.hasNext(); )
123         {
124             Declaration decl = ( Declaration ) i.next();
125             check( decl );
126         }
127     }
128
129     /**
130      * Emits additional artifacts for input Declarations that are annotated with
131      * annotations claimed by this AnnotationProcessor.
132      */

133     public void generate()
134     {
135         try
136         {
137             for ( int i = 0; i < _atds.length; i++ )
138             {
139                 AnnotationTypeDeclaration atd = _atds[i];
140                 Declaration[] decls = getAnnotationProcessorEnvironment().getDeclarationsAnnotatedWith( atd );
141                 
142                 for ( int j = 0; j < decls.length; j++ )
143                 {
144                     generate( decls[j] );
145                 }
146             }
147         }
148         catch ( FatalCompileTimeException e )
149         {
150             e.printDiagnostic( this );
151         }
152     }
153
154     /**
155      * The check method is responsible for all semantic validation of the input Declaration.
156      * <p/>
157      * All semantic errors/warnings associated with the input Declaration should
158      * be output during check via methods on {@link Diagnostics}.
159      * <p/>
160      * If the presence of the input Declaration implies the need to add new files,
161      * and those files need to be visible during the check phase for
162      * other Declarations, then the AnnotationProcessorEnvironment's Filer API should be
163      * used to add those files in this phase. The adding of such files at this point
164      * should typically not result in their emission to persistent storage (i.e. disk),
165      * but rather be kept in memory to be referenced by the check phase of other
166      * Declarations.
167      */

168     public abstract void check( Declaration decl )
169         throws FatalCompileTimeException;
170
171     /**
172      * The generate method is responsible for the generation of any additional artifacts
173      * (source, class, or binary) that are derived from the input Declaration.
174      */

175     public abstract void generate( Declaration decl )
176             throws FatalCompileTimeException;
177
178     //
179
// Helper functions for handling diagnostics
180
//
181

182     protected String JavaDoc getResourceString( String JavaDoc id, Object JavaDoc[] args )
183     {
184         ResourceBundle rb = ResourceBundle.getBundle( getClass().getPackage().getName() + ".strings", _locale );
185         String JavaDoc pattern = rb.getString( id );
186         return MessageFormat.format( pattern, args );
187     }
188
189     private AnnotationTypeDeclaration[] _atds;
190     private Locale _locale;
191 }
192
Popular Tags