Source Code Cross Referenced for ComponentVerifier.java in  » Inversion-of-Control » DNA » org » codehaus » dna » tools » verifier » 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 » Inversion of Control » DNA » org.codehaus.dna.tools.verifier 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) The DNA Group. All rights reserved.
003:         *
004:         * This software is published under the terms of the DNA
005:         * Software License version 1.1, a copy of which has been included
006:         * with this distribution in the LICENSE.txt file.
007:         */
008:        package org.codehaus.dna.tools.verifier;
009:
010:        import java.lang.reflect.Method;
011:        import java.lang.reflect.Modifier;
012:        import java.net.URL;
013:        import java.text.MessageFormat;
014:        import java.util.ArrayList;
015:        import java.util.List;
016:        import java.util.ResourceBundle;
017:
018:        import org.codehaus.dna.Active;
019:        import org.codehaus.dna.Composable;
020:        import org.codehaus.dna.Configurable;
021:        import org.codehaus.dna.Configuration;
022:        import org.codehaus.dna.LogEnabled;
023:        import org.codehaus.dna.ResourceLocator;
024:        import org.codehaus.metaclass.Attributes;
025:        import org.codehaus.metaclass.model.Attribute;
026:
027:        /**
028:         * Utility class to help verify that component respects the
029:         * rules of an DNA component.
030:         *
031:         * @author Peter Donald
032:         * @version $Revision: 1.2 $ $Date: 2004/05/01 09:51:48 $
033:         */
034:        public class ComponentVerifier {
035:            /**
036:             * Key used to look up ResourceBundle.
037:             */
038:            private static final String BASE_NAME = ComponentVerifier.class
039:                    .getName()
040:                    + "Resources";
041:
042:            /**
043:             * The resource bundle.
044:             */
045:            private static final ResourceBundle BUNDLE = ResourceBundle
046:                    .getBundle(BASE_NAME);
047:
048:            /**
049:             * Constant for array of 0 classes. Saves recreating array everytime
050:             * look up constructor with no args.
051:             */
052:            private static final Class[] EMPTY_TYPES = new Class[0];
053:
054:            /**
055:             * The interfaces representing lifecycle stages.
056:             */
057:            private static final Class[] FRAMEWORK_CLASSES = new Class[] {
058:                    LogEnabled.class, Composable.class, Configurable.class,
059:                    Active.class };
060:
061:            /**
062:             * The name of the Configurable.configure() method.
063:             */
064:            private static final String CONFIGURE_METHOD_NAME = "configure";
065:
066:            /**
067:             * The parameter types of the Configurable.configure() method.
068:             */
069:            private static final Class[] CONFIGURE_PARAMETER_TYPES = new Class[] { Configuration.class };
070:
071:            /**
072:             * The name of the Composable.compose() method.
073:             */
074:            private static final String COMPOSE_METHOD_NAME = "compose";
075:
076:            /**
077:             * The parameter types of the Composable.compose() method.
078:             */
079:            private static final Class[] COMPOSE_PARAMETER_TYPES = new Class[] { ResourceLocator.class };
080:
081:            /**
082:             * Verfiy that specified components designate classes that implement the
083:             * advertised interfaces.
084:             *
085:             * @param type the component type
086:             * @return an array of issues
087:             */
088:            public VerifyIssue[] verifyType(final Class type) {
089:                final List issues = new ArrayList();
090:                verifyMetaData(type, issues);
091:                verifyDependencyMetaData(type, issues);
092:                verifyConfigurationMetaData(type, issues);
093:
094:                final Class[] interfaces = getServiceClasses(type, issues);
095:
096:                verifyClass(type, issues);
097:                verifyImplementsServices(type, interfaces, issues);
098:                for (int i = 0; i < interfaces.length; i++) {
099:                    verifyService(interfaces[i], issues);
100:                }
101:
102:                return (VerifyIssue[]) issues.toArray(new VerifyIssue[issues
103:                        .size()]);
104:            }
105:
106:            /**
107:             * Verify that the component is annotated with the
108:             * dna.component metadata.
109:             *
110:             * @param type the type
111:             * @param issues the list of issues
112:             */
113:            void verifyMetaData(final Class type, final List issues) {
114:                final Attribute attribute = Attributes.getAttribute(type,
115:                        "dna.component");
116:                if (null == attribute) {
117:                    final String message = getMessage("CV001");
118:                    final VerifyIssue issue = new VerifyIssue(
119:                            VerifyIssue.ERROR, message);
120:                    issues.add(issue);
121:                }
122:            }
123:
124:            /**
125:             * Verify that the configuration metadata for component is valid.
126:             *
127:             * @param type the type
128:             * @param issues the list of issues
129:             */
130:            void verifyConfigurationMetaData(final Class type, final List issues) {
131:                Attribute attribute = getConfigurationMetaData(type);
132:                if (null != attribute) {
133:                    final String location = attribute.getParameter("location");
134:                    if (null == location) {
135:                        final Object[] args = new Object[] { "type" };
136:                        final String message = getMessage("CV019", args);
137:                        final VerifyIssue issue = new VerifyIssue(
138:                                VerifyIssue.ERROR, message);
139:                        issues.add(issue);
140:                    } else {
141:                        verifyLocation(type, location, issues);
142:                    }
143:                }
144:            }
145:
146:            /**
147:             * Return the configuration metadata for component if any.
148:             * Protected to allow overiding in subclasses.
149:             *
150:             * @param type the component type
151:             * @return the metadata if any
152:             */
153:            protected Attribute getConfigurationMetaData(final Class type) {
154:                try {
155:                    final Method method = getConfigurationMethod(type);
156:                    return Attributes.getAttribute(method, "dna.configuration");
157:                } catch (final NoSuchMethodException nsme) {
158:                    return null;
159:                }
160:            }
161:
162:            /**
163:             * Return the method used to pass configuration to component.
164:             *
165:             * @param type the components type
166:             * @return the method
167:             * @throws NoSuchMethodException if unable to locate method
168:             */
169:            protected Method getConfigurationMethod(final Class type)
170:                    throws NoSuchMethodException {
171:                if (!Configurable.class.isAssignableFrom(type)) {
172:                    throw new NoSuchMethodException();
173:                }
174:                return type.getMethod(CONFIGURE_METHOD_NAME,
175:                        CONFIGURE_PARAMETER_TYPES);
176:            }
177:
178:            /**
179:             * Verify that the location specified for the schema actually exists.
180:             *
181:             * @param type the component type
182:             * @param location the location of schmea
183:             * @param issues the list of issues
184:             */
185:            void verifyLocation(final Class type, final String location,
186:                    final List issues) {
187:                final URL url = type.getResource(location);
188:                if (null == url) {
189:                    final Object[] args = new Object[] { location };
190:                    final String message = getMessage("CV020", args);
191:                    final VerifyIssue issue = new VerifyIssue(
192:                            VerifyIssue.ERROR, message);
193:                    issues.add(issue);
194:                }
195:            }
196:
197:            /**
198:             * Verify that the dependency metadata for component is valid.
199:             *
200:             * @param type the type
201:             * @param issues the list of issues
202:             */
203:            void verifyDependencyMetaData(final Class type, final List issues) {
204:                final Attribute[] attributes = getDependencyAttributes(type);
205:                for (int i = 0; i < attributes.length; i++) {
206:                    final Attribute attribute = attributes[i];
207:                    verifyDependencyMetaData(type, attribute, issues);
208:                }
209:            }
210:
211:            /**
212:             * Return the dependency attributes for component.
213:             * Made protected so that it is possible to overload
214:             * in subclasses.
215:             *
216:             * @param type the component type
217:             * @return the dependency attributes
218:             */
219:            protected Attribute[] getDependencyAttributes(final Class type) {
220:                try {
221:                    final Method method = getComposeMethod(type);
222:                    return Attributes.getAttributes(method, "dna.dependency");
223:                } catch (NoSuchMethodException e) {
224:                    return Attribute.EMPTY_SET;
225:                }
226:            }
227:
228:            /**
229:             * Return the method via which component is passed services.
230:             * This method is protected so can overload in subclasses
231:             * and get alternative methods.
232:             *
233:             * @param type the components type
234:             * @return the method
235:             * @throws NoSuchMethodException if can not locate method
236:             */
237:            protected Method getComposeMethod(final Class type)
238:                    throws NoSuchMethodException {
239:                if (!Composable.class.isAssignableFrom(type)) {
240:                    throw new NoSuchMethodException();
241:                }
242:                return type.getMethod(COMPOSE_METHOD_NAME,
243:                        COMPOSE_PARAMETER_TYPES);
244:            }
245:
246:            /**
247:             * Verify that the dependency metadata tag is valid.
248:             *
249:             * @param type the component type
250:             * @param attribute the metadata tag
251:             * @param issues the list of issues
252:             */
253:            void verifyDependencyMetaData(final Class type,
254:                    final Attribute attribute, final List issues) {
255:                final String optional = attribute.getParameter("optional");
256:                verifyOptionalParameter(optional, issues);
257:
258:                final String typeName = attribute.getParameter("type");
259:                if (null == typeName) {
260:                    final Object[] args = new Object[] { "type" };
261:                    final String message = getMessage("CV015", args);
262:                    final VerifyIssue issue = new VerifyIssue(
263:                            VerifyIssue.ERROR, message);
264:                    issues.add(issue);
265:                } else {
266:                    verifyDependencyType(type, typeName, issues);
267:                    final String key = attribute.getParameter("key");
268:                    if (null == key) {
269:                        final Object[] args = new Object[] { "key" };
270:                        final String message = getMessage("CV015", args);
271:                        final VerifyIssue issue = new VerifyIssue(
272:                                VerifyIssue.ERROR, message);
273:                        issues.add(issue);
274:                    } else {
275:                        verifyDependencyKeyConforms(typeName, key, issues);
276:                    }
277:                }
278:            }
279:
280:            /**
281:             * Verify optional parameter for dependency metadata.
282:             *
283:             * @param optional the value of parameter
284:             * @param issues the list of issues
285:             */
286:            void verifyOptionalParameter(final String optional,
287:                    final List issues) {
288:                if (null == optional) {
289:                    final Object[] args = new Object[] { "optional" };
290:                    final String message = getMessage("CV015", args);
291:                    final VerifyIssue issue = new VerifyIssue(
292:                            VerifyIssue.ERROR, message);
293:                    issues.add(issue);
294:                } else {
295:                    verifyDependencyOptionalValid(optional, issues);
296:                }
297:            }
298:
299:            /**
300:             * Verify that value of optional value is valid.
301:             *
302:             * @param optional the optional value
303:             * @param issues the list of issues
304:             */
305:            void verifyDependencyOptionalValid(final String optional,
306:                    final List issues) {
307:                if (!optional.equals("true") && !optional.equals("false")) {
308:                    final Object[] args = new Object[] { optional };
309:                    final String message = getMessage("CV018", args);
310:                    final VerifyIssue issue = new VerifyIssue(
311:                            VerifyIssue.ERROR, message);
312:                    issues.add(issue);
313:                }
314:            }
315:
316:            /**
317:             * Verify that the key conforms to the expectation
318:             * of being (type)[/(qualifier)]
319:             *
320:             * @param typeName the name of dependency type
321:             * @param key the dependency key
322:             * @param issues the list of issues
323:             */
324:            void verifyDependencyKeyConforms(final String typeName,
325:                    final String key, final List issues) {
326:                final int typeLength = typeName.length();
327:                final int keyLength = key.length();
328:                final String prefix;
329:                if (typeLength == keyLength) {
330:                    prefix = typeName;
331:                } else {
332:                    prefix = typeName + "/";
333:                }
334:                if (!key.startsWith(prefix)) {
335:                    final Object[] args = new Object[] { key };
336:                    final String message = getMessage("CV017", args);
337:                    final VerifyIssue issue = new VerifyIssue(
338:                            VerifyIssue.NOTICE, message);
339:                    issues.add(issue);
340:                }
341:            }
342:
343:            /**
344:             * Verify that the type specified dependency can be loaded.
345:             *
346:             * @param type the component type
347:             * @param typeName the type of dependency
348:             * @param issues the list of issues
349:             */
350:            void verifyDependencyType(final Class type, final String typeName,
351:                    final List issues) {
352:                try {
353:                    type.getClassLoader().loadClass(typeName);
354:                } catch (final Throwable t) {
355:                    final Object[] args = new Object[] { typeName, t };
356:                    final String message = getMessage("CV016", args);
357:                    final VerifyIssue issue = new VerifyIssue(
358:                            VerifyIssue.ERROR, message);
359:                    issues.add(issue);
360:                }
361:            }
362:
363:            /**
364:             * Verify that the supplied implementation implements the specified
365:             * services.
366:             *
367:             * @param implementation the class representign component
368:             * @param services the services that the implementation must provide
369:             * @param issues the list of issues
370:             */
371:            void verifyImplementsServices(final Class implementation,
372:                    final Class[] services, final List issues) {
373:                for (int i = 0; i < services.length; i++) {
374:                    if (!services[i].isAssignableFrom(implementation)) {
375:                        final Object[] args = new Object[] { services[i]
376:                                .getName() };
377:                        final String message = getMessage("CV002", args);
378:                        final VerifyIssue issue = new VerifyIssue(
379:                                VerifyIssue.ERROR, message);
380:                        issues.add(issue);
381:                    }
382:                }
383:            }
384:
385:            /**
386:             * Verify that the supplied class is a valid type for
387:             * a component.
388:             *
389:             * @param type the class representing component
390:             * @param issues the list of issues
391:             */
392:            void verifyClass(final Class type, final List issues) {
393:                verifyNoArgConstructor(type, issues);
394:                verifyNonAbstract(type, issues);
395:                verifyNonArray(type, issues);
396:                verifyNonInterface(type, issues);
397:                verifyNonPrimitive(type, issues);
398:                verifyPublic(type, issues);
399:            }
400:
401:            /**
402:             * Verify that the supplied class is a valid class for
403:             * a service.
404:             *
405:             * @param clazz the class representign service
406:             * @param issues the list of issues
407:             */
408:            void verifyService(final Class clazz, final List issues) {
409:                verifyServiceIsaInterface(clazz, issues);
410:                verifyServiceIsPublic(clazz, issues);
411:                verifyServiceNotALifecycle(clazz, issues);
412:            }
413:
414:            /**
415:             * Verify that the service implemented by
416:             * specified component is an interface.
417:             *
418:             * @param clazz the class representign service
419:             * @param issues the list of issues
420:             */
421:            void verifyServiceIsaInterface(final Class clazz, final List issues) {
422:                if (!clazz.isInterface()) {
423:                    final Object[] args = new Object[] { clazz.getName() };
424:                    final String message = getMessage("CV004", args);
425:                    final VerifyIssue issue = new VerifyIssue(
426:                            VerifyIssue.ERROR, message);
427:                    issues.add(issue);
428:                }
429:            }
430:
431:            /**
432:             * Verify that the service implemented by
433:             * specified component is public.
434:             *
435:             * @param clazz the class representign service
436:             * @param issues the list of issues
437:             */
438:            void verifyServiceIsPublic(final Class clazz, final List issues) {
439:                final boolean isPublic = Modifier
440:                        .isPublic(clazz.getModifiers());
441:                if (!isPublic) {
442:                    final Object[] args = new Object[] { clazz.getName() };
443:                    final String message = getMessage("CV005", args);
444:                    final VerifyIssue issue = new VerifyIssue(
445:                            VerifyIssue.ERROR, message);
446:                    issues.add(issue);
447:                }
448:            }
449:
450:            /**
451:             * Verify that the service implemented by
452:             * specified component does not extend any lifecycle interfaces.
453:             *
454:             * @param clazz the class representign service
455:             * @param issues the list of issues
456:             */
457:            void verifyServiceNotALifecycle(final Class clazz, final List issues) {
458:                for (int i = 0; i < FRAMEWORK_CLASSES.length; i++) {
459:                    final Class lifecycle = FRAMEWORK_CLASSES[i];
460:                    if (lifecycle.isAssignableFrom(clazz)) {
461:                        final Object[] args = new Object[] { clazz.getName(),
462:                                lifecycle.getName() };
463:                        final String message = getMessage("CV006", args);
464:                        final VerifyIssue issue = new VerifyIssue(
465:                                VerifyIssue.ERROR, message);
466:                        issues.add(issue);
467:                    }
468:                }
469:            }
470:
471:            /**
472:             * Verify that the component has a no-arg aka default
473:             * constructor.
474:             *
475:             * @param clazz the class representign component
476:             * @param issues the list of issues
477:             */
478:            void verifyNoArgConstructor(final Class clazz, final List issues) {
479:                try {
480:                    clazz.getConstructor(EMPTY_TYPES);
481:                } catch (final NoSuchMethodException nsme) {
482:                    final String message = getMessage("CV008");
483:                    final VerifyIssue issue = new VerifyIssue(
484:                            VerifyIssue.ERROR, message);
485:                    issues.add(issue);
486:                }
487:            }
488:
489:            /**
490:             * Verify that the component is not represented by
491:             * abstract class.
492:             *
493:             * @param clazz the class representign component
494:             * @param issues the list of issues
495:             */
496:            void verifyNonAbstract(final Class clazz, final List issues) {
497:                final boolean isAbstract = Modifier.isAbstract(clazz
498:                        .getModifiers());
499:                if (isAbstract) {
500:                    final String message = getMessage("CV009");
501:                    final VerifyIssue issue = new VerifyIssue(
502:                            VerifyIssue.ERROR, message);
503:                    issues.add(issue);
504:                }
505:            }
506:
507:            /**
508:             * Verify that the component is not represented by
509:             * abstract class.
510:             *
511:             * @param clazz the class representign component
512:             * @param issues the list of issues
513:             */
514:            void verifyPublic(final Class clazz, final List issues) {
515:                final boolean isPublic = Modifier
516:                        .isPublic(clazz.getModifiers());
517:                if (!isPublic) {
518:                    final String message = getMessage("CV010");
519:                    final VerifyIssue issue = new VerifyIssue(
520:                            VerifyIssue.ERROR, message);
521:                    issues.add(issue);
522:                }
523:            }
524:
525:            /**
526:             * Verify that the component is not represented by
527:             * primitive class.
528:             *
529:             * @param clazz the class representign component
530:             * @param issues the list of issues
531:             */
532:            void verifyNonPrimitive(final Class clazz, final List issues) {
533:                if (clazz.isPrimitive()) {
534:                    final String message = getMessage("CV011");
535:                    final VerifyIssue issue = new VerifyIssue(
536:                            VerifyIssue.ERROR, message);
537:                    issues.add(issue);
538:                }
539:            }
540:
541:            /**
542:             * Verify that the component is not represented by
543:             * interface class.
544:             *
545:             * @param clazz the class representign component
546:             * @param issues the list of issues
547:             */
548:            void verifyNonInterface(final Class clazz, final List issues) {
549:                if (clazz.isInterface()) {
550:                    final String message = getMessage("CV012");
551:                    final VerifyIssue issue = new VerifyIssue(
552:                            VerifyIssue.ERROR, message);
553:                    issues.add(issue);
554:                }
555:            }
556:
557:            /**
558:             * Verify that the component is not represented by
559:             * an array class.
560:             *
561:             * @param clazz the class representign component
562:             * @param issues the list of issues
563:             */
564:            void verifyNonArray(final Class clazz, final List issues) {
565:                if (clazz.isArray()) {
566:                    final String message = getMessage("CV013");
567:                    final VerifyIssue issue = new VerifyIssue(
568:                            VerifyIssue.ERROR, message);
569:                    issues.add(issue);
570:                }
571:            }
572:
573:            /**
574:             * Retrieve an array of Classes for all the services that a Component
575:             * offers. This method also makes sure all services offered are
576:             * interfaces.
577:             *
578:             * @param type the component type
579:             * @param issues the list of issues
580:             * @return an array of Classes for all the services
581:             */
582:            Class[] getServiceClasses(final Class type, final List issues) {
583:                final List services = new ArrayList();
584:                final ClassLoader classLoader = type.getClassLoader();
585:                final Attribute[] attributes = Attributes.getAttributes(type,
586:                        "dna.service");
587:                for (int i = 0; i < attributes.length; i++) {
588:                    final String classname = attributes[i].getParameter("type");
589:                    try {
590:                        final Class clazz = classLoader.loadClass(classname);
591:                        services.add(clazz);
592:                    } catch (final Throwable t) {
593:                        final Object[] args = new Object[] { classname, t };
594:                        final String message = getMessage("CV014", args);
595:                        final VerifyIssue issue = new VerifyIssue(
596:                                VerifyIssue.ERROR, message);
597:                        issues.add(issue);
598:                    }
599:                }
600:
601:                return (Class[]) services.toArray(new Class[services.size()]);
602:            }
603:
604:            /**
605:             * Get message out of resource bundle with specified key.
606:             *
607:             * @param key the key
608:             * @return the message
609:             */
610:            String getMessage(final String key) {
611:                return BUNDLE.getString(key);
612:            }
613:
614:            /**
615:             * Get message out of resource bungle with specified key
616:             * and format wit specified arguments.
617:             *
618:             * @param key the keys
619:             * @param args the arguments
620:             * @return the message
621:             */
622:            String getMessage(final String key, final Object[] args) {
623:                final String pattern = getMessage(key);
624:                return MessageFormat.format(pattern, args);
625:            }
626:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.