[jboss-cvs] JBossAS SVN: r67987 - trunk/ejb3/src/main/org/jboss/ejb3.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Dec 6 06:06:34 EST 2007


Author: ALRubinger
Date: 2007-12-06 06:06:34 -0500 (Thu, 06 Dec 2007)
New Revision: 67987

Modified:
   trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
Log:
[JBCTS-705][JBCTS-726] Bug Fixes for proper handling/definitions of 3.0 and 2.1 Views

Modified: trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java	2007-12-06 11:05:17 UTC (rev 67986)
+++ trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java	2007-12-06 11:06:34 UTC (rev 67987)
@@ -23,6 +23,8 @@
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -82,72 +84,88 @@
     * @return       the local interfaces of the container or an empty array
     */
    public static Class<?>[] getLocalAndBusinessLocalInterfaces(Container container)
-   {
+   {      
+      // Initialize
+      Set<Class<?>> localAndBusinessLocalInterfaces = new HashSet<Class<?>>();
+      
+      // Obtain Bean Class
+      Class<?> beanClass = container.getBeanClass();
+      
       // Obtain @Local
-      Local localAnnotation = ((EJBContainer) container).getAnnotation(javax.ejb.Local.class);
+      Local localAnnotation = ((EJBContainer) container).getAnnotation(Local.class);
 
+      // Obtain @LocalHome
+      LocalHome localHomeAnnotation = ((EJBContainer)container).getAnnotation(LocalHome.class);
+      
       // Obtain @Remote
       Remote remoteAnnotation = ((EJBContainer) container).getAnnotation(Remote.class);
+      
+      // Obtain Remote and Business Remote interfaces
+      Class<?>[] remoteAndBusinessRemoteInterfaces = ProxyFactoryHelper.getRemoteAndBusinessRemoteInterfaces(container);
 
-      // Obtain all business interfaces
-      Set<Class<?>> businessInterfaces = getBusinessInterfaces(container.getBeanClass());
-
-      // JIRA EJBTHREE-1062
-      // EJB 3 4.6.6
-      // If no @Local is defined on the bean class, and the bean class implements a single interface, 
-      // this interface is a local business interface unless denoted otherwise
-      if (localAnnotation == null && container.getBeanClass().getInterfaces().length == 1)
+      // Obtain all business interfaces from the bean class
+      Set<Class<?>> businessInterfacesImplementedByBeanClass = ProxyFactoryHelper.getBusinessInterfaces(beanClass);
+      
+      // Obtain all business interfaces directly implemented by the bean class (not including supers)
+      Set<Class<?>> businessInterfacesDirectlyImplementedByBeanClass = ProxyFactoryHelper.getBusinessInterfaces(beanClass,false);
+      
+      // EJBTHREE-1127
+      // Determine local interface from return value of "create" in Local Home
+      if(localHomeAnnotation!=null)
       {
+         localAndBusinessLocalInterfaces.add(ProxyFactoryHelper.getTypeFromCreateMethod(localHomeAnnotation.value()));
+      }
+      
+      // For each of the business interfaces implemented by the bean class
+      for (Class<?> clazz : businessInterfacesImplementedByBeanClass)
+      {
+         // If @Local is on the interface
+         if (clazz.isAnnotationPresent(Local.class))
+         {
+            // Add to the list of locals
+            localAndBusinessLocalInterfaces.add(clazz);
+         }
+      }
+      
+      // EJBTHREE-1062
+      // EJB 3 Core Specification 4.6.6
+      // If bean class implements a single interface, that interface is assumed to be the 
+      // business interface of the bean. This business interface will be a local interface unless the
+      // interface is designated as a remote business interface by use of the Remote 
+      // annotation on the bean class or interface or by means of the deployment descriptor. 
+      if (businessInterfacesDirectlyImplementedByBeanClass.size() == 1 && localAndBusinessLocalInterfaces.size()==0)
+      {
          // Obtain the implemented interface
-         Class<?> singleInterface =  container.getBeanClass().getInterfaces()[0];
+         Class<?> singleInterface = businessInterfacesDirectlyImplementedByBeanClass.iterator().next();
          
          // If not explicitly marked as @Remote, and is a valid business interface
-         if (remoteAnnotation==null
-               && businessInterfaces.contains(singleInterface))
+         if (remoteAnnotation == null && singleInterface.getAnnotation(Remote.class)==null)
          {
-            // Return the implemented interface  
-            return container.getBeanClass().getInterfaces();            
+            // Return the implemented interface, adding to the container  
+            Class<?>[] returnValue = new Class[]{singleInterface};
+            Local li = new LocalImpl(returnValue);
+            ((EJBContainer) container).getAnnotations().addClassAnnotation(Local.class, li);
+            return returnValue;
          }
       }
-
-      // If @Local is present
+      
+      // @Local was defined
       if (localAnnotation != null)
       {
-         // If @Local.value is defined
-         if (localAnnotation.value().length > 0)
+         // If @Local has no value or empty value
+         if(localAnnotation.value()==null || localAnnotation.value().length==0)
          {
-            // Return the value array defined
-            return localAnnotation.value();
-         }
-  
-         // If @Local is defined with no value and there are no business interfaces
-         if (businessInterfaces.size() == 0){
-            throw new RuntimeException("Use of empty @Local on bean " + container.getEjbName() + " and there are no valid business interfaces");            
-         }
-         // If @Local is defined with no value and there is more than one business interface 
-         else if (businessInterfaces.size() > 0)
-         {
-            // Define list to hold all interfaces implemented directly by bean class that are valid business interfaces
-            List<Class<?>> beanClassBusinessInterfaces = new ArrayList<Class<?>>();
-            // All business interfaces
-            for(Class<?> businessInterface : businessInterfaces)
+            // If @Local is defined with no value and there are no business interfaces
+            if (businessInterfacesImplementedByBeanClass.size() == 0)
             {
-               // All interfaces directly implemented by bean class
-               for(Class<?> beanClassInterface : container.getBeanClass().getInterfaces())
-               {
-                  // If interface directly implemented by bean class is business interface
-                  if(businessInterface.equals(beanClassInterface))
-                  {
-                     // Add to list
-                     beanClassBusinessInterfaces.add(businessInterface);
-                  }
-               }
+               throw new RuntimeException("Use of empty @Local on bean " + container.getEjbName()
+                     + " and there are no valid business interfaces");
             }
-            
             // If more than one business interface is directly implemented by the bean class
-            if(beanClassBusinessInterfaces.size()>1)
+            else if (businessInterfacesImplementedByBeanClass.size() > 1)
             {
-               throw new RuntimeException("Use of empty @Local on bean " + container.getEjbName() + " with more than one default interface " + beanClassBusinessInterfaces);
+               throw new RuntimeException("Use of empty @Local on bean " + container.getEjbName()
+                     + " with more than one default interface " + businessInterfacesImplementedByBeanClass);
             }
             // JIRA EJBTHREE-1062
             // EJB 3 4.6.6
@@ -158,104 +176,80 @@
                // If not explicitly marked as @Remote
                if (remoteAnnotation == null)
                {
-                  // Return the implemented interface  
-                  return beanClassBusinessInterfaces.toArray(new Class<?>[]
+                  // Return the implemented interface and add to container
+                  Class<?>[] returnValue = businessInterfacesImplementedByBeanClass.toArray(new Class<?>[]
                   {});
+                  Local li = new LocalImpl(returnValue);
+                  ((EJBContainer) container).getAnnotations().addClassAnnotation(Local.class, li);
+                  return returnValue;
                }
             }
          }
-         
-         Class<?>[] rtn = {(Class<?>) businessInterfaces.iterator().next()};
-         localAnnotation = new LocalImpl(rtn);
-         ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
-         return rtn;
-      }
-
-      Class<?> beanClass = container.getBeanClass();
-      String endpoint = getEndpointInterface(container);
-      Class<?>[] remoteInterfaces = getRemoteAndBusinessRemoteInterfaces(container);
-      
-      // EJBTHREE-1127
-      // Determine remote interface from return value of "create" in Local Home
-      LocalHome localHomeAnnotation = ((EJBContainer)container).getAnnotation(LocalHome.class);
-      if(localHomeAnnotation!=null)
-      {
-         localAnnotation = new LocalImpl(new Class<?>[]
-         {ProxyFactoryHelper.getTypeFromCreateMethod(localHomeAnnotation.value())});
-      }
-
-      if (localAnnotation == null && remoteInterfaces.length == 0 && endpoint == null
-            && (beanClass.getInterfaces() == null || beanClass.getInterfaces().length == 0))
-         throw new RuntimeException(
-               "Bean Class "
-                     + beanClass.getName()
-                     + " has no local, webservice, or remote interfaces defined and does not implement at least one business interface: "
-                     + container.getEjbName());
-
-      // introspect implemented interfaces.
-      if (localAnnotation == null)
-      {
-         Set<Class<?>> intfs = getBusinessInterfaces(beanClass);
-         ArrayList<Class<?>> locals = new ArrayList<Class<?>>();
-         for (Class<?> clazz : intfs)
+         // @Local has value 
+         else
          {
-            if (clazz.isAnnotationPresent(javax.ejb.Local.class))
+            // For each of the interfaces in @Local.value
+            for (Class<?> clazz : localAnnotation.value())
             {
-               locals.add(clazz);
+               // Add to the list of locals
+               localAndBusinessLocalInterfaces.add(clazz);
             }
-         }
-         if (locals.size() > 0)
-         {
-            localAnnotation = new LocalImpl(locals.toArray(new Class[]{}));
-            ((Advisor) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
-            //return li.value(); ALR Removed (EJBTHREE-751)
-         }
+            
+            // For each of the business interfaces implemented by the bean class
+            for (Class<?> clazz : businessInterfacesImplementedByBeanClass)
+            {
+               // If @Local is on the interface
+               if (clazz.isAnnotationPresent(Local.class))
+               {
+                  // Add to the list of locals
+                  localAndBusinessLocalInterfaces.add(clazz);
+               }
+            }
+         }         
       }
-
-      // no @Local interfaces implemented
-      if (localAnnotation == null)
+      
+      // If local interfaces have been defined/discovered
+      if (localAndBusinessLocalInterfaces.size() > 0)
       {
-         // search for default
-         Set<Class<?>> interfaces = getBusinessInterfaces(beanClass);
-         if (interfaces.size() != 1) return new Class[]{}; // indeterminate
-
-         Class<?> intf = interfaces.iterator().next();
-         if (remoteInterfaces != null)
+         // Check to ensure @Local and @Remote are not defined on the same interface
+         // EJBTHREE-751
+         for (Class<?> remoteInterface : remoteAndBusinessRemoteInterfaces)
          {
-            for (Class<?> rintf : remoteInterfaces)
+            for (Class<?> localInterface : localAndBusinessLocalInterfaces)
             {
-               if (intf.getName().equals(rintf.getName()))
+               if (localInterface.equals(remoteInterface))
                {
-                  return new Class[]{};
+                  throw new RuntimeException("@Remote and @Local may not both be specified on the same interface \""
+                        + remoteInterface.toString() + "\" per EJB3 Spec 4.6.7, Bullet 5.4");
                }
             }
          }
-
-         if (intf.getName().equals(endpoint))
-            return new Class[]{};
-
-         Class<?>[] rtn = {intf};
+         
+         // Return local interfaces, first adding to the container
+         Class<?>[] rtn = localAndBusinessLocalInterfaces.toArray(new Class<?>[]
+         {});
          localAnnotation = new LocalImpl(rtn);
-         ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
+         ((EJBContainer) container).getAnnotations().addClassAnnotation(Local.class, localAnnotation);
          return rtn;
       }
+      // If no local interfaces have been defined/discovered
+      else
+      {
+         // Obtain WS Endpoint
+         String endpoint = ProxyFactoryHelper.getEndpointInterface(container);
 
+         // If neither WS Endpoint or remotes are defined
+         if (remoteAndBusinessRemoteInterfaces.length == 0 && endpoint == null)
+            throw new RuntimeException(
+                  "Bean Class "
+                        + beanClass.getName()
+                        + " has no local, webservice, or remote interfaces defined and does not implement at least one business interface: "
+                        + container.getEjbName());
 
-      // Check to ensure @Local and @Remote are not defined on the same interface
-      // JIRA EJBTHREE-751
-      for (Class<?> remoteInterface : remoteInterfaces)
-      {
-         for (Class<?> localInterface : localAnnotation.value())
-         {
-            if (localInterface.equals(remoteInterface))
-            {
-               throw new RuntimeException("@Remote and @Local may not both be specified on the same interface \""
-                     + remoteInterface.toString() + "\" per EJB3 Spec 4.6.7, Bullet 5.4");
-            }
-         }
       }
-
-      return localAnnotation.value();
+      
+      // No local or business local interfaces discovered
+      return new Class<?>[]{};
    }
 
    /**
@@ -600,59 +594,91 @@
    public static Class<?>[] getRemoteAndBusinessRemoteInterfaces(Container container)
    {
       // Initialize
-      Remote ri = (Remote) ((Advisor) container).resolveAnnotation(Remote.class);
-      RemoteHome remoteHomeAnnotation = ((EJBContainer)container).getAnnotation(RemoteHome.class);
-      
-      if (ri == null)
+      Remote remoteAnnotation = ((EJBContainer) container).getAnnotation(Remote.class);
+      RemoteHome remoteHomeAnnotation = ((EJBContainer) container).getAnnotation(RemoteHome.class);
+      Set<Class<?>> remoteAndRemoteBusinessInterfaces = new HashSet<Class<?>>();
+      Class<?> beanClass = container.getBeanClass();
+
+      // Obtain business interfaces
+      Class<?>[] businessInterfaces = ProxyFactoryHelper.getBusinessInterfaces(beanClass).toArray(new Class[]
+      {});
+
+      // EJBTHREE-1127
+      // Determine remote interface from return value of "create" in Remote Home
+      if (remoteHomeAnnotation != null)
       {
-         Class<?> beanClass = container.getBeanClass();
-         Class<?>[] intfs = ProxyFactoryHelper.getBusinessInterfaces(beanClass).toArray(new Class[]{});
-         Set<Class<?>> remotes = new HashSet<Class<?>>();
-         for (Class<?> clazz : intfs)
+         remoteAndRemoteBusinessInterfaces
+               .add(ProxyFactoryHelper.getTypeFromCreateMethod(remoteHomeAnnotation.value()));
+      }
+
+      // If @Remote is not defined
+      if (remoteAnnotation == null)
+      {
+         // For each of the business interfaces
+         for (Class<?> clazz : businessInterfaces)
          {
+            // If @Remote is on the business interface
             if (clazz.isAnnotationPresent(Remote.class))
             {
-               remotes.add(clazz);
+               // Add to the list of remotes
+               remoteAndRemoteBusinessInterfaces.add(clazz);
             }
          }
-         
-         // EJBTHREE-1127
-         // Determine remote interface from return value of "create" in Remote Home
-         if(remoteHomeAnnotation!=null)
+      }
+      // @Remote was defined
+      else
+      {
+         // @Remote declares interfaces, add these
+         if (remoteAnnotation.value().length > 0)
          {
-            remotes.add(ProxyFactoryHelper.getTypeFromCreateMethod(remoteHomeAnnotation.value()));
+            for (Class<?> clazz : remoteAnnotation.value())
+            {
+               remoteAndRemoteBusinessInterfaces.add(clazz);
+            }
          }
-         
-         if (remotes.size() > 0)
+         // @Remote is empty
+         else
          {
-            intfs = remotes.toArray(new Class[remotes.size()]);
-            ri = new RemoteImpl(intfs);
-            ((Advisor) container).getAnnotations().addClassAnnotation(Remote.class, ri);
-            return ri.value();
+            // No business interfaces were defined on the bean
+            if (businessInterfaces.length == 0)
+            {
+               throw new RuntimeException("Use of empty @Remote on bean " + container.getEjbName()
+                     + " and there are no valid business interfaces");
+            }
+
+            // More than one default interface, cannot be marked as @Remote
+            else if (businessInterfaces.length > 1)
+            {
+               throw new RuntimeException("Use of empty @Remote on bean " + container.getEjbName()
+                     + " with more than one default interface " + businessInterfaces);
+            }
+            // Only one default interface, mark as @Remote and return
+            else
+            {
+               Class<?>[] rtn =
+               {(Class<?>) businessInterfaces[0]};
+               remoteAnnotation = new RemoteImpl(rtn);
+               ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Remote.class, remoteAnnotation);
+               return rtn;
+            }
          }
+      }
 
+      // If remotes were found
+      if (remoteAndRemoteBusinessInterfaces.size() > 0)
+      {
+         // Set interfaces and return
+         Class<?>[] remotesArray = remoteAndRemoteBusinessInterfaces
+               .toArray(new Class[remoteAndRemoteBusinessInterfaces.size()]);
+         remoteAnnotation = new RemoteImpl(remotesArray);
+         ((Advisor) container).getAnnotations().addClassAnnotation(Remote.class, remoteAnnotation);
+         return remoteAnnotation.value();
+      }
+      // No remotes were found
+      else
+      {
          return new Class<?>[]{};
       }
-
-      if (ri.value().length > 0) return ri.value();
-
-      // Obtain business interfaces
-      Set<Class<?>> remoteBusinessInterfaces = getBusinessInterfaces(container.getBeanClass());
-
-      // We have an emtpy @Remote annotated bean class
-      if (remoteBusinessInterfaces.size() == 0)
-         throw new RuntimeException("Use of empty @Remote on bean " + container.getEjbName()
-               + " and there are no valid business interfaces");
-      // More than one default interface
-      if (remoteBusinessInterfaces.size() > 1)
-         throw new RuntimeException("Use of empty @Remote on bean " + container.getEjbName()
-               + " with more than one default interface " + remoteBusinessInterfaces);
-      // Only one default interface
-      Class<?>[] rtn =
-      {(Class<?>) remoteBusinessInterfaces.iterator().next()};
-      ri = new RemoteImpl(rtn);
-      ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Remote.class, ri);
-      return rtn;
    }
    
    




More information about the jboss-cvs-commits mailing list