Source Code Cross Referenced for EJBVerifier20.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » verifier » strategy » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.verifier.strategy 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JBoss, Home of Professional Open Source.
0003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004:         * as indicated by the @author tags. See the copyright.txt file in the
0005:         * distribution for a full listing of individual contributors.
0006:         *
0007:         * This is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU Lesser General Public License as
0009:         * published by the Free Software Foundation; either version 2.1 of
0010:         * the License, or (at your option) any later version.
0011:         *
0012:         * This software is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this software; if not, write to the Free
0019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021:         */
0022:        package org.jboss.verifier.strategy;
0023:
0024:        // $Id: EJBVerifier20.java 57209 2006-09-26 12:21:57Z dimitris@jboss.org $
0025:
0026:        import org.jboss.logging.Logger;
0027:        import org.jboss.metadata.BeanMetaData;
0028:        import org.jboss.metadata.EntityMetaData;
0029:        import org.jboss.metadata.MessageDrivenMetaData;
0030:        import org.jboss.metadata.SessionMetaData;
0031:        import org.jboss.verifier.Section;
0032:
0033:        import java.lang.reflect.Method;
0034:        import java.util.Arrays;
0035:        import java.util.Iterator;
0036:
0037:        /**
0038:         * EJB 2.0 bean verifier.
0039:         *
0040:         * @author Juha Lindfors   (jplindfo@helsinki.fi)
0041:         * @author Jay Walters     (jwalters@computer.org)
0042:         * @author <a href="mailto:criege@riege.com">Christian Riege</a>
0043:         * @author Thomas.Diesler@jboss.org
0044:         *
0045:         * @version $Revision: 57209 $
0046:         * @since   JDK 1.3
0047:         */
0048:        public class EJBVerifier20 extends AbstractEJB2xVerifier {
0049:            private static Logger log = Logger.getLogger(EJBVerifier20.class);
0050:
0051:            /*
0052:             * Constructor
0053:             */
0054:            public EJBVerifier20(VerificationContext context) {
0055:                super (context);
0056:            }
0057:
0058:            public String getMessageBundle() {
0059:                return "EJB20Messages.properties";
0060:            }
0061:
0062:            /***********************************************************************
0063:             *
0064:             *    IMPLEMENTS VERIFICATION STRATEGY INTERFACE
0065:             *
0066:             ************************************************************************/
0067:            public void checkSession(SessionMetaData session) {
0068:                boolean localOrRemoteExists = false;
0069:                boolean verified = false;
0070:
0071:                if (!verifyBean(session))
0072:                    return;
0073:
0074:                verified = verifySessionBean(session);
0075:
0076:                if (hasRemoteInterfaces(session)) {
0077:                    // Check remote interfaces
0078:                    localOrRemoteExists = true;
0079:                    verified = verified && verifySessionRemote(session);
0080:                    verified = verified && verifySessionHome(session);
0081:                }
0082:
0083:                if (hasLocalInterfaces(session)) {
0084:                    // Check local interfaces
0085:                    localOrRemoteExists = true;
0086:                    verified = verified && verifySessionLocal(session);
0087:                    verified = verified && verifySessionLocalHome(session);
0088:                }
0089:
0090:                // The session bean MUST implement either a remote home and
0091:                // remote, or local home and local interface.  It MAY implement a
0092:                // remote home, remote, local home or local interface.
0093:                //
0094:                // Spec 7.10.1
0095:                //
0096:                if (!localOrRemoteExists) {
0097:                    fireSpecViolationEvent(session, new Section("7.10.1"));
0098:                    verified = false;
0099:                }
0100:
0101:                if (verified) {
0102:                    // All OK; full steam ahead
0103:                    fireBeanVerifiedEvent(session);
0104:                }
0105:            }
0106:
0107:            public void checkEntity(EntityMetaData entity) {
0108:                if (entity.isCMP1x()) {
0109:                    cmp1XVerifier.checkEntity(entity);
0110:                } else {
0111:                    checkBmpOrCmp2Entity(entity);
0112:                }
0113:            }
0114:
0115:            public void checkMessageBean(MessageDrivenMetaData mdb) {
0116:                boolean beanVerified = false;
0117:
0118:                if (!verifyBean(mdb))
0119:                    return;
0120:
0121:                beanVerified = verifyMessageDrivenBean(mdb);
0122:
0123:                if (beanVerified) {
0124:                    // OK, we're done
0125:                    fireBeanVerifiedEvent(mdb);
0126:                }
0127:            }
0128:
0129:            private void checkBmpOrCmp2Entity(EntityMetaData entity) {
0130:                boolean localOrRemoteExists = false;
0131:                boolean verified = false;
0132:
0133:                if (!verifyBean(entity))
0134:                    return;
0135:
0136:                if (entity.isCMP()) {
0137:                    verified = verifyCMPEntityBean(entity);
0138:                } else if (entity.isBMP()) {
0139:                    verified = verifyBMPEntityBean(entity);
0140:                }
0141:
0142:                if (hasRemoteInterfaces(entity)) {
0143:                    // Check remote interfaces
0144:                    localOrRemoteExists = true;
0145:                    verified = verified && verifyEntityRemote(entity);
0146:                    verified = verified && verifyEntityHome(entity);
0147:                }
0148:
0149:                if (hasLocalInterfaces(entity)) {
0150:                    // Check local interfaces
0151:                    localOrRemoteExists = true;
0152:                    verified = verified && verifyEntityLocal(entity);
0153:                    verified = verified && verifyEntityLocalHome(entity);
0154:                }
0155:
0156:                verified = verified && verifyPrimaryKey(entity);
0157:
0158:                if (!localOrRemoteExists) {
0159:                    // The entity bean MUST implement either a remote home and
0160:                    // remote, or local home and local interface.  It MAY implement
0161:                    // a remote home, remote, local home or local interface.
0162:                    //
0163:                    // Spec 10.6.1 (CMP) / 12.2.1 (BMP)
0164:                    //
0165:                    if (entity.isCMP()) {
0166:                        fireSpecViolationEvent(entity, new Section("10.6.1"));
0167:                        verified = false;
0168:                    } else {
0169:                        fireSpecViolationEvent(entity, new Section("12.2.1"));
0170:                        verified = false;
0171:                    }
0172:                }
0173:
0174:                if (verified) {
0175:                    fireBeanVerifiedEvent(entity);
0176:                }
0177:            }
0178:
0179:            /**
0180:             * Try to load the beans class declared in the &lt;ejb-class&gt;
0181:             * element.
0182:             *
0183:             * @return <code>true</code> if everything went alright
0184:             */
0185:            protected boolean verifyBean(BeanMetaData theBean) {
0186:                String beanName = theBean.getEjbClass();
0187:
0188:                if (beanName == null)
0189:                    return false;
0190:
0191:                try {
0192:                    bean = classloader.loadClass(beanName);
0193:                    return true;
0194:                } catch (ClassNotFoundException cnfe) {
0195:                    fireSpecViolationEvent(theBean, new Section("22.2.b",
0196:                            "Class not found on '" + beanName + "': "
0197:                                    + cnfe.getMessage()));
0198:                    return false;
0199:                }
0200:            }
0201:
0202:            /**
0203:             * Check whether the bean has declared local interfaces and whether
0204:             * we can load the defined classes
0205:             *
0206:             * @return <code>true</code> if everything went alright
0207:             */
0208:            protected boolean hasRemoteInterfaces(BeanMetaData bean) {
0209:                boolean status = true;
0210:                String homeName = bean.getHome();
0211:                String remoteName = bean.getRemote();
0212:
0213:                if (homeName == null || remoteName == null)
0214:                    return false;
0215:
0216:                // Verify the <home> class
0217:                try {
0218:                    home = classloader.loadClass(homeName);
0219:                } catch (ClassNotFoundException cnfe) {
0220:                    fireSpecViolationEvent(bean, new Section("22.2.c",
0221:                            "Class not found on '" + homeName + "': "
0222:                                    + cnfe.getMessage()));
0223:                    status = false;
0224:                }
0225:
0226:                // Verify the <remote> class
0227:                try {
0228:                    remote = classloader.loadClass(remoteName);
0229:                } catch (ClassNotFoundException cnfe) {
0230:                    fireSpecViolationEvent(bean, new Section("22.2.d",
0231:                            "Class not found on '" + remoteName + "': "
0232:                                    + cnfe.getMessage()));
0233:                    status = false;
0234:                }
0235:
0236:                return status;
0237:            }
0238:
0239:            /**
0240:             * Check whether the bean has declared local interfaces and whether
0241:             * we can load the defined classes
0242:             *
0243:             * @return <code>true</code> if everything went alright
0244:             */
0245:            protected boolean hasLocalInterfaces(BeanMetaData bean) {
0246:                boolean status = true;
0247:                String localHomeName = bean.getLocalHome();
0248:                String localName = bean.getLocal();
0249:
0250:                if (localHomeName == null || localName == null)
0251:                    return false;
0252:
0253:                // Verify the <local-home> class
0254:                try {
0255:                    localHome = classloader.loadClass(localHomeName);
0256:                } catch (ClassNotFoundException cnfe) {
0257:                    fireSpecViolationEvent(bean, new Section("22.2.e",
0258:                            "Class not found on '" + localHomeName + "': "
0259:                                    + cnfe.getMessage()));
0260:                    status = false;
0261:                }
0262:
0263:                try {
0264:                    local = classloader.loadClass(localName);
0265:                } catch (ClassNotFoundException cnfe) {
0266:                    fireSpecViolationEvent(bean, new Section("22.2.f",
0267:                            "Class not found on '" + localName + "': "
0268:                                    + cnfe.getMessage()));
0269:                    status = false;
0270:                }
0271:
0272:                return status;
0273:            }
0274:
0275:            /**
0276:             * Verifies the session bean remote home interface against the EJB 2.0
0277:             * specification.
0278:             *
0279:             * @param   session     XML metadata of the session bean
0280:             */
0281:            protected boolean verifySessionHome(SessionMetaData session) {
0282:                boolean status = true;
0283:
0284:                // The home interface of a stateless session bean MUST have one
0285:                // create() method that takes no arguments.
0286:                //
0287:                // The create() method MUST return the session bean's remote
0288:                // interface.
0289:                //
0290:                // There CAN NOT be other create() methods in the home interface.
0291:                //
0292:                // Spec 7.10.6
0293:                //
0294:                if (session.isStateless()) {
0295:                    if (!hasDefaultCreateMethod(home)) {
0296:                        fireSpecViolationEvent(session,
0297:                                new Section("7.10.6.d2"));
0298:                        status = false;
0299:                    } else {
0300:                        Method create = getDefaultCreateMethod(home);
0301:
0302:                        if (hasMoreThanOneCreateMethods(home)) {
0303:                            fireSpecViolationEvent(session, new Section(
0304:                                    "7.10.6.d2"));
0305:                            status = false;
0306:                        }
0307:                    }
0308:                }
0309:
0310:                // The session bean's home interface MUST extend the
0311:                // javax.ejb.EJBHome interface.
0312:                //
0313:                // Spec 7.10.6
0314:                //
0315:                if (!hasEJBHomeInterface(home)) {
0316:                    fireSpecViolationEvent(session, new Section("7.10.6.a"));
0317:                    status = false;
0318:                }
0319:
0320:                // Method arguments defined in the home interface MUST be
0321:                // of valid types for RMI/IIOP.
0322:                //
0323:                // Method return values defined in the home interface MUST
0324:                // be of valid types for RMI/IIOP.
0325:                //
0326:                // Methods defined in the home interface MUST include
0327:                // java.rmi.RemoteException in their throws clause.
0328:                //
0329:                // Spec 7.10.6
0330:                ///
0331:                Iterator it = Arrays.asList(home.getMethods()).iterator();
0332:                while (it.hasNext()) {
0333:                    Method method = (Method) it.next();
0334:
0335:                    if (!hasLegalRMIIIOPArguments(method)) {
0336:                        fireSpecViolationEvent(session, method, new Section(
0337:                                "7.10.6.b1"));
0338:                        status = false;
0339:                    }
0340:
0341:                    if (!hasLegalRMIIIOPReturnType(method)) {
0342:                        fireSpecViolationEvent(session, method, new Section(
0343:                                "7.10.6.b2"));
0344:                        status = false;
0345:                    }
0346:
0347:                    if (!throwsRemoteException(method)) {
0348:                        fireSpecViolationEvent(session, method, new Section(
0349:                                "7.10.6.b3"));
0350:                        status = false;
0351:                    }
0352:                }
0353:
0354:                // A session bean's home interface MUST define one or more
0355:                // create(...) methods.
0356:                //
0357:                // Spec 7.10.6
0358:                //
0359:                if (!hasCreateMethod(home)) {
0360:                    fireSpecViolationEvent(session, new Section("7.10.6.d1"));
0361:                    status = false;
0362:                }
0363:
0364:                // Each create(...) method in the session bean's home interface
0365:                // MUST have a matching ejbCreate(...) method in the session
0366:                // bean's class.
0367:                //
0368:                // Each create(...) method in the session bean's home interface
0369:                // MUST have the same number and types of arguments to its
0370:                // matching ejbCreate(...) method.
0371:                //
0372:                // The return type for a create(...) method MUST be the session
0373:                // bean's remote interface type.
0374:                //
0375:                // All the exceptions defined in the throws clause of the matching
0376:                // ejbCreate(...) method of the enterprise bean class MUST be
0377:                // included in the throws clause of a matching create(...) method.
0378:                //
0379:                // The throws clause of a create(...) method MUST include the
0380:                // javax.ejb.CreateException.
0381:                //
0382:                // Spec 7.10.6
0383:                //
0384:                Iterator createMethods = getCreateMethods(home);
0385:                while (createMethods.hasNext()) {
0386:                    Method create = (Method) createMethods.next();
0387:
0388:                    if (!hasMatchingEJBCreate(bean, create)) {
0389:                        fireSpecViolationEvent(session, create, new Section(
0390:                                "7.10.6.e"));
0391:                        status = false;
0392:                    }
0393:
0394:                    if (!hasRemoteReturnType(session, create)) {
0395:                        fireSpecViolationEvent(session, create, new Section(
0396:                                "7.10.6.f"));
0397:                        status = false;
0398:                    }
0399:
0400:                    if (hasMatchingEJBCreate(bean, create)) {
0401:                        Method ejbCreate = getMatchingEJBCreate(bean, create);
0402:                        if (!hasMatchingExceptions(ejbCreate, create)) {
0403:                            fireSpecViolationEvent(session, create,
0404:                                    new Section("7.10.6.g"));
0405:                            status = false;
0406:                        }
0407:                    }
0408:
0409:                    if (!throwsCreateException(create)) {
0410:                        fireSpecViolationEvent(session, create, new Section(
0411:                                "7.10.6.h"));
0412:                        status = false;
0413:                    }
0414:                }
0415:
0416:                return status;
0417:            }
0418:
0419:            /**
0420:             * Verifies the session bean local home interface against the EJB 2.0
0421:             * specification.
0422:             *
0423:             * @param session parsed metadata of the session bean
0424:             */
0425:            protected boolean verifySessionLocalHome(SessionMetaData session) {
0426:                boolean status = true;
0427:
0428:                // The local home interface of a stateless session bean MUST have
0429:                // one create() method that takes no arguments.
0430:                //
0431:                // There CAN NOT be other create() methods in the home interface.
0432:                //
0433:                // Spec 7.10.8
0434:                //
0435:                if (session.isStateless()) {
0436:                    if (!hasDefaultCreateMethod(localHome)) {
0437:                        fireSpecViolationEvent(session,
0438:                                new Section("7.10.8.d2"));
0439:                        status = false;
0440:                    } else {
0441:                        Method create = getDefaultCreateMethod(localHome);
0442:
0443:                        if (hasMoreThanOneCreateMethods(localHome)) {
0444:                            fireSpecViolationEvent(session, new Section(
0445:                                    "7.10.8.d2"));
0446:                            status = false;
0447:                        }
0448:                    }
0449:                }
0450:
0451:                // The session bean's home interface MUST extend the
0452:                // javax.ejb.EJBLocalHome interface.
0453:                //
0454:                // Spec 7.10.8
0455:                //
0456:                if (!hasEJBLocalHomeInterface(localHome)) {
0457:                    fireSpecViolationEvent(session, new Section("7.10.8.a"));
0458:                    status = false;
0459:                }
0460:
0461:                // Methods defined in the local home interface MUST NOT include
0462:                // java.rmi.RemoteException in their throws clause.
0463:                //
0464:                // Spec 7.10.8
0465:                //
0466:                Iterator it = Arrays.asList(localHome.getMethods()).iterator();
0467:                while (it.hasNext()) {
0468:                    Method method = (Method) it.next();
0469:
0470:                    if (throwsRemoteException(method)) {
0471:                        fireSpecViolationEvent(session, method, new Section(
0472:                                "7.10.8.b"));
0473:                        status = false;
0474:                    }
0475:                }
0476:
0477:                // A session bean's home interface MUST define one or more
0478:                // create(...) methods.
0479:                //
0480:                // Spec 7.10.8
0481:                //
0482:                if (!hasCreateMethod(localHome)) {
0483:                    fireSpecViolationEvent(session, new Section("7.10.8.d1"));
0484:                    status = false;
0485:                }
0486:
0487:                // Each create(...) method in the session bean's local home
0488:                // interface MUST have a matching ejbCreate(...) method in the
0489:                // session bean's class.
0490:                //
0491:                // Each create(...) method in the session bean's home interface
0492:                // MUST have the same number and types of arguments to its
0493:                // matching ejbCreate(...) method.
0494:                //
0495:                // The return type for a create(...) method MUST be the session
0496:                // bean's local interface type.
0497:                //
0498:                // All the exceptions defined in the throws clause of the matching
0499:                // ejbCreate(...) method of the enterprise bean class MUST be
0500:                // included in the throws clause of a matching create(...) method.
0501:                //
0502:                // The throws clause of a create(...) method MUST include the
0503:                // javax.ejb.CreateException.
0504:                //
0505:                // Spec 7.10.8
0506:                //
0507:                Iterator createMethods = getCreateMethods(localHome);
0508:                while (createMethods.hasNext()) {
0509:                    Method create = (Method) createMethods.next();
0510:
0511:                    if (!hasMatchingEJBCreate(bean, create)) {
0512:                        fireSpecViolationEvent(session, create, new Section(
0513:                                "7.10.8.e"));
0514:                        status = false;
0515:                    }
0516:
0517:                    if (!hasLocalReturnType(session, create)) {
0518:                        fireSpecViolationEvent(session, create, new Section(
0519:                                "7.10.8.f"));
0520:                        status = false;
0521:                    }
0522:
0523:                    if (hasMatchingEJBCreate(bean, create)) {
0524:                        Method ejbCreate = getMatchingEJBCreate(bean, create);
0525:                        if (!hasMatchingExceptions(ejbCreate, create)) {
0526:                            fireSpecViolationEvent(session, create,
0527:                                    new Section("7.10.8.g"));
0528:                        }
0529:                    }
0530:
0531:                    if (!throwsCreateException(create)) {
0532:                        fireSpecViolationEvent(session, create, new Section(
0533:                                "7.10.8.h"));
0534:                        status = false;
0535:                    }
0536:                }
0537:
0538:                return status;
0539:            }
0540:
0541:            /*
0542:             * Verify Session Bean Remote Interface
0543:             */
0544:            protected boolean verifySessionRemote(SessionMetaData session) {
0545:                boolean status = true;
0546:
0547:                // The remote interface MUST extend the javax.ejb.EJBObject
0548:                // interface.
0549:                //
0550:                // Spec 7.10.5
0551:                //
0552:                if (!hasEJBObjectInterface(remote)) {
0553:                    fireSpecViolationEvent(session, new Section("7.10.5.a"));
0554:                    status = false;
0555:                }
0556:
0557:                // Method arguments defined in the remote interface MUST be
0558:                // of valid types for RMI/IIOP.
0559:                //
0560:                // Method return values defined in the remote interface MUST
0561:                // be of valid types for RMI/IIOP.
0562:                //
0563:                // Methods defined in the remote interface MUST include
0564:                // java.rmi.RemoteException in their throws clause.
0565:                //
0566:                // Spec 7.10.5
0567:                //
0568:                Iterator it = Arrays.asList(remote.getMethods()).iterator();
0569:                while (it.hasNext()) {
0570:                    Method method = (Method) it.next();
0571:
0572:                    if (!hasLegalRMIIIOPArguments(method)) {
0573:                        fireSpecViolationEvent(session, method, new Section(
0574:                                "7.10.5.b1"));
0575:                        status = false;
0576:                    }
0577:
0578:                    if (!hasLegalRMIIIOPReturnType(method)) {
0579:                        fireSpecViolationEvent(session, method, new Section(
0580:                                "7.10.5.b2"));
0581:                        status = false;
0582:                    }
0583:
0584:                    if (!throwsRemoteException(method)) {
0585:                        fireSpecViolationEvent(session, method, new Section(
0586:                                "7.10.5.b3"));
0587:                        status = false;
0588:                    }
0589:                }
0590:
0591:                // For each method defined in the remote interface, there MUST be
0592:                // a matching method in the session bean's class. The matching
0593:                // method MUST have:
0594:                //
0595:                //  - the same name
0596:                //  - the same number and types of arguments, and the same
0597:                //    return type
0598:                //  - All the exceptions defined in the throws clause of the
0599:                //    matching method of the session bean class must be defined
0600:                //    in the throws clause of the method of the remote interface
0601:                //
0602:                // Spec 7.10.5
0603:                //
0604:                it = Arrays.asList(remote.getDeclaredMethods()).iterator();
0605:                while (it.hasNext()) {
0606:                    Method remoteMethod = (Method) it.next();
0607:
0608:                    if (!hasMatchingMethod(bean, remoteMethod)) {
0609:                        fireSpecViolationEvent(session, remoteMethod,
0610:                                new Section("7.10.5.d1"));
0611:
0612:                        status = false;
0613:                    }
0614:
0615:                    if (hasMatchingMethod(bean, remoteMethod)) {
0616:                        try {
0617:                            Method beanMethod = bean.getMethod(remoteMethod
0618:                                    .getName(), remoteMethod
0619:                                    .getParameterTypes());
0620:
0621:                            if (!hasMatchingReturnType(remoteMethod, beanMethod)) {
0622:                                fireSpecViolationEvent(session, remoteMethod,
0623:                                        new Section("7.10.5.d2"));
0624:                                status = false;
0625:                            }
0626:
0627:                            if (!hasMatchingExceptions(beanMethod, remoteMethod)) {
0628:                                fireSpecViolationEvent(session, remoteMethod,
0629:                                        new Section("7.10.5.d3"));
0630:                                status = false;
0631:                            }
0632:                        } catch (NoSuchMethodException ignored) {
0633:                        }
0634:                    }
0635:                }
0636:
0637:                return status;
0638:            }
0639:
0640:            /*
0641:             * Verify Session Bean Local Interface
0642:             */
0643:            protected boolean verifySessionLocal(SessionMetaData session) {
0644:                boolean status = true;
0645:
0646:                // The local interface MUST extend the javax.ejb.EJBLocalObject
0647:                // interface.
0648:                //
0649:                // Spec 7.10.7
0650:                //
0651:                if (!hasEJBLocalObjectInterface(local)) {
0652:                    fireSpecViolationEvent(session, new Section("7.10.7.a"));
0653:                    status = false;
0654:                }
0655:
0656:                // Methods defined in the local interface MUST NOT include
0657:                // java.rmi.RemoteException in their throws clause.
0658:                //
0659:                // Spec 7.10.7
0660:                //
0661:                Iterator it = Arrays.asList(local.getMethods()).iterator();
0662:                while (it.hasNext()) {
0663:                    Method method = (Method) it.next();
0664:                    if (throwsRemoteException(method)) {
0665:                        fireSpecViolationEvent(session, method, new Section(
0666:                                "7.10.7.b"));
0667:                        status = false;
0668:                    }
0669:                }
0670:
0671:                // For each method defined in the local interface, there MUST be
0672:                // a matching method in the session bean's class. The matching
0673:                // method MUST have:
0674:                //
0675:                //  - the same name
0676:                //  - the same number and types of arguments, and the same
0677:                //    return type
0678:                //  - All the exceptions defined in the throws clause of the
0679:                //    matching method of the session bean class must be defined
0680:                //    in the throws clause of the method of the remote interface
0681:                //
0682:                // Spec 7.10.7
0683:                //
0684:                it = Arrays.asList(local.getDeclaredMethods()).iterator();
0685:                while (it.hasNext()) {
0686:                    Method localMethod = (Method) it.next();
0687:
0688:                    if (!hasMatchingMethod(bean, localMethod)) {
0689:                        fireSpecViolationEvent(session, localMethod,
0690:                                new Section("7.10.7.d1"));
0691:                        status = false;
0692:                    }
0693:
0694:                    if (hasMatchingMethod(bean, localMethod)) {
0695:                        try {
0696:                            Method beanMethod = bean
0697:                                    .getMethod(localMethod.getName(),
0698:                                            localMethod.getParameterTypes());
0699:
0700:                            if (!hasMatchingReturnType(localMethod, beanMethod)) {
0701:                                fireSpecViolationEvent(session, localMethod,
0702:                                        new Section("7.10.7.d2"));
0703:                                status = false;
0704:                            }
0705:
0706:                            if (!hasMatchingExceptions(beanMethod, localMethod)) {
0707:                                fireSpecViolationEvent(session, localMethod,
0708:                                        new Section("7.10.7.d3"));
0709:                                status = false;
0710:                            }
0711:                        } catch (NoSuchMethodException ignored) {
0712:                        }
0713:                    }
0714:                }
0715:
0716:                return status;
0717:            }
0718:
0719:            /*
0720:             * Verify Session Bean
0721:             */
0722:            protected boolean verifySessionBean(SessionMetaData session) {
0723:                boolean status = true;
0724:
0725:                // A session bean MUST implement, directly or indirectly,
0726:                // javax.ejb.SessionBean interface.
0727:                //
0728:                // Spec 7.10.2
0729:                //
0730:                if (!hasSessionBeanInterface(bean)) {
0731:                    fireSpecViolationEvent(session, new Section("7.10.2.a"));
0732:                    status = false;
0733:                }
0734:
0735:                // Only a stateful container-managed transaction demarcation
0736:                // session bean MAY implement the SessionSynchronization
0737:                // interface.
0738:                //
0739:                // A stateless Session bean MUST NOT implement the
0740:                // SessionSynchronization interface.
0741:                //
0742:                // Spec 7.5.3
0743:                //
0744:                if (hasSessionSynchronizationInterface(bean)) {
0745:                    if (session.isStateless()) {
0746:                        fireSpecViolationEvent(session, new Section("7.5.3.a"));
0747:                        status = false;
0748:                    }
0749:
0750:                    if (session.isBeanManagedTx()) {
0751:                        fireSpecViolationEvent(session, new Section("7.5.3.b"));
0752:                        status = false;
0753:                    }
0754:                }
0755:
0756:                //
0757:                // A session bean MUST implement AT LEAST one ejbCreate method.
0758:                //
0759:                // Spec 7.10.3
0760:                //
0761:                if (!hasEJBCreateMethod(bean, true)) {
0762:                    fireSpecViolationEvent(session, new Section("7.10.3"));
0763:                    status = false;
0764:                }
0765:
0766:                // A session with bean-managed transaction demarcation CANNOT
0767:                // implement the SessionSynchronization interface.
0768:                //
0769:                // Spec 7.6.1 (table 2)
0770:                //
0771:                if (hasSessionSynchronizationInterface(bean)
0772:                        && session.isBeanManagedTx()) {
0773:                    fireSpecViolationEvent(session, new Section("7.6.1"));
0774:                    status = false;
0775:                }
0776:
0777:                // The session bean class MUST be defined as public.
0778:                //
0779:                // Spec 7.10.2
0780:                //
0781:                if (!isPublic(bean)) {
0782:                    fireSpecViolationEvent(session, new Section("7.10.2.b1"));
0783:                    status = false;
0784:                }
0785:
0786:                // The session bean class MUST NOT be final.
0787:                //
0788:                // Spec 7.10.2
0789:                //
0790:                if (isFinal(bean)) {
0791:                    fireSpecViolationEvent(session, new Section("7.10.2.b2"));
0792:                    status = false;
0793:                }
0794:
0795:                // The session bean class MUST NOT be abstract.
0796:                //
0797:                // Spec 7.10.2
0798:                //
0799:                if (isAbstract(bean)) {
0800:                    fireSpecViolationEvent(session, new Section("7.10.2.b3"));
0801:                    status = false;
0802:                }
0803:
0804:                // The session bean class MUST have a public constructor that
0805:                // takes no arguments.
0806:                //
0807:                // Spec 7.10.2
0808:                //
0809:                if (!hasDefaultConstructor(bean)) {
0810:                    fireSpecViolationEvent(session, new Section("7.10.2.c"));
0811:                    status = false;
0812:                }
0813:
0814:                // The session bean class MUST NOT define the finalize() method.
0815:                //
0816:                // Spec 7.10.2
0817:                //
0818:                if (hasFinalizer(bean)) {
0819:                    fireSpecViolationEvent(session, new Section("7.10.2.d"));
0820:                    status = false;
0821:                }
0822:
0823:                // The ejbCreate(...) method signatures MUST follow these rules:
0824:                //
0825:                //      - The method name MUST have ejbCreate as its prefix
0826:                //      - The method MUST be declared as public
0827:                //      - The method MUST NOT be declared as final or static
0828:                //      - The return type MUST be void
0829:                //      - The method arguments MUST be legal types for RMI/IIOP
0830:                //      - The method SHOULD not throw a java.rmi.RemoteException
0831:                //        (NOTE we don't test for this as it's not a MUST)
0832:                //
0833:                // Spec 7.10.3
0834:                //
0835:                if (hasEJBCreateMethod(bean, true)) {
0836:                    Iterator it = getEJBCreateMethods(bean);
0837:                    while (it.hasNext()) {
0838:                        Method ejbCreate = (Method) it.next();
0839:
0840:                        if (!isPublic(ejbCreate)) {
0841:                            fireSpecViolationEvent(session, ejbCreate,
0842:                                    new Section("7.10.3.b"));
0843:                            status = false;
0844:                        }
0845:
0846:                        if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
0847:                            fireSpecViolationEvent(session, ejbCreate,
0848:                                    new Section("7.10.3.c"));
0849:                            status = false;
0850:                        }
0851:
0852:                        if (!hasVoidReturnType(ejbCreate)) {
0853:                            fireSpecViolationEvent(session, ejbCreate,
0854:                                    new Section("7.10.3.d"));
0855:                            status = false;
0856:                        }
0857:
0858:                        if (!hasLegalRMIIIOPArguments(ejbCreate)) {
0859:                            fireSpecViolationEvent(session, ejbCreate,
0860:                                    new Section("7.10.3.e"));
0861:                            status = false;
0862:                        }
0863:                    }
0864:                }
0865:
0866:                return status;
0867:            }
0868:
0869:            /*
0870:             * Verify Entity Bean Home Interface
0871:             */
0872:            private boolean verifyEntityHome(EntityMetaData entity) {
0873:                boolean status = true;
0874:
0875:                // Entity bean's home interface MUST extend the javax.ejb.EJBHome
0876:                // interface.
0877:                //
0878:                // Spec 12.2.9
0879:                //
0880:                if (!hasEJBHomeInterface(home)) {
0881:                    fireSpecViolationEvent(entity, new Section("12.2.9.a"));
0882:                    status = false;
0883:                }
0884:
0885:                // The methods defined in the entity bean's home interface MUST
0886:                // have valid RMI-IIOP argument types.
0887:                //
0888:                // The methods defined in the entity bean's home interface MUST
0889:                // have valid RMI-IIOP return types.
0890:                //
0891:                // The methods defined in the entity bean's home interface MUST
0892:                // have java.rmi.RemoteException in their throws clause.
0893:                //
0894:                // Spec 12.2.9
0895:                //
0896:                Iterator methods = Arrays.asList(home.getMethods()).iterator();
0897:                while (methods.hasNext()) {
0898:                    Method method = (Method) methods.next();
0899:
0900:                    if (!hasLegalRMIIIOPArguments(method)) {
0901:                        fireSpecViolationEvent(entity, method, new Section(
0902:                                "12.2.9.b1"));
0903:                        status = false;
0904:                    }
0905:
0906:                    if (!hasLegalRMIIIOPReturnType(method)) {
0907:                        fireSpecViolationEvent(entity, method, new Section(
0908:                                "12.2.9.b2"));
0909:                        status = false;
0910:                    }
0911:
0912:                    if (!throwsRemoteException(method)) {
0913:                        fireSpecViolationEvent(entity, method, new Section(
0914:                                "12.2.9.b3"));
0915:                        status = false;
0916:                    }
0917:                }
0918:
0919:                // Each method defined in the entity bean's home interface must be
0920:                // one of the following:
0921:                //
0922:                //    - a create method
0923:                //    - a finder method
0924:                //    - a home method
0925:                //
0926:                // Spec 12.2.9
0927:                //
0928:                methods = Arrays.asList(home.getMethods()).iterator();
0929:                while (methods.hasNext()) {
0930:                    Method method = (Method) methods.next();
0931:
0932:                    // Do not check the methods of the javax.ejb.EJBHome interface
0933:                    if (method.getDeclaringClass().getName().equals(
0934:                            EJB_HOME_INTERFACE))
0935:                        continue;
0936:
0937:                    if (isCreateMethod(method)) {
0938:                        // Each create(...) method in the entity bean's home
0939:                        // interface MUST have a matching ejbCreate(...) method in
0940:                        // the entity bean's class.
0941:                        //
0942:                        // Each create(...) method in the entity bean's home
0943:                        // interface MUST have the same number and types of
0944:                        // arguments to its matching ejbCreate(...) method.
0945:                        //
0946:                        // The return type for a create(...) method MUST be the
0947:                        // entity bean's remote interface type.
0948:                        //
0949:                        // All the exceptions defined in the throws clause of the
0950:                        // matching ejbCreate(...) and ejbPostCreate(...) methods of
0951:                        // the enterprise bean class MUST be included in the throws
0952:                        // clause of a matching create(...) method.
0953:                        //
0954:                        // The throws clause of a create(...) method MUST include
0955:                        // the javax.ejb.CreateException.
0956:                        //
0957:                        // Spec 12.2.9
0958:                        //
0959:                        if (!hasMatchingEJBCreate(bean, method)) {
0960:                            fireSpecViolationEvent(entity, method, new Section(
0961:                                    "12.2.9.d"));
0962:                            status = false;
0963:                        }
0964:
0965:                        if (!hasRemoteReturnType(entity, method)) {
0966:                            fireSpecViolationEvent(entity, method, new Section(
0967:                                    "12.2.9.e"));
0968:                            status = false;
0969:                        }
0970:
0971:                        if (hasMatchingEJBCreate(bean, method)
0972:                                && hasMatchingEJBPostCreate(bean, method)) {
0973:                            Method ejbCreate = getMatchingEJBCreate(bean,
0974:                                    method);
0975:                            Method ejbPostCreate = getMatchingEJBPostCreate(
0976:                                    bean, method);
0977:
0978:                            if (!(hasMatchingExceptions(ejbCreate, method) && hasMatchingExceptions(
0979:                                    ejbPostCreate, method))) {
0980:                                fireSpecViolationEvent(entity, method,
0981:                                        new Section("12.2.9.f"));
0982:                            }
0983:                        }
0984:
0985:                        if (!throwsCreateException(method)) {
0986:                            fireSpecViolationEvent(entity, method, new Section(
0987:                                    "12.2.9.g"));
0988:                            status = false;
0989:                        }
0990:                    } else if (isFinderMethod(method)) {
0991:                        // Each finder method MUST match one of the ejbFind<METHOD>
0992:                        // methods defined in the entity bean class.
0993:                        //
0994:                        // The matching ejbFind<METHOD> method MUST have the same
0995:                        // number and types of arguments.
0996:                        //
0997:                        // The return type for a find<METHOD> method MUST be the
0998:                        // entity bean's remote interface type (single-object
0999:                        // finder) or a collection thereof (for a multi-object
1000:                        // finder).
1001:                        //
1002:                        // All the exceptions defined in the throws clause of an
1003:                        // ejbFind method of the entity bean class MUST be included
1004:                        // in the throws clause of the matching find method of the
1005:                        // home interface.
1006:                        //
1007:                        // The throws clause of a finder method MUST include the
1008:                        // javax.ejb.FinderException.
1009:                        //
1010:                        // Spec 12.2.9
1011:                        //
1012:                        if (entity.isBMP()) { // Check for BMP violations
1013:                            if ((!hasMatchingEJBFind(bean, method))) {
1014:                                fireSpecViolationEvent(entity, method,
1015:                                        new Section("12.2.9.h"));
1016:                                status = false;
1017:                            }
1018:
1019:                            if (!(hasRemoteReturnType(entity, method) || isMultiObjectFinder(method))) {
1020:                                fireSpecViolationEvent(entity, method,
1021:                                        new Section("12.2.9.j"));
1022:                                status = false;
1023:                            }
1024:
1025:                            if ((hasMatchingEJBFind(bean, method))) {
1026:                                Method ejbFind = getMatchingEJBFind(bean,
1027:                                        method);
1028:                                if (!(hasMatchingExceptions(ejbFind, method))) {
1029:                                    fireSpecViolationEvent(entity, method,
1030:                                            new Section("12.2.9.k"));
1031:                                    status = false;
1032:                                }
1033:                            }
1034:
1035:                            if (!throwsFinderException(method)) {
1036:                                fireSpecViolationEvent(entity, method,
1037:                                        new Section("12.2.9.l"));
1038:                                status = false;
1039:                            }
1040:                        } // if( entity.isBMP() )
1041:
1042:                        if (entity.isCMP()) {
1043:
1044:                            if (!(hasRemoteReturnType(entity, method) || isMultiObjectFinder(method))) {
1045:                                fireSpecViolationEvent(entity, method,
1046:                                        new Section("10.6.10.a"));
1047:                                status = false;
1048:                            }
1049:
1050:                            if (!throwsFinderException(method)) {
1051:                                fireSpecViolationEvent(entity, method,
1052:                                        new Section("10.6.10.b"));
1053:                                status = false;
1054:                            }
1055:
1056:                            // For every finder method there must be a matching
1057:                            // <query> element defined in the deployment descriptor
1058:                            // with the exception of findByPrimaryKey
1059:                            //
1060:                            // JBoss Extension: 'findAll' is _also_ ignored.
1061:                            //
1062:                            if (!method.getName().equals("findByPrimaryKey")
1063:                                    && !method.getName().equals("findAll")
1064:                                    && !hasMatchingQuery(method, entity)) {
1065:                                fireSpecViolationEvent(entity, method,
1066:                                        new Section("10.5.6"));
1067:                                status = false;
1068:                            }
1069:                        } // if( entity.isCMP() )
1070:                    } else // Neither Create nor Finder method
1071:                    {
1072:                        // Each home method MUST match a method defined in the
1073:                        // entity bean class.
1074:                        //
1075:                        // The matching ejbHome<METHOD> method MUST have the same
1076:                        // number and types of arguments, and a matching return
1077:                        // type.
1078:                        //
1079:                        // Spec 12.2.9
1080:                        //
1081:                        if (!hasMatchingEJBHome(bean, method)) {
1082:                            fireSpecViolationEvent(entity, method, new Section(
1083:                                    "12.2.9.m"));
1084:                            status = false;
1085:                        }
1086:                    }
1087:                } // while( methods.hasNext() )
1088:
1089:                return status;
1090:            }
1091:
1092:            /*
1093:             * Verify Entity Bean Local Home Interface
1094:             */
1095:            private boolean verifyEntityLocalHome(EntityMetaData entity) {
1096:                boolean status = true;
1097:
1098:                // Entity bean's local home interface MUST extend the
1099:                // javax.ejb.EJBLocalHome interface.
1100:                //
1101:                // Spec 12.2.11
1102:                //
1103:                if (!hasEJBLocalHomeInterface(localHome)) {
1104:                    fireSpecViolationEvent(entity, new Section("12.2.11.a"));
1105:                    status = false;
1106:                }
1107:
1108:                // The methods defined in the entity bean's home interface MUST
1109:                // NOT have java.rmi.RemoteException in their throws clause.
1110:                //
1111:                // Spec 12.2.11
1112:                //
1113:                Iterator homeMethods = Arrays.asList(localHome.getMethods())
1114:                        .iterator();
1115:                while (homeMethods.hasNext()) {
1116:                    Method method = (Method) homeMethods.next();
1117:
1118:                    if (throwsRemoteException(method)) {
1119:                        fireSpecViolationEvent(entity, method, new Section(
1120:                                "12.2.11.b"));
1121:                        status = false;
1122:                    }
1123:                }
1124:
1125:                // Each method defined in the entity bean's local home interface
1126:                // must be one of the following:
1127:                //
1128:                //    - a create method
1129:                //    - a finder method
1130:                //    - a home method
1131:                //
1132:                // Spec 12.2.11
1133:                //
1134:                homeMethods = Arrays.asList(localHome.getMethods()).iterator();
1135:                while (homeMethods.hasNext()) {
1136:                    Method method = (Method) homeMethods.next();
1137:
1138:                    // Do not check the methods of the javax.ejb.EJBLocalHome interface
1139:                    if (method.getDeclaringClass().getName().equals(
1140:                            EJB_LOCAL_HOME_INTERFACE))
1141:                        continue;
1142:
1143:                    if (isCreateMethod(method)) {
1144:                        // Each create(...) method in the entity bean's local home
1145:                        // interface MUST have a matching ejbCreate(...) method in
1146:                        // the entity bean's class.
1147:                        //
1148:                        // Each create(...) method in the entity bean's local home
1149:                        // interface MUST have the same number and types of
1150:                        // arguments to its matching ejbCreate(...) method.
1151:                        //
1152:                        // The return type for a create(...) method MUST be the
1153:                        // entity bean's local interface type.
1154:                        //
1155:                        // All the exceptions defined in the throws clause of the
1156:                        // matching ejbCreate(...) and ejbPostCreate(...) methods of
1157:                        // the enterprise bean class MUST be included in the throws
1158:                        // clause of a matching create(...) method.
1159:                        //
1160:                        // The throws clause of a create(...) method MUST include
1161:                        // the javax.ejb.CreateException.
1162:                        //
1163:                        // Spec 12.2.11
1164:                        //
1165:                        if (!hasMatchingEJBCreate(bean, method)) {
1166:                            fireSpecViolationEvent(entity, method, new Section(
1167:                                    "12.2.11.e"));
1168:                            status = false;
1169:                        }
1170:
1171:                        if (!hasLocalReturnType(entity, method)) {
1172:                            fireSpecViolationEvent(entity, method, new Section(
1173:                                    "12.2.11.f"));
1174:                            status = false;
1175:                        }
1176:
1177:                        if (hasMatchingEJBCreate(bean, method)
1178:                                && hasMatchingEJBPostCreate(bean, method)) {
1179:                            Method ejbCreate = getMatchingEJBCreate(bean,
1180:                                    method);
1181:                            Method ejbPostCreate = getMatchingEJBPostCreate(
1182:                                    bean, method);
1183:
1184:                            if (!(hasMatchingExceptions(ejbCreate, method) && hasMatchingExceptions(
1185:                                    ejbPostCreate, method))) {
1186:                                fireSpecViolationEvent(entity, method,
1187:                                        new Section("12.2.11.g"));
1188:                            }
1189:                        }
1190:
1191:                        if (!throwsCreateException(method)) {
1192:                            fireSpecViolationEvent(entity, method, new Section(
1193:                                    "12.2.11.h"));
1194:                            status = false;
1195:                        }
1196:                    } else if (isFinderMethod(method)) {
1197:                        // Each finder method MUST match one of the ejbFind<METHOD>
1198:                        // methods defined in the entity bean class.
1199:                        //
1200:                        // The matching ejbFind<METHOD> method MUST have the same
1201:                        // number and types of arguments.
1202:                        //
1203:                        // The return type for a find<METHOD> method MUST be the
1204:                        // entity bean's local interface type (single-object finder)
1205:                        // or a collection thereof (for a multi-object finder).
1206:                        //
1207:                        // All the exceptions defined in the throws clause of an
1208:                        // ejbFind method of the entity bean class MUST be included
1209:                        // in the throws clause of the matching find method of the
1210:                        // home interface.
1211:                        //
1212:                        // The throws clause of a finder method MUST include the
1213:                        // javax.ejb.FinderException.
1214:                        //
1215:                        // Spec 12.2.11
1216:                        //
1217:                        if (!(hasLocalReturnType(entity, method) || isMultiObjectFinder(method))) {
1218:                            fireSpecViolationEvent(entity, method, new Section(
1219:                                    "12.2.11.j"));
1220:                            status = false;
1221:                        }
1222:
1223:                        if (!throwsFinderException(method)) {
1224:                            fireSpecViolationEvent(entity, method, new Section(
1225:                                    "12.2.11.k"));
1226:                            status = false;
1227:                        }
1228:
1229:                        if (entity.isCMP()) {
1230:                            // The entity bean class does not implement the finder
1231:                            // methods. The implementation of the finder methods are
1232:                            // provided by the Container
1233:                            //
1234:                            // Spec 10.6.2
1235:                            //
1236:                            if (hasMatchingEJBFind(bean, method)) {
1237:                                fireSpecViolationEvent(entity, method,
1238:                                        new Section("10.6.2.j"));
1239:                                status = false;
1240:                            }
1241:
1242:                            // For every finder method there must be a matching
1243:                            // <query> element defined in the deployment descriptor
1244:                            // with the exception of findByPrimaryKey
1245:                            //
1246:                            // JBoss Extension: 'findAll' is _also_ ignored.
1247:                            //
1248:                            // Spec 10.5.6
1249:                            //
1250:                            if (!method.getName().equals("findByPrimaryKey")
1251:                                    && !method.getName().equals("findAll")
1252:                                    && !hasMatchingQuery(method, entity)) {
1253:                                fireSpecViolationEvent(entity, method,
1254:                                        new Section("10.5.6"));
1255:                                status = false;
1256:                            }
1257:                        }
1258:
1259:                        if (entity.isBMP()) {
1260:                            if (!hasMatchingEJBFind(bean, method)) {
1261:                                fireSpecViolationEvent(entity, method,
1262:                                        new Section("12.2.11.i"));
1263:                                status = false;
1264:                            } else {
1265:                                Method ejbFind = getMatchingEJBFind(bean,
1266:                                        method);
1267:
1268:                                if (!(hasMatchingExceptions(ejbFind, method))) {
1269:                                    fireSpecViolationEvent(entity, method,
1270:                                            new Section("12.2.11.l"));
1271:                                }
1272:                            }
1273:                        }
1274:                    } else {
1275:                        // Each home method MUST match a method defined in the
1276:                        // entity bean class.
1277:                        //
1278:                        // The matching ejbHome<METHOD> method MUST have the same
1279:                        // number and types of arguments, and a matching return
1280:                        // type.
1281:                        //
1282:                        // Spec 12.2.9
1283:                        //
1284:                        if (!hasMatchingEJBHome(bean, method)) {
1285:                            fireSpecViolationEvent(entity, method, new Section(
1286:                                    "12.2.11.m"));
1287:                            status = false;
1288:                        }
1289:                    }
1290:                } // while( homeMethods.hasNext() )
1291:
1292:                return status;
1293:            }
1294:
1295:            /*
1296:             * Verify Entity Bean Local Interface
1297:             */
1298:            private boolean verifyEntityLocal(EntityMetaData entity) {
1299:                boolean status = true;
1300:
1301:                // Entity bean's local interface MUST extend
1302:                // the javax.ejb.EJBLocalObject interface.
1303:                //
1304:                // Spec 12.2.10
1305:                //
1306:                if (!hasEJBLocalObjectInterface(local)) {
1307:                    fireSpecViolationEvent(entity, new Section("12.2.10.a"));
1308:                    status = false;
1309:                }
1310:
1311:                // The methods defined in the entity bean's local interface MUST
1312:                // NOT have java.rmi.RemoteException in their throws clause.
1313:                //
1314:                // Spec 12.2.10
1315:                //
1316:                Iterator localMethods = Arrays.asList(local.getMethods())
1317:                        .iterator();
1318:                while (localMethods.hasNext()) {
1319:                    Method method = (Method) localMethods.next();
1320:
1321:                    if (throwsRemoteException(method)) {
1322:                        fireSpecViolationEvent(entity, method, new Section(
1323:                                "12.2.10.b"));
1324:                        status = false;
1325:                    }
1326:                }
1327:
1328:                // For each method defined in the local interface, there MUST be
1329:                // a matching method in the entity bean's class. The matching
1330:                // method MUST have:
1331:                //
1332:                //     - The same name.
1333:                //     - The same number and types of its arguments.
1334:                //     - The same return type.
1335:                //     - All the exceptions defined in the throws clause of the
1336:                //       matching method of the enterprise Bean class must be
1337:                //       defined in the throws clause of the method of the local
1338:                //       interface.
1339:                //
1340:                // Spec 12.2.10
1341:                //
1342:                localMethods = Arrays.asList(local.getMethods()).iterator();
1343:                while (localMethods.hasNext()) {
1344:                    Method method = (Method) localMethods.next();
1345:
1346:                    // Do not check the methods of the javax.ejb.EJBLocalObject
1347:                    // interface
1348:                    if (method.getDeclaringClass().getName().equals(
1349:                            EJB_LOCAL_OBJECT_INTERFACE))
1350:                        continue;
1351:
1352:                    if (!hasMatchingMethod(bean, method)) {
1353:                        fireSpecViolationEvent(entity, method, new Section(
1354:                                "12.2.10.c"));
1355:                        status = false;
1356:                    }
1357:
1358:                    if (hasMatchingMethod(bean, method)) {
1359:                        try {
1360:                            Method beanMethod = bean.getMethod(
1361:                                    method.getName(), method
1362:                                            .getParameterTypes());
1363:
1364:                            if (!hasMatchingReturnType(beanMethod, method)) {
1365:                                fireSpecViolationEvent(entity, method,
1366:                                        new Section("12.2.10.d"));
1367:                                status = false;
1368:                            }
1369:
1370:                            if (!hasMatchingExceptions(beanMethod, method)) {
1371:                                fireSpecViolationEvent(entity, method,
1372:                                        new Section("12.2.10.e"));
1373:
1374:                                status = false;
1375:                            }
1376:                        } catch (NoSuchMethodException ignored) {
1377:                        }
1378:                    }
1379:                }
1380:
1381:                return status;
1382:            }
1383:
1384:            /*
1385:             * Verify Entity Bean Remote Interface
1386:             */
1387:            private boolean verifyEntityRemote(EntityMetaData entity) {
1388:                boolean status = true;
1389:
1390:                // Entity bean's remote interface MUST extend
1391:                // the javax.ejb.EJBObject interface.
1392:                //
1393:                // Spec 9.2.7
1394:                //
1395:                if (!hasEJBObjectInterface(remote)) {
1396:                    fireSpecViolationEvent(entity, new Section("9.2.7.a"));
1397:                    status = false;
1398:                }
1399:
1400:                // The methods defined in the entity bean's remote interface MUST
1401:                // have valid RMI-IIOP argument types.
1402:                //
1403:                // The methods defined in the entity bean's home interface MUST
1404:                // have valid RMI-IIOP return types.
1405:                //
1406:                // The methods defined in the entity bean's home interface MUST
1407:                // have java.rmi.RemoteException in their throws clause.
1408:                //
1409:                // Spec 9.2.7
1410:                //
1411:                Iterator it = Arrays.asList(remote.getMethods()).iterator();
1412:                while (it.hasNext()) {
1413:                    Method method = (Method) it.next();
1414:
1415:                    if (!hasLegalRMIIIOPArguments(method)) {
1416:                        fireSpecViolationEvent(entity, method, new Section(
1417:                                "9.2.7.b"));
1418:                        status = false;
1419:                    }
1420:
1421:                    if (!hasLegalRMIIIOPReturnType(method)) {
1422:                        fireSpecViolationEvent(entity, method, new Section(
1423:                                "9.2.7.c"));
1424:                        status = false;
1425:                    }
1426:
1427:                    if (!hasLegalRMIIIOPExceptionTypes(method)) {
1428:                        fireSpecViolationEvent(entity, method, new Section(
1429:                                "9.2.7.h"));
1430:                        status = false;
1431:                    }
1432:
1433:                    if (!throwsRemoteException(method)) {
1434:                        fireSpecViolationEvent(entity, method, new Section(
1435:                                "9.2.7.d"));
1436:                        status = false;
1437:                    }
1438:                }
1439:
1440:                // For each method defined in the remote interface, there MUST be
1441:                // a matching method in the entity bean's class. The matching
1442:                // method MUST have:
1443:                //
1444:                //     - The same name.
1445:                //     - The same number and types of its arguments.
1446:                //     - The same return type.
1447:                //     - All the exceptions defined in the throws clause of the
1448:                //       matching method of the enterprise Bean class must be
1449:                //       defined in the throws clause of the method of the remote
1450:                //       interface.
1451:                //
1452:                // Spec 9.2.7
1453:                //
1454:                it = Arrays.asList(remote.getMethods()).iterator();
1455:                while (it.hasNext()) {
1456:                    Method method = (Method) it.next();
1457:
1458:                    // Do not check the methods of the javax.ejb.EJBObject interface
1459:                    if (method.getDeclaringClass().getName().equals(
1460:                            EJB_OBJECT_INTERFACE))
1461:                        continue;
1462:
1463:                    if (!hasMatchingMethod(bean, method)) {
1464:                        fireSpecViolationEvent(entity, method, new Section(
1465:                                "9.2.7.e"));
1466:                        status = false;
1467:                    }
1468:
1469:                    if (hasMatchingMethod(bean, method)) {
1470:                        try {
1471:                            Method beanMethod = bean.getMethod(
1472:                                    method.getName(), method
1473:                                            .getParameterTypes());
1474:
1475:                            if (!hasMatchingReturnType(beanMethod, method)) {
1476:                                fireSpecViolationEvent(entity, method,
1477:                                        new Section("9.2.7.f"));
1478:                                status = false;
1479:                            }
1480:
1481:                            if (!hasMatchingExceptions(beanMethod, method)) {
1482:                                fireSpecViolationEvent(entity, method,
1483:                                        new Section("9.2.7.g"));
1484:                                status = false;
1485:                            }
1486:                        } catch (NoSuchMethodException ignored) {
1487:                        }
1488:                    }
1489:                }
1490:
1491:                return status;
1492:            }
1493:
1494:            /*
1495:             * Verify Entity Bean Class
1496:             */
1497:            private boolean verifyCMPEntityBean(EntityMetaData entity) {
1498:                boolean status = true;
1499:
1500:                // The enterprise bean class MUST implement, directly or
1501:                // indirectly, the javax.ejb.EntityBean interface.
1502:                //
1503:                // Spec 10.6.2
1504:                //
1505:                if (!hasEntityBeanInterface(bean)) {
1506:                    fireSpecViolationEvent(entity, new Section("10.6.2.a"));
1507:                    status = false;
1508:                }
1509:
1510:                // The entity bean class MUST be defined as public and abstract.
1511:                //
1512:                // Spec 10.6.2
1513:                //
1514:                if (!isPublic(bean) || !isAbstract(bean)) {
1515:                    fireSpecViolationEvent(entity, new Section("10.6.2.b"));
1516:                    status = false;
1517:                }
1518:
1519:                // The entity bean class MUST define a public constructor that
1520:                // takes no arguments
1521:                //
1522:                // Spec 10.6.2
1523:                //
1524:                if (!hasDefaultConstructor(bean)) {
1525:                    fireSpecViolationEvent(entity, new Section("10.6.2.c"));
1526:                    status = false;
1527:                }
1528:
1529:                // The entity bean class MUST NOT define the finalize() method.
1530:                //
1531:                // Spec 10.6.2
1532:                //
1533:                if (hasFinalizer(bean)) {
1534:                    fireSpecViolationEvent(entity, new Section("10.6.2.d"));
1535:                    status = false;
1536:                }
1537:
1538:                // The ejbCreate(...) method signatures MUST follow these rules:
1539:                //
1540:                //      - The method MUST be declared as public
1541:                //      - The method MUST NOT be declared as final or static
1542:                //      - The return type MUST be the entity bean's primary key type
1543:                //      --- Only if method is on remote home ---
1544:                //      - The method arguments MUST be legal types for RMI/IIOP
1545:                //      - The method return value type MUST be legal type for RMI/IIOP
1546:                //      --- End of only if method is on remote home ---
1547:                //      - The method must define the javax.ejb.CreateException
1548:                //
1549:                // Spec 10.6.4
1550:                //
1551:                if (hasEJBCreateMethod(bean, false)) {
1552:                    Iterator it = getEJBCreateMethods(bean);
1553:                    while (it.hasNext()) {
1554:                        Method ejbCreate = (Method) it.next();
1555:                        if (!isPublic(ejbCreate)) {
1556:                            fireSpecViolationEvent(entity, ejbCreate,
1557:                                    new Section("10.6.4.b"));
1558:                            status = false;
1559:                        }
1560:
1561:                        if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
1562:                            fireSpecViolationEvent(entity, ejbCreate,
1563:                                    new Section("10.6.4.c"));
1564:                            status = false;
1565:                        }
1566:
1567:                        if (!hasPrimaryKeyReturnType(entity, ejbCreate)) {
1568:                            fireSpecViolationEvent(entity, ejbCreate,
1569:                                    new Section("10.6.4.d"));
1570:                            status = false;
1571:                        }
1572:
1573:                        /* FIXME
1574:                         *  This is only true if the method is on the remote home
1575:                         * interface
1576:                         if (!hasLegalRMIIIOPArguments(ejbCreate)) {
1577:                         fireSpecViolationEvent(entity, ejbCreate, new Section("10.6.4.d"));
1578:                         status = false;
1579:                         }
1580:
1581:                         if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
1582:                         fireSpecViolationEvent(entity, ejbCreate, new Section("10.5.4.f"));
1583:                         status = false;
1584:                         }
1585:                         */
1586:
1587:                        if (!throwsCreateException(ejbCreate)) {
1588:                            fireSpecViolationEvent(entity, ejbCreate,
1589:                                    new Section("10.6.4.g"));
1590:                            status = false;
1591:                        }
1592:                    }
1593:                }
1594:
1595:                // For each ejbCreate(...) method, the entity bean class MUST
1596:                // define a matching ejbPostCreate(...) method.
1597:                //
1598:                // The ejbPostCreate(...) method MUST follow these rules:
1599:                //
1600:                //   - the method MUST be declared as public
1601:                //   - the method MUST NOT be declared as final or static
1602:                //   - the return type MUST be void
1603:                //   - the method arguments MUST be the same as the matching
1604:                //     ejbCreate(...) method
1605:                //
1606:                // Spec 10.6.5
1607:                //
1608:                if (hasEJBCreateMethod(bean, false)) {
1609:                    Iterator it = getEJBCreateMethods(bean);
1610:
1611:                    while (it.hasNext()) {
1612:                        Method ejbCreate = (Method) it.next();
1613:
1614:                        if (!hasMatchingEJBPostCreate(bean, ejbCreate)) {
1615:                            fireSpecViolationEvent(entity, ejbCreate,
1616:                                    new Section("10.6.5.a"));
1617:                            status = false;
1618:                        }
1619:
1620:                        if (hasMatchingEJBPostCreate(bean, ejbCreate)) {
1621:                            Method ejbPostCreate = getMatchingEJBPostCreate(
1622:                                    bean, ejbCreate);
1623:
1624:                            if (!isPublic(ejbPostCreate)) {
1625:                                fireSpecViolationEvent(entity, ejbPostCreate,
1626:                                        new Section("10.6.5.b"));
1627:                                status = false;
1628:                            }
1629:
1630:                            if (isStatic(ejbPostCreate)) {
1631:                                fireSpecViolationEvent(entity, ejbPostCreate,
1632:                                        new Section("10.6.5.c"));
1633:                                status = false;
1634:                            }
1635:
1636:                            if (isFinal(ejbPostCreate)) {
1637:                                fireSpecViolationEvent(entity, ejbPostCreate,
1638:                                        new Section("10.6.5.d"));
1639:                                status = false;
1640:                            }
1641:
1642:                            if (!hasVoidReturnType(ejbPostCreate)) {
1643:                                fireSpecViolationEvent(entity, ejbPostCreate,
1644:                                        new Section("10.6.5.e"));
1645:                                status = false;
1646:                            }
1647:                        }
1648:                    }
1649:                }
1650:
1651:                // The ejbHome(...) method signatures MUST follow these rules:
1652:                //
1653:                //      - The method name MUST have ejbHome as its prefix.
1654:                //      - The method MUST be declared as public
1655:                //      - The method MUST NOT be declared as static.
1656:                //      - The method MUST NOT define the java.rmi.RemoteException
1657:                //
1658:                // Spec 10.6.6
1659:                //
1660:                Iterator it = getEjbHomeMethods(bean);
1661:                while (it.hasNext()) {
1662:                    Method ejbHome = (Method) it.next();
1663:                    if (!isPublic(ejbHome)) {
1664:                        fireSpecViolationEvent(entity, ejbHome, new Section(
1665:                                "10.6.6.a"));
1666:                        status = false;
1667:                    }
1668:
1669:                    if (isStatic(ejbHome)) {
1670:                        fireSpecViolationEvent(entity, ejbHome, new Section(
1671:                                "10.6.6.b"));
1672:                        status = false;
1673:                    }
1674:
1675:                    if (throwsRemoteException(ejbHome)) {
1676:                        fireSpecViolationEvent(entity, ejbHome, new Section(
1677:                                "10.6.6.c"));
1678:                        status = false;
1679:                    }
1680:                }
1681:
1682:                // The CMP entity bean MUST implement get and set accessor methods for
1683:                // each field within the abstract persistance schema.
1684:                //
1685:                // Spec 10.6.2
1686:                //
1687:                it = entity.getCMPFields();
1688:                while (it.hasNext()) {
1689:                    String fieldName = (String) it.next();
1690:                    String getName = "get"
1691:                            + fieldName.substring(0, 1).toUpperCase()
1692:                            + fieldName.substring(1);
1693:                    Class fieldType = null;
1694:
1695:                    try {
1696:                        Method m = bean.getMethod(getName, new Class[0]);
1697:                        fieldType = m.getReturnType();
1698:
1699:                        // The getter must not return 'void' according to the JavaBeans
1700:                        // Spec
1701:                        if (fieldType == Void.TYPE) {
1702:                            fireSpecViolationEvent(entity, new Section(
1703:                                    "jb.7.1.b", "Field: " + fieldName));
1704:                        }
1705:                    } catch (NoSuchMethodException nsme) {
1706:                        fireSpecViolationEvent(entity, new Section("10.6.2.g",
1707:                                "Field: " + fieldName));
1708:                        status = false;
1709:                    }
1710:
1711:                    String setName = "set"
1712:                            + fieldName.substring(0, 1).toUpperCase()
1713:                            + fieldName.substring(1);
1714:                    Class[] args = new Class[1];
1715:                    args[0] = fieldType;
1716:
1717:                    try {
1718:                        Method m = bean.getMethod(setName, args);
1719:                        fieldType = m.getReturnType();
1720:
1721:                        // According to the JavaBeans Spec, a setter method must
1722:                        // return 'void'
1723:                        if (fieldType != Void.TYPE) {
1724:                            fireSpecViolationEvent(entity, new Section(
1725:                                    "jb.7.1.a", "Field: " + fieldName));
1726:                        }
1727:                    } catch (NoSuchMethodException nsme) {
1728:                        // Try with java.util.Collection
1729:                        //
1730:                        // FIXME: This should only be tried for CMR methods; a CMP
1731:                        //        setter cannot accept a Collection!
1732:                        try {
1733:                            args[0] = classloader
1734:                                    .loadClass("java.util.Collection");
1735:                            Method m = bean.getMethod(setName, args);
1736:                        } catch (NoSuchMethodException nsme2) {
1737:                            fireSpecViolationEvent(entity, new Section(
1738:                                    "10.6.2.h", "Field: " + fieldName));
1739:                            status = false;
1740:                        } catch (ClassNotFoundException cnfe) {
1741:                            // Something is really broken
1742:                        }
1743:                    }
1744:                }
1745:
1746:                // The ejbSelect(...) method signatures MUST follow these rules:
1747:                //
1748:                //      - The method name MUST have ejbSelect as its prefix.
1749:                //      - The method MUST be declared as public
1750:                //      - The method MUST be declared as abstract.
1751:                //      - The method MUST define the javax.ejb.FinderException
1752:                //
1753:                // Spec 10.6.7
1754:                //
1755:                it = getEjbSelectMethods(bean);
1756:                while (it.hasNext()) {
1757:                    Method ejbSelect = (Method) it.next();
1758:
1759:                    if (!isPublic(ejbSelect)) {
1760:                        fireSpecViolationEvent(entity, ejbSelect, new Section(
1761:                                "10.6.7.a"));
1762:                        status = false;
1763:                    }
1764:
1765:                    if (!isAbstract(ejbSelect)) {
1766:                        fireSpecViolationEvent(entity, ejbSelect, new Section(
1767:                                "10.6.7.b"));
1768:                        status = false;
1769:                    }
1770:
1771:                    if (!throwsFinderException(ejbSelect)) {
1772:                        fireSpecViolationEvent(entity, ejbSelect, new Section(
1773:                                "10.6.7.c"));
1774:                        status = false;
1775:                    }
1776:
1777:                    if (!hasMatchingQuery(ejbSelect, entity)) {
1778:                        fireSpecViolationEvent(entity, ejbSelect, new Section(
1779:                                "10.5.7"));
1780:                        status = false;
1781:                    }
1782:                }
1783:
1784:                // A CMP Entity Bean must not define Finder methods.
1785:                //
1786:                // Spec 10.6.2
1787:                //
1788:                if (hasFinderMethod(bean)) {
1789:                    fireSpecViolationEvent(entity, new Section("10.6.2.i"));
1790:                    status = false;
1791:                }
1792:
1793:                return status;
1794:            }
1795:
1796:            /*
1797:             * Verify BMP Entity Class
1798:             */
1799:            private boolean verifyBMPEntityBean(EntityMetaData entity) {
1800:                boolean status = true;
1801:
1802:                // The enterprise bean class MUST implement, directly or
1803:                // indirectly, the javax.ejb.EntityBean interface.
1804:                //
1805:                // Spec 12.2.2
1806:                //
1807:                if (!hasEntityBeanInterface(bean)) {
1808:                    fireSpecViolationEvent(entity, new Section("12.2.2.a"));
1809:                    status = false;
1810:                }
1811:
1812:                // The entity bean class MUST be defined as public and NOT abstract.
1813:                //
1814:                // Spec 12.2.2
1815:                //
1816:                if (!isPublic(bean) || isAbstract(bean)) {
1817:                    fireSpecViolationEvent(entity, new Section("12.2.2.b"));
1818:                    status = false;
1819:                }
1820:
1821:                // The entity bean class MUST NOT be defined as final.
1822:                //
1823:                // Spec 12.2.2
1824:                //
1825:                if (isFinal(bean)) {
1826:                    fireSpecViolationEvent(entity, new Section("12.2.2.c"));
1827:                    status = false;
1828:                }
1829:
1830:                // The entity bean class MUST define a public constructor that
1831:                // takes no arguments
1832:                //
1833:                // Spec 12.2.2
1834:                //
1835:                if (!hasDefaultConstructor(bean)) {
1836:                    fireSpecViolationEvent(entity, new Section("12.2.2.d"));
1837:                    status = false;
1838:                }
1839:
1840:                // The entity bean class MUST NOT define the finalize() method.
1841:                //
1842:                // Spec 12.2.2
1843:                //
1844:                if (hasFinalizer(bean)) {
1845:                    fireSpecViolationEvent(entity, new Section("12.2.2.e"));
1846:                    status = false;
1847:                }
1848:
1849:                // The ejbCreate(...) method signatures MUST follow these rules:
1850:                //
1851:                //      - The method MUST be declared as public
1852:                //      - The method MUST NOT be declared as final or static
1853:                //      - The return type MUST be the entity bean's primary key type
1854:                //      --- If the method is on the remote home interface ---
1855:                //      - The method arguments MUST be legal types for RMI/IIOP
1856:                //      - The method return value type MUST be legal type for RMI/IIOP
1857:                //      --- End if the method is on the remote home interface ---
1858:                //
1859:                // Spec 12.2.3
1860:                //
1861:                if (hasEJBCreateMethod(bean, false)) {
1862:                    Iterator it = getEJBCreateMethods(bean);
1863:                    while (it.hasNext()) {
1864:                        Method ejbCreate = (Method) it.next();
1865:                        if (!isPublic(ejbCreate)) {
1866:                            fireSpecViolationEvent(entity, ejbCreate,
1867:                                    new Section("12.2.3.a"));
1868:                            status = false;
1869:                        }
1870:
1871:                        if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
1872:                            fireSpecViolationEvent(entity, ejbCreate,
1873:                                    new Section("12.2.3.b"));
1874:                            status = false;
1875:                        }
1876:
1877:                        if (!hasPrimaryKeyReturnType(entity, ejbCreate)) {
1878:                            fireSpecViolationEvent(entity, ejbCreate,
1879:                                    new Section("12.2.3.c"));
1880:                            status = false;
1881:                        }
1882:
1883:                        /* FIXME
1884:                         * This code needs to only be invoked if the method is on the
1885:                         * remote home.
1886:                         if (!hasLegalRMIIIOPArguments(ejbCreate)) {
1887:                         fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.d"));
1888:                         status = false;
1889:                         }
1890:                         if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
1891:                         fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.e"));
1892:                         status = false;
1893:                         }
1894:                         */
1895:                    }
1896:                }
1897:
1898:                // For each ejbCreate(...) method, the entity bean class MUST
1899:                // define a matching ejbPostCreate(...) method.
1900:                //
1901:                // The ejbPostCreate(...) method MUST follow these rules:
1902:                //
1903:                //   - the method MUST be declared as public
1904:                //   - the method MUST NOT be declared as final or static
1905:                //   - the return type MUST be void
1906:                //   - the method arguments MUST be the same as the matching
1907:                //     ejbCreate(...) method
1908:                //
1909:                // Spec 12.2.4
1910:                //
1911:                if (hasEJBCreateMethod(bean, false)) {
1912:                    Iterator it = getEJBCreateMethods(bean);
1913:                    while (it.hasNext()) {
1914:                        Method ejbCreate = (Method) it.next();
1915:
1916:                        if (!hasMatchingEJBPostCreate(bean, ejbCreate)) {
1917:                            fireSpecViolationEvent(entity, ejbCreate,
1918:                                    new Section("12.2.4.a"));
1919:                            status = false;
1920:                        }
1921:
1922:                        if (hasMatchingEJBPostCreate(bean, ejbCreate)) {
1923:                            Method ejbPostCreate = getMatchingEJBPostCreate(
1924:                                    bean, ejbCreate);
1925:
1926:                            if (!isPublic(ejbPostCreate)) {
1927:                                fireSpecViolationEvent(entity, ejbPostCreate,
1928:                                        new Section("12.2.4.b"));
1929:                                status = false;
1930:                            }
1931:
1932:                            if (isStatic(ejbPostCreate)
1933:                                    || isFinal(ejbPostCreate)) {
1934:                                fireSpecViolationEvent(entity, ejbPostCreate,
1935:                                        new Section("12.2.4.c"));
1936:                                status = false;
1937:                            }
1938:
1939:                            if (!hasVoidReturnType(ejbPostCreate)) {
1940:                                fireSpecViolationEvent(entity, ejbPostCreate,
1941:                                        new Section("12.2.4.d"));
1942:                                status = false;
1943:                            }
1944:                        }
1945:                    }
1946:                }
1947:
1948:                // Every entity bean MUST define the ejbFindByPrimaryKey method.
1949:                //
1950:                // The return type for the ejbFindByPrimaryKey method MUST be the
1951:                // primary key type.
1952:                //
1953:                // The ejbFindByPrimaryKey method MUST be a single-object finder.
1954:                //
1955:                // Spec 12.2.5
1956:                //
1957:                if (!hasEJBFindByPrimaryKey(bean)) {
1958:                    fireSpecViolationEvent(entity, new Section("12.2.5.e"));
1959:                    status = false;
1960:                }
1961:
1962:                if (hasEJBFindByPrimaryKey(bean)) {
1963:                    Method ejbFindByPrimaryKey = getEJBFindByPrimaryKey(bean);
1964:
1965:                    if (!hasPrimaryKeyReturnType(entity, ejbFindByPrimaryKey)) {
1966:                        fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
1967:                                new Section("12.2.5.e1"));
1968:                        status = false;
1969:                    }
1970:
1971:                    if (!isSingleObjectFinder(entity, ejbFindByPrimaryKey)) {
1972:                        fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
1973:                                new Section("12.2.5.e2"));
1974:                        status = false;
1975:                    }
1976:                }
1977:
1978:                // A finder method MUST be declared as public.
1979:                //
1980:                // A finder method MUST NOT be declared as static.
1981:                //
1982:                // A finder method MUST NOT be declared as final.
1983:                //
1984:                // The finder method argument types MUST be legal types for
1985:                // RMI/IIOP
1986:                //
1987:                // The finder method return type MUST be either the entity bean's
1988:                // primary key type, or java.lang.util.Enumeration interface or
1989:                // java.lang.util.Collection interface.
1990:                //
1991:                // Spec 12.2.5
1992:                //
1993:                if (hasFinderMethod(bean)) {
1994:                    Iterator it = getEJBFindMethods(bean);
1995:                    while (it.hasNext()) {
1996:                        Method finder = (Method) it.next();
1997:
1998:                        if (!isPublic(finder)) {
1999:                            fireSpecViolationEvent(entity, finder, new Section(
2000:                                    "12.2.5.a"));
2001:                            status = false;
2002:                        }
2003:
2004:                        if (isFinal(finder) || isStatic(finder)) {
2005:                            fireSpecViolationEvent(entity, finder, new Section(
2006:                                    "12.2.5.b"));
2007:                            status = false;
2008:                        }
2009:
2010:                        /** FIXME
2011:                         * this path should only get invoked if the finder is on the
2012:                         * remote interface.
2013:                         if (!hasLegalRMIIIOPArguments(finder)) {
2014:                         fireSpecViolationEvent(entity, finder, new Section("12.2.5.c"));
2015:                         status = false;
2016:                         }
2017:                         */
2018:
2019:                        if (!(isSingleObjectFinder(entity, finder) || isMultiObjectFinder(finder))) {
2020:                            fireSpecViolationEvent(entity, finder, new Section(
2021:                                    "12.2.5.d"));
2022:                            status = false;
2023:                        }
2024:                    }
2025:                }
2026:
2027:                // The ejbHome(...) method signatures MUST follow these rules:
2028:                //
2029:                //      - The method name MUST have ejbHome as its prefix.
2030:                //      - The method MUST be declared as public
2031:                //      - The method MUST NOT be declared as static.
2032:                //      - The method MUST NOT define the java.rmi.RemoteException
2033:                //
2034:                // Spec 10.6.6
2035:                //
2036:                Iterator it = getEjbHomeMethods(bean);
2037:                while (it.hasNext()) {
2038:                    Method ejbHome = (Method) it.next();
2039:
2040:                    if (!isPublic(ejbHome)) {
2041:                        fireSpecViolationEvent(entity, ejbHome, new Section(
2042:                                "10.6.6.a"));
2043:                        status = false;
2044:                    }
2045:
2046:                    if (isStatic(ejbHome)) {
2047:                        fireSpecViolationEvent(entity, ejbHome, new Section(
2048:                                "10.6.6.b"));
2049:                        status = false;
2050:                    }
2051:
2052:                    if (throwsRemoteException(ejbHome)) {
2053:                        fireSpecViolationEvent(entity, ejbHome, new Section(
2054:                                "10.6.6.c"));
2055:                        status = false;
2056:                    }
2057:                }
2058:
2059:                return status;
2060:            }
2061:
2062:            /*
2063:             * Verify Primary Key
2064:             */
2065:            private boolean verifyPrimaryKey(EntityMetaData entity) {
2066:                boolean status = true;
2067:                boolean cmp = entity.isCMP();
2068:
2069:                if (entity.getPrimaryKeyClass() == null
2070:                        || entity.getPrimaryKeyClass().length() == 0) {
2071:                    if (cmp)
2072:                        fireSpecViolationEvent(entity, new Section("10.6.1.a"));
2073:                    else
2074:                        fireSpecViolationEvent(entity, new Section("12.2.1.a"));
2075:
2076:                    // We can't get any further if there's no PK class specified!
2077:                    return false;
2078:                }
2079:
2080:                // FIXME - Still missing the bits from 10.8.2 for CMP primary
2081:                // keys.  Primarily the class must be public, all fields in the
2082:                // class must be public and the fields must also be a subset of
2083:                // the CMP fields within the bean.
2084:                //
2085:                Class cls = null;
2086:                try {
2087:                    cls = classloader.loadClass(entity.getPrimaryKeyClass());
2088:                } catch (ClassNotFoundException e) {
2089:                    if (cmp)
2090:                        fireSpecViolationEvent(entity, new Section("10.6.13.a"));
2091:                    else
2092:                        fireSpecViolationEvent(entity, new Section("12.2.12.a"));
2093:
2094:                    // Can't do any other checks if the class is null!
2095:                    return false;
2096:                }
2097:
2098:                // The primary key type must be a valid type in RMI-IIOP.
2099:                //
2100:                // Spec 10.6.13 & 12.2.12
2101:                //
2102:                if (!isRMIIDLValueType(cls)) {
2103:                    if (cmp)
2104:                        fireSpecViolationEvent(entity, new Section("10.6.13.b"));
2105:                    else
2106:                        fireSpecViolationEvent(entity, new Section("12.2.12.b"));
2107:                    status = false;
2108:                }
2109:
2110:                // No primary key field specified, just a primary key class.
2111:                if (entity.getPrimKeyField() == null
2112:                        || entity.getPrimKeyField().length() == 0) {
2113:                    // This is a check for some interesting implementation of
2114:                    // equals() and hashCode().  I am not sure how well it works in
2115:                    // the end.
2116:                    //
2117:                    if (!cls.getName().equals("java.lang.Object")) {
2118:                        Object one, two;
2119:
2120:                        try {
2121:                            one = cls.newInstance();
2122:                            two = cls.newInstance();
2123:                            try {
2124:                                if (!one.equals(two)) {
2125:                                    if (cmp) {
2126:                                        // fireSpecViolationEvent(entity, new Section("10.6.13.c"));
2127:                                        log
2128:                                                .warn("Default instances of primary key: "
2129:                                                        + cls
2130:                                                        + " do not equate, check your equals method");
2131:                                    } else {
2132:                                        //fireSpecViolationEvent(entity, new Section("12.2.12.c"));
2133:                                        log
2134:                                                .warn("Default instances of primary key: "
2135:                                                        + cls
2136:                                                        + " do not equate, check your equals method");
2137:                                    }
2138:                                    status = true;
2139:                                }
2140:                            } catch (NullPointerException e) {
2141:                                // That's OK - the implementor expected the fields to
2142:                                // have values
2143:                            }
2144:
2145:                            try {
2146:                                if (one.hashCode() != two.hashCode()) {
2147:                                    if (cmp) {
2148:                                        //fireSpecViolationEvent(entity, new Section("10.6.13.d"));
2149:                                        log
2150:                                                .warn("Default instances of primary key: "
2151:                                                        + cls
2152:                                                        + " do not have the same hash, check your hashCode method");
2153:                                    } else {
2154:                                        //fireSpecViolationEvent(entity, new Section("12.2.12.d"));
2155:                                        log
2156:                                                .warn("Default instances of primary key: "
2157:                                                        + cls
2158:                                                        + " do not have the same hash, check your hashCode method");
2159:                                    }
2160:                                    status = true;
2161:                                }
2162:                            } catch (NullPointerException e) {
2163:                                // That's OK - the implementor expected the fields to have values
2164:                            }
2165:                        } catch (IllegalAccessException e) {
2166:                            // If CMP primary key class MUST have a public
2167:                            // constructor with no parameters.  10.8.2.a
2168:                            ///
2169:                            if (cmp) {
2170:                                fireSpecViolationEvent(entity, new Section(
2171:                                        "10.8.2.a"));
2172:                                status = false;
2173:                            }
2174:                        } catch (InstantiationException e) {
2175:                            //Not sure what condition this is at the moment - JMW
2176:                            //fireSpecViolationEvent(entity, new Section("9.2.9.a"));
2177:                            //status = false;
2178:                        }
2179:                    }
2180:                } else {
2181:                    //  BMP Beans MUST not include the primkey-field element in
2182:                    //  their deployment descriptor.  Deployment descriptor comment
2183:                    //
2184:                    if (entity.isBMP()) {
2185:                        fireSpecViolationEvent(entity, new Section("dd.a"));
2186:                        status = false;
2187:                    }
2188:
2189:                    // The primary keyfield MUST be a CMP field within the
2190:                    // entity bean.
2191:                    //
2192:                    // Spec 10.8.1
2193:                    //
2194:                    boolean found = false;
2195:                    Iterator it = entity.getCMPFields();
2196:                    while (it.hasNext()) {
2197:                        String fieldName = (String) it.next();
2198:                        if (fieldName.equals(entity.getPrimKeyField())) {
2199:                            found = true;
2200:                            break;
2201:                        }
2202:                    }
2203:
2204:                    if (!found) {
2205:                        status = false;
2206:                        fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2207:                    }
2208:
2209:                    try {
2210:                        // The class of the primary key field MUST match the
2211:                        // primary key class specified for the entity bean.  We
2212:                        // figure out the class of this field by getting the
2213:                        // return type of the get<FieldName> accessor method.
2214:                        //
2215:                        // Spec 10.8.1
2216:                        //
2217:                        String pkField = entity.getPrimKeyField();
2218:                        String methodName = "get"
2219:                                + pkField.substring(0, 1).toUpperCase()
2220:                                + pkField.substring(1);
2221:
2222:                        Method method = bean
2223:                                .getMethod(methodName, new Class[0]);
2224:                        if (!entity.getPrimaryKeyClass().equals(
2225:                                method.getReturnType().getName())) {
2226:                            status = false;
2227:                            fireSpecViolationEvent(entity, new Section(
2228:                                    "10.8.1.a"));
2229:                        }
2230:
2231:                    } catch (NoSuchMethodException e) {
2232:                        // The primary keyfield MUST be a CMP field within the
2233:                        // entity bean.
2234:                        //
2235:                        // Spec 10.8.1
2236:                        //
2237:                        status = false;
2238:                        fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2239:                    }
2240:                }
2241:
2242:                return status;
2243:            }
2244:
2245:            /*
2246:             * Verify Message Driven Bean
2247:             */
2248:            protected boolean verifyMessageDrivenBean(
2249:                    MessageDrivenMetaData mdBean) {
2250:                boolean status = true;
2251:
2252:                // A message driven bean MUST implement, directly or indirectly,
2253:                // javax.ejb.MessageDrivenBean interface.
2254:                //
2255:                // Spec 15.7.2
2256:                //
2257:                if (!hasMessageDrivenBeanInterface(bean)) {
2258:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.a"));
2259:                    status = false;
2260:                }
2261:
2262:                // A message driven bean MUST implement, directly or indirectly,
2263:                // javax.jms.MessageListener interface.
2264:                //
2265:                // Spec 15.7.2
2266:                //
2267:                if (!hasMessageListenerInterface(bean)) {
2268:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.b"));
2269:                    status = false;
2270:                }
2271:
2272:                // The message driven bean class MUST be defined as public.
2273:                //
2274:                // Spec 15.7.2
2275:                //
2276:                if (!isPublic(bean)) {
2277:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.c1"));
2278:                    status = false;
2279:                }
2280:
2281:                // The message driven bean class MUST NOT be final.
2282:                //
2283:                // Spec 15.7.2
2284:                //
2285:                if (isFinal(bean)) {
2286:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.c2"));
2287:                    status = false;
2288:                }
2289:
2290:                // The message driven bean class MUST NOT be abstract.
2291:                //
2292:                // Spec 15.7.2
2293:                //
2294:                if (isAbstract(bean)) {
2295:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.c3"));
2296:                    status = false;
2297:                }
2298:
2299:                // The message driven bean class MUST have a public constructor that
2300:                // takes no arguments.
2301:                //
2302:                // Spec 15.7.2
2303:                //
2304:                if (!hasDefaultConstructor(bean)) {
2305:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.d"));
2306:                    status = false;
2307:                }
2308:
2309:                // The message driven bean class MUST NOT define the finalize() method.
2310:                //
2311:                // Spec 15.7.2
2312:                //
2313:                if (hasFinalizer(bean)) {
2314:                    fireSpecViolationEvent(mdBean, new Section("15.7.2.e"));
2315:                    status = false;
2316:                }
2317:
2318:                // A message driven bean MUST implement the ejbCreate() method.
2319:                // The ejbCreate() method signature MUST follow these rules:
2320:                //
2321:                //      - The method name MUST be ejbCreate
2322:                //      - The method MUST be declared as public
2323:                //      - The method MUST NOT be declared as final or static
2324:                //      - The return type MUST be void
2325:                //      - The method arguments MUST have no arguments.
2326:                //      - The method MUST NOT define any application exceptions.
2327:                //
2328:                // Spec 15.7.2, 3
2329:                //
2330:                if (hasEJBCreateMethod(bean, false)) {
2331:                    Iterator it = getEJBCreateMethods(bean);
2332:                    Method ejbCreate = (Method) it.next();
2333:
2334:                    if (!isPublic(ejbCreate)) {
2335:                        fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2336:                                "15.7.3.b"));
2337:                        status = false;
2338:                    }
2339:
2340:                    if ((isFinal(ejbCreate)) || (isStatic(ejbCreate))) {
2341:                        fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2342:                                "15.7.3.c"));
2343:                        status = false;
2344:                    }
2345:
2346:                    if (!hasVoidReturnType(ejbCreate)) {
2347:                        fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2348:                                "15.7.3.d"));
2349:                        status = false;
2350:                    }
2351:
2352:                    if (!hasNoArguments(ejbCreate)) {
2353:                        fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2354:                                "15.7.3.e"));
2355:                        status = false;
2356:                    }
2357:
2358:                    if (!throwsNoException(ejbCreate)) {
2359:                        fireSpecViolationEvent(mdBean, ejbCreate, new Section(
2360:                                "15.7.3.f"));
2361:                        status = false;
2362:                    }
2363:
2364:                    if (it.hasNext()) {
2365:                        fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2366:                        status = false;
2367:                    }
2368:                } else {
2369:                    fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2370:                    status = false;
2371:                }
2372:
2373:                // A message driven bean MUST implement the onMessage(...) method.
2374:                // The onMessage() method signature MUST follow these rules:
2375:                //
2376:                //      - The method name MUST be onMessage
2377:                //      - The method MUST be declared as public
2378:                //      - The method MUST NOT be declared as final or static
2379:                //      - The return type MUST be void
2380:                //      - The method arguments MUST have a single argument of type
2381:                //        javax.jms.Message.
2382:                //      - The method MUST NOT define any application exceptions.
2383:                //
2384:                // Spec 15.7.4
2385:                //
2386:                if (hasOnMessageMethod(bean)) {
2387:                    Iterator it = getOnMessageMethods(bean);
2388:                    Method onMessage = (Method) it.next();
2389:
2390:                    if (!isPublic(onMessage)) {
2391:                        fireSpecViolationEvent(mdBean, onMessage, new Section(
2392:                                "15.7.4.b"));
2393:                        status = false;
2394:                    }
2395:
2396:                    if ((isFinal(onMessage)) || (isStatic(onMessage))) {
2397:                        fireSpecViolationEvent(mdBean, onMessage, new Section(
2398:                                "15.7.4.c"));
2399:                        status = false;
2400:                    }
2401:
2402:                    try {
2403:                        Class message = classloader
2404:                                .loadClass("javax.jms.Message");
2405:                        if (!hasSingleArgument(onMessage, message)) {
2406:                            fireSpecViolationEvent(mdBean, onMessage,
2407:                                    new Section("15.7.4.e"));
2408:                            status = false;
2409:                        }
2410:
2411:                        if (!throwsNoException(onMessage)) {
2412:                            fireSpecViolationEvent(mdBean, onMessage,
2413:                                    new Section("15.7.4.f"));
2414:                            status = false;
2415:                        }
2416:
2417:                        if (it.hasNext()) {
2418:                            fireSpecViolationEvent(mdBean, new Section(
2419:                                    "15.7.4.a"));
2420:                            status = false;
2421:                        }
2422:                    } catch (ClassNotFoundException cnfe) {
2423:                        // javax.jms.Message is not available?!
2424:                    }
2425:                } else {
2426:                    fireSpecViolationEvent(mdBean, new Section("15.7.4.a"));
2427:                    status = false;
2428:                }
2429:
2430:                // A message driven bean MUST implement the ejbRemove() method.
2431:                // The ejbRemove() method signature MUST follow these rules:
2432:                //
2433:                //      - The method name MUST be ejbRemove
2434:                //      - The method MUST be declared as public
2435:                //      - The method MUST NOT be declared as final or static
2436:                //      - The return type MUST be void
2437:                //      - The method MUST have no arguments.
2438:                //      - The method MUST NOT define any application exceptions.
2439:                //
2440:                // Spec 15.7.5
2441:                //
2442:                if (hasEJBRemoveMethod(bean)) {
2443:                    Iterator it = getEJBRemoveMethods(bean);
2444:                    Method ejbRemove = (Method) it.next();
2445:
2446:                    if (!isPublic(ejbRemove)) {
2447:                        fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2448:                                "15.7.5.b"));
2449:                        status = false;
2450:                    }
2451:
2452:                    if ((isFinal(ejbRemove)) || (isStatic(ejbRemove))) {
2453:                        fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2454:                                "15.7.5.c"));
2455:                        status = false;
2456:                    }
2457:
2458:                    if (!hasVoidReturnType(ejbRemove)) {
2459:                        fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2460:                                "15.7.5.d"));
2461:                        status = false;
2462:                    }
2463:
2464:                    if (!hasNoArguments(ejbRemove)) {
2465:                        fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2466:                                "15.7.5.e"));
2467:                        status = false;
2468:                    }
2469:
2470:                    if (!throwsNoException(ejbRemove)) {
2471:                        fireSpecViolationEvent(mdBean, ejbRemove, new Section(
2472:                                "15.7.5.f"));
2473:                        status = false;
2474:                    }
2475:
2476:                    if (it.hasNext()) {
2477:                        fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2478:                        status = false;
2479:                    }
2480:                } else {
2481:                    fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2482:                    status = false;
2483:                }
2484:
2485:                return status;
2486:            }
2487:
2488:        }
2489:
2490:        /*
2491:         vim:ts=3:sw=3:et
2492:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.