KickJava   Java API By Example, From Geeks To Geeks.

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


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 // standard imports
25

26 import org.gjt.lindfors.pattern.StrategyContext;
27 import org.jboss.logging.Logger;
28 import org.jboss.metadata.BeanMetaData;
29 import org.jboss.metadata.EntityMetaData;
30 import org.jboss.metadata.MessageDrivenMetaData;
31 import org.jboss.util.Classes;
32 import org.jboss.verifier.Section;
33 import org.jboss.verifier.event.VerificationEvent;
34 import org.jboss.verifier.factory.DefaultEventFactory;
35 import org.jboss.verifier.factory.VerificationEventFactory;
36
37 import java.lang.reflect.Constructor JavaDoc;
38 import java.lang.reflect.Field JavaDoc;
39 import java.lang.reflect.Member JavaDoc;
40 import java.lang.reflect.Method JavaDoc;
41 import java.lang.reflect.Modifier JavaDoc;
42 import java.net.URL JavaDoc;
43 import java.net.URLClassLoader JavaDoc;
44 import java.rmi.RemoteException JavaDoc;
45 import java.util.Arrays JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.LinkedList JavaDoc;
48 import java.util.List JavaDoc;
49
50 import javax.jms.Message JavaDoc;
51
52
53 /**
54  * Abstract superclass for verifiers containing a bunch of useful methods.
55  *
56  * @see org.jboss.verifier.strategy.VerificationStrategy
57  *
58  * @author <a HREF="mailto:juha.lindfors@jboss.org">Juha Lindfors</a>
59  * @author Aaron Mulder (ammulder@alumni.princeton.edu)
60  * @author Vinay Menon (menonv@cpw.co.uk)
61  * @author <a HREF="mailto:andreas@jboss.org">Andreas Schaefer</a>
62  * @author <a HREF="mailto:luke@mkeym.com">Luke Taylor</a>
63  * @author <a HREF="mailto:jwalters@computer.org">Jay Walters</a>
64  * @author Scott.Stark@jboss.org
65  *
66  * @version $Revision: 45238 $
67  * @since JDK 1.3
68  */

69 public abstract class AbstractVerifier
70         implements VerificationStrategy
71 {
72    static final Logger log = Logger.getLogger(AbstractVerifier.class);
73
74    protected final static String JavaDoc EJB_OBJECT_INTERFACE =
75            "javax.ejb.EJBObject";
76
77    protected final static String JavaDoc EJB_HOME_INTERFACE =
78            "javax.ejb.EJBHome";
79
80    protected final static String JavaDoc EJB_LOCAL_OBJECT_INTERFACE =
81            "javax.ejb.EJBLocalObject";
82
83    protected final static String JavaDoc EJB_LOCAL_HOME_INTERFACE =
84            "javax.ejb.EJBLocalHome";
85    
86    /**
87     * The application classloader. This can be provided by the context
88     * directly via {@link VerificationContext#getClassLoader} method, or
89     * constructed by this object by creating a classloader to the URL
90     * returned by {@link VerificationContext#getJarLocation} method. <p>
91     *
92     * Initialized in the constructor.
93     */

94    protected ClassLoader JavaDoc classloader = null;
95
96    /**
97     * Factory for generating the verifier events. <p>
98     *
99     * Initialized in the constructor.
100     *
101     * @see org.jboss.verifier.factory.DefaultEventFactory
102     */

103    private VerificationEventFactory factory = null;
104
105    /**
106     * Context is used for retrieving application level information,
107     * such as the application meta data, location of the jar file, etc.
108     * <p>
109     *
110     * Initialized in the constructor.
111     */

112    private VerificationContext context = null;
113
114    /**************************************************************************
115     *
116     * CONSTRUCTORS
117     *
118     **************************************************************************/

119    public AbstractVerifier(VerificationContext context)
120    {
121       this.context = context;
122       this.classloader = context.getClassLoader();
123       this.factory = new DefaultEventFactory(getMessageBundle());
124
125       if (this.classloader == null)
126       {
127          URL JavaDoc[] list = {context.getJarLocation()};
128
129          ClassLoader JavaDoc parent = Thread.currentThread().getContextClassLoader();
130          this.classloader = new URLClassLoader JavaDoc(list, parent);
131       }
132    }
133
134
135 /*
136  *************************************************************************
137  *
138  * PUBLIC INSTANCE METHODS
139  *
140  *************************************************************************
141  */

142
143    public boolean isAssignableFrom(String JavaDoc className, Class JavaDoc assignableFromClass)
144    {
145       try
146       {
147          Class JavaDoc clazz = this.classloader.loadClass(className);
148          return clazz.isAssignableFrom(assignableFromClass);
149       }
150       catch (ClassNotFoundException JavaDoc e)
151       {
152          log.warn("Failed to find class: " + className, e);
153       }
154       return false;
155    }
156
157    public boolean isAssignableFrom(Class JavaDoc clazz, String JavaDoc assignableFromClassName)
158    {
159       try
160       {
161          Class JavaDoc assignableFromClass = this.classloader.loadClass(assignableFromClassName);
162          return clazz.isAssignableFrom(assignableFromClass);
163       }
164       catch (ClassNotFoundException JavaDoc e)
165       {
166          log.warn("Failed to find class: " + assignableFromClassName, e);
167       }
168       return false;
169    }
170
171    public abstract String JavaDoc getMessageBundle();
172
173    public abstract boolean isCreateMethod(Method JavaDoc m);
174
175    public abstract boolean isEjbCreateMethod(Method JavaDoc m);
176
177    public boolean hasLegalRMIIIOPArguments(Method JavaDoc method)
178    {
179       Class JavaDoc[] params = method.getParameterTypes();
180
181       for (int i = 0; i < params.length; ++i)
182       {
183          if (!isRMIIIOPType(params[i]))
184             return false;
185       }
186
187       return true;
188    }
189
190    public boolean hasLegalRMIIIOPReturnType(Method JavaDoc method)
191    {
192       return isRMIIIOPType(method.getReturnType());
193    }
194
195
196    public boolean hasLegalRMIIIOPExceptionTypes(Method JavaDoc method)
197    {
198       /*
199        * All checked exception classes used in method declarations
200        * (other than java.rmi.RemoteException) MUST be conforming
201        * RMI/IDL exception types.
202        *
203        * Spec 28.2.3 (4)
204        */

205       Iterator JavaDoc it = Arrays.asList(method.getExceptionTypes()).iterator();
206       while (it.hasNext())
207       {
208          Class JavaDoc exception = (Class JavaDoc)it.next();
209
210          if (!isRMIIDLExceptionType(exception))
211             return false;
212       }
213
214       return true;
215    }
216
217    /**
218     * Checks if the method includes java.rmi.RemoteException or its
219     * subclass in its throws clause.
220     *
221     * See bug report #434739 and #607805
222     */

223    public boolean throwsRemoteException(Method JavaDoc method)
224    {
225       Class JavaDoc[] exception = method.getExceptionTypes();
226
227       for (int i = 0; i < exception.length; ++i)
228       {
229          // Fix for bug #607805: an IOException is OK for local interfaces
230
// Fix for bug #626430: java.lang.Exception is also OK
231
if (exception[i].equals(java.io.IOException JavaDoc.class)
232                  || exception[i].equals(java.lang.Exception JavaDoc.class))
233          {
234             continue;
235          }
236 // Not true see bug report #434739
237
// if (java.rmi.RemoteException.class.isAssignableFrom(exception[i]))
238
// According to the RMI spec. a remote interface must throw an RemoteException
239
// or any of its super classes therefore the check must be done vice versa
240

241          if (isAssignableFrom(exception[i], "java.rmi.RemoteException"))
242          {
243             return true;
244          }
245       }
246
247       return false;
248    }
249
250    /**
251     * checks if the method accepts a single parameter of a specified type.
252     */

253    public boolean hasSingleArgument(Method JavaDoc method, Class JavaDoc argClass)
254    {
255       Class JavaDoc[] params = method.getParameterTypes();
256       if (params.length == 1)
257       {
258          if (params[0].equals(argClass))
259             return true;
260       }
261
262       return false;
263    }
264
265    /**
266     * checks if the method accepts any parameters.
267     */

268    public boolean hasNoArguments(Method JavaDoc method)
269    {
270       Class JavaDoc[] params = method.getParameterTypes();
271       return (params.length == 0) ? true : false;
272    }
273
274    /**
275     * checks if the method throws no checked exceptions in its throws clause.
276     */

277    public boolean throwsNoException(Method JavaDoc method)
278    {
279       boolean hasCheckedException = false;
280       Class JavaDoc[] exceptions = method.getExceptionTypes();
281       for (int e = 0; e < exceptions.length; e++)
282       {
283          Class JavaDoc ex = exceptions[e];
284          boolean isError = Error JavaDoc.class.isAssignableFrom(ex);
285          boolean isRuntimeException = RuntimeException JavaDoc.class.isAssignableFrom(ex);
286          boolean isRemoteException = RemoteException JavaDoc.class.isAssignableFrom(ex);
287          if (isError == false && isRuntimeException == false && isRemoteException == false)
288             hasCheckedException = true;
289       }
290       return hasCheckedException == false;
291    }
292
293    /**
294     * checks if the method includes java.ejb.CreateException in its
295     * throws clause.
296     */

297    public boolean throwsCreateException(Method JavaDoc method)
298    {
299       Class JavaDoc[] exception = method.getExceptionTypes();
300       for (int i = 0; i < exception.length; ++i)
301       {
302          if (isAssignableFrom("javax.ejb.CreateException", exception[i]))
303             return true;
304       }
305
306       return false;
307    }
308
309    /**
310     * checks if the methods includes javax.ejb.FinderException in its
311     * throws clause.
312     */

313    public boolean throwsFinderException(Method JavaDoc method)
314    {
315       Class JavaDoc[] exception = method.getExceptionTypes();
316
317       for (int i = 0; i < exception.length; ++i)
318       {
319          if (isAssignableFrom("javax.ejb.FinderException", exception[i]))
320             return true;
321       }
322
323       return false;
324    }
325
326    /**
327     * checks if a class's member (method, constructor or field) has a
328     * <code>static</code> modifier.
329     */

330    public boolean isStatic(Member JavaDoc member)
331    {
332       return (Modifier.isStatic(member.getModifiers()));
333    }
334
335    /**
336     * checks if the given class is declared as static (inner classes only)
337     */

338    public boolean isStatic(Class JavaDoc c)
339    {
340       return (Modifier.isStatic(c.getModifiers()));
341    }
342
343    /**
344     * checks if a class's member (method, constructor or field) has a
345     * <code>final</code> modifier.
346     */

347    public boolean isFinal(Member JavaDoc member)
348    {
349       return (Modifier.isFinal(member.getModifiers()));
350    }
351
352    /**
353     * checks if the given class is declared as final
354     */

355    public boolean isFinal(Class JavaDoc c)
356    {
357       return (Modifier.isFinal(c.getModifiers()));
358    }
359
360    /**
361     * checks if a class's member (method, constructor or field) has a
362     * <code>public</code> modifier.
363     */

364    public boolean isPublic(Member JavaDoc member)
365    {
366       return (Modifier.isPublic(member.getModifiers()));
367    }
368
369    /**
370     * checks if the given class is declared as <code>public</code>
371     */

372    public boolean isPublic(Class JavaDoc c)
373    {
374       return (Modifier.isPublic(c.getModifiers()));
375    }
376
377    /**
378     * Checks whether all the fields in the class are declared as public.
379     */

380    public boolean isAllFieldsPublic(Class JavaDoc c)
381    {
382       try
383       {
384          Field JavaDoc list[] = c.getFields();
385          for (int i = 0; i < list.length; i++)
386          {
387             if (!Modifier.isPublic(list[i].getModifiers()))
388                return false;
389          }
390       }
391       catch (Exception JavaDoc e)
392       {
393          return false;
394       }
395
396       return true;
397    }
398
399    /**
400     * checks if the given class is declared as abstract
401     */

402    public boolean isAbstract(Class JavaDoc c)
403    {
404       return (Modifier.isAbstract(c.getModifiers()));
405    }
406
407    /**
408     * checks if the given method is declared as abstract
409     */

410    public boolean isAbstract(Method JavaDoc m)
411    {
412       return (Modifier.isAbstract(m.getModifiers()));
413    }
414
415    /**
416     * checks if finder returns the primary key type
417     */

418    public boolean isSingleObjectFinder(EntityMetaData entity,
419                                        Method JavaDoc finder)
420    {
421       return hasPrimaryKeyReturnType(entity, finder);
422    }
423
424    /**
425     * checks if finder method returns either Collection or Enumeration
426     */

427    public boolean isMultiObjectFinder(Method JavaDoc f)
428    {
429       return (java.util.Collection JavaDoc.class.isAssignableFrom(f.getReturnType())
430               || java.util.Enumeration JavaDoc.class.isAssignableFrom(f.getReturnType()));
431    }
432
433    /**
434     * checks the return type of method matches the bean's remote interface
435     */

436    public boolean hasRemoteReturnType(BeanMetaData bean, Method JavaDoc m)
437    {
438       try
439       {
440          Class JavaDoc clazz = classloader.loadClass(bean.getRemote());
441          return m.getReturnType().isAssignableFrom(clazz);
442       }
443       catch (Exception JavaDoc e)
444       {
445          // e.printStackTrace();
446
return false;
447       }
448    }
449
450    /**
451     * checks the return type of method matches the bean's local interface
452     */

453    public boolean hasLocalReturnType(BeanMetaData bean, Method JavaDoc m)
454    {
455       try
456       {
457          Class JavaDoc clazz = classloader.loadClass(bean.getLocal());
458          return m.getReturnType().isAssignableFrom(clazz);
459       }
460       catch (Exception JavaDoc e)
461       {
462          // e.printStackTrace();
463
return false;
464       }
465    }
466
467    /**
468     * checks if a method has a void return type
469     */

470    public boolean hasVoidReturnType(Method JavaDoc method)
471    {
472       return (method.getReturnType() == Void.TYPE);
473    }
474
475    /**
476     * Finds java.ejb.MessageDrivenBean interface from the class
477     */

478    public boolean hasMessageDrivenBeanInterface(Class JavaDoc c)
479    {
480       return isAssignableFrom("javax.ejb.MessageDrivenBean", c);
481    }
482
483    /**
484     * Finds javax.jms.MessageListener interface from the class
485     */

486    public boolean hasMessageListenerInterface(Class JavaDoc c)
487    {
488       return isAssignableFrom("javax.jms.MessageListener", c);
489    }
490
491    /**
492     * Finds java.ejb.SessionBean interface from the class
493     */

494    public boolean hasSessionBeanInterface(Class JavaDoc c)
495    {
496       return isAssignableFrom("javax.ejb.SessionBean", c);
497    }
498
499    /**
500     * Finds java.ejb.EntityBean interface from the class
501     */

502    public boolean hasEntityBeanInterface(Class JavaDoc c)
503    {
504       return isAssignableFrom("javax.ejb.EntityBean", c);
505    }
506
507    /**
508     * Finds java.ejb.EJBObject interface from the class
509     */

510    public boolean hasEJBObjectInterface(Class JavaDoc c)
511    {
512       return isAssignableFrom("javax.ejb.EJBObject", c);
513    }
514
515    /**
516     * Finds java.ejb.EJBLocalObject interface from the class
517     */

518    public boolean hasEJBLocalObjectInterface(Class JavaDoc c)
519    {
520       return isAssignableFrom("javax.ejb.EJBLocalObject", c);
521    }
522
523    /**
524     * Finds javax.ejb.EJBHome interface from the class or its
525     * superclasses
526     */

527    public boolean hasEJBHomeInterface(Class JavaDoc c)
528    {
529       return isAssignableFrom("javax.ejb.EJBHome", c);
530    }
531
532    /**
533     * Finds javax.ejb.EJBLocalHome interface from the class or its
534     * superclasses
535     */

536    public boolean hasEJBLocalHomeInterface(Class JavaDoc c)
537    {
538       return isAssignableFrom("javax.ejb.EJBLocalHome", c);
539    }
540
541    /**
542     * Finds javax.ejb.SessionSynchronization interface from the class
543     */

544    public boolean hasSessionSynchronizationInterface(Class JavaDoc c)
545    {
546       return isAssignableFrom("javax.ejb.SessionSynchronization", c);
547    }
548
549    /**
550     * Checks if a class has a default (no args) constructor
551     */

552    public boolean hasDefaultConstructor(Class JavaDoc c)
553    {
554       try
555       {
556          Constructor JavaDoc ctr = c.getConstructor(new Class JavaDoc[0]);
557       }
558       catch (NoSuchMethodException JavaDoc e)
559       {
560          if( log.isTraceEnabled() )
561          {
562             StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasDefaultConstructor(");
563             tmp.append(") failure, ");
564             Classes.displayClassInfo(c, tmp);
565             log.trace(tmp.toString(), e);
566          }
567          return false;
568       }
569
570       return true;
571    }
572
573    /**
574     * Checks of the class defines a finalize() method
575     */

576    public boolean hasFinalizer(Class JavaDoc c)
577    {
578       try
579       {
580          Method JavaDoc finalizer = c.getDeclaredMethod(FINALIZE_METHOD, new Class JavaDoc[0]);
581       }
582       catch (NoSuchMethodException JavaDoc e)
583       {
584          return false;
585       }
586
587       return true;
588    }
589
590    /**
591     * check if a class has one or more finder methods
592     */

593    public boolean hasFinderMethod(Class JavaDoc c)
594    {
595       Method JavaDoc[] method = c.getMethods();
596       for (int i = 0; i < method.length; ++i)
597       {
598          if (method[i].getName().startsWith("ejbFind"))
599             return true;
600       }
601
602       return false;
603    }
604
605    /**
606     * Check if this is a finder method
607     */

608    public boolean isFinderMethod(Method JavaDoc m)
609    {
610       return (m.getName().startsWith("find"));
611    }
612
613    /**
614     * Check if the given message is the onMessage() method
615     */

616    public boolean isOnMessageMethod(Method JavaDoc m)
617    {
618       if ("onMessage".equals(m.getName()))
619       {
620          Class JavaDoc[] paramTypes = m.getParameterTypes();
621          if (paramTypes.length == 1)
622          {
623             if (Message JavaDoc.class.equals(paramTypes[0]))
624                return true;
625          }
626       }
627       return false;
628    }
629    
630    /**
631     * Checks for at least one non-static field.
632     */

633    public boolean hasANonStaticField(Class JavaDoc c)
634    {
635       try
636       {
637          Field JavaDoc list[] = c.getFields();
638          for (int i = 0; i < list.length; i++)
639          {
640             if (!Modifier.isStatic(list[i].getModifiers()))
641                return true;
642          }
643       }
644       catch (Exception JavaDoc ignored)
645       {
646       }
647
648       return false;
649    }
650
651    /**
652     * Searches for an instance of a public onMessage method from the class
653     */

654    public boolean hasOnMessageMethod(Class JavaDoc c)
655    {
656       Method JavaDoc[] method = c.getMethods();
657       for (int i = 0; i < method.length; ++i)
658       {
659          if (isOnMessageMethod(method[i]))
660             return true;
661       }
662
663       return false;
664    }
665
666    /**
667     * Searches for an instance of a public create method from the class
668     */

669    public boolean hasCreateMethod(Class JavaDoc c)
670    {
671       Method JavaDoc[] method = c.getMethods();
672
673       for (int i = 0; i < method.length; ++i)
674       {
675          if (isCreateMethod(method[i]))
676             return true;
677       }
678
679       return false;
680    }
681
682    /**
683     * Searches for an instance of a public ejbCreate method from the class
684     */

685    public boolean hasEJBCreateMethod(Class JavaDoc c, boolean isSession)
686    {
687       Method JavaDoc[] method = c.getMethods();
688       for (int i = 0; i < method.length; ++i)
689       {
690          if (isEjbCreateMethod(method[i]))
691          {
692             if (!isStatic(method[i]) && !isFinal(method[i])
693                     && ((isSession && hasVoidReturnType(method[i]))
694                     || (!isSession))
695             )
696             {
697                return true;
698             }
699          }
700       }
701
702       return false;
703    }
704
705    /**
706     * Searches the class or interface, and its superclass or superinterface
707     * for a create() method that takes no arguments
708     */

709    public boolean hasDefaultCreateMethod(Class JavaDoc home)
710    {
711       Method JavaDoc[] method = home.getMethods();
712
713       for (int i = 0; i < method.length; ++i)
714       {
715          if (isCreateMethod(method[i]))
716          {
717             Class JavaDoc[] params = method[i].getParameterTypes();
718             if (params.length == 0)
719                return true;
720          }
721       }
722
723       return false;
724    }
725
726    /**
727     * checks if the class has an ejbFindByPrimaryKey method
728     */

729    public boolean hasEJBFindByPrimaryKey(Class JavaDoc c)
730    {
731       Method JavaDoc[] method = c.getMethods();
732       for (int i = 0; i < method.length; ++i)
733       {
734          if (method[i].getName().equals(EJB_FIND_BY_PRIMARY_KEY))
735             return true;
736       }
737
738       return false;
739    }
740
741    /**
742     * checks the return type of method matches the entity's primary key
743     * class or is a super class of the primary key class
744     */

745    public boolean hasPrimaryKeyReturnType(EntityMetaData entity, Method JavaDoc m)
746    {
747       try
748       {
749          return
750                  m.getReturnType().isAssignableFrom(classloader.loadClass(entity.getPrimaryKeyClass()));
751       }
752       catch (ClassNotFoundException JavaDoc cnfe)
753       {
754          // Only check equality
755
return
756                  m.getReturnType().getName().equals(entity.getPrimaryKeyClass());
757       }
758    }
759
760    /**
761     * @return Returns the default create method or <code>null</code>
762     * if none is found
763     */

764    public Method JavaDoc getDefaultCreateMethod(Class JavaDoc c)
765    {
766       Method JavaDoc method = null;
767
768       try
769       {
770          method = c.getMethod(CREATE_METHOD, null);
771       }
772       catch (NoSuchMethodException JavaDoc ignored)
773       {
774       }
775
776       return method;
777    }
778
779    /**
780     * Returns the ejbFindByPrimaryKey method
781     */

782    public Method JavaDoc getEJBFindByPrimaryKey(Class JavaDoc c)
783    {
784       Method JavaDoc[] method = c.getMethods();
785       for (int i = 0; i < method.length; ++i)
786       {
787          if (method[i].getName().equals(EJB_FIND_BY_PRIMARY_KEY))
788             return method[i];
789       }
790
791       return null;
792    }
793
794    /**
795     * returns the ejbFind<METHOD> methods of a bean
796     */

797    public Iterator JavaDoc getEJBFindMethods(Class JavaDoc c)
798    {
799       List JavaDoc finders = new LinkedList JavaDoc();
800       Method JavaDoc[] method = c.getMethods();
801       for (int i = 0; i < method.length; ++i)
802       {
803          if (method[i].getName().startsWith("ejbFind"))
804             finders.add(method[i]);
805       }
806
807       return finders.iterator();
808    }
809
810
811    /**
812     * returns the finder methods of a home interface
813     */

814    public Iterator JavaDoc getFinderMethods(Class JavaDoc home)
815    {
816       List JavaDoc finders = new LinkedList JavaDoc();
817       Method JavaDoc[] method = home.getMethods();
818
819       for (int i = 0; i < method.length; ++i)
820       {
821          if (method[i].getName().startsWith("find"))
822             finders.add(method[i]);
823       }
824
825       return finders.iterator();
826    }
827
828    /**
829     * Returns the onMessage(...) method of a bean
830     */

831    public Iterator JavaDoc getOnMessageMethods(Class JavaDoc c)
832    {
833       List JavaDoc onMessages = new LinkedList JavaDoc();
834       Method JavaDoc[] method = c.getMethods();
835
836       for (int i = 0; i < method.length; ++i)
837       {
838          if (isOnMessageMethod(method[i]))
839             onMessages.add(method[i]);
840       }
841
842       return onMessages.iterator();
843    }
844
845    /**
846     * Returns the ejbCreate(...) methods of a bean
847     */

848    public Iterator JavaDoc getEJBCreateMethods(Class JavaDoc c)
849    {
850       List JavaDoc ejbCreates = new LinkedList JavaDoc();
851       Method JavaDoc[] method = c.getMethods();
852
853       for (int i = 0; i < method.length; ++i)
854       {
855          if (isEjbCreateMethod(method[i]))
856             ejbCreates.add(method[i]);
857       }
858
859       return ejbCreates.iterator();
860    }
861
862    /**
863     * Return all create methods of a class
864     */

865    public Iterator JavaDoc getCreateMethods(Class JavaDoc c)
866    {
867       List JavaDoc creates = new LinkedList JavaDoc();
868       Method JavaDoc[] method = c.getMethods();
869
870       for (int i = 0; i < method.length; ++i)
871       {
872          if (isCreateMethod(method[i]))
873             creates.add(method[i]);
874       }
875
876       return creates.iterator();
877    }
878
879    /**
880     * Check whether a class has more than one create method
881     */

882    public boolean hasMoreThanOneCreateMethods(Class JavaDoc c)
883    {
884       int count = 0;
885       Method JavaDoc[] method = c.getMethods();
886       for (int i = 0; i < method.length; ++i)
887       {
888          if (isCreateMethod(method[i]))
889          {
890             ++count;
891          }
892       }
893
894       return (count > 1);
895    }
896
897    /**
898     * Check whether two given methods declare the same Exceptions
899     */

900    public boolean hasMatchingExceptions(Method JavaDoc source, Method JavaDoc target)
901    {
902       // target must be a superset of source
903
Class JavaDoc[] a = source.getExceptionTypes();
904       Class JavaDoc[] b = target.getExceptionTypes();
905       Class JavaDoc rteClass = null;
906       Class JavaDoc errorClass = null;
907
908       try
909       {
910          rteClass = classloader.loadClass("java.lang.RuntimeException");
911          errorClass = classloader.loadClass("java.lang.Error");
912       }
913       catch (ClassNotFoundException JavaDoc cnfe)
914       {
915          // Ignored, if this happens we have more serious problems :)
916
}
917
918       for (int i = 0; i < a.length; ++i)
919       {
920          if (rteClass.isAssign