Source Code Cross Referenced for FlowControllerChecker.java in  » Library » Apache-beehive-1.0.2-src » org » apache » beehive » netui » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache beehive 1.0.2 src » org.apache.beehive.netui.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         *
017:         * $Header:$
018:         */
019:        package org.apache.beehive.netui.compiler;
020:
021:        import org.apache.beehive.netui.compiler.genmodel.GenStrutsApp;
022:        import org.apache.beehive.netui.compiler.grammar.ActionGrammar;
023:        import org.apache.beehive.netui.compiler.grammar.ExceptionHandlerGrammar;
024:        import org.apache.beehive.netui.compiler.grammar.WebappPathType;
025:        import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationInstance;
026:        import org.apache.beehive.netui.compiler.typesystem.declaration.AnnotationValue;
027:        import org.apache.beehive.netui.compiler.typesystem.declaration.ClassDeclaration;
028:        import org.apache.beehive.netui.compiler.typesystem.declaration.FieldDeclaration;
029:        import org.apache.beehive.netui.compiler.typesystem.declaration.MethodDeclaration;
030:        import org.apache.beehive.netui.compiler.typesystem.declaration.Modifier;
031:        import org.apache.beehive.netui.compiler.typesystem.declaration.PackageDeclaration;
032:        import org.apache.beehive.netui.compiler.typesystem.declaration.ParameterDeclaration;
033:        import org.apache.beehive.netui.compiler.typesystem.declaration.TypeDeclaration;
034:        import org.apache.beehive.netui.compiler.typesystem.env.CoreAnnotationProcessorEnv;
035:        import org.apache.beehive.netui.compiler.typesystem.type.ClassType;
036:        import org.apache.beehive.netui.compiler.typesystem.type.TypeInstance;
037:        import org.apache.beehive.netui.compiler.processor.SilentDiagnostics;
038:
039:        import java.io.File;
040:        import java.io.FilenameFilter;
041:        import java.io.IOException;
042:        import java.util.ArrayList;
043:        import java.util.Collection;
044:        import java.util.HashMap;
045:        import java.util.HashSet;
046:        import java.util.Iterator;
047:        import java.util.List;
048:        import java.util.Map;
049:        import java.util.Set;
050:
051:        public abstract class FlowControllerChecker extends BaseChecker
052:                implements  JpfLanguageConstants {
053:            private AnnotationGrammar _controllerGrammar;
054:            private AnnotationGrammar _actionGrammar;
055:            private AnnotationGrammar _exceptionHandlerGrammar;
056:            private AnnotationGrammar _actionGrammarSilentDiagnostics;
057:            private AnnotationGrammar _exceptionHandlerGrammarSilentDiagnostics;
058:            private FormBeanChecker _formBeanChecker;
059:            private Map _checkResultMap;
060:
061:            protected FlowControllerChecker(CoreAnnotationProcessorEnv env,
062:                    FlowControllerInfo fcInfo, Diagnostics diags) {
063:                super (env, fcInfo, diags);
064:            }
065:
066:            protected void doAdditionalClassChecks(ClassDeclaration jpfClass) {
067:            }
068:
069:            protected Map getCheckResultMap() {
070:                return _checkResultMap;
071:            }
072:
073:            protected abstract String getDesiredBaseClass(
074:                    ClassDeclaration jclass);
075:
076:            protected abstract AnnotationGrammar getControllerGrammar();
077:
078:            public Map onCheck(ClassDeclaration jclass)
079:                    throws FatalCompileTimeException {
080:                FlowControllerInfo fcInfo = getFCSourceFileInfo();
081:
082:                _checkResultMap = new HashMap();
083:                _controllerGrammar = getControllerGrammar();
084:                _actionGrammar = new ActionGrammar(getEnv(), getDiagnostics(),
085:                        getRuntimeVersionChecker(), fcInfo);
086:                _exceptionHandlerGrammar = new ExceptionHandlerGrammar(
087:                        getEnv(), getDiagnostics(), getRuntimeVersionChecker(),
088:                        fcInfo);
089:                _formBeanChecker = new FormBeanChecker(getEnv(),
090:                        getDiagnostics());
091:
092:                SilentDiagnostics silentDiagnostics = new SilentDiagnostics();
093:                _actionGrammarSilentDiagnostics = new ActionGrammar(getEnv(),
094:                        silentDiagnostics, getRuntimeVersionChecker(), fcInfo);
095:                _exceptionHandlerGrammarSilentDiagnostics = new ExceptionHandlerGrammar(
096:                        getEnv(), silentDiagnostics,
097:                        getRuntimeVersionChecker(), fcInfo);
098:
099:                fcInfo.startBuild(getEnv(), jclass);
100:
101:                try {
102:                    return onCheckInternal(jclass);
103:                } finally {
104:                    fcInfo.endBuild();
105:                }
106:            }
107:
108:            private Map onCheckInternal(ClassDeclaration jclass)
109:                    throws FatalCompileTimeException {
110:                FlowControllerInfo fcInfo = getFCSourceFileInfo();
111:
112:                //
113:                // Check the base class.
114:                //
115:                String desiredBaseClass = getDesiredBaseClass(jclass);
116:                if (desiredBaseClass != null
117:                        && !CompilerUtils.isAssignableFrom(desiredBaseClass,
118:                                jclass, getEnv())) {
119:                    getDiagnostics().addError(jclass,
120:                            "error.does-not-extend-base", desiredBaseClass);
121:                }
122:
123:                //
124:                // Check the annotations on the class.
125:                //
126:                startCheckClass(jclass);
127:
128:                //
129:                // Check the fields.  Note that we're checking public and protected inherited fields, too.
130:                //
131:                Collection fields = CompilerUtils.getClassFields(jclass);
132:
133:                for (Iterator ii = fields.iterator(); ii.hasNext();) {
134:                    FieldDeclaration field = (FieldDeclaration) ii.next();
135:                    checkField(field, jclass);
136:                }
137:
138:                //
139:                // Check the methods.  Note that we're checking public and protected inherited methods, too.
140:                //
141:                MethodDeclaration[] methods = CompilerUtils.getClassMethods(
142:                        jclass, null);
143:
144:                for (int i = 0; i < methods.length; i++) {
145:                    MethodDeclaration method = methods[i];
146:                    TypeDeclaration declaringType = method.getDeclaringType();
147:
148:                    //
149:                    // Only add diagnostics if the method is in this class, or if it's inherited from a class that's *not* on
150:                    // sourcepath (i.e., its SourcePosition is null).
151:                    //
152:                    if (declaringType.equals(jclass)
153:                            || declaringType.getPosition() == null) {
154:                        checkMethod(method, jclass, _actionGrammar,
155:                                _exceptionHandlerGrammar);
156:                    } else {
157:                        //
158:                        // We still want to run the checks, which aggregate information into the FlowControllerInfo.  We just
159:                        // don't want diagnostics to be printed.
160:                        //
161:                        checkMethod(method, jclass,
162:                                _actionGrammarSilentDiagnostics,
163:                                _exceptionHandlerGrammarSilentDiagnostics);
164:                    }
165:                }
166:
167:                //
168:                // Check the inner classes.
169:                //
170:                Collection innerTypes = CompilerUtils
171:                        .getClassNestedTypes(jclass);
172:
173:                for (Iterator ii = innerTypes.iterator(); ii.hasNext();) {
174:                    TypeDeclaration innerType = (TypeDeclaration) ii.next();
175:                    if (innerType instanceof  ClassDeclaration)
176:                        checkInnerClass((ClassDeclaration) innerType);
177:                }
178:
179:                //
180:                // Run additional .jpf- or .app-specific checks.
181:                //
182:                doAdditionalClassChecks(jclass);
183:
184:                //
185:                // Runtime performance enhancement: enable saving of previous-page and previous-action information based on
186:                // whether there were Forwards that contained navigateTo attributes.
187:                //
188:                enableNavigateTo(jclass,
189:                        fcInfo.getMergedControllerAnnotation(), fcInfo);
190:                Map sharedFlowTypes = fcInfo.getSharedFlowTypes();
191:
192:                if (sharedFlowTypes != null) {
193:                    for (Iterator ii = sharedFlowTypes.values().iterator(); ii
194:                            .hasNext();) {
195:                        TypeDeclaration sharedFlowType = (TypeDeclaration) ii
196:                                .next();
197:                        //
198:                        // Saving of previous-page/previous-action info must be enabled if any of the referenced shared flows
199:                        // use this feature.
200:                        //
201:                        enableNavigateTo(sharedFlowType,
202:                                new MergedControllerAnnotation(sharedFlowType),
203:                                fcInfo);
204:                    }
205:                }
206:
207:                endCheckClass(jclass);
208:                _checkResultMap.put(
209:                        JpfLanguageConstants.ExtraInfoKeys.flowControllerInfo,
210:                        fcInfo);
211:                return _checkResultMap;
212:            }
213:
214:            private static void enableNavigateTo(
215:                    TypeDeclaration flowControllerClass,
216:                    MergedControllerAnnotation controllerAnn,
217:                    FlowControllerInfo fcInfo) {
218:                //
219:                // Look through Forwards and SimpleActions in the Controller annotation.
220:                //
221:                enableNavigateTo(controllerAnn.getForwards(), fcInfo);
222:                enableNavigateTo(controllerAnn.getSimpleActions(), fcInfo);
223:
224:                //
225:                // Look through Forwards on Action and ExceptionHandler methods.
226:                //
227:                MethodDeclaration[] methods = CompilerUtils.getClassMethods(
228:                        flowControllerClass, null);
229:
230:                for (int i = 0; i < methods.length; i++) {
231:                    MethodDeclaration method = methods[i];
232:                    AnnotationInstance ann = CompilerUtils.getAnnotation(
233:                            method, ACTION_TAG_NAME);
234:
235:                    if (ann != null) {
236:                        enableNavigateTo(CompilerUtils.getAnnotation(ann,
237:                                VALIDATION_ERROR_FORWARD_ATTR, true), fcInfo);
238:                    }
239:
240:                    if (ann == null)
241:                        ann = CompilerUtils.getAnnotation(method,
242:                                EXCEPTION_HANDLER_TAG_NAME);
243:                    if (ann != null)
244:                        enableNavigateTo(CompilerUtils.getAnnotationArray(ann,
245:                                FORWARDS_ATTR, true), fcInfo);
246:                }
247:            }
248:
249:            private static void enableNavigateTo(Collection childAnnotations,
250:                    FlowControllerInfo fcInfo) {
251:                if (childAnnotations != null) {
252:                    for (Iterator ii = childAnnotations.iterator(); ii
253:                            .hasNext();) {
254:                        AnnotationInstance childAnnotation = (AnnotationInstance) ii
255:                                .next();
256:                        enableNavigateTo(childAnnotation, fcInfo);
257:                    }
258:                }
259:            }
260:
261:            private static void enableNavigateTo(AnnotationInstance ann,
262:                    FlowControllerInfo fcInfo) {
263:                if (ann == null)
264:                    return;
265:                String val = CompilerUtils.getEnumFieldName(ann,
266:                        NAVIGATE_TO_ATTR, true);
267:
268:                if (val != null) {
269:                    if (val.equals(NAVIGATE_TO_CURRENT_PAGE_STR)
270:                            || val.equals(NAVIGATE_TO_PREVIOUS_PAGE_STR)
271:                            || val.equals(NAVIGATE_TO_PAGE_LEGACY_STR)) {
272:                        fcInfo.enableNavigateToPage();
273:                    } else if (val.equals(NAVIGATE_TO_PREVIOUS_ACTION_STR)) {
274:                        fcInfo.enableNavigateToAction();
275:                    }
276:                }
277:            }
278:
279:            protected void endCheckClass(ClassDeclaration jclass) {
280:            }
281:
282:            protected abstract GenStrutsApp createStrutsApp(
283:                    ClassDeclaration jclass) throws IOException,
284:                    FatalCompileTimeException;
285:
286:            protected void startCheckClass(ClassDeclaration jclass)
287:                    throws FatalCompileTimeException {
288:                //
289:                // Check for basic things like writability of the struts-config file.
290:                //
291:                GenStrutsApp strutsApp = null;
292:                File strutsConfigFile = null;
293:
294:                //
295:                // Make sure we can write to the struts-config XML file.
296:                //
297:                try {
298:                    strutsApp = createStrutsApp(jclass);
299:                    strutsConfigFile = strutsApp.getStrutsConfigFile();
300:                } catch (IOException e) {
301:                    // will be reported at generate time
302:                }
303:
304:                if (strutsConfigFile != null) {
305:                    getFCSourceFileInfo().addReferencedFile(strutsConfigFile);
306:
307:                    if (strutsConfigFile.exists() && strutsApp != null
308:                            && !strutsApp.canWrite()) {
309:                        getDiagnostics().addError(jclass,
310:                                "error.struts-config-not-writable",
311:                                strutsConfigFile);
312:                    }
313:                }
314:
315:                getRuntimeVersionChecker().checkRuntimeVersion(
316:                        VERSION_8_SP2_STRING, jclass, getDiagnostics(),
317:                        "warning.runtime-version",
318:                        new Object[] { PAGEFLOW_RUNTIME_JAR });
319:
320:                //
321:                // Check the Jpf.Controller annotation on this class.
322:                //
323:                AnnotationInstance controllerAnnotation = CompilerUtils
324:                        .getAnnotation(jclass, CONTROLLER_TAG_NAME);
325:                if (controllerAnnotation != null)
326:                    _controllerGrammar
327:                            .check(controllerAnnotation, null, jclass);
328:
329:                //
330:                // Check relative paths on Jpf.Catch, Jpf.Forward, and Jpf.SimpleAction annotations on superclasses.
331:                // If inheritLocalPaths is set to true on @Jpf.Controller, then we don't need to do this check, since
332:                // inherited paths will always resolve.
333:                //
334:                if (!getFCSourceFileInfo().getMergedControllerAnnotation()
335:                        .isInheritLocalPaths()) {
336:                    checkInheritedRelativePaths(jclass);
337:                }
338:
339:                // check for duplicate expressions in conditional forwards
340:                checkConditionalForwardsExpressions(jclass);
341:            }
342:
343:            /**
344:             * Check relative paths in annotations inherited from a base class.
345:             */
346:            private void checkInheritedRelativePaths(ClassDeclaration jclass)
347:                    throws FatalCompileTimeException {
348:                for (ClassType type = jclass.getSuperclass(); type != null
349:                        && CompilerUtils.isAssignableFrom(
350:                                FLOWCONTROLLER_BASE_CLASS, type, getEnv()); type = type
351:                        .getSuperclass()) {
352:                    TypeDeclaration decl = CompilerUtils.getDeclaration(type);
353:
354:                    //
355:                    // Check simple actions in the Controller annotation.
356:                    //
357:                    List simpleActions = CompilerUtils.getAnnotationArrayValue(
358:                            decl, CONTROLLER_TAG_NAME, SIMPLE_ACTIONS_ATTR,
359:                            true);
360:
361:                    if (simpleActions != null) {
362:                        for (Iterator j = simpleActions.iterator(); j.hasNext();) {
363:                            AnnotationInstance i = (AnnotationInstance) j
364:                                    .next();
365:                            checkRelativePath(i, PATH_ATTR, jclass, decl, false);
366:                            List conditionalForwards = CompilerUtils
367:                                    .getAnnotationArray(i,
368:                                            CONDITIONAL_FORWARDS_ATTR, true);
369:
370:                            if (conditionalForwards != null) {
371:                                for (Iterator k = conditionalForwards
372:                                        .iterator(); k.hasNext();) {
373:                                    AnnotationInstance ann = (AnnotationInstance) k
374:                                            .next();
375:                                    checkRelativePath(ann, PATH_ATTR, jclass,
376:                                            decl, false);
377:                                }
378:                            }
379:                        }
380:                    }
381:
382:                    //
383:                    // Check Forwards in the Controller annotation.
384:                    //
385:                    List forwards = CompilerUtils.getAnnotationArrayValue(decl,
386:                            CONTROLLER_TAG_NAME, FORWARDS_ATTR, true);
387:
388:                    if (forwards != null) {
389:                        for (Iterator ii = forwards.iterator(); ii.hasNext();) {
390:                            AnnotationInstance i = (AnnotationInstance) ii
391:                                    .next();
392:                            checkRelativePath(i, PATH_ATTR, jclass, decl, false);
393:                        }
394:                    }
395:
396:                    //
397:                    // Check Catches in the Controller annotation.
398:                    //
399:                    List catches = CompilerUtils.getAnnotationArrayValue(decl,
400:                            CONTROLLER_TAG_NAME, CATCHES_ATTR, true);
401:
402:                    if (catches != null) {
403:                        for (Iterator j = catches.iterator(); j.hasNext();) {
404:                            AnnotationInstance i = (AnnotationInstance) j
405:                                    .next();
406:                            checkRelativePath(i, PATH_ATTR, jclass, decl, false);
407:                        }
408:                    }
409:
410:                    //
411:                    // Check strutsMerge and validatorMerge in the Controller annotation.
412:                    //
413:                    AnnotationInstance controllerAnnotation = CompilerUtils
414:                            .getAnnotation(decl, CONTROLLER_TAG_NAME);
415:
416:                    if (controllerAnnotation != null) {
417:                        checkRelativePath(controllerAnnotation,
418:                                VALIDATOR_MERGE_ATTR, jclass, decl, true);
419:                        checkRelativePath(controllerAnnotation,
420:                                STRUTSMERGE_ATTR, jclass, decl, true);
421:                    }
422:
423:                    //
424:                    // Check Forwards and Catches on action methods and exception-handler methods.
425:                    //
426:                    MethodDeclaration[] methods = decl.getMethods();
427:                    for (int i = 0; i < methods.length; i++) {
428:                        MethodDeclaration method = methods[i];
429:                        AnnotationInstance ann = CompilerUtils.getAnnotation(
430:                                method, ACTION_TAG_NAME);
431:                        if (ann == null)
432:                            ann = CompilerUtils.getAnnotation(method,
433:                                    EXCEPTION_HANDLER_TAG_NAME);
434:
435:                        if (ann != null) {
436:                            List methodForwards = CompilerUtils
437:                                    .getAnnotationArray(ann, FORWARDS_ATTR,
438:                                            true);
439:                            String methodName = method.getSimpleName();
440:
441:                            if (methodForwards != null) {
442:                                for (Iterator j = methodForwards.iterator(); j
443:                                        .hasNext();) {
444:                                    AnnotationInstance methodForward = (AnnotationInstance) j
445:                                            .next();
446:                                    checkRelativePath(methodName,
447:                                            methodForward, PATH_ATTR, jclass,
448:                                            decl, false);
449:                                }
450:                            }
451:
452:                            List methodCatches = CompilerUtils
453:                                    .getAnnotationArray(ann, CATCHES_ATTR, true);
454:
455:                            if (methodCatches != null) {
456:                                for (Iterator j = methodCatches.iterator(); j
457:                                        .hasNext();) {
458:                                    AnnotationInstance methodCatch = (AnnotationInstance) j
459:                                            .next();
460:                                    checkRelativePath(methodName, methodCatch,
461:                                            PATH_ATTR, jclass, decl, false);
462:                                }
463:                            }
464:                        }
465:                    }
466:                }
467:            }
468:
469:            private void checkRelativePath(AnnotationInstance ann,
470:                    String memberName, TypeDeclaration jclass,
471:                    TypeDeclaration baseType, boolean isError)
472:                    throws FatalCompileTimeException {
473:                if (ann != null) {
474:                    AnnotationValue pathVal = CompilerUtils.getAnnotationValue(
475:                            ann, memberName, true);
476:
477:                    if (pathVal != null) {
478:                        String path = (String) pathVal.getValue();
479:
480:                        if (path.length() > 0
481:                                && path.charAt(0) != '/'
482:                                && !WebappPathType.relativePathExists(path,
483:                                        jclass, getEnv())) {
484:                            String[] args = {
485:                                    path,
486:                                    ANNOTATION_INTERFACE_PREFIX
487:                                            + ann.getAnnotationType()
488:                                                    .getDeclaration()
489:                                                    .getSimpleName(),
490:                                    baseType.getQualifiedName() };
491:
492:                            if (isError) {
493:                                getDiagnostics().addErrorArrayArgs(ann,
494:                                        "message.inherited-file-not-found",
495:                                        args);
496:                            } else {
497:                                getDiagnostics().addWarningArrayArgs(ann,
498:                                        "message.inherited-file-not-found",
499:                                        args);
500:                            }
501:                        }
502:                    }
503:                }
504:            }
505:
506:            private void checkRelativePath(String methodName,
507:                    AnnotationInstance ann, String memberName,
508:                    TypeDeclaration jclass, TypeDeclaration baseType,
509:                    boolean isError) throws FatalCompileTimeException {
510:                if (ann != null) {
511:                    AnnotationValue pathVal = CompilerUtils.getAnnotationValue(
512:                            ann, memberName, true);
513:
514:                    if (pathVal != null) {
515:                        String path = (String) pathVal.getValue();
516:
517:                        if (path.length() > 0
518:                                && path.charAt(0) != '/'
519:                                && !WebappPathType.relativePathExists(path,
520:                                        jclass, getEnv())) {
521:                            String[] args = {
522:                                    path,
523:                                    ANNOTATION_INTERFACE_PREFIX
524:                                            + ann.getAnnotationType()
525:                                                    .getDeclaration()
526:                                                    .getSimpleName(),
527:                                    methodName, baseType.getQualifiedName() };
528:
529:                            if (isError) {
530:                                getDiagnostics()
531:                                        .addErrorArrayArgs(
532:                                                jclass,
533:                                                "message.method-inherited-file-not-found",
534:                                                args);
535:                            } else {
536:                                getDiagnostics()
537:                                        .addWarningArrayArgs(
538:                                                jclass,
539:                                                "message.method-inherited-file-not-found",
540:                                                args);
541:                            }
542:                        }
543:                    }
544:                }
545:            }
546:
547:            /**
548:             * Check for duplicate expressions in conditional forwards of the
549:             * simple action annotations.
550:             */
551:            private void checkConditionalForwardsExpressions(
552:                    ClassDeclaration jclass) throws FatalCompileTimeException {
553:                // Get simple actions in the Controller annotation.
554:                List simpleActions = CompilerUtils.getAnnotationArrayValue(
555:                        jclass, CONTROLLER_TAG_NAME, SIMPLE_ACTIONS_ATTR, true);
556:
557:                if (simpleActions != null) {
558:                    HashSet expressionsFound = new HashSet();
559:                    for (Iterator j = simpleActions.iterator(); j.hasNext();) {
560:                        AnnotationInstance sa = (AnnotationInstance) j.next();
561:                        List conditionalForwards = CompilerUtils
562:                                .getAnnotationArray(sa,
563:                                        CONDITIONAL_FORWARDS_ATTR, true);
564:
565:                        if (conditionalForwards != null) {
566:                            for (Iterator k = conditionalForwards.iterator(); k
567:                                    .hasNext();) {
568:                                AnnotationInstance cf = (AnnotationInstance) k
569:                                        .next();
570:                                String expression = CompilerUtils.getString(cf,
571:                                        CONDITION_ATTR, true);
572:                                assert expression != null;
573:
574:                                if (expressionsFound.contains(expression)) {
575:                                    String name = CompilerUtils.getString(sa,
576:                                            NAME_ATTR, true);
577:                                    getDiagnostics()
578:                                            .addWarning(
579:                                                    cf,
580:                                                    "warning.duplicate-conditional-forward-expression",
581:                                                    expression, name);
582:                                } else {
583:                                    expressionsFound.add(expression);
584:                                }
585:                            }
586:                        }
587:                        expressionsFound.clear();
588:                    }
589:                }
590:            }
591:
592:            protected void checkField(FieldDeclaration field,
593:                    TypeDeclaration jclass) {
594:                //
595:                // Only warn about nonserializable member data that's defined in this particular class.
596:                //
597:                if (CompilerUtils.typesAreEqual(jclass, field
598:                        .getDeclaringType())) {
599:                    TypeInstance type = field.getType();
600:
601:                    if (!field.hasModifier(Modifier.TRANSIENT)
602:                            && !field.hasModifier(Modifier.STATIC)
603:                            && type instanceof  ClassType
604:                            && !CompilerUtils.isAssignableFrom(
605:                                    SERIALIZABLE_CLASS_NAME, type, getEnv())) {
606:                        getDiagnostics().addWarning(field,
607:                                "warning.nonserializable-member-data");
608:                    }
609:                }
610:            }
611:
612:            protected void checkMethod(MethodDeclaration method,
613:                    ClassDeclaration jclass, AnnotationGrammar actionGrammar,
614:                    AnnotationGrammar exceptionHandlerGrammar)
615:                    throws FatalCompileTimeException {
616:                AnnotationInstance[] annotations = method
617:                        .getAnnotationInstances();
618:
619:                for (int i = 0; i < annotations.length; i++) {
620:                    AnnotationInstance annotation = annotations[i];
621:                    String annotationName = CompilerUtils.getDeclaration(
622:                            annotation.getAnnotationType()).getSimpleName();
623:
624:                    if (annotationName.equals(ACTION_TAG_NAME)) {
625:                        actionGrammar.check(annotation, null, method);
626:
627:                        if (!CompilerUtils.isAssignableFrom(FORWARD_CLASS_NAME,
628:                                method.getReturnType(), getEnv())) {
629:                            getDiagnostics().addError(method,
630:                                    "error.method-wrong-return-type",
631:                                    FORWARD_CLASS_NAME);
632:                        }
633:                    } else if (annotationName
634:                            .equals(EXCEPTION_HANDLER_TAG_NAME)) {
635:                        exceptionHandlerGrammar.check(annotation, null, method);
636:                        checkExceptionHandlerMethod(method);
637:                    }
638:                }
639:            }
640:
641:            /*
642:             * Run a check of form bean classes that might not otherwise
643:             * be processed. A @FormBean instance will get processed by the
644:             * PageFlowCoreAnnotationProcessor and FormBeanChecker. Otherwise,
645:             * run the class through the FormBeanChecker for other possible errors.
646:             */
647:            private void checkInnerClass(ClassDeclaration jclass)
648:                    throws FatalCompileTimeException {
649:                boolean noFormBeanAnnotation = true;
650:                if (CompilerUtils.getAnnotation(jclass, FORM_BEAN_TAG_NAME,
651:                        true) != null) {
652:                    noFormBeanAnnotation = false;
653:                } else {
654:                    //
655:                    // check the methods for validatable property annotations that
656:                    // would be processed elsewhere.
657:                    //
658:                    MethodDeclaration[] methods = CompilerUtils
659:                            .getClassMethods(jclass, null);
660:                    for (int i = 0; i < methods.length && noFormBeanAnnotation; i++) {
661:                        MethodDeclaration method = methods[i];
662:                        if (CompilerUtils.getAnnotation(method,
663:                                VALIDATABLE_PROPERTY_TAG_NAME) != null) {
664:                            noFormBeanAnnotation = false;
665:                        }
666:                    }
667:                }
668:
669:                if (noFormBeanAnnotation) {
670:                    _formBeanChecker.check(jclass);
671:                }
672:            }
673:
674:            private void checkExceptionHandlerMethod(MethodDeclaration method) {
675:                if (!CompilerUtils.isAssignableFrom(FORWARD_CLASS_NAME, method
676:                        .getReturnType(), getEnv())) {
677:                    getDiagnostics().addError(method,
678:                            "error.method-wrong-return-type",
679:                            FORWARD_CLASS_NAME);
680:                }
681:
682:                ParameterDeclaration[] parameters = method.getParameters();
683:
684:                if (parameters.length == 4) {
685:                    if (!CompilerUtils.isAssignableFrom(THROWABLE_CLASS_NAME,
686:                            parameters[0].getType(), getEnv())) {
687:                        getDiagnostics().addError(method,
688:                                "error.exception-method-wrong-exception-arg",
689:                                THROWABLE_CLASS_NAME);
690:                    }
691:
692:                    checkExceptionHandlerArgType(method, parameters, 1,
693:                            STRING_CLASS_NAME);
694:                    checkExceptionHandlerArgType(method, parameters, 2,
695:                            STRING_CLASS_NAME);
696:
697:                    //
698:                    // The use of org.apache.struts.action.ActionForm or org.apache.beehive.netui.pageflow.FormData as the
699:                    // fourth argument is deprecated.  Forms can be any Object type now.
700:                    //
701:                    if (CompilerUtils.isAssignableFrom(STRUTS_FORM_CLASS_NAME,
702:                            parameters[3].getType(), getEnv())) {
703:                        getDiagnostics().addWarning(method,
704:                                "warning.exception-method-deprecated-form-arg");
705:                    } else {
706:                        checkExceptionHandlerArgType(method, parameters, 3,
707:                                OBJECT_CLASS_NAME);
708:                    }
709:                } else {
710:                    getDiagnostics().addError(method,
711:                            "error.exception-method-wrong-arg-count",
712:                            new Integer(4));
713:                }
714:            }
715:
716:            private void checkExceptionHandlerArgType(MethodDeclaration method,
717:                    ParameterDeclaration[] parameters, int index,
718:                    String className) {
719:                if (!CompilerUtils.isOfClass(parameters[index].getType(),
720:                        className, getEnv())) {
721:                    getDiagnostics().addError(method,
722:                            "error.exception-method-wrong-arg-type",
723:                            new Integer(index + 1), className);
724:                }
725:            }
726:
727:            protected void checkForOverlappingClasses(
728:                    ClassDeclaration jpfClass, String baseClass,
729:                    String fileExtension, String errorKey) {
730:                File jpfFile = CompilerUtils.getSourceFile(jpfClass, true);
731:                File parentDir = jpfFile.getParentFile();
732:                PackageDeclaration pkg = jpfClass.getPackage();
733:                ClassDeclaration[] packageClasses = pkg.getClasses();
734:                Set overlapping = new HashSet();
735:                List overlappingFiles = new ArrayList();
736:
737:                //
738:                // First go through the other classes in this package to look for other classes of this type.  Only one per
739:                // directory is allowed.
740:                //
741:                for (int i = 0; i < packageClasses.length; i++) {
742:                    ClassDeclaration classDecl = packageClasses[i];
743:                    if (CompilerUtils.getAnnotation(classDecl,
744:                            CONTROLLER_TAG_NAME) != null
745:                            && CompilerUtils.isAssignableFrom(baseClass,
746:                                    classDecl, getEnv())) {
747:                        File file = CompilerUtils.getSourceFile(classDecl,
748:                                false);
749:
750:                        //
751:                        // Add the dependency if it's a different file and if the file exists (it may have been deleted
752:                        // sometime after the list of classes in this package got built.
753:                        //
754:                        if (!jpfFile.equals(file) && file != null
755:                                && file.exists()) {
756:                            overlapping.add(file.getName());
757:                            overlappingFiles.add(file);
758:                        }
759:                    }
760:                }
761:
762:                //
763:                // Additionally, we'll go through the parent directory to make sure there are no other files of this type. 
764:                // This is a double-check for the case where duplicate files have the same class names inside them, which means
765:                // that iterating through the list of package classes is hit or miss (only one of them will show up, and it may
766:                // be this class or the duplicate class).
767:                //
768:                File[] peers = parentDir.listFiles(new ExtensionFileFilter(
769:                        fileExtension));
770:
771:                if (peers != null) // make sure the directory hasn't been deleted while we're running
772:                {
773:                    for (int i = 0; i < peers.length; i++) {
774:                        File peer = peers[i];
775:                        if (!peer.equals(jpfFile)) {
776:                            String name = peer.getName();
777:
778:                            if (!overlapping.contains(name)) {
779:                                overlapping.add(name);
780:                                overlappingFiles.add(peer);
781:                            }
782:                        }
783:                    }
784:                }
785:
786:                int len = overlapping.size();
787:                if (len > 0) {
788:                    if (len > 3) {
789:                        getDiagnostics().addErrorArrayArgs(jpfClass, errorKey,
790:                                overlapping.toArray());
791:                    } else {
792:                        getDiagnostics().addErrorArrayArgs(jpfClass,
793:                                errorKey + len, overlapping.toArray());
794:                    }
795:                }
796:
797:                getCheckResultMap()
798:                        .put(
799:                                JpfLanguageConstants.ExtraInfoKeys.overlappingPageFlowFiles,
800:                                overlappingFiles);
801:            }
802:
803:            private static class ExtensionFileFilter implements  FilenameFilter {
804:                private String _extension;
805:
806:                public ExtensionFileFilter(String extension) {
807:                    _extension = extension;
808:                }
809:
810:                public boolean accept(File dir, String name) {
811:                    return name.endsWith(_extension);
812:                }
813:            }
814:
815:            protected FlowControllerInfo getFCSourceFileInfo() {
816:                return (FlowControllerInfo) super.getSourceFileInfo();
817:            }
818:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.