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.isAssignableFrom(a[i])
921                  || errorClass.isAssignableFrom(a[i]))
922          {
923             // Skip over subclasses of java.lang.RuntimeException and
924
// java.lang.Error
925
continue;
926          }
927
928          boolean found = false;
929          for (int j = 0; j < b.length; ++j)
930          {
931             if (b[j].isAssignableFrom(a[i]))
932             {
933                found = true;
934                break;
935             }
936          }
937
938          if (!found)
939          {
940             return false;
941          }
942       }
943
944       return true;
945    }
946
947    /**
948     * Check if a class (or its superclasses) declare a given method
949     */

950    public boolean hasMatchingMethod(Class JavaDoc bean, Method JavaDoc method)
951    {
952       try
953       {
954          bean.getMethod(method.getName(), method.getParameterTypes());
955          return true;
956       }
957       catch (NoSuchMethodException JavaDoc e)
958       {
959          if( log.isTraceEnabled() )
960          {
961             StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasMatchingMethod(");
962             tmp.append(method.toString());
963             tmp.append(") failure, ");
964             Classes.displayClassInfo(bean, tmp);
965             log.trace(tmp.toString(), e);
966          }
967          return false;
968       }
969    }
970
971    /**
972     * Check whether two methods have the same return type
973     */

974    public boolean hasMatchingReturnType(Method JavaDoc a, Method JavaDoc b)
975    {
976       return (a.getReturnType() == b.getReturnType());
977    }
978
979    /**
980     * Check whether a bean has a matching ejbPostCreate methods for
981     * a given ejbCreate method
982     */

983    public boolean hasMatchingEJBPostCreate(Class JavaDoc bean, Method JavaDoc create)
984    {
985       try
986       {
987          return (bean.getMethod(getMatchingEJBPostCreateName(create.getName()),
988                  create.getParameterTypes()) != null);
989       }
990       catch (NoSuchMethodException JavaDoc e)
991       {
992          if( log.isTraceEnabled() )
993          {
994             StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasMatchingEJBPostCreate(");
995             tmp.append(create.toString());
996             tmp.append(") failure, ");
997             Classes.displayClassInfo(bean, tmp);
998             log.trace(tmp.toString(), e);
999          }
1000         return false;
1001      }
1002   }
1003
1004   public boolean hasMatchingEJBCreate(Class JavaDoc bean, Method JavaDoc create)
1005   {
1006      try
1007      {
1008         return (bean.getMethod(getMatchingEJBCreateName(create.getName()), create.getParameterTypes()) != null);
1009      }
1010      catch (NoSuchMethodException JavaDoc e)
1011      {
1012         if( log.isTraceEnabled() )
1013         {
1014            StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasMatchingEJBCreate(");
1015            tmp.append(create.toString());
1016            tmp.append(") failure, ");
1017            Classes.displayClassInfo(bean, tmp);
1018            log.trace(tmp.toString(), e);
1019         }
1020         return false;
1021      }
1022   }
1023
1024   public Method JavaDoc getMatchingEJBPostCreate(Class JavaDoc bean, Method JavaDoc create)
1025   {
1026      try
1027      {
1028         return bean.getMethod(getMatchingEJBPostCreateName(create.getName()), create.getParameterTypes());
1029      }
1030      catch (NoSuchMethodException JavaDoc e)
1031      {
1032         return null;
1033      }
1034   }
1035
1036   public Method JavaDoc getMatchingEJBCreate(Class JavaDoc bean, Method JavaDoc create)
1037   {
1038      try
1039      {
1040         return bean.getMethod(getMatchingEJBCreateName(create.getName()), create.getParameterTypes());
1041      }
1042      catch (NoSuchMethodException JavaDoc e)
1043      {
1044         return null;
1045      }
1046   }
1047
1048   public boolean hasMatchingEJBFind(Class JavaDoc bean, Method JavaDoc finder)
1049   {
1050      try
1051      {
1052         String JavaDoc methodName = "ejbF" + finder.getName().substring(1);
1053         return (bean.getMethod(methodName, finder.getParameterTypes()) != null);
1054      }
1055      catch (NoSuchMethodException JavaDoc e)
1056      {
1057         if( log.isTraceEnabled() )
1058         {
1059            StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasMatchingEJBFind(");
1060            tmp.append(finder.toString());
1061            tmp.append(") failure, ");
1062            Classes.displayClassInfo(bean, tmp);
1063            log.trace(tmp.toString(), e);
1064         }
1065         return false;
1066      }
1067   }
1068
1069   public Method JavaDoc getMatchingEJBFind(Class JavaDoc bean, Method JavaDoc finder)
1070   {
1071      try
1072      {
1073         String JavaDoc methodName = "ejbF" + finder.getName().substring(1);
1074         return bean.getMethod(methodName, finder.getParameterTypes());
1075      }
1076      catch (NoSuchMethodException JavaDoc e)
1077      {
1078         return null;
1079      }
1080   }
1081
1082   public boolean hasMatchingEJBHome(Class JavaDoc bean, Method JavaDoc home)
1083   {
1084      try
1085      {
1086         return (bean.getMethod(getMatchingEJBHomeName(home.getName()), home.getParameterTypes()) != null);
1087      }
1088      catch (NoSuchMethodException JavaDoc e)
1089      {
1090         if( log.isTraceEnabled() )
1091         {
1092            StringBuffer JavaDoc tmp = new StringBuffer JavaDoc("hasMatchingEJBHome(");
1093            tmp.append(home.toString());
1094            tmp.append(") failure, ");
1095            Classes.displayClassInfo(bean, tmp);
1096            log.trace(tmp.toString(), e);
1097         }
1098         return false;
1099      }
1100   }
1101
1102
1103/*
1104 *************************************************************************
1105 *
1106 * PROTECTED INSTANCE METHODS
1107 *
1108 *************************************************************************
1109 */

1110
1111   protected void fireSpecViolationEvent(BeanMetaData bean, Section section)
1112   {
1113      fireSpecViolationEvent(bean, null /* method */, section);
1114   }
1115
1116   protected void fireSpecViolationEvent(BeanMetaData bean, Method JavaDoc method,
1117                                         Section section)
1118   {
1119      VerificationEvent event = factory.createSpecViolationEvent(context,
1120              section);
1121      event.setName(bean.getEjbName());
1122      event.setMethod(method);
1123
1124      context.fireSpecViolation(event);
1125   }
1126
1127   protected final void fireBeanVerifiedEvent(BeanMetaData bean)
1128   {
1129      fireBeanVerifiedEvent(bean, null);
1130   }
1131
1132   protected final void fireBeanVerifiedEvent(BeanMetaData bean, String JavaDoc msg)
1133   {
1134      VerificationEvent event = factory.createBeanVerifiedEvent(context);
1135      event.setName(bean.getEjbName());
1136
1137      if (msg != null)
1138      {
1139         event.setMessage(msg);
1140      }
1141
1142      context.fireBeanChecked(event);
1143   }
1144
1145/*
1146 *************************************************************************
1147 *
1148 * IMPLEMENTS VERIFICATIONSTRATEGY INTERFACE
1149 *
1150 *************************************************************************
1151 */

1152
1153   /**
1154    * Provides an empty default implementation for EJB 1.1 verifier (message
1155    * beans are for EJB 2.0 and greater only).
1156    *
1157    * @param bean the message bean to verify
1158    */

1159   public void checkMessageBean(MessageDrivenMetaData bean)
1160   {
1161   }
1162
1163   /**
1164    * Returns the context object reference for this strategy implementation.
1165    *
1166    * @return the client object using this algorithm implementation
1167    */

1168   public StrategyContext getContext()
1169   {
1170      return context;
1171   }
1172
1173
1174/*
1175 *************************************************************************
1176 *
1177 * PRIVATE INSTANCE METHODS
1178 *
1179 *************************************************************************
1180 */

1181
1182   protected boolean isRMIIIOPType(Class JavaDoc type)
1183   {
1184      /*
1185       * Java Language to IDL Mapping
1186       *
1187       * ftp://ftp.omg.org/pub/docs/ptc/99-03-09.pdf
1188       *
1189       * A conforming RMI/IDL type is a Java type whose values may be
1190       * transmitted across an RMI/IDL remote interface at run-time.
1191       * A Java data type is a conforming RMI/IDL type if it is:
1192       *
1193       * - one of the Java primitive types (see Primitive Types on
1194       * page 28-2).
1195       * - a conforming remote interface (as defined in RMI/IDL
1196       * Remote Interfaces on page 28-2).
1197       * - a conforming value type (as defined in RMI/IDL Value Types
1198       * on page 28-4).
1199       * - an array of conforming RMI/IDL types (see RMI/IDL Arrays on
1200       * page 28-5).
1201       * - a conforming exception type (see RMI/IDL Exception Types on
1202       * page 28-5).
1203       * - a conforming CORBA object reference type (see CORBA Object
1204       * Reference Types on page 28-6).
1205       * - a conforming IDL entity type see IDL Entity Types on page
1206       * 28-6).
1207       */

1208
1209      /*
1210       * Primitive types.
1211       *
1212       * Spec 28.2.2
1213       */

1214      if (type.isPrimitive())
1215         return true;
1216
1217      /*
1218       * Conforming array.
1219       *
1220       * Spec 28.2.5
1221       */

1222      if (type.isArray())
1223         return isRMIIIOPType(type.getComponentType());
1224
1225      /*
1226       * Conforming CORBA reference type
1227       *
1228       * Spec 28.2.7
1229       */

1230      if (org.omg.CORBA.Object JavaDoc.class.isAssignableFrom(type))
1231         return true;
1232
1233      /*
1234       * Conforming IDL Entity type
1235       *
1236       * Spec 28.2.8
1237       */

1238      if (org.omg.CORBA.portable.IDLEntity JavaDoc.class.isAssignableFrom(type))
1239         return true;
1240
1241      /*
1242       * Conforming remote interface.
1243       *
1244       * Spec 28.2.3
1245       */

1246      if (isRMIIDLRemoteInterface(type))
1247         return true;
1248
1249      /*
1250       * Conforming exception.
1251       *
1252       * Spec 28.2.6
1253       */

1254      if (isRMIIDLExceptionType(type))
1255         return true;
1256
1257      /*
1258       * Conforming value type.
1259       *
1260       * Spec 28.2.4
1261       */

1262      if (isRMIIDLValueType(type))
1263         return true;
1264
1265      return false;
1266   }
1267
1268   private boolean isRMIIDLRemoteInterface(Class JavaDoc type)
1269   {
1270      /*
1271       * If does not implement java.rmi.Remote, cannot be valid RMI-IDL
1272       * remote interface.
1273       */

1274
1275      if (!java.rmi.Remote JavaDoc.class.isAssignableFrom(type))
1276         return false;
1277
1278      Iterator JavaDoc methodIterator = Arrays.asList(type.getMethods()).iterator();
1279      while (methodIterator.hasNext())
1280      {
1281         Method JavaDoc m = (Method JavaDoc)methodIterator.next();
1282
1283         /*
1284          * All methods in the interface MUST throw
1285          * java.rmi.RemoteException or its subclass.
1286          *
1287          * Spec 28.2.3 (2)
1288          */

1289         if (!throwsRemoteException(m))
1290            return false;
1291
1292         /*
1293          * All checked exception classes used in method declarations
1294          * (other than java.rmi.RemoteException) MUST be conforming
1295          * RMI/IDL exception types.
1296          *
1297          * Spec 28.2.3 (4)
1298          */

1299         Iterator JavaDoc it = Arrays.asList(m.getExceptionTypes()).iterator();
1300         while (it.hasNext())
1301         {
1302            Class JavaDoc exception = (Class JavaDoc)it.next();
1303            if (!isRMIIDLExceptionType(exception))
1304               return false;
1305         }
1306      }
1307
1308      /*
1309       * The constant values defined in the interface MUST be
1310       * compile-time types of RMI/IDL primitive types or String.
1311       *
1312       * Spec 28.2.3 (6)
1313       */

1314      Iterator JavaDoc fieldIterator = Arrays.asList(type.getFields()).iterator();
1315      while (fieldIterator.hasNext())
1316      {
1317         Field JavaDoc f = (Field JavaDoc)fieldIterator.next();
1318
1319         if (f.getType().isPrimitive())
1320            continue;
1321
1322         if (f.getType().equals(java.lang.String JavaDoc.class))
1323            continue;
1324
1325         return false;
1326      }
1327
1328      return true;
1329   }
1330
1331   private boolean isRMIIDLExceptionType(Class JavaDoc type)
1332   {
1333      /*
1334       * A conforming RMI/IDL Exception class MUST be a checked
1335       * exception class and MUST be a valid RMI/IDL value type.
1336       *
1337       * Spec 28.2.6
1338       */

1339      if (!Throwable JavaDoc.class.isAssignableFrom(type))
1340         return false;
1341
1342      if (Error JavaDoc.class.isAssignableFrom(type))
1343         return false;
1344
1345// 28.3.4.4 (6) java.rmi.RemoteException and its subclasses, and unchecked
1346
// exception classes, are assumed to be mapped to the implicit
1347
// CORBA system exception, and are therefore not explicitly
1348
// declared in OMG IDL.
1349
//
1350
// if (RuntimeException.class.isAssignableFrom(type))
1351
// return false;
1352

1353      if (!isRMIIDLValueType(type))
1354         return false;
1355
1356      return true;
1357   }
1358
1359   protected boolean isRMIIDLValueType(Class JavaDoc type)
1360   {
1361      /*
1362       * A value type MUST NOT either directly or indirectly implement the
1363       * java.rmi.Remote interface.
1364       *
1365       * Spec 28.2.4 (4)
1366       */

1367      if (java.rmi.Remote JavaDoc.class.isAssignableFrom(type))
1368         return false;
1369
1370      /*
1371       * If class is a non-static inner class then its containing class must
1372       * also be a conforming RMI/IDL value type.
1373       *
1374       * Spec 28.2.4 (3)
1375       */

1376      if (type.getDeclaringClass() != null && !isStatic(type))
1377      {
1378         if (!isRMIIDLValueType(type.getDeclaringClass()))
1379            return false;
1380      }
1381
1382      return true;
1383   }
1384
1385   private String JavaDoc getMatchingEJBHomeName(String JavaDoc homeName)
1386   {
1387      return "ejbHome" + homeName.substring(0, 1).toUpperCase() +
1388              homeName.substring(1);
1389   }
1390
1391   private String JavaDoc getMatchingEJBCreateName(String JavaDoc createName)
1392   {
1393      return "ejb" + createName.substring(0, 1).toUpperCase() +
1394              createName.substring(1);
1395   }
1396
1397   private String JavaDoc getMatchingEJBPostCreateName(String JavaDoc createName)
1398   {
1399      int createIdx = createName.indexOf("Create");
1400      return "ejbPost" + createName.substring(createIdx >= 0 ? createIdx : 0);
1401   }
1402
1403/*
1404 *************************************************************************
1405 *
1406 * STRING CONSTANTS
1407 *
1408 *************************************************************************
1409 */

1410
1411   /*
1412    * Ejb-jar DTD
1413    */

1414   public final static String JavaDoc BEAN_MANAGED_TX =
1415           "Bean";
1416
1417   public final static String JavaDoc CONTAINER_MANAGED_TX =
1418           "Container";
1419
1420   public final static String JavaDoc STATEFUL_SESSION =
1421           "Stateful";
1422
1423   public final static String JavaDoc STATELESS_SESSION =
1424           "Stateless";
1425
1426   /*
1427    * method names
1428    */

1429   private final static String JavaDoc EJB_FIND_BY_PRIMARY_KEY =
1430           "ejbFindByPrimaryKey";
1431
1432   protected final static String JavaDoc EJB_CREATE_METHOD =
1433           "ejbCreate";
1434
1435   protected final static String JavaDoc EJB_REMOVE_METHOD =
1436           "ejbRemove";
1437
1438   private final static String JavaDoc EJB_POST_CREATE_METHOD =
1439           "ejbPostCreate";
1440
1441   protected final static String JavaDoc CREATE_METHOD =
1442           "create";
1443
1444   protected final static String JavaDoc EJB_HOME_METHOD =
1445           "ejbHome";
1446
1447   protected final static String JavaDoc EJB_SELECT_METHOD =
1448           "ejbSelect";
1449
1450   private final static String JavaDoc FINALIZE_METHOD =
1451           "finalize";
1452
1453   private final static String JavaDoc REMOVE_METHOD =
1454           "remove";
1455
1456   private final static String JavaDoc GET_HOME_HANDLE_METHOD =
1457           "getHomeHandle";
1458
1459   private final static String JavaDoc GET_EJB_METADATA_METHOD =
1460           "getEJBMetaData";
1461}
1462
1463/*
1464vim:ts=3:sw=3:et
1465*/

1466
Popular Tags