KickJava   Java API By Example, From Geeks To Geeks.

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


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: EJBVerifier21.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.1 bean verifier.
39  *
40  * @author <a HREF="mailto:christoph.jung@infor.de">Christoph G. Jung</a>
41  * @author Thomas.Diesler@jboss.org
42  *
43  * @version $Revision: 41248 $
44  * @since 02.12.2003
45  */

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

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

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

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

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

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

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

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

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

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