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     &nbs