KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > verifier > strategy > EJBVerifier20


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.verifier.strategy;
23
24 // $Id: EJBVerifier20.java 41248 2006-02-17 08:31:12Z starksm $
25

26 import org.jboss.logging.Logger;
27 import org.jboss.metadata.BeanMetaData;
28 import org.jboss.metadata.EntityMetaData;
29 import org.jboss.metadata.MessageDrivenMetaData;
30 import org.jboss.metadata.SessionMetaData;
31 import org.jboss.verifier.Section;
32
33 import java.lang.reflect.Method JavaDoc;
34 import java.util.Arrays JavaDoc;
35 import java.util.Iterator JavaDoc;
36
37 /**
38  * EJB 2.0 bean verifier.
39  *
40  * @author Juha Lindfors (jplindfo@helsinki.fi)
41  * @author Jay Walters (jwalters@computer.org)
42  * @author <a HREF="mailto:criege@riege.com">Christian Riege</a>
43  * @author Thomas.Diesler@jboss.org
44  *
45  * @version $Revision: 41248 $
46  * @since JDK 1.3
47  */

48 public class EJBVerifier20 extends AbstractEJB2xVerifier
49 {
50    private static Logger log = Logger.getLogger(EJBVerifier20.class);
51
52    /*
53     * Constructor
54     */

55    public EJBVerifier20(VerificationContext context)
56    {
57       super(context);
58    }
59
60    public String JavaDoc getMessageBundle()
61    {
62       return "EJB20Messages.properties";
63    }
64
65    /***********************************************************************
66     *
67     * IMPLEMENTS VERIFICATION STRATEGY INTERFACE
68     *
69     ************************************************************************/

70    public void checkSession(SessionMetaData session)
71    {
72       boolean localOrRemoteExists = false;
73       boolean verified = false;
74
75       if (!verifyBean(session))
76          return;
77
78       verified = verifySessionBean(session);
79
80       if (hasRemoteInterfaces(session))
81       {
82          // Check remote interfaces
83
localOrRemoteExists = true;
84          verified = verified && verifySessionRemote(session);
85          verified = verified && verifySessionHome(session);
86       }
87
88       if (hasLocalInterfaces(session))
89       {
90          // Check local interfaces
91
localOrRemoteExists = true;
92          verified = verified && verifySessionLocal(session);
93          verified = verified && verifySessionLocalHome(session);
94       }
95
96       // The session bean MUST implement either a remote home and
97
// remote, or local home and local interface. It MAY implement a
98
// remote home, remote, local home or local interface.
99
//
100
// Spec 7.10.1
101
//
102
if (!localOrRemoteExists)
103       {
104          fireSpecViolationEvent(session, new Section("7.10.1"));
105          verified = false;
106       }
107
108       if (verified)
109       {
110          // All OK; full steam ahead
111
fireBeanVerifiedEvent(session);
112       }
113    }
114
115    public void checkEntity(EntityMetaData entity)
116    {
117       if (entity.isCMP1x())
118       {
119          cmp1XVerifier.checkEntity(entity);
120       }
121       else
122       {
123          checkBmpOrCmp2Entity(entity);
124       }
125    }
126
127    public void checkMessageBean(MessageDrivenMetaData mdb)
128    {
129       boolean beanVerified = false;
130
131       if (!verifyBean(mdb))
132          return;
133
134       beanVerified = verifyMessageDrivenBean(mdb);
135
136       if (beanVerified)
137       {
138          // OK, we're done
139
fireBeanVerifiedEvent(mdb);
140       }
141    }
142
143    private void checkBmpOrCmp2Entity(EntityMetaData entity)
144    {
145       boolean localOrRemoteExists = false;
146       boolean verified = false;
147
148       if (!verifyBean(entity))
149          return;
150
151       if (entity.isCMP())
152       {
153          verified = verifyCMPEntityBean(entity);
154       }
155       else if (entity.isBMP())
156       {
157          verified = verifyBMPEntityBean(entity);
158       }
159
160       if (hasRemoteInterfaces(entity))
161       {
162          // Check remote interfaces
163
localOrRemoteExists = true;
164          verified = verified && verifyEntityRemote(entity);
165          verified = verified && verifyEntityHome(entity);
166       }
167
168       if (hasLocalInterfaces(entity))
169       {
170          // Check local interfaces
171
localOrRemoteExists = true;
172          verified = verified && verifyEntityLocal(entity);
173          verified = verified && verifyEntityLocalHome(entity);
174       }
175
176       verified = verified && verifyPrimaryKey(entity);
177
178       if (!localOrRemoteExists)
179       {
180          // The entity bean MUST implement either a remote home and
181
// remote, or local home and local interface. It MAY implement
182
// a remote home, remote, local home or local interface.
183
//
184
// Spec 10.6.1 (CMP) / 12.2.1 (BMP)
185
//
186
if (entity.isCMP())
187          {
188             fireSpecViolationEvent(entity, new Section("10.6.1"));
189             verified = false;
190          }
191          else
192          {
193             fireSpecViolationEvent(entity, new Section("12.2.1"));
194             verified = false;
195          }
196       }
197
198       if (verified)
199       {
200          fireBeanVerifiedEvent(entity);
201       }
202    }
203
204    /**
205     * Try to load the beans class declared in the &lt;ejb-class&gt;
206     * element.
207     *
208     * @return <code>true</code> if everything went alright
209     */

210    protected boolean verifyBean(BeanMetaData theBean)
211    {
212       String JavaDoc beanName = theBean.getEjbClass();
213
214       if (beanName == null)
215          return false;
216
217       try
218       {
219          bean = classloader.loadClass(beanName);
220          return true;
221       }
222       catch (ClassNotFoundException JavaDoc cnfe)
223       {
224          fireSpecViolationEvent(theBean, new Section("22.2.b",
225                  "Class not found on '" + beanName + "': " + cnfe.getMessage()));
226          return false;
227       }
228    }
229
230    /**
231     * Check whether the bean has declared local interfaces and whether
232     * we can load the defined classes
233     *
234     * @return <code>true</code> if everything went alright
235     */

236    protected boolean hasRemoteInterfaces(BeanMetaData bean)
237    {
238       boolean status = true;
239       String JavaDoc homeName = bean.getHome();
240       String JavaDoc remoteName = bean.getRemote();
241
242       if (homeName == null || remoteName == null)
243          return false;
244
245       // Verify the <home> class
246
try
247       {
248          home = classloader.loadClass(homeName);
249       }
250       catch (ClassNotFoundException JavaDoc cnfe)
251       {
252          fireSpecViolationEvent(bean, new Section("22.2.c",
253                  "Class not found on '" + homeName + "': " + cnfe.getMessage()));
254          status = false;
255       }
256
257       // Verify the <remote> class
258
try
259       {
260          remote = classloader.loadClass(remoteName);
261       }
262       catch (ClassNotFoundException JavaDoc cnfe)
263       {
264          fireSpecViolationEvent(bean, new Section("22.2.d",
265                  "Class not found on '" + remoteName + "': " + cnfe.getMessage()));
266          status = false;
267       }
268
269       return status;
270    }
271
272    /**
273     * Check whether the bean has declared local interfaces and whether
274     * we can load the defined classes
275     *
276     * @return <code>true</code> if everything went alright
277     */

278    protected boolean hasLocalInterfaces(BeanMetaData bean)
279    {
280       boolean status = true;
281       String JavaDoc localHomeName = bean.getLocalHome();
282       String JavaDoc localName = bean.getLocal();
283
284       if (localHomeName == null || localName == null)
285          return false;
286
287       // Verify the <local-home> class
288
try
289       {
290          localHome = classloader.loadClass(localHomeName);
291       }
292       catch (ClassNotFoundException JavaDoc cnfe)
293       {
294          fireSpecViolationEvent(bean, new Section("22.2.e",
295                  "Class not found on '" + localHomeName + "': " +
296                  cnfe.getMessage()));
297          status = false;
298       }
299
300       try
301       {
302          local = classloader.loadClass(localName);
303       }
304       catch (ClassNotFoundException JavaDoc cnfe)
305       {
306          fireSpecViolationEvent(bean, new Section("22.2.f",
307                  "Class not found on '" + localName + "': " + cnfe.getMessage()));
308          status = false;
309       }
310
311       return status;
312    }
313
314    /**
315     * Verifies the session bean remote home interface against the EJB 2.0
316     * specification.
317     *
318     * @param session XML metadata of the session bean
319     */

320    protected boolean verifySessionHome(SessionMetaData session)
321    {
322       boolean status = true;
323
324       // The home interface of a stateless session bean MUST have one
325
// create() method that takes no arguments.
326
//
327
// The create() method MUST return the session bean's remote
328
// interface.
329
//
330
// There CAN NOT be other create() methods in the home interface.
331
//
332
// Spec 7.10.6
333
//
334
if (session.isStateless())
335       {
336          if (!hasDefaultCreateMethod(home))
337          {
338             fireSpecViolationEvent(session, new Section("7.10.6.d2"));
339             status = false;
340          }
341          else
342          {
343             Method JavaDoc create = getDefaultCreateMethod(home);
344
345             if (hasMoreThanOneCreateMethods(home))
346             {
347                fireSpecViolationEvent(session, new Section("7.10.6.d2"));
348                status = false;
349             }
350          }
351       }
352
353       // The session bean's home interface MUST extend the
354
// javax.ejb.EJBHome interface.
355
//
356
// Spec 7.10.6
357
//
358
if (!hasEJBHomeInterface(home))
359       {
360          fireSpecViolationEvent(session, new Section("7.10.6.a"));
361          status = false;
362       }
363
364       // Method arguments defined in the home interface MUST be
365
// of valid types for RMI/IIOP.
366
//
367
// Method return values defined in the home interface MUST
368
// be of valid types for RMI/IIOP.
369
//
370
// Methods defined in the home interface MUST include
371
// java.rmi.RemoteException in their throws clause.
372
//
373
// Spec 7.10.6
374
///
375
Iterator JavaDoc it = Arrays.asList(home.getMethods()).iterator();
376       while (it.hasNext())
377       {
378          Method JavaDoc method = (Method JavaDoc)it.next();
379
380          if (!hasLegalRMIIIOPArguments(method))
381          {
382             fireSpecViolationEvent(session, method, new Section("7.10.6.b1"));
383             status = false;
384          }
385
386          if (!hasLegalRMIIIOPReturnType(method))
387          {
388             fireSpecViolationEvent(session, method, new Section("7.10.6.b2"));
389             status = false;
390          }
391
392          if (!throwsRemoteException(method))
393          {
394             fireSpecViolationEvent(session, method, new Section("7.10.6.b3"));
395             status = false;
396          }
397       }
398
399       // A session bean's home interface MUST define one or more
400
// create(...) methods.
401
//
402
// Spec 7.10.6
403
//
404
if (!hasCreateMethod(home))
405       {
406          fireSpecViolationEvent(session, new Section("7.10.6.d1"));
407          status = false;
408       }
409
410       // Each create(...) method in the session bean's home interface
411
// MUST have a matching ejbCreate(...) method in the session
412
// bean's class.
413
//
414
// Each create(...) method in the session bean's home interface
415
// MUST have the same number and types of arguments to its
416
// matching ejbCreate(...) method.
417
//
418
// The return type for a create(...) method MUST be the session
419
// bean's remote interface type.
420
//
421
// All the exceptions defined in the throws clause of the matching
422
// ejbCreate(...) method of the enterprise bean class MUST be
423
// included in the throws clause of a matching create(...) method.
424
//
425
// The throws clause of a create(...) method MUST include the
426
// javax.ejb.CreateException.
427
//
428
// Spec 7.10.6
429
//
430
Iterator JavaDoc createMethods = getCreateMethods(home);
431       while (createMethods.hasNext())
432       {
433          Method JavaDoc create = (Method JavaDoc)createMethods.next();
434
435          if (!hasMatchingEJBCreate(bean, create))
436          {
437             fireSpecViolationEvent(session, create, new Section("7.10.6.e"));
438             status = false;
439          }
440
441          if (!hasRemoteReturnType(session, create))
442          {
443             fireSpecViolationEvent(session, create, new Section("7.10.6.f"));
444             status = false;
445          }
446
447          if (hasMatchingEJBCreate(bean, create))
448          {
449             Method JavaDoc ejbCreate = getMatchingEJBCreate(bean, create);
450             if (!hasMatchingExceptions(ejbCreate, create))
451             {
452                fireSpecViolationEvent(session, create,
453                        new Section("7.10.6.g"));
454                status = false;
455             }
456          }
457
458          if (!throwsCreateException(create))
459          {
460             fireSpecViolationEvent(session, create, new Section("7.10.6.h"));
461             status = false;
462          }
463       }
464
465       return status;
466    }
467
468    /**
469     * Verifies the session bean local home interface against the EJB 2.0
470     * specification.
471     *
472     * @param session parsed metadata of the session bean
473     */

474    protected boolean verifySessionLocalHome(SessionMetaData session)
475    {
476       boolean status = true;
477
478       // The local home interface of a stateless session bean MUST have
479
// one create() method that takes no arguments.
480
//
481
// There CAN NOT be other create() methods in the home interface.
482
//
483
// Spec 7.10.8
484
//
485
if (session.isStateless())
486       {
487          if (!hasDefaultCreateMethod(localHome))
488          {
489             fireSpecViolationEvent(session, new Section("7.10.8.d2"));
490             status = false;
491          }
492          else
493          {
494             Method JavaDoc create = getDefaultCreateMethod(localHome);
495
496             if (hasMoreThanOneCreateMethods(localHome))
497             {
498                fireSpecViolationEvent(session, new Section("7.10.8.d2"));
499                status = false;
500             }
501          }
502       }
503
504       // The session bean's home interface MUST extend the
505
// javax.ejb.EJBLocalHome interface.
506
//
507
// Spec 7.10.8
508
//
509
if (!hasEJBLocalHomeInterface(localHome))
510       {
511          fireSpecViolationEvent(session, new Section("7.10.8.a"));
512          status = false;
513       }
514
515       // Methods defined in the local home interface MUST NOT include
516
// java.rmi.RemoteException in their throws clause.
517
//
518
// Spec 7.10.8
519
//
520
Iterator JavaDoc it = Arrays.asList(localHome.getMethods()).iterator();
521       while (it.hasNext())
522       {
523          Method JavaDoc method = (Method JavaDoc)it.next();
524
525          if (throwsRemoteException(method))
526          {
527             fireSpecViolationEvent(session, method, new Section("7.10.8.b"));
528             status = false;
529          }
530       }
531
532       // A session bean's home interface MUST define one or more
533
// create(...) methods.
534
//
535
// Spec 7.10.8
536
//
537
if (!hasCreateMethod(localHome))
538       {
539          fireSpecViolationEvent(session, new Section("7.10.8.d1"));
540          status = false;
541       }
542
543       // Each create(...) method in the session bean's local home
544
// interface MUST have a matching ejbCreate(...) method in the
545
// session bean's class.
546
//
547
// Each create(...) method in the session bean's home interface
548
// MUST have the same number and types of arguments to its
549
// matching ejbCreate(...) method.
550
//
551
// The return type for a create(...) method MUST be the session
552
// bean's local interface type.
553
//
554
// All the exceptions defined in the throws clause of the matching
555
// ejbCreate(...) method of the enterprise bean class MUST be
556
// included in the throws clause of a matching create(...) method.
557
//
558
// The throws clause of a create(...) method MUST include the
559
// javax.ejb.CreateException.
560
//
561
// Spec 7.10.8
562
//
563
Iterator JavaDoc createMethods = getCreateMethods(localHome);
564       while (createMethods.hasNext())
565       {
566          Method JavaDoc create = (Method JavaDoc)createMethods.next();
567
568          if (!hasMatchingEJBCreate(bean, create))
569          {
570             fireSpecViolationEvent(session, create,
571                     new Section("7.10.8.e"));
572             status = false;
573          }
574
575          if (!hasLocalReturnType(session, create))
576          {
577             fireSpecViolationEvent(session, create,
578                     new Section("7.10.8.f"));
579             status = false;
580          }
581
582          if (hasMatchingEJBCreate(bean, create))
583          {
584             Method JavaDoc ejbCreate = getMatchingEJBCreate(bean, create);
585             if (!hasMatchingExceptions(ejbCreate, create))
586             {
587                fireSpecViolationEvent(session, create,
588                        new Section("7.10.8.g"));
589             }
590          }
591
592          if (!throwsCreateException(create))
593          {
594             fireSpecViolationEvent(session, create,
595                     new Section("7.10.8.h"));
596             status = false;
597          }
598       }
599
600       return status;
601    }
602
603    /*
604     * Verify Session Bean Remote Interface
605     */

606    protected boolean verifySessionRemote(SessionMetaData session)
607    {
608       boolean status = true;
609
610       // The remote interface MUST extend the javax.ejb.EJBObject
611
// interface.
612
//
613
// Spec 7.10.5
614
//
615
if (!hasEJBObjectInterface(remote))
616       {
617          fireSpecViolationEvent(session, new Section("7.10.5.a"));
618          status = false;
619       }
620
621       // Method arguments defined in the remote interface MUST be
622
// of valid types for RMI/IIOP.
623
//
624
// Method return values defined in the remote interface MUST
625
// be of valid types for RMI/IIOP.
626
//
627
// Methods defined in the remote interface MUST include
628
// java.rmi.RemoteException in their throws clause.
629
//
630
// Spec 7.10.5
631
//
632
Iterator JavaDoc it = Arrays.asList(remote.getMethods()).iterator();
633       while (it.hasNext())
634       {
635          Method JavaDoc method = (Method JavaDoc)it.next();
636
637          if (!hasLegalRMIIIOPArguments(method))
638          {
639             fireSpecViolationEvent(session, method, new Section("7.10.5.b1"));
640             status = false;
641          }
642
643          if (!hasLegalRMIIIOPReturnType(method))
644          {
645             fireSpecViolationEvent(session, method, new Section("7.10.5.b2"));
646             status = false;
647          }
648
649          if (!throwsRemoteException(method))
650          {
651             fireSpecViolationEvent(session, method, new Section("7.10.5.b3"));
652             status = false;
653          }
654       }
655
656       // For each method defined in the remote interface, there MUST be
657
// a matching method in the session bean's class. The matching
658
// method MUST have:
659
//
660
// - the same name
661
// - the same number and types of arguments, and the same
662
// return type
663
// - All the exceptions defined in the throws clause of the
664
// matching method of the session bean class must be defined
665
// in the throws clause of the method of the remote interface
666
//
667
// Spec 7.10.5
668
//
669
it = Arrays.asList(remote.getDeclaredMethods()).iterator();
670       while (it.hasNext())
671       {
672          Method JavaDoc remoteMethod = (Method JavaDoc)it.next();
673
674          if (!hasMatchingMethod(bean, remoteMethod))
675          {
676             fireSpecViolationEvent(session, remoteMethod,
677                     new Section("7.10.5.d1"));
678
679             status = false;
680          }
681
682          if (hasMatchingMethod(bean, remoteMethod))
683          {
684             try
685             {
686                Method JavaDoc beanMethod = bean.getMethod(remoteMethod.getName(),
687                        remoteMethod.getParameterTypes());
688
689                if (!hasMatchingReturnType(remoteMethod, beanMethod))
690                {
691                   fireSpecViolationEvent(session, remoteMethod,
692                           new Section("7.10.5.d2"));
693                   status = false;
694                }
695
696                if (!hasMatchingExceptions(beanMethod, remoteMethod))
697                {
698                   fireSpecViolationEvent(session, remoteMethod,
699                           new Section("7.10.5.d3"));
700                   status = false;
701                }
702             }
703             catch (NoSuchMethodException JavaDoc ignored)
704             {
705             }
706          }
707       }
708
709       return status;
710    }
711
712    /*
713     * Verify Session Bean Local Interface
714     */

715    protected boolean verifySessionLocal(SessionMetaData session)
716    {
717       boolean status = true;
718
719       // The local interface MUST extend the javax.ejb.EJBLocalObject
720
// interface.
721
//
722
// Spec 7.10.7
723
//
724
if (!hasEJBLocalObjectInterface(local))
725       {
726          fireSpecViolationEvent(session, new Section("7.10.7.a"));
727          status = false;
728       }
729
730       // Methods defined in the local interface MUST NOT include
731
// java.rmi.RemoteException in their throws clause.
732
//
733
// Spec 7.10.7
734
//
735
Iterator JavaDoc it = Arrays.asList(local.getMethods()).iterator();
736       while (it.hasNext())
737       {
738          Method JavaDoc method = (Method JavaDoc)it.next();
739          if (throwsRemoteException(method))
740          {
741             fireSpecViolationEvent(session, method, new Section("7.10.7.b"));
742             status = false;
743          }
744       }
745
746       // For each method defined in the local interface, there MUST be
747
// a matching method in the session bean's class. The matching
748
// method MUST have:
749
//
750
// - the same name
751
// - the same number and types of arguments, and the same
752
// return type
753
// - All the exceptions defined in the throws clause of the
754
// matching method of the session bean class must be defined
755
// in the throws clause of the method of the remote interface
756
//
757
// Spec 7.10.7
758
//
759
it = Arrays.asList(local.getDeclaredMethods()).iterator();
760       while (it.hasNext())
761       {
762          Method JavaDoc localMethod = (Method JavaDoc)it.next();
763
764          if (!hasMatchingMethod(bean, localMethod))
765          {
766             fireSpecViolationEvent(session, localMethod,
767                     new Section("7.10.7.d1"));
768             status = false;
769          }
770
771          if (hasMatchingMethod(bean, localMethod))
772          {
773             try
774             {
775                Method JavaDoc beanMethod = bean.getMethod(localMethod.getName(),
776                        localMethod.getParameterTypes());
777
778                if (!hasMatchingReturnType(localMethod, beanMethod))
779                {
780                   fireSpecViolationEvent(session, localMethod,
781                           new Section("7.10.7.d2"));
782                   status = false;
783                }
784
785                if (!hasMatchingExceptions(beanMethod, localMethod))
786                {
787                   fireSpecViolationEvent(session, localMethod,
788                           new Section("7.10.7.d3"));
789                   status = false;
790                }
791             }
792             catch (NoSuchMethodException JavaDoc ignored)
793             {
794             }
795          }
796       }
797
798       return status;
799    }
800
801    /*
802     * Verify Session Bean
803     */

804    protected boolean verifySessionBean(SessionMetaData session)
805    {
806       boolean status = true;
807
808       // A session bean MUST implement, directly or indirectly,
809
// javax.ejb.SessionBean interface.
810
//
811
// Spec 7.10.2
812
//
813
if (!hasSessionBeanInterface(bean))
814       {
815          fireSpecViolationEvent(session, new Section("7.10.2.a"));
816          status = false;
817       }
818
819       // Only a stateful container-managed transaction demarcation
820
// session bean MAY implement the SessionSynchronization
821
// interface.
822
//
823
// A stateless Session bean MUST NOT implement the
824
// SessionSynchronization interface.
825
//
826
// Spec 7.5.3
827
//
828
if (hasSessionSynchronizationInterface(bean))
829       {
830          if (session.isStateless())
831          {
832             fireSpecViolationEvent(session, new Section("7.5.3.a"));
833             status = false;
834          }
835
836          if (session.isBeanManagedTx())
837          {
838             fireSpecViolationEvent(session, new Section("7.5.3.b"));
839             status = false;
840          }
841       }
842
843       //
844
// A session bean MUST implement AT LEAST one ejbCreate method.
845
//
846
// Spec 7.10.3
847
//
848
if (!hasEJBCreateMethod(bean, true))
849       {
850          fireSpecViolationEvent(session, new Section("7.10.3"));
851          status = false;
852       }
853
854       // A session with bean-managed transaction demarcation CANNOT
855
// implement the SessionSynchronization interface.
856
//
857
// Spec 7.6.1 (table 2)
858
//
859
if (hasSessionSynchronizationInterface(bean)
860               && session.isBeanManagedTx())
861       {
862          fireSpecViolationEvent(session, new Section("7.6.1"));
863          status = false;
864       }
865
866       // The session bean class MUST be defined as public.
867
//
868
// Spec 7.10.2
869
//
870
if (!isPublic(bean))
871       {
872          fireSpecViolationEvent(session, new Section("7.10.2.b1"));
873          status = false;
874       }
875
876       // The session bean class MUST NOT be final.
877
//
878
// Spec 7.10.2
879
//
880
if (isFinal(bean))
881       {
882          fireSpecViolationEvent(session, new Section("7.10.2.b2"));
883          status = false;
884       }
885
886       // The session bean class MUST NOT be abstract.
887
//
888
// Spec 7.10.2
889
//
890
if (isAbstract(bean))
891       {
892          fireSpecViolationEvent(session, new Section("7.10.2.b3"));
893          status = false;
894       }
895
896       // The session bean class MUST have a public constructor that
897
// takes no arguments.
898
//
899
// Spec 7.10.2
900
//
901
if (!hasDefaultConstructor(bean))
902       {
903          fireSpecViolationEvent(session, new Section("7.10.2.c"));
904          status = false;
905       }
906
907       // The session bean class MUST NOT define the finalize() method.
908
//
909
// Spec 7.10.2
910
//
911
if (hasFinalizer(bean))
912       {
913          fireSpecViolationEvent(session, new Section("7.10.2.d"));
914          status = false;
915       }
916
917       // The ejbCreate(...) method signatures MUST follow these rules:
918
//
919
// - The method name MUST have ejbCreate as its prefix
920
// - The method MUST be declared as public
921
// - The method MUST NOT be declared as final or static
922
// - The return type MUST be void
923
// - The method arguments MUST be legal types for RMI/IIOP
924
// - The method SHOULD not throw a java.rmi.RemoteException
925
// (NOTE we don't test for this as it's not a MUST)
926
//
927
// Spec 7.10.3
928
//
929
if (hasEJBCreateMethod(bean, true))
930       {
931          Iterator JavaDoc it = getEJBCreateMethods(bean);
932          while (it.hasNext())
933          {
934             Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
935
936             if (!isPublic(ejbCreate))
937             {
938                fireSpecViolationEvent(session, ejbCreate,
939                        new Section("7.10.3.b"));
940                status = false;
941             }
942
943             if ((isFinal(ejbCreate)) || (isStatic(ejbCreate)))
944             {
945                fireSpecViolationEvent(session, ejbCreate,
946                        new Section("7.10.3.c"));
947                status = false;
948             }
949
950             if (!hasVoidReturnType(ejbCreate))
951             {
952                fireSpecViolationEvent(session, ejbCreate,
953                        new Section("7.10.3.d"));
954                status = false;
955             }
956
957             if (!hasLegalRMIIIOPArguments(ejbCreate))
958             {
959                fireSpecViolationEvent(session, ejbCreate,
960                        new Section("7.10.3.e"));
961                status = false;
962             }
963          }
964       }
965
966       return status;
967    }
968
969    /*
970     * Verify Entity Bean Home Interface
971     */

972    private boolean verifyEntityHome(EntityMetaData entity)
973    {
974       boolean status = true;
975
976       // Entity bean's home interface MUST extend the javax.ejb.EJBHome
977
// interface.
978
//
979
// Spec 12.2.9
980
//
981
if (!hasEJBHomeInterface(home))
982       {
983          fireSpecViolationEvent(entity, new Section("12.2.9.a"));
984          status = false;
985       }
986
987       // The methods defined in the entity bean's home interface MUST
988
// have valid RMI-IIOP argument types.
989
//
990
// The methods defined in the entity bean's home interface MUST
991
// have valid RMI-IIOP return types.
992
//
993
// The methods defined in the entity bean's home interface MUST
994
// have java.rmi.RemoteException in their throws clause.
995
//
996
// Spec 12.2.9
997
//
998
Iterator JavaDoc methods = Arrays.asList(home.getMethods()).iterator();
999       while (methods.hasNext())
1000      {
1001         Method JavaDoc method = (Method JavaDoc)methods.next();
1002
1003         if (!hasLegalRMIIIOPArguments(method))
1004         {
1005            fireSpecViolationEvent(entity, method,
1006                    new Section("12.2.9.b1"));
1007            status = false;
1008         }
1009
1010         if (!hasLegalRMIIIOPReturnType(method))
1011         {
1012            fireSpecViolationEvent(entity, method,
1013                    new Section("12.2.9.b2"));
1014            status = false;
1015         }
1016
1017         if (!throwsRemoteException(method))
1018         {
1019            fireSpecViolationEvent(entity, method,
1020                    new Section("12.2.9.b3"));
1021            status = false;
1022         }
1023      }
1024
1025      // Each method defined in the entity bean's home interface must be
1026
// one of the following:
1027
//
1028
// - a create method
1029
// - a finder method
1030
// - a home method
1031
//
1032
// Spec 12.2.9
1033
//
1034
methods = Arrays.asList(home.getMethods()).iterator();
1035      while (methods.hasNext())
1036      {
1037         Method JavaDoc method = (Method JavaDoc)methods.next();
1038
1039         // Do not check the methods of the javax.ejb.EJBHome interface
1040
if (method.getDeclaringClass().getName().equals(EJB_HOME_INTERFACE))
1041            continue;
1042
1043         if (isCreateMethod(method))
1044         {
1045            // Each create(...) method in the entity bean's home
1046
// interface MUST have a matching ejbCreate(...) method in
1047
// the entity bean's class.
1048
//
1049
// Each create(...) method in the entity bean's home
1050
// interface MUST have the same number and types of
1051
// arguments to its matching ejbCreate(...) method.
1052
//
1053
// The return type for a create(...) method MUST be the
1054
// entity bean's remote interface type.
1055
//
1056
// All the exceptions defined in the throws clause of the
1057
// matching ejbCreate(...) and ejbPostCreate(...) methods of
1058
// the enterprise bean class MUST be included in the throws
1059
// clause of a matching create(...) method.
1060
//
1061
// The throws clause of a create(...) method MUST include
1062
// the javax.ejb.CreateException.
1063
//
1064
// Spec 12.2.9
1065
//
1066
if (!hasMatchingEJBCreate(bean, method))
1067            {
1068               fireSpecViolationEvent(entity, method, new Section("12.2.9.d"));
1069               status = false;
1070            }
1071
1072            if (!hasRemoteReturnType(entity, method))
1073            {
1074               fireSpecViolationEvent(entity, method, new Section("12.2.9.e"));
1075               status = false;
1076            }
1077
1078            if (hasMatchingEJBCreate(bean, method)
1079                    && hasMatchingEJBPostCreate(bean, method))
1080            {
1081               Method JavaDoc ejbCreate = getMatchingEJBCreate(bean, method);
1082               Method JavaDoc ejbPostCreate = getMatchingEJBPostCreate(bean, method);
1083
1084               if (!(hasMatchingExceptions(ejbCreate, method)
1085                       && hasMatchingExceptions(ejbPostCreate, method)))
1086               {
1087                  fireSpecViolationEvent(entity, method,
1088                          new Section("12.2.9.f"));
1089               }
1090            }
1091
1092            if (!throwsCreateException(method))
1093            {
1094               fireSpecViolationEvent(entity, method, new Section("12.2.9.g"));
1095               status = false;
1096            }
1097         }
1098         else if (isFinderMethod(method))
1099         {
1100            // Each finder method MUST match one of the ejbFind<METHOD>
1101
// methods defined in the entity bean class.
1102
//
1103
// The matching ejbFind<METHOD> method MUST have the same
1104
// number and types of arguments.
1105
//
1106
// The return type for a find<METHOD> method MUST be the
1107
// entity bean's remote interface type (single-object
1108
// finder) or a collection thereof (for a multi-object
1109
// finder).
1110
//
1111
// All the exceptions defined in the throws clause of an
1112
// ejbFind method of the entity bean class MUST be included
1113
// in the throws clause of the matching find method of the
1114
// home interface.
1115
//
1116
// The throws clause of a finder method MUST include the
1117
// javax.ejb.FinderException.
1118
//
1119
// Spec 12.2.9
1120
//
1121
if (entity.isBMP())
1122            { // Check for BMP violations
1123
if ((!hasMatchingEJBFind(bean, method)))
1124               {
1125                  fireSpecViolationEvent(entity, method,
1126                          new Section("12.2.9.h"));
1127                  status = false;
1128               }
1129
1130               if (!(hasRemoteReturnType(entity, method)
1131                       || isMultiObjectFinder(method)))
1132               {
1133                  fireSpecViolationEvent(entity, method,
1134                          new Section("12.2.9.j"));
1135                  status = false;
1136               }
1137
1138               if ((hasMatchingEJBFind(bean, method)))
1139               {
1140                  Method JavaDoc ejbFind = getMatchingEJBFind(bean, method);
1141                  if (!(hasMatchingExceptions(ejbFind, method)))
1142                  {
1143                     fireSpecViolationEvent(entity, method,
1144                             new Section("12.2.9.k"));
1145                     status = false;
1146                  }
1147               }
1148
1149               if (!throwsFinderException(method))
1150               {
1151                  fireSpecViolationEvent(entity, method,
1152                          new Section("12.2.9.l"));
1153                  status = false;
1154               }
1155            } // if( entity.isBMP() )
1156

1157            if (entity.isCMP())
1158            {
1159
1160               if (!(hasRemoteReturnType(entity, method)
1161                       || isMultiObjectFinder(method)))
1162               {
1163                  fireSpecViolationEvent(entity, method,
1164                          new Section("10.6.10.a"));
1165                  status = false;
1166               }
1167
1168               if (!throwsFinderException(method))
1169               {
1170                  fireSpecViolationEvent(entity, method,
1171                          new Section("10.6.10.b"));
1172                  status = false;
1173               }
1174
1175               // For every finder method there must be a matching
1176
// <query> element defined in the deployment descriptor
1177
// with the exception of findByPrimaryKey
1178
//
1179
// JBoss Extension: 'findAll' is _also_ ignored.
1180
//
1181
if (!method.getName().equals("findByPrimaryKey")
1182                       && !method.getName().equals("findAll")
1183                       && !hasMatchingQuery(method, entity))
1184               {
1185                  fireSpecViolationEvent(entity, method,
1186                          new Section("10.5.6"));
1187                  status = false;
1188               }
1189            } // if( entity.isCMP() )
1190
}
1191         else // Neither Create nor Finder method
1192
{
1193            // Each home method MUST match a method defined in the
1194
// entity bean class.
1195
//
1196
// The matching ejbHome<METHOD> method MUST have the same
1197
// number and types of arguments, and a matching return
1198
// type.
1199
//
1200
// Spec 12.2.9
1201
//
1202
if (!hasMatchingEJBHome(bean, method))
1203            {
1204               fireSpecViolationEvent(entity, method,
1205                       new Section("12.2.9.m"));
1206               status = false;
1207            }
1208         }
1209      } // while( methods.hasNext() )
1210

1211
1212      return status;
1213   }
1214
1215   /*
1216    * Verify Entity Bean Local Home Interface
1217    */

1218   private boolean verifyEntityLocalHome(EntityMetaData entity)
1219   {
1220      boolean status = true;
1221
1222      // Entity bean's local home interface MUST extend the
1223
// javax.ejb.EJBLocalHome interface.
1224
//
1225
// Spec 12.2.11
1226
//
1227
if (!hasEJBLocalHomeInterface(localHome))
1228      {
1229         fireSpecViolationEvent(entity, new Section("12.2.11.a"));
1230         status = false;
1231      }
1232
1233      // The methods defined in the entity bean's home interface MUST
1234
// NOT have java.rmi.RemoteException in their throws clause.
1235
//
1236
// Spec 12.2.11
1237
//
1238
Iterator JavaDoc homeMethods = Arrays.asList(localHome.getMethods()).iterator();
1239      while (homeMethods.hasNext())
1240      {
1241         Method JavaDoc method = (Method JavaDoc)homeMethods.next();
1242
1243         if (throwsRemoteException(method))
1244         {
1245            fireSpecViolationEvent(entity, method, new Section("12.2.11.b"));
1246            status = false;
1247         }
1248      }
1249
1250      // Each method defined in the entity bean's local home interface
1251
// must be one of the following:
1252
//
1253
// - a create method
1254
// - a finder method
1255
// - a home method
1256
//
1257
// Spec 12.2.11
1258
//
1259
homeMethods = Arrays.asList(localHome.getMethods()).iterator();
1260      while (homeMethods.hasNext())
1261      {
1262         Method JavaDoc method = (Method JavaDoc)homeMethods.next();
1263
1264         // Do not check the methods of the javax.ejb.EJBLocalHome interface
1265
if (method.getDeclaringClass().getName().equals(EJB_LOCAL_HOME_INTERFACE))
1266            continue;
1267
1268         if (isCreateMethod(method))
1269         {
1270            // Each create(...) method in the entity bean's local home
1271
// interface MUST have a matching ejbCreate(...) method in
1272
// the entity bean's class.
1273
//
1274
// Each create(...) method in the entity bean's local home
1275
// interface MUST have the same number and types of
1276
// arguments to its matching ejbCreate(...) method.
1277
//
1278
// The return type for a create(...) method MUST be the
1279
// entity bean's local interface type.
1280
//
1281
// All the exceptions defined in the throws clause of the
1282
// matching ejbCreate(...) and ejbPostCreate(...) methods of
1283
// the enterprise bean class MUST be included in the throws
1284
// clause of a matching create(...) method.
1285
//
1286
// The throws clause of a create(...) method MUST include
1287
// the javax.ejb.CreateException.
1288
//
1289
// Spec 12.2.11
1290
//
1291
if (!hasMatchingEJBCreate(bean, method))
1292            {
1293               fireSpecViolationEvent(entity, method,
1294                       new Section("12.2.11.e"));
1295               status = false;
1296            }
1297
1298            if (!hasLocalReturnType(entity, method))
1299            {
1300               fireSpecViolationEvent(entity, method,
1301                       new Section("12.2.11.f"));
1302               status = false;
1303            }
1304
1305            if (hasMatchingEJBCreate(bean, method)
1306                    && hasMatchingEJBPostCreate(bean, method))
1307            {
1308               Method JavaDoc ejbCreate = getMatchingEJBCreate(bean, method);
1309               Method JavaDoc ejbPostCreate = getMatchingEJBPostCreate(bean, method);
1310
1311               if (!(hasMatchingExceptions(ejbCreate, method)
1312                       && hasMatchingExceptions(ejbPostCreate, method)))
1313               {
1314                  fireSpecViolationEvent(entity, method,
1315                          new Section("12.2.11.g"));
1316               }
1317            }
1318
1319            if (!throwsCreateException(method))
1320            {
1321               fireSpecViolationEvent(entity, method,
1322                       new Section("12.2.11.h"));
1323               status = false;
1324            }
1325         }
1326         else if (isFinderMethod(method))
1327         {
1328            // Each finder method MUST match one of the ejbFind<METHOD>
1329
// methods defined in the entity bean class.
1330
//
1331
// The matching ejbFind<METHOD> method MUST have the same
1332
// number and types of arguments.
1333
//
1334
// The return type for a find<METHOD> method MUST be the
1335
// entity bean's local interface type (single-object finder)
1336
// or a collection thereof (for a multi-object finder).
1337
//
1338
// All the exceptions defined in the throws clause of an
1339
// ejbFind method of the entity bean class MUST be included
1340
// in the throws clause of the matching find method of the
1341
// home interface.
1342
//
1343
// The throws clause of a finder method MUST include the
1344
// javax.ejb.FinderException.
1345
//
1346
// Spec 12.2.11
1347
//
1348
if (!(hasLocalReturnType(entity, method)
1349                    || isMultiObjectFinder(method)))
1350            {
1351               fireSpecViolationEvent(entity, method,
1352                       new Section("12.2.11.j"));
1353               status = false;
1354            }
1355
1356            if (!throwsFinderException(method))
1357            {
1358               fireSpecViolationEvent(entity, method,
1359                       new Section("12.2.11.k"));
1360               status = false;
1361            }
1362
1363            if (entity.isCMP())
1364            {
1365               // The entity bean class does not implement the finder
1366
// methods. The implementation of the finder methods are
1367
// provided by the Container
1368
//
1369
// Spec 10.6.2
1370
//
1371
if (hasMatchingEJBFind(bean, method))
1372               {
1373                  fireSpecViolationEvent(entity, method,
1374                          new Section("10.6.2.j"));
1375                  status = false;
1376               }
1377
1378               // For every finder method there must be a matching
1379
// <query> element defined in the deployment descriptor
1380
// with the exception of findByPrimaryKey
1381
//
1382
// JBoss Extension: 'findAll' is _also_ ignored.
1383
//
1384
// Spec 10.5.6
1385
//
1386
if (!method.getName().equals("findByPrimaryKey")
1387                       && !method.getName().equals("findAll")
1388                       && !hasMatchingQuery(method, entity))
1389               {
1390                  fireSpecViolationEvent(entity, method,
1391                          new Section("10.5.6"));
1392                  status = false;
1393               }
1394            }
1395
1396            if (entity.isBMP())
1397            {
1398               if (!hasMatchingEJBFind(bean, method))
1399               {
1400                  fireSpecViolationEvent(entity, method,
1401                          new Section("12.2.11.i"));
1402                  status = false;
1403               }
1404               else
1405               {
1406                  Method JavaDoc ejbFind = getMatchingEJBFind(bean, method);
1407
1408                  if (!(hasMatchingExceptions(ejbFind, method)))
1409                  {
1410                     fireSpecViolationEvent(entity, method,
1411                             new Section("12.2.11.l"));
1412                  }
1413               }
1414            }
1415         }
1416         else
1417         {
1418            // Each home method MUST match a method defined in the
1419
// entity bean class.
1420
//
1421
// The matching ejbHome<METHOD> method MUST have the same
1422
// number and types of arguments, and a matching return
1423
// type.
1424
//
1425
// Spec 12.2.9
1426
//
1427
if (!hasMatchingEJBHome(bean, method))
1428            {
1429               fireSpecViolationEvent(entity, method,
1430                       new Section("12.2.11.m"));
1431               status = false;
1432            }
1433         }
1434      } // while( homeMethods.hasNext() )
1435

1436      return status;
1437   }
1438
1439   /*
1440    * Verify Entity Bean Local Interface
1441    */

1442   private boolean verifyEntityLocal(EntityMetaData entity)
1443   {
1444      boolean status = true;
1445
1446      // Entity bean's local interface MUST extend
1447
// the javax.ejb.EJBLocalObject interface.
1448
//
1449
// Spec 12.2.10
1450
//
1451
if (!hasEJBLocalObjectInterface(local))
1452      {
1453         fireSpecViolationEvent(entity, new Section("12.2.10.a"));
1454         status = false;
1455      }
1456
1457      // The methods defined in the entity bean's local interface MUST
1458
// NOT have java.rmi.RemoteException in their throws clause.
1459
//
1460
// Spec 12.2.10
1461
//
1462
Iterator JavaDoc localMethods = Arrays.asList(local.getMethods()).iterator();
1463      while (localMethods.hasNext())
1464      {
1465         Method JavaDoc method = (Method JavaDoc)localMethods.next();
1466
1467         if (throwsRemoteException(method))
1468         {
1469            fireSpecViolationEvent(entity, method, new Section("12.2.10.b"));
1470            status = false;
1471         }
1472      }
1473
1474      // For each method defined in the local interface, there MUST be
1475
// a matching method in the entity bean's class. The matching
1476
// method MUST have:
1477
//
1478
// - The same name.
1479
// - The same number and types of its arguments.
1480
// - The same return type.
1481
// - All the exceptions defined in the throws clause of the
1482
// matching method of the enterprise Bean class must be
1483
// defined in the throws clause of the method of the local
1484
// interface.
1485
//
1486
// Spec 12.2.10
1487
//
1488
localMethods = Arrays.asList(local.getMethods()).iterator();
1489      while (localMethods.hasNext())
1490      {
1491         Method JavaDoc method = (Method JavaDoc)localMethods.next();
1492
1493         // Do not check the methods of the javax.ejb.EJBLocalObject
1494
// interface
1495
if (method.getDeclaringClass().getName().equals(EJB_LOCAL_OBJECT_INTERFACE))
1496            continue;
1497
1498         if (!hasMatchingMethod(bean, method))
1499         {
1500            fireSpecViolationEvent(entity, method, new Section("12.2.10.c"));
1501            status = false;
1502         }
1503
1504         if (hasMatchingMethod(bean, method))
1505         {
1506            try
1507            {
1508               Method JavaDoc beanMethod = bean.getMethod(method.getName(),
1509                       method.getParameterTypes());
1510
1511               if (!hasMatchingReturnType(beanMethod, method))
1512               {
1513                  fireSpecViolationEvent(entity, method,
1514                          new Section("12.2.10.d"));
1515                  status = false;
1516               }
1517
1518               if (!hasMatchingExceptions(beanMethod, method))
1519               {
1520                  fireSpecViolationEvent(entity, method,
1521                          new Section("12.2.10.e"));
1522
1523                  status = false;
1524               }
1525            }
1526            catch (NoSuchMethodException JavaDoc ignored)
1527            {
1528            }
1529         }
1530      }
1531
1532      return status;
1533   }
1534
1535   /*
1536    * Verify Entity Bean Remote Interface
1537    */

1538   private boolean verifyEntityRemote(EntityMetaData entity)
1539   {
1540      boolean status = true;
1541
1542      // Entity bean's remote interface MUST extend
1543
// the javax.ejb.EJBObject interface.
1544
//
1545
// Spec 9.2.7
1546
//
1547
if (!hasEJBObjectInterface(remote))
1548      {
1549         fireSpecViolationEvent(entity, new Section("9.2.7.a"));
1550         status = false;
1551      }
1552
1553      // The methods defined in the entity bean's remote interface MUST
1554
// have valid RMI-IIOP argument types.
1555
//
1556
// The methods defined in the entity bean's home interface MUST
1557
// have valid RMI-IIOP return types.
1558
//
1559
// The methods defined in the entity bean's home interface MUST
1560
// have java.rmi.RemoteException in their throws clause.
1561
//
1562
// Spec 9.2.7
1563
//
1564
Iterator JavaDoc it = Arrays.asList(remote.getMethods()).iterator();
1565      while (it.hasNext())
1566      {
1567         Method JavaDoc method = (Method JavaDoc)it.next();
1568
1569         if (!hasLegalRMIIIOPArguments(method))
1570         {
1571            fireSpecViolationEvent(entity, method, new Section("9.2.7.b"));
1572            status = false;
1573         }
1574
1575         if (!hasLegalRMIIIOPReturnType(method))
1576         {
1577            fireSpecViolationEvent(entity, method, new Section("9.2.7.c"));
1578            status = false;
1579         }
1580
1581         if (!hasLegalRMIIIOPExceptionTypes(method))
1582         {
1583            fireSpecViolationEvent(entity, method, new Section("9.2.7.h"));
1584            status = false;
1585         }
1586
1587         if (!throwsRemoteException(method))
1588         {
1589            fireSpecViolationEvent(entity, method, new Section("9.2.7.d"));
1590            status = false;
1591         }
1592      }
1593
1594      // For each method defined in the remote interface, there MUST be
1595
// a matching method in the entity bean's class. The matching
1596
// method MUST have:
1597
//
1598
// - The same name.
1599
// - The same number and types of its arguments.
1600
// - The same return type.
1601
// - All the exceptions defined in the throws clause of the
1602
// matching method of the enterprise Bean class must be
1603
// defined in the throws clause of the method of the remote
1604
// interface.
1605
//
1606
// Spec 9.2.7
1607
//
1608
it = Arrays.asList(remote.getMethods()).iterator();
1609      while (it.hasNext())
1610      {
1611         Method JavaDoc method = (Method JavaDoc)it.next();
1612
1613         // Do not check the methods of the javax.ejb.EJBObject interface
1614
if (method.getDeclaringClass().getName().equals(EJB_OBJECT_INTERFACE))
1615            continue;
1616
1617         if (!hasMatchingMethod(bean, method))
1618         {
1619            fireSpecViolationEvent(entity, method, new Section("9.2.7.e"));
1620            status = false;
1621         }
1622
1623         if (hasMatchingMethod(bean, method))
1624         {
1625            try
1626            {
1627               Method JavaDoc beanMethod = bean.getMethod(method.getName(),
1628                       method.getParameterTypes());
1629
1630               if (!hasMatchingReturnType(beanMethod, method))
1631               {
1632                  fireSpecViolationEvent(entity, method,
1633                          new Section("9.2.7.f"));
1634                  status = false;
1635               }
1636
1637               if (!hasMatchingExceptions(beanMethod, method))
1638               {
1639                  fireSpecViolationEvent(entity, method,
1640                          new Section("9.2.7.g"));
1641                  status = false;
1642               }
1643            }
1644            catch (NoSuchMethodException JavaDoc ignored)
1645            {
1646            }
1647         }
1648      }
1649
1650      return status;
1651   }
1652
1653   /*
1654    * Verify Entity Bean Class
1655    */

1656   private boolean verifyCMPEntityBean(EntityMetaData entity)
1657   {
1658      boolean status = true;
1659
1660      // The enterprise bean class MUST implement, directly or
1661
// indirectly, the javax.ejb.EntityBean interface.
1662
//
1663
// Spec 10.6.2
1664
//
1665
if (!hasEntityBeanInterface(bean))
1666      {
1667         fireSpecViolationEvent(entity, new Section("10.6.2.a"));
1668         status = false;
1669      }
1670
1671      // The entity bean class MUST be defined as public and abstract.
1672
//
1673
// Spec 10.6.2
1674
//
1675
if (!isPublic(bean) || !isAbstract(bean))
1676      {
1677         fireSpecViolationEvent(entity, new Section("10.6.2.b"));
1678         status = false;
1679      }
1680
1681      // The entity bean class MUST define a public constructor that
1682
// takes no arguments
1683
//
1684
// Spec 10.6.2
1685
//
1686
if (!hasDefaultConstructor(bean))
1687      {
1688         fireSpecViolationEvent(entity, new Section("10.6.2.c"));
1689         status = false;
1690      }
1691
1692      // The entity bean class MUST NOT define the finalize() method.
1693
//
1694
// Spec 10.6.2
1695
//
1696
if (hasFinalizer(bean))
1697      {
1698         fireSpecViolationEvent(entity, new Section("10.6.2.d"));
1699         status = false;
1700      }
1701
1702      // The ejbCreate(...) method signatures MUST follow these rules:
1703
//
1704
// - The method MUST be declared as public
1705
// - The method MUST NOT be declared as final or static
1706
// - The return type MUST be the entity bean's primary key type
1707
// --- Only if method is on remote home ---
1708
// - The method arguments MUST be legal types for RMI/IIOP
1709
// - The method return value type MUST be legal type for RMI/IIOP
1710
// --- End of only if method is on remote home ---
1711
// - The method must define the javax.ejb.CreateException
1712
//
1713
// Spec 10.6.4
1714
//
1715
if (hasEJBCreateMethod(bean, false))
1716      {
1717         Iterator JavaDoc it = getEJBCreateMethods(bean);
1718         while (it.hasNext())
1719         {
1720            Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
1721            if (!isPublic(ejbCreate))
1722            {
1723               fireSpecViolationEvent(entity, ejbCreate,
1724                       new Section("10.6.4.b"));
1725               status = false;
1726            }
1727
1728            if ((isFinal(ejbCreate)) || (isStatic(ejbCreate)))
1729            {
1730               fireSpecViolationEvent(entity, ejbCreate,
1731                       new Section("10.6.4.c"));
1732               status = false;
1733            }
1734
1735            if (!hasPrimaryKeyReturnType(entity, ejbCreate))
1736            {
1737               fireSpecViolationEvent(entity, ejbCreate,
1738                       new Section("10.6.4.d"));
1739               status = false;
1740            }
1741
1742            /* FIXME
1743             * This is only true if the method is on the remote home
1744             * interface
1745             if (!hasLegalRMIIIOPArguments(ejbCreate)) {
1746             fireSpecViolationEvent(entity, ejbCreate, new Section("10.6.4.d"));
1747             status = false;
1748             }
1749
1750             if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
1751             fireSpecViolationEvent(entity, ejbCreate, new Section("10.5.4.f"));
1752             status = false;
1753             }
1754             */

1755
1756            if (!throwsCreateException(ejbCreate))
1757            {
1758               fireSpecViolationEvent(entity, ejbCreate,
1759                       new Section("10.6.4.g"));
1760               status = false;
1761            }
1762         }
1763      }
1764
1765      // For each ejbCreate(...) method, the entity bean class MUST
1766
// define a matching ejbPostCreate(...) method.
1767
//
1768
// The ejbPostCreate(...) method MUST follow these rules:
1769
//
1770
// - the method MUST be declared as public
1771
// - the method MUST NOT be declared as final or static
1772
// - the return type MUST be void
1773
// - the method arguments MUST be the same as the matching
1774
// ejbCreate(...) method
1775
//
1776
// Spec 10.6.5
1777
//
1778
if (hasEJBCreateMethod(bean, false))
1779      {
1780         Iterator JavaDoc it = getEJBCreateMethods(bean);
1781
1782         while (it.hasNext())
1783         {
1784            Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
1785
1786            if (!hasMatchingEJBPostCreate(bean, ejbCreate))
1787            {
1788               fireSpecViolationEvent(entity, ejbCreate,
1789                       new Section("10.6.5.a"));
1790               status = false;
1791            }
1792
1793            if (hasMatchingEJBPostCreate(bean, ejbCreate))
1794            {
1795               Method JavaDoc ejbPostCreate = getMatchingEJBPostCreate(bean,
1796                       ejbCreate);
1797
1798               if (!isPublic(ejbPostCreate))
1799               {
1800                  fireSpecViolationEvent(entity, ejbPostCreate,
1801                          new Section("10.6.5.b"));
1802                  status = false;
1803               }
1804
1805               if (isStatic(ejbPostCreate))
1806               {
1807                  fireSpecViolationEvent(entity, ejbPostCreate,
1808                          new Section("10.6.5.c"));
1809                  status = false;
1810               }
1811
1812               if (isFinal(ejbPostCreate))
1813               {
1814                  fireSpecViolationEvent(entity, ejbPostCreate,
1815                          new Section("10.6.5.d"));
1816                  status = false;
1817               }
1818
1819               if (!hasVoidReturnType(ejbPostCreate))
1820               {
1821                  fireSpecViolationEvent(entity, ejbPostCreate,
1822                          new Section("10.6.5.e"));
1823                  status = false;
1824               }
1825            }
1826         }
1827      }
1828
1829      // The ejbHome(...) method signatures MUST follow these rules:
1830
//
1831
// - The method name MUST have ejbHome as its prefix.
1832
// - The method MUST be declared as public
1833
// - The method MUST NOT be declared as static.
1834
// - The method MUST NOT define the java.rmi.RemoteException
1835
//
1836
// Spec 10.6.6
1837
//
1838
Iterator JavaDoc it = getEjbHomeMethods(bean);
1839      while (it.hasNext())
1840      {
1841         Method JavaDoc ejbHome = (Method JavaDoc)it.next();
1842         if (!isPublic(ejbHome))
1843         {
1844            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.a"));
1845            status = false;
1846         }
1847
1848         if (isStatic(ejbHome))
1849         {
1850            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.b"));
1851            status = false;
1852         }
1853
1854         if (throwsRemoteException(ejbHome))
1855         {
1856            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.c"));
1857            status = false;
1858         }
1859      }
1860
1861      // The CMP entity bean MUST implement get and set accessor methods for
1862
// each field within the abstract persistance schema.
1863
//
1864
// Spec 10.6.2
1865
//
1866
it = entity.getCMPFields();
1867      while (it.hasNext())
1868      {
1869         String JavaDoc fieldName = (String JavaDoc)it.next();
1870         String JavaDoc getName = "get" + fieldName.substring(0, 1).toUpperCase() +
1871                 fieldName.substring(1);
1872         Class JavaDoc fieldType = null;
1873
1874         try
1875         {
1876            Method JavaDoc m = bean.getMethod(getName, new Class JavaDoc[0]);
1877            fieldType = m.getReturnType();
1878
1879            // The getter must not return 'void' according to the JavaBeans
1880
// Spec
1881
if (fieldType == Void.TYPE)
1882            {
1883               fireSpecViolationEvent(entity,
1884                       new Section("jb.7.1.b", "Field: " + fieldName));
1885            }
1886         }
1887         catch (NoSuchMethodException JavaDoc nsme)
1888         {
1889            fireSpecViolationEvent(entity,
1890                    new Section("10.6.2.g", "Field: " + fieldName));
1891            status = false;
1892         }
1893
1894         String JavaDoc setName = "set" + fieldName.substring(0, 1).toUpperCase() +
1895                 fieldName.substring(1);
1896         Class JavaDoc[] args = new Class JavaDoc[1];
1897         args[0] = fieldType;
1898
1899         try
1900         {
1901            Method JavaDoc m = bean.getMethod(setName, args);
1902            fieldType = m.getReturnType();
1903
1904            // According to the JavaBeans Spec, a setter method must
1905
// return 'void'
1906
if (fieldType != Void.TYPE)
1907            {
1908               fireSpecViolationEvent(entity,
1909                       new Section("jb.7.1.a", "Field: " + fieldName));
1910            }
1911         }
1912         catch (NoSuchMethodException JavaDoc nsme)
1913         {
1914            // Try with java.util.Collection
1915
//
1916
// FIXME: This should only be tried for CMR methods; a CMP
1917
// setter cannot accept a Collection!
1918
try
1919            {
1920               args[0] = classloader.loadClass("java.util.Collection");
1921               Method JavaDoc m = bean.getMethod(setName, args);
1922            }
1923            catch (NoSuchMethodException JavaDoc nsme2)
1924            {
1925               fireSpecViolationEvent(entity,
1926                       new Section("10.6.2.h", "Field: " + fieldName));
1927               status = false;
1928            }
1929            catch (ClassNotFoundException JavaDoc cnfe)
1930            {
1931               // Something is really broken
1932
}
1933         }
1934      }
1935
1936      // The ejbSelect(...) method signatures MUST follow these rules:
1937
//
1938
// - The method name MUST have ejbSelect as its prefix.
1939
// - The method MUST be declared as public
1940
// - The method MUST be declared as abstract.
1941
// - The method MUST define the javax.ejb.FinderException
1942
//
1943
// Spec 10.6.7
1944
//
1945
it = getEjbSelectMethods(bean);
1946      while (it.hasNext())
1947      {
1948         Method JavaDoc ejbSelect = (Method JavaDoc)it.next();
1949
1950         if (!isPublic(ejbSelect))
1951         {
1952            fireSpecViolationEvent(entity, ejbSelect, new Section("10.6.7.a"));
1953            status = false;
1954         }
1955
1956         if (!isAbstract(ejbSelect))
1957         {
1958            fireSpecViolationEvent(entity, ejbSelect, new Section("10.6.7.b"));
1959            status = false;
1960         }
1961
1962         if (!throwsFinderException(ejbSelect))
1963         {
1964            fireSpecViolationEvent(entity, ejbSelect, new Section("10.6.7.c"));
1965            status = false;
1966         }
1967
1968         if (!hasMatchingQuery(ejbSelect, entity))
1969         {
1970            fireSpecViolationEvent(entity, ejbSelect, new Section("10.5.7"));
1971            status = false;
1972         }
1973      }
1974
1975      // A CMP Entity Bean must not define Finder methods.
1976
//
1977
// Spec 10.6.2
1978
//
1979
if (hasFinderMethod(bean))
1980      {
1981         fireSpecViolationEvent(entity, new Section("10.6.2.i"));
1982         status = false;
1983      }
1984
1985      return status;
1986   }
1987
1988   /*
1989    * Verify BMP Entity Class
1990    */

1991   private boolean verifyBMPEntityBean(EntityMetaData entity)
1992   {
1993      boolean status = true;
1994
1995      // The enterprise bean class MUST implement, directly or
1996
// indirectly, the javax.ejb.EntityBean interface.
1997
//
1998
// Spec 12.2.2
1999
//
2000
if (!hasEntityBeanInterface(bean))
2001      {
2002         fireSpecViolationEvent(entity, new Section("12.2.2.a"));
2003         status = false;
2004      }
2005
2006      // The entity bean class MUST be defined as public and NOT abstract.
2007
//
2008
// Spec 12.2.2
2009
//
2010
if (!isPublic(bean) || isAbstract(bean))
2011      {
2012         fireSpecViolationEvent(entity, new Section("12.2.2.b"));
2013         status = false;
2014      }
2015
2016      // The entity bean class MUST NOT be defined as final.
2017
//
2018
// Spec 12.2.2
2019
//
2020
if (isFinal(bean))
2021      {
2022         fireSpecViolationEvent(entity, new Section("12.2.2.c"));
2023         status = false;
2024      }
2025
2026      // The entity bean class MUST define a public constructor that
2027
// takes no arguments
2028
//
2029
// Spec 12.2.2
2030
//
2031
if (!hasDefaultConstructor(bean))
2032      {
2033         fireSpecViolationEvent(entity, new Section("12.2.2.d"));
2034         status = false;
2035      }
2036
2037      // The entity bean class MUST NOT define the finalize() method.
2038
//
2039
// Spec 12.2.2
2040
//
2041
if (hasFinalizer(bean))
2042      {
2043         fireSpecViolationEvent(entity, new Section("12.2.2.e"));
2044         status = false;
2045      }
2046
2047      // The ejbCreate(...) method signatures MUST follow these rules:
2048
//
2049
// - The method MUST be declared as public
2050
// - The method MUST NOT be declared as final or static
2051
// - The return type MUST be the entity bean's primary key type
2052
// --- If the method is on the remote home interface ---
2053
// - The method arguments MUST be legal types for RMI/IIOP
2054
// - The method return value type MUST be legal type for RMI/IIOP
2055
// --- End if the method is on the remote home interface ---
2056
//
2057
// Spec 12.2.3
2058
//
2059
if (hasEJBCreateMethod(bean, false))
2060      {
2061         Iterator JavaDoc it = getEJBCreateMethods(bean);
2062         while (it.hasNext())
2063         {
2064            Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
2065            if (!isPublic(ejbCreate))
2066            {
2067               fireSpecViolationEvent(entity, ejbCreate,
2068                       new Section("12.2.3.a"));
2069               status = false;
2070            }
2071
2072            if ((isFinal(ejbCreate)) || (isStatic(ejbCreate)))
2073            {
2074               fireSpecViolationEvent(entity, ejbCreate,
2075                       new Section("12.2.3.b"));
2076               status = false;
2077            }
2078
2079            if (!hasPrimaryKeyReturnType(entity, ejbCreate))
2080            {
2081               fireSpecViolationEvent(entity, ejbCreate,
2082                       new Section("12.2.3.c"));
2083               status = false;
2084            }
2085
2086            /* FIXME
2087             * This code needs to only be invoked if the method is on the
2088             * remote home.
2089             if (!hasLegalRMIIIOPArguments(ejbCreate)) {
2090             fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.d"));
2091             status = false;
2092             }
2093             if (!hasLegalRMIIIOPReturnType(ejbCreate)) {
2094             fireSpecViolationEvent(entity, ejbCreate, new Section("9.2.3.e"));
2095             status = false;
2096             }
2097            */

2098         }
2099      }
2100
2101      // For each ejbCreate(...) method, the entity bean class MUST
2102
// define a matching ejbPostCreate(...) method.
2103
//
2104
// The ejbPostCreate(...) method MUST follow these rules:
2105
//
2106
// - the method MUST be declared as public
2107
// - the method MUST NOT be declared as final or static
2108
// - the return type MUST be void
2109
// - the method arguments MUST be the same as the matching
2110
// ejbCreate(...) method
2111
//
2112
// Spec 12.2.4
2113
//
2114
if (hasEJBCreateMethod(bean, false))
2115      {
2116         Iterator JavaDoc it = getEJBCreateMethods(bean);
2117         while (it.hasNext())
2118         {
2119            Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
2120
2121            if (!hasMatchingEJBPostCreate(bean, ejbCreate))
2122            {
2123               fireSpecViolationEvent(entity, ejbCreate,
2124                       new Section("12.2.4.a"));
2125               status = false;
2126            }
2127
2128            if (hasMatchingEJBPostCreate(bean, ejbCreate))
2129            {
2130               Method JavaDoc ejbPostCreate = getMatchingEJBPostCreate(bean,
2131                       ejbCreate);
2132
2133               if (!isPublic(ejbPostCreate))
2134               {
2135                  fireSpecViolationEvent(entity, ejbPostCreate,
2136                          new Section("12.2.4.b"));
2137                  status = false;
2138               }
2139
2140               if (isStatic(ejbPostCreate) || isFinal(ejbPostCreate))
2141               {
2142                  fireSpecViolationEvent(entity, ejbPostCreate,
2143                          new Section("12.2.4.c"));
2144                  status = false;
2145               }
2146
2147               if (!hasVoidReturnType(ejbPostCreate))
2148               {
2149                  fireSpecViolationEvent(entity, ejbPostCreate,
2150                          new Section("12.2.4.d"));
2151                  status = false;
2152               }
2153            }
2154         }
2155      }
2156
2157      // Every entity bean MUST define the ejbFindByPrimaryKey method.
2158
//
2159
// The return type for the ejbFindByPrimaryKey method MUST be the
2160
// primary key type.
2161
//
2162
// The ejbFindByPrimaryKey method MUST be a single-object finder.
2163
//
2164
// Spec 12.2.5
2165
//
2166
if (!hasEJBFindByPrimaryKey(bean))
2167      {
2168         fireSpecViolationEvent(entity, new Section("12.2.5.e"));
2169         status = false;
2170      }
2171
2172      if (hasEJBFindByPrimaryKey(bean))
2173      {
2174         Method JavaDoc ejbFindByPrimaryKey = getEJBFindByPrimaryKey(bean);
2175
2176         if (!hasPrimaryKeyReturnType(entity, ejbFindByPrimaryKey))
2177         {
2178            fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
2179                    new Section("12.2.5.e1"));
2180            status = false;
2181         }
2182
2183         if (!isSingleObjectFinder(entity, ejbFindByPrimaryKey))
2184         {
2185            fireSpecViolationEvent(entity, ejbFindByPrimaryKey,
2186                    new Section("12.2.5.e2"));
2187            status = false;
2188         }
2189      }
2190
2191      // A finder method MUST be declared as public.
2192
//
2193
// A finder method MUST NOT be declared as static.
2194
//
2195
// A finder method MUST NOT be declared as final.
2196
//
2197
// The finder method argument types MUST be legal types for
2198
// RMI/IIOP
2199
//
2200
// The finder method return type MUST be either the entity bean's
2201
// primary key type, or java.lang.util.Enumeration interface or
2202
// java.lang.util.Collection interface.
2203
//
2204
// Spec 12.2.5
2205
//
2206
if (hasFinderMethod(bean))
2207      {
2208         Iterator JavaDoc it = getEJBFindMethods(bean);
2209         while (it.hasNext())
2210         {
2211            Method JavaDoc finder = (Method JavaDoc)it.next();
2212
2213            if (!isPublic(finder))
2214            {
2215               fireSpecViolationEvent(entity, finder, new Section("12.2.5.a"));
2216               status = false;
2217            }
2218
2219            if (isFinal(finder) || isStatic(finder))
2220            {
2221               fireSpecViolationEvent(entity, finder, new Section("12.2.5.b"));
2222               status = false;
2223            }
2224
2225            /** FIXME
2226             * this path should only get invoked if the finder is on the
2227             * remote interface.
2228             if (!hasLegalRMIIIOPArguments(finder)) {
2229             fireSpecViolationEvent(entity, finder, new Section("12.2.5.c"));
2230             status = false;
2231             }
2232             */

2233
2234            if (!(isSingleObjectFinder(entity, finder)
2235                    || isMultiObjectFinder(finder)))
2236            {
2237               fireSpecViolationEvent(entity, finder, new Section("12.2.5.d"));
2238               status = false;
2239            }
2240         }
2241      }
2242
2243      // The ejbHome(...) method signatures MUST follow these rules:
2244
//
2245
// - The method name MUST have ejbHome as its prefix.
2246
// - The method MUST be declared as public
2247
// - The method MUST NOT be declared as static.
2248
// - The method MUST NOT define the java.rmi.RemoteException
2249
//
2250
// Spec 10.6.6
2251
//
2252
Iterator JavaDoc it = getEjbHomeMethods(bean);
2253      while (it.hasNext())
2254      {
2255         Method JavaDoc ejbHome = (Method JavaDoc)it.next();
2256
2257         if (!isPublic(ejbHome))
2258         {
2259            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.a"));
2260            status = false;
2261         }
2262
2263         if (isStatic(ejbHome))
2264         {
2265            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.b"));
2266            status = false;
2267         }
2268
2269         if (throwsRemoteException(ejbHome))
2270         {
2271            fireSpecViolationEvent(entity, ejbHome, new Section("10.6.6.c"));
2272            status = false;
2273         }
2274      }
2275
2276      return status;
2277   }
2278
2279   /*
2280    * Verify Primary Key
2281    */

2282   private boolean verifyPrimaryKey(EntityMetaData entity)
2283   {
2284      boolean status = true;
2285      boolean cmp = entity.isCMP();
2286
2287      if (entity.getPrimaryKeyClass() == null
2288              || entity.getPrimaryKeyClass().length() == 0)
2289      {
2290         if (cmp)
2291            fireSpecViolationEvent(entity, new Section("10.6.1.a"));
2292         else
2293            fireSpecViolationEvent(entity, new Section("12.2.1.a"));
2294
2295         // We can't get any further if there's no PK class specified!
2296
return false;
2297      }
2298
2299      // FIXME - Still missing the bits from 10.8.2 for CMP primary
2300
// keys. Primarily the class must be public, all fields in the
2301
// class must be public and the fields must also be a subset of
2302
// the CMP fields within the bean.
2303
//
2304
Class JavaDoc cls = null;
2305      try
2306      {
2307         cls = classloader.loadClass(entity.getPrimaryKeyClass());
2308      }
2309      catch (ClassNotFoundException JavaDoc e)
2310      {
2311         if (cmp)
2312            fireSpecViolationEvent(entity, new Section("10.6.13.a"));
2313         else
2314            fireSpecViolationEvent(entity, new Section("12.2.12.a"));
2315
2316         // Can't do any other checks if the class is null!
2317
return false;
2318      }
2319
2320      // The primary key type must be a valid type in RMI-IIOP.
2321
//
2322
// Spec 10.6.13 & 12.2.12
2323
//
2324
if (!isRMIIDLValueType(cls))
2325      {
2326         if (cmp)
2327            fireSpecViolationEvent(entity, new Section("10.6.13.b"));
2328         else
2329            fireSpecViolationEvent(entity, new Section("12.2.12.b"));
2330         status = false;
2331      }
2332
2333      // No primary key field specified, just a primary key class.
2334
if (entity.getPrimKeyField() == null ||
2335              entity.getPrimKeyField().length() == 0)
2336      {
2337         // This is a check for some interesting implementation of
2338
// equals() and hashCode(). I am not sure how well it works in
2339
// the end.
2340
//
2341
if (!cls.getName().equals("java.lang.Object"))
2342         {
2343            Object JavaDoc one, two;
2344
2345            try
2346            {
2347               one = cls.newInstance();
2348               two = cls.newInstance();
2349               try
2350               {
2351                  if (!one.equals(two))
2352                  {
2353                     if (cmp)
2354                     {
2355                        // fireSpecViolationEvent(entity, new Section("10.6.13.c"));
2356
log.warn("Default instances of primary key: " + cls
2357                                + " do not equate, check your equals method");
2358                     }
2359                     else
2360                     {
2361                        //fireSpecViolationEvent(entity, new Section("12.2.12.c"));
2362
log.warn("Default instances of primary key: " + cls
2363                                + " do not equate, check your equals method");
2364                     }
2365                     status = true;
2366                  }
2367               }
2368               catch (NullPointerException JavaDoc e)
2369               {
2370                  // That's OK - the implementor expected the fields to
2371
// have values
2372
}
2373
2374               try
2375               {
2376                  if (one.hashCode() != two.hashCode())
2377                  {
2378                     if (cmp)
2379                     {
2380                        //fireSpecViolationEvent(entity, new Section("10.6.13.d"));
2381
log.warn("Default instances of primary key: " + cls
2382                                + " do not have the same hash, check your hashCode method");
2383                     }
2384                     else
2385                     {
2386                        //fireSpecViolationEvent(entity, new Section("12.2.12.d"));
2387
log.warn("Default instances of primary key: " + cls
2388                                + " do not have the same hash, check your hashCode method");
2389                     }
2390                     status = true;
2391                  }
2392               }
2393               catch (NullPointerException JavaDoc e)
2394               {
2395                  // That's OK - the implementor expected the fields to have values
2396
}
2397            }
2398            catch (IllegalAccessException JavaDoc e)
2399            {
2400               // If CMP primary key class MUST have a public
2401
// constructor with no parameters. 10.8.2.a
2402
///
2403
if (cmp)
2404               {
2405                  fireSpecViolationEvent(entity, new Section("10.8.2.a"));
2406                  status = false;
2407               }
2408            }
2409            catch (InstantiationException JavaDoc e)
2410            {
2411               //Not sure what condition this is at the moment - JMW
2412
//fireSpecViolationEvent(entity, new Section("9.2.9.a"));
2413
//status = false;
2414
}
2415         }
2416      }
2417      else
2418      {
2419         // BMP Beans MUST not include the primkey-field element in
2420
// their deployment descriptor. Deployment descriptor comment
2421
//
2422
if (entity.isBMP())
2423         {
2424            fireSpecViolationEvent(entity, new Section("dd.a"));
2425            status = false;
2426         }
2427
2428         // The primary keyfield MUST be a CMP field within the
2429
// entity bean.
2430
//
2431
// Spec 10.8.1
2432
//
2433
boolean found = false;
2434         Iterator JavaDoc it = entity.getCMPFields();
2435         while (it.hasNext())
2436         {
2437            String JavaDoc fieldName = (String JavaDoc)it.next();
2438            if (fieldName.equals(entity.getPrimKeyField()))
2439            {
2440               found = true;
2441               break;
2442            }
2443         }
2444
2445         if (!found)
2446         {
2447            status = false;
2448            fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2449         }
2450
2451         try
2452         {
2453            // The class of the primary key field MUST match the
2454
// primary key class specified for the entity bean. We
2455
// figure out the class of this field by getting the
2456
// return type of the get<FieldName> accessor method.
2457
//
2458
// Spec 10.8.1
2459
//
2460
String JavaDoc pkField = entity.getPrimKeyField();
2461            String JavaDoc methodName = "get" +
2462                    pkField.substring(0, 1).toUpperCase() + pkField.substring(1);
2463
2464            Method JavaDoc method = bean.getMethod(methodName, new Class JavaDoc[0]);
2465            if (!entity.getPrimaryKeyClass().equals(method.getReturnType().getName())
2466            )
2467            {
2468               status = false;
2469               fireSpecViolationEvent(entity, new Section("10.8.1.a"));
2470            }
2471
2472         }
2473         catch (NoSuchMethodException JavaDoc e)
2474         {
2475            // The primary keyfield MUST be a CMP field within the
2476
// entity bean.
2477
//
2478
// Spec 10.8.1
2479
//
2480
status = false;
2481            fireSpecViolationEvent(entity, new Section("10.8.1.b"));
2482         }
2483      }
2484
2485      return status;
2486   }
2487
2488   /*
2489    * Verify Message Driven Bean
2490    */

2491   protected boolean verifyMessageDrivenBean(MessageDrivenMetaData mdBean)
2492   {
2493      boolean status = true;
2494
2495      // A message driven bean MUST implement, directly or indirectly,
2496
// javax.ejb.MessageDrivenBean interface.
2497
//
2498
// Spec 15.7.2
2499
//
2500
if (!hasMessageDrivenBeanInterface(bean))
2501      {
2502         fireSpecViolationEvent(mdBean, new Section("15.7.2.a"));
2503         status = false;
2504      }
2505
2506      // A message driven bean MUST implement, directly or indirectly,
2507
// javax.jms.MessageListener interface.
2508
//
2509
// Spec 15.7.2
2510
//
2511
if (!hasMessageListenerInterface(bean))
2512      {
2513         fireSpecViolationEvent(mdBean, new Section("15.7.2.b"));
2514         status = false;
2515      }
2516
2517      // The message driven bean class MUST be defined as public.
2518
//
2519
// Spec 15.7.2
2520
//
2521
if (!isPublic(bean))
2522      {
2523         fireSpecViolationEvent(mdBean, new Section("15.7.2.c1"));
2524         status = false;
2525      }
2526
2527      // The message driven bean class MUST NOT be final.
2528
//
2529
// Spec 15.7.2
2530
//
2531
if (isFinal(bean))
2532      {
2533         fireSpecViolationEvent(mdBean, new Section("15.7.2.c2"));
2534         status = false;
2535      }
2536
2537      // The message driven bean class MUST NOT be abstract.
2538
//
2539
// Spec 15.7.2
2540
//
2541
if (isAbstract(bean))
2542      {
2543         fireSpecViolationEvent(mdBean, new Section("15.7.2.c3"));
2544         status = false;
2545      }
2546
2547      // The message driven bean class MUST have a public constructor that
2548
// takes no arguments.
2549
//
2550
// Spec 15.7.2
2551
//
2552
if (!hasDefaultConstructor(bean))
2553      {
2554         fireSpecViolationEvent(mdBean, new Section("15.7.2.d"));
2555         status = false;
2556      }
2557
2558      // The message driven bean class MUST NOT define the finalize() method.
2559
//
2560
// Spec 15.7.2
2561
//
2562
if (hasFinalizer(bean))
2563      {
2564         fireSpecViolationEvent(mdBean, new Section("15.7.2.e"));
2565         status = false;
2566      }
2567
2568      // A message driven bean MUST implement the ejbCreate() method.
2569
// The ejbCreate() method signature MUST follow these rules:
2570
//
2571
// - The method name MUST be ejbCreate
2572
// - The method MUST be declared as public
2573
// - The method MUST NOT be declared as final or static
2574
// - The return type MUST be void
2575
// - The method arguments MUST have no arguments.
2576
// - The method MUST NOT define any application exceptions.
2577
//
2578
// Spec 15.7.2, 3
2579
//
2580
if (hasEJBCreateMethod(bean, false))
2581      {
2582         Iterator JavaDoc it = getEJBCreateMethods(bean);
2583         Method JavaDoc ejbCreate = (Method JavaDoc)it.next();
2584
2585         if (!isPublic(ejbCreate))
2586         {
2587            fireSpecViolationEvent(mdBean, ejbCreate, new Section("15.7.3.b"));
2588            status = false;
2589         }
2590
2591         if ((isFinal(ejbCreate)) || (isStatic(ejbCreate)))
2592         {
2593            fireSpecViolationEvent(mdBean, ejbCreate, new Section("15.7.3.c"));
2594            status = false;
2595         }
2596
2597         if (!hasVoidReturnType(ejbCreate))
2598         {
2599            fireSpecViolationEvent(mdBean, ejbCreate, new Section("15.7.3.d"));
2600            status = false;
2601         }
2602
2603         if (!hasNoArguments(ejbCreate))
2604         {
2605            fireSpecViolationEvent(mdBean, ejbCreate, new Section("15.7.3.e"));
2606            status = false;
2607         }
2608
2609         if (!throwsNoException(ejbCreate))
2610         {
2611            fireSpecViolationEvent(mdBean, ejbCreate, new Section("15.7.3.f"));
2612            status = false;
2613         }
2614
2615         if (it.hasNext())
2616         {
2617            fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2618            status = false;
2619         }
2620      }
2621      else
2622      {
2623         fireSpecViolationEvent(mdBean, new Section("15.7.3.a"));
2624         status = false;
2625      }
2626
2627      // A message driven bean MUST implement the onMessage(...) method.
2628
// The onMessage() method signature MUST follow these rules:
2629
//
2630
// - The method name MUST be onMessage
2631
// - The method MUST be declared as public
2632
// - The method MUST NOT be declared as final or static
2633
// - The return type MUST be void
2634
// - The method arguments MUST have a single argument of type
2635
// javax.jms.Message.
2636
// - The method MUST NOT define any application exceptions.
2637
//
2638
// Spec 15.7.4
2639
//
2640
if (hasOnMessageMethod(bean))
2641      {
2642         Iterator JavaDoc it = getOnMessageMethods(bean);
2643         Method JavaDoc onMessage = (Method JavaDoc)it.next();
2644
2645         if (!isPublic(onMessage))
2646         {
2647            fireSpecViolationEvent(mdBean, onMessage, new Section("15.7.4.b"));
2648            status = false;
2649         }
2650
2651         if ((isFinal(onMessage)) || (isStatic(onMessage)))
2652         {
2653            fireSpecViolationEvent(mdBean, onMessage, new Section("15.7.4.c"));
2654            status = false;
2655         }
2656
2657         try
2658         {
2659            Class JavaDoc message = classloader.loadClass("javax.jms.Message");
2660            if (!hasSingleArgument(onMessage, message))
2661            {
2662               fireSpecViolationEvent(mdBean, onMessage,
2663                       new Section("15.7.4.e"));
2664               status = false;
2665            }
2666
2667            if (!throwsNoException(onMessage))
2668            {
2669               fireSpecViolationEvent(mdBean, onMessage,
2670                       new Section("15.7.4.f"));
2671               status = false;
2672            }
2673
2674            if (it.hasNext())
2675            {
2676               fireSpecViolationEvent(mdBean, new Section("15.7.4.a"));
2677               status = false;
2678            }
2679         }
2680         catch (ClassNotFoundException JavaDoc cnfe)
2681         {
2682            // javax.jms.Message is not available?!
2683
}
2684      }
2685      else
2686      {
2687         fireSpecViolationEvent(mdBean, new Section("15.7.4.a"));
2688         status = false;
2689      }
2690
2691      // A message driven bean MUST implement the ejbRemove() method.
2692
// The ejbRemove() method signature MUST follow these rules:
2693
//
2694
// - The method name MUST be ejbRemove
2695
// - The method MUST be declared as public
2696
// - The method MUST NOT be declared as final or static
2697
// - The return type MUST be void
2698
// - The method MUST have no arguments.
2699
// - The method MUST NOT define any application exceptions.
2700
//
2701
// Spec 15.7.5
2702
//
2703
if (hasEJBRemoveMethod(bean))
2704      {
2705         Iterator JavaDoc it = getEJBRemoveMethods(bean);
2706         Method JavaDoc ejbRemove = (Method JavaDoc)it.next();
2707
2708         if (!isPublic(ejbRemove))
2709         {
2710            fireSpecViolationEvent(mdBean, ejbRemove, new Section("15.7.5.b"));
2711            status = false;
2712         }
2713
2714         if ((isFinal(ejbRemove)) || (isStatic(ejbRemove)))
2715         {
2716            fireSpecViolationEvent(mdBean, ejbRemove, new Section("15.7.5.c"));
2717            status = false;
2718         }
2719
2720         if (!hasVoidReturnType(ejbRemove))
2721         {
2722            fireSpecViolationEvent(mdBean, ejbRemove, new Section("15.7.5.d"));
2723            status = false;
2724         }
2725
2726         if (!hasNoArguments(ejbRemove))
2727         {
2728            fireSpecViolationEvent(mdBean, ejbRemove, new Section("15.7.5.e"));
2729            status = false;
2730         }
2731
2732         if (!throwsNoException(ejbRemove))
2733         {
2734            fireSpecViolationEvent(mdBean, ejbRemove, new Section("15.7.5.f"));
2735            status = false;
2736         }
2737
2738         if (it.hasNext())
2739         {
2740            fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2741            status = false;
2742         }
2743      }
2744      else
2745      {
2746         fireSpecViolationEvent(mdBean, new Section("15.7.5.a"));
2747         status = false;
2748      }
2749
2750      return status;
2751   }
2752
2753}
2754
2755/*
2756vim:ts=3:sw=3:et
2757*/

2758
Popular Tags