KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > compiler > AnnotationGrammar


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;
19
20 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance;
21 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationTypeElementDeclaration;
22 import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue;
23 import org.apache.beehive.netui.compiler.typesystem.declaration.Declaration;
24 import org.apache.beehive.netui.compiler.typesystem.declaration.MemberDeclaration;
25 import org.apache.beehive.netui.compiler.typesystem.env.AnnotationProcessorEnvironment;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33
34
35 /**
36  * Our base class for customizable annotation tag grammars. It has stock behavior for basic
37  * things like making sure required attributes exist, and provides plugin points for more
38  * complex checks.
39  */

40 public abstract class AnnotationGrammar
41         implements JpfLanguageConstants
42 {
43     /**
44      * If this tag requires a particular runtime version...
45      */

46     private String JavaDoc _requiredRuntimeVersion = null;
47     private RuntimeVersionChecker _runtimeVersionChecker;
48     private AnnotationProcessorEnvironment _env;
49     private Diagnostics _diagnostics;
50     private Map JavaDoc _memberGrammars = new HashMap JavaDoc();
51     private Map JavaDoc _memberArrayGrammars = new HashMap JavaDoc();
52     private Map JavaDoc _memberTypes = new HashMap JavaDoc();
53     
54
55     /**
56      * @param requiredRuntimeVersion causes an error to be produced if the version in the manifest of beehive-netui-pageflow.jar
57      * is not high enough.
58      */

59     protected AnnotationGrammar( AnnotationProcessorEnvironment env, Diagnostics diags, String JavaDoc requiredRuntimeVersion,
60                                  RuntimeVersionChecker runtimeVersionChecker )
61     {
62         _env = env;
63         _diagnostics = diags;
64         _runtimeVersionChecker = runtimeVersionChecker;
65         _requiredRuntimeVersion = requiredRuntimeVersion;
66     }
67
68     public final AnnotationProcessorEnvironment getEnv()
69     {
70         return _env;
71     }
72     
73     public Diagnostics getDiagnostics()
74     {
75         return _diagnostics;
76     }
77
78     public final Object JavaDoc check( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
79                                MemberDeclaration classMember )
80             throws FatalCompileTimeException
81     {
82         return check( annotation, parentAnnotations, classMember, -1 );
83     }
84     
85     public final Object JavaDoc check( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
86                                MemberDeclaration classMember, int annotationArrayIndex )
87             throws FatalCompileTimeException
88     {
89         if ( ! beginCheck( annotation, parentAnnotations, classMember ) ) return null;
90         
91         Map JavaDoc valuesPresent = annotation.getElementValues();
92         HashSet JavaDoc wasPresent = new HashSet JavaDoc();
93         HashMap JavaDoc checkResults = new HashMap JavaDoc();
94         
95         if ( parentAnnotations == null ) parentAnnotations = new AnnotationInstance[0];
96         int oldLen = parentAnnotations.length;
97         AnnotationInstance[] parentsIncludingMe = new AnnotationInstance[oldLen + 1];
98         System.arraycopy( parentAnnotations, 0, parentsIncludingMe, 0, oldLen );
99         parentsIncludingMe[oldLen] = annotation;
100         
101         for ( Iterator JavaDoc ii = valuesPresent.entrySet().iterator(); ii.hasNext(); )
102         {
103             Map.Entry JavaDoc i = ( Map.Entry JavaDoc ) ii.next();
104             AnnotationTypeElementDeclaration decl = ( AnnotationTypeElementDeclaration ) i.getKey();
105             AnnotationValue value = ( AnnotationValue ) i.getValue();
106             String JavaDoc memberName = decl.getSimpleName();
107             
108             wasPresent.add( memberName );
109             onCheckMember( decl, value, annotation, parentAnnotations, classMember );
110             Object JavaDoc grammarOrType = null;
111             
112             if ( ( grammarOrType = _memberGrammars.get( memberName ) ) != null )
113             {
114                 AnnotationGrammar childGrammar = ( AnnotationGrammar ) grammarOrType;
115                 
116                 if ( childGrammar != null ) // it will be non-null unless there are other, more basic, errors
117
{
118                     Object JavaDoc result =
119                         childGrammar.check( ( AnnotationInstance ) value.getValue(), parentsIncludingMe, classMember );
120                     
121                     if ( result != null )
122                     {
123                         checkResults.put( memberName, result );
124                     }
125                 }
126             }
127             else if ( ( grammarOrType = _memberArrayGrammars.get( memberName ) ) != null )
128             {
129                 AnnotationGrammar arrayGrammar = ( AnnotationGrammar ) grammarOrType;
130             
131                 if ( arrayGrammar != null )
132                 {
133                     List JavaDoc annotations = CompilerUtils.getAnnotationArray( value );
134                 
135                     for ( int j = 0; j < annotations.size(); ++j )
136                     {
137                         AnnotationInstance ann = ( AnnotationInstance ) annotations.get( j );
138                         arrayGrammar.check( ann, parentsIncludingMe, classMember, j );
139                     }
140                 }
141             }
142             else
143             {
144                 AnnotationMemberType memberType = ( AnnotationMemberType ) _memberTypes.get( memberName );
145                 
146                 if ( memberType != null ) // it will be non-null unless there are other, more basic, errors
147
{
148                     Object JavaDoc result =
149                             memberType.check( decl, value, parentsIncludingMe, classMember, annotationArrayIndex );
150                     if ( result != null ) checkResults.put( memberName, result );
151                 }
152             }
153         }
154         
155         return endCheck( annotation, parentAnnotations, classMember, wasPresent, checkResults );
156     }
157     
158     public final boolean beginCheck( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
159                                      MemberDeclaration classMember )
160             throws FatalCompileTimeException
161     {
162         //
163
// First check to see if there's a required runtime version.
164
//
165
if ( ! _runtimeVersionChecker.checkRuntimeVersion( _requiredRuntimeVersion, annotation, _diagnostics,
166                                                            "error.required-runtime-version-annotation",
167                                                            new Object JavaDoc[]{ PAGEFLOW_RUNTIME_JAR } ) )
168         {
169             return false;
170         }
171         
172         return onBeginCheck( annotation, parentAnnotations, classMember ); // for derived classes
173
}
174
175     protected void addError( Declaration element, String JavaDoc key )
176     {
177         getDiagnostics().addError( element, key, null );
178     }
179     
180     protected void addError( Declaration element, String JavaDoc key, Object JavaDoc[] args )
181     {
182         getDiagnostics().addErrorArrayArgs( element, key, args );
183     }
184     
185     protected void addError( Declaration element, String JavaDoc key, Object JavaDoc arg )
186     {
187         getDiagnostics().addError( element, key, arg );
188     }
189     
190     protected void addError( Declaration element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
191     {
192         getDiagnostics().addError( element, key, arg1, arg2 );
193     }
194     
195     protected void addError( Declaration element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
196     {
197         getDiagnostics().addError( element, key, arg1, arg2, arg3 );
198     }
199     
200     protected void addError( AnnotationValue element, String JavaDoc key )
201     {
202         getDiagnostics().addError( element, key, null );
203     }
204     
205     protected void addError( AnnotationValue element, String JavaDoc key, Object JavaDoc[] args )
206     {
207         getDiagnostics().addErrorArrayArgs( element, key, args );
208     }
209     
210     protected void addError( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1 )
211     {
212         getDiagnostics().addError( element, key, arg1 );
213     }
214     
215     protected void addError( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
216     {
217         getDiagnostics().addError( element, key, arg1, arg2 );
218     }
219     
220     protected void addError( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
221     {
222         getDiagnostics().addError( element, key, arg1, arg2, arg3 );
223     }
224     
225     protected void addError( AnnotationInstance element, String JavaDoc key )
226     {
227         getDiagnostics().addError( element, key, null );
228     }
229     
230     protected void addError( AnnotationInstance element, String JavaDoc key, Object JavaDoc[] args )
231     {
232         getDiagnostics().addErrorArrayArgs( element, key, args );
233     }
234     
235     protected void addError( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1 )
236     {
237         getDiagnostics().addError( element, key, arg1 );
238     }
239     
240     protected void addError( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
241     {
242         getDiagnostics().addError( element, key, arg1, arg2 );
243     }
244     
245     protected void addError( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
246     {
247         getDiagnostics().addError( element, key, arg1, arg2, arg3 );
248     }
249     
250     protected void addWarning( Declaration element, String JavaDoc key )
251     {
252         getDiagnostics().addWarning( element, key, null );
253     }
254     
255     protected void addWarning( Declaration element, String JavaDoc key, Object JavaDoc[] args )
256     {
257         getDiagnostics().addWarningArrayArgs( element, key, args );
258     }
259     
260     protected void addWarning( Declaration element, String JavaDoc key, Object JavaDoc arg )
261     {
262         getDiagnostics().addWarning( element, key, arg );
263     }
264     
265     protected void addWarning( Declaration element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
266     {
267         getDiagnostics().addWarning( element, key, arg1, arg2 );
268     }
269     
270     protected void addWarning( Declaration element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
271     {
272         getDiagnostics().addWarning( element, key, arg1, arg2, arg3 );
273     }
274     
275     protected void addWarning( AnnotationValue element, String JavaDoc key )
276     {
277         getDiagnostics().addWarning( element, key, null );
278     }
279     
280     protected void addWarning( AnnotationValue element, String JavaDoc key, Object JavaDoc[] args )
281     {
282         getDiagnostics().addWarningArrayArgs( element, key, args );
283     }
284     
285     protected void addWarning( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1 )
286     {
287         getDiagnostics().addWarning( element, key, arg1 );
288     }
289     
290     protected void addWarning( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
291     {
292         getDiagnostics().addWarning( element, key, arg1, arg2 );
293     }
294     
295     protected void addWarning( AnnotationValue element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
296     {
297         getDiagnostics().addWarning( element, key, arg1, arg2, arg3 );
298     }
299     
300     protected void addWarning( AnnotationInstance element, String JavaDoc key )
301     {
302         getDiagnostics().addWarning( element, key, null );
303     }
304     
305     protected void addWarning( AnnotationInstance element, String JavaDoc key, Object JavaDoc[] args )
306     {
307         getDiagnostics().addWarningArrayArgs( element, key, args );
308     }
309     
310     protected void addWarning( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1 )
311     {
312         getDiagnostics().addWarning( element, key, arg1 );
313     }
314     
315     protected void addWarning( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2 )
316     {
317         getDiagnostics().addWarning( element, key, arg1, arg2 );
318     }
319     
320     protected void addWarning( AnnotationInstance element, String JavaDoc key, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3 )
321     {
322         getDiagnostics().addWarning( element, key, arg1, arg2, arg3 );
323     }
324     
325     /**
326      * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
327      */

328     public final Object JavaDoc endCheck( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
329                                   MemberDeclaration classMember, Set JavaDoc wasPresent, Map JavaDoc checkResults )
330     {
331         //
332
// Check mutually-exclusive attributes and child annotations.
333
//
334
String JavaDoc[][] mutuallyExclusiveAttrs = getMutuallyExclusiveAttrs();
335         for ( int i = 0; mutuallyExclusiveAttrs != null && i < mutuallyExclusiveAttrs.length; ++i )
336         {
337             String JavaDoc alreadyFound = null;
338             
339             for ( int j = 0; j < mutuallyExclusiveAttrs[i].length; ++j )
340             {
341                 String JavaDoc thisAttr = mutuallyExclusiveAttrs[i][j];
342                 
343                 if ( wasPresent.contains( thisAttr ) )
344                 {
345                     if ( alreadyFound == null )
346                     {
347                         alreadyFound = thisAttr;
348                     }
349                     else
350                     {
351                         String JavaDoc errorKey = "error.atmost-one-may-exist-" + mutuallyExclusiveAttrs[i].length;
352                         getDiagnostics().addErrorArrayArgs( annotation, errorKey, mutuallyExclusiveAttrs[i] );
353                     }
354                 }
355             }
356         }
357         
358         //
359
// Check required attributes and child annotations.
360
//
361
String JavaDoc[][] requiredAttrs = getRequiredAttrs();
362         for ( int i = 0; requiredAttrs != null && i < requiredAttrs.length; ++i )
363         {
364             boolean foundOne = false;
365             
366             for ( int j = 0; j < requiredAttrs[i].length; ++j )
367             {
368                 String JavaDoc thisAttr = requiredAttrs[i][j];
369                 
370                 if ( wasPresent.contains( thisAttr ) )
371                 {
372                     foundOne = true;
373                     break;
374                 }
375             }
376
377             if ( ! foundOne )
378             {
379                 String JavaDoc errorKey = "error.atleast-one-must-exist-" + requiredAttrs[i].length;
380                 getDiagnostics().addErrorArrayArgs( annotation, errorKey, requiredAttrs[i] );
381             }
382         }
383         
384         //
385
// Check inter-dependencies for attributes and child annotations.
386
//
387
String JavaDoc[][] attrDependencies = getAttrDependencies();
388         for ( int i = 0; attrDependencies != null && i < attrDependencies.length; ++i )
389         {
390             String JavaDoc thisAttr = attrDependencies[i][0];
391             
392             if ( wasPresent.contains( thisAttr ) )
393             {
394                 boolean foundOne = false;
395                 
396                 for ( int j = 1; j < attrDependencies[i].length; ++j )
397                 {
398                     if ( wasPresent.contains( attrDependencies[i][j] ) )
399                     {
400                         foundOne = true;
401                         break;
402                     }
403                 }
404                 
405                 if ( ! foundOne )
406                 {
407                     String JavaDoc key = "error.attr-dependency-not-found-" + ( attrDependencies[i].length - 1 );
408                     getDiagnostics().addErrorArrayArgs( annotation, key, attrDependencies[i] );
409                 }
410             }
411         }
412         
413         return onEndCheck( annotation, parentAnnotations, classMember, checkResults ); // for derived classes
414
}
415
416     protected boolean onBeginCheck( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
417                                     MemberDeclaration classMember )
418             throws FatalCompileTimeException
419     {
420         return true;
421     }
422     
423     /**
424      * @param checkResults map of member-name (String) -> result-from-checking (Object)
425      * @return a result (any Object) that will be passed back to the parent checker. May be null</code>.
426      */

427     protected Object JavaDoc onEndCheck( AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
428                                  MemberDeclaration classMember, Map JavaDoc checkResults )
429     {
430         return null;
431     }
432     
433     protected void onCheckMember( AnnotationTypeElementDeclaration memberDecl, AnnotationValue member,
434                                   AnnotationInstance annotation, AnnotationInstance[] parentAnnotations,
435                                   MemberDeclaration classMember )
436     {
437     }
438     
439     /**
440      * Each entry in this array (a String[]) lists mutually exclusive attributes.
441      */

442     public String JavaDoc[][] getMutuallyExclusiveAttrs()
443     {
444         return null;
445     }
446     
447     /**
448      * Each entry in this array (a String[]) lists attributes of which one must exist in this tag.
449      */

450     public String JavaDoc[][] getRequiredAttrs()
451     {
452         return null;
453     }
454     
455     /**
456      * Each entry in this array (a String[]) is an array whose first element is an attribute that
457      * requires at least one of the subsequent elements to exist as an attribute.
458      */

459     public String JavaDoc[][] getAttrDependencies()
460     {
461         return null;
462     }
463     
464     protected void addMemberGrammar( String JavaDoc memberName, AnnotationGrammar grammar )
465     {
466         _memberGrammars.put( memberName, grammar );
467     }
468     
469     protected void addMemberArrayGrammar( String JavaDoc memberName, AnnotationGrammar grammar )
470     {
471         _memberArrayGrammars.put( memberName, grammar );
472     }
473     
474     protected void addMemberType( String JavaDoc memberName, AnnotationMemberType type )
475     {
476         _memberTypes.put( memberName, type );
477     }
478
479     public String JavaDoc getRequiredRuntimeVersion()
480     {
481         return _requiredRuntimeVersion;
482     }
483
484     public RuntimeVersionChecker getRuntimeVersionChecker()
485     {
486         return _runtimeVersionChecker;
487     }
488 }
489
Popular Tags