[jboss-cvs] JBossAS SVN: r67782 - branches/JBPAPP_4_2_0_GA_CP/ejb3/src/main/org/jboss/ejb3.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Dec 3 11:49:43 EST 2007
Author: bdecoste
Date: 2007-12-03 11:49:43 -0500 (Mon, 03 Dec 2007)
New Revision: 67782
Modified:
branches/JBPAPP_4_2_0_GA_CP/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
Log:
[JBPAPP-478] merged fix for [EJBTHREE-785] [EJBTHREE-1062]
Modified: branches/JBPAPP_4_2_0_GA_CP/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java 2007-12-03 16:47:32 UTC (rev 67781)
+++ branches/JBPAPP_4_2_0_GA_CP/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java 2007-12-03 16:49:43 UTC (rev 67782)
@@ -21,17 +21,15 @@
*/
package org.jboss.ejb3;
-import org.jboss.annotation.ejb.LocalHomeBinding;
-import org.jboss.annotation.ejb.RemoteHomeBinding;
-import org.jboss.annotation.ejb.LocalBinding;
-import org.jboss.annotation.ejb.RemoteBinding;
-import org.jboss.annotation.ejb.RemoteBindings;
-import org.jboss.aop.Advisor;
-import org.jboss.ejb.LocalImpl;
-import org.jboss.ejb.RemoteImpl;
-import org.jboss.logging.Logger;
-import org.jboss.ejb3.remoting.RemoteProxyFactory;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import javax.ejb.EJBLocalObject;
+import javax.ejb.EJBObject;
import javax.ejb.Local;
import javax.ejb.LocalHome;
import javax.ejb.Remote;
@@ -41,10 +39,17 @@
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
+import org.jboss.annotation.ejb.LocalBinding;
+import org.jboss.annotation.ejb.LocalHomeBinding;
+import org.jboss.annotation.ejb.RemoteBinding;
+import org.jboss.annotation.ejb.RemoteBindings;
+import org.jboss.annotation.ejb.RemoteHomeBinding;
+import org.jboss.aop.Advisor;
+import org.jboss.ejb.LocalImpl;
+import org.jboss.ejb.RemoteImpl;
+import org.jboss.ejb3.remoting.RemoteProxyFactory;
+import org.jboss.logging.Logger;
/**
* Comment
*
@@ -80,38 +85,109 @@
}
- public static Class[] getLocalInterfaces(Container container)
+ public static Class<?>[] getLocalInterfaces(Container container)
{
- Local li = (javax.ejb.Local) ((EJBContainer) container).resolveAnnotation(javax.ejb.Local.class);
+ // Obtain @Local
+ Local localAnnotation = (Local)((EJBContainer) container).resolveAnnotation(javax.ejb.Local.class);
- if (li != null)
+ // Obtain @Remote
+ Remote remoteAnnotation = (Remote)((EJBContainer) container).resolveAnnotation(Remote.class);
+
+ // Obtain all business interfaces
+ List<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)
{
- if (li.value().length > 0) return li.value();
+ // Obtain the implemented interface
+ Class<?> singleInterface = container.getBeanClass().getInterfaces()[0];
+
+ // If not explicitly marked as @Remote, and is a valid business interface
+ if (remoteAnnotation==null
+ && businessInterfaces.contains(singleInterface))
+ {
+ // Return the implemented interface
+ return container.getBeanClass().getInterfaces();
+ }
+ }
- // We have an emtpy @Local annotated bean class
+ // If @Local is present
+ if (localAnnotation != null)
+ {
+ // If @Local.value is defined
+ if (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 class and there are no valid business interfaces: " + container.getEjbName());
+ }
+ // 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)
+ {
+ // 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);
+ }
+ }
+ }
+
+ // If more than one business interface is directly implemented by the bean class
+ if(beanClassBusinessInterfaces.size()>1)
+ {
+ throw new RuntimeException("Use of empty @Local on bean class and there are more than one default interface: " + container.getEjbName());
+ }
+ // JIRA EJBTHREE-1062
+ // EJB 3 4.6.6
+ // If the bean class implements only one business interface, that
+ //interface is exposed as local business if not denoted as @Remote
+ else
+ {
+ // If not explicitly marked as @Remote
+ if (remoteAnnotation == null)
+ {
+ // Return the implemented interface
+ return beanClassBusinessInterfaces.toArray(new Class<?>[]
+ {});
+ }
- ArrayList list = getBusinessInterfaces(container.getBeanClass());
- if (list.size() == 0)
- throw new RuntimeException("Use of empty @Local on bean class and there are no valid business interfaces: " + container.getEjbName());
- if (list.size() > 1)
- throw new RuntimeException("Use of empty @Local on bean class and there are more than one default interface: " + container.getEjbName());
- Class[] rtn = {(Class) list.get(0)};
- li = new LocalImpl(rtn);
- ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, li);
+ }
+ }
+
+ Class[] rtn = {(Class) businessInterfaces.get(0)};
+ localAnnotation = new LocalImpl(rtn);
+ ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
return rtn;
}
Class beanClass = container.getBeanClass();
String endpoint = getEndpointInterface(container);
- Class[] ri = getRemoteInterfaces(container);
+ Class[] remoteInterfaces = getRemoteInterfaces(container);
- if (li == null && ri == null && endpoint == null && (beanClass.getInterfaces() == null || beanClass.getInterfaces().length == 0))
+ if (localAnnotation == null && (remoteInterfaces != null && remoteInterfaces.length == 0) && endpoint == null
+ && (beanClass.getInterfaces() == null || beanClass.getInterfaces().length == 0))
throw new RuntimeException("bean class has no local, webservice, or remote interfaces defined and does not implement at least one business interface: " + container.getEjbName());
// introspect implemented interfaces.
- if (li == null)
+ if (localAnnotation == null)
{
- Class[] intfs = beanClass.getInterfaces();
+ List<Class<?>> intfs = getBusinessInterfaces(beanClass);
ArrayList<Class> locals = new ArrayList<Class>();
for (Class clazz : intfs)
{
@@ -122,23 +198,22 @@
}
if (locals.size() > 0)
{
- intfs = locals.toArray(new Class[locals.size()]);
- li = new LocalImpl(intfs);
- ((Advisor) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, li);
+ localAnnotation = new LocalImpl(locals.toArray(new Class[]{}));
+ ((Advisor) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
//return li.value(); ALR Removed (EJBTHREE-751)
}
}
// no @Local interfaces implemented
- if (li == null)
+ if (localAnnotation == null)
{
// search for default
- ArrayList<Class> interfaces = getBusinessInterfaces(beanClass);
+ List<Class<?>> interfaces = getBusinessInterfaces(beanClass);
if (interfaces.size() != 1) return null; // indeterminate
Class intf = interfaces.get(0);
- if (ri != null)
+ if (remoteInterfaces != null)
{
- for (Class rintf : ri)
+ for (Class rintf : remoteInterfaces)
{
if (intf.getName().equals(rintf.getName()))
{
@@ -149,19 +224,19 @@
if (intf.getName().equals(endpoint)) return null;
Class[] rtn = {intf};
- li = new LocalImpl(rtn);
- ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, li);
+ localAnnotation = new LocalImpl(rtn);
+ ((EJBContainer) container).getAnnotations().addClassAnnotation(javax.ejb.Local.class, localAnnotation);
return rtn;
}
// Check to ensure @Local and @Remote are not defined on the same interface
// JIRA EJBTHREE-751
- if(ri != null)
+ if (remoteInterfaces != null)
{
- for (Class remoteInterface : ri)
+ for (Class<?> remoteInterface : remoteInterfaces)
{
- for (Class localInterface : li.value())
+ for (Class<?> localInterface : localAnnotation.value())
{
if (localInterface.equals(remoteInterface))
{
@@ -172,22 +247,61 @@
}
}
- return li.value();
+ return localAnnotation.value();
}
+
+ /**
+ * Resolve the potential business interfaces on an enterprise bean.
+ * Returns all interfaces implemented by this class and it's supers which
+ * are potentially a business interface.
+ *
+ * Note: for normal operation call container.getBusinessInterfaces().
+ *
+ * @param beanClass the EJB implementation class
+ * @return a list of potential business interfaces
+ * @see org.jboss.ejb3.EJBContainer#getBusinessInterfaces()
+ */
+ public static List<Class<?>> getBusinessInterfaces(Class<?> beanClass)
+ {
+ // Obtain all business interfaces implemented by this bean class and its superclasses
+ return getBusinessInterfaces(beanClass, new ArrayList<Class<?>>());
+ }
- public static ArrayList<Class> getBusinessInterfaces(Class beanClass)
+
+ private static List<Class<?>> getBusinessInterfaces(Class<?> beanClass, List<Class<?>> interfaces)
{
- ArrayList<Class> interfaces = new ArrayList<Class>(Arrays.asList(beanClass.getInterfaces()));
- interfaces.remove(java.io.Serializable.class);
- interfaces.remove(java.io.Externalizable.class);
- interfaces.remove(javax.ejb.SessionSynchronization.class);
- interfaces.remove(javax.ejb.TimedObject.class);
- Iterator<Class> it = interfaces.iterator();
- while (it.hasNext())
+ /*
+ * 4.6.6:
+ * The following interfaces are excluded when determining whether the bean class has
+ * more than one interface: java.io.Serializable; java.io.Externaliz-
+ * able; any of the interfaces defined by the javax.ejb package.
+ */
+ for(Class<?> intf : beanClass.getInterfaces())
{
- if (it.next().getName().startsWith("javax.ejb")) it.remove();
+ if(intf.equals(java.io.Externalizable.class))
+ continue;
+ if(intf.equals(java.io.Serializable.class))
+ continue;
+ if(intf.getName().startsWith("javax.ejb"))
+ continue;
+
+ // FIXME Other aop frameworks might add other interfaces, this should really be configurable
+ if(intf.getName().startsWith("org.jboss.aop"))
+ continue;
+
+ interfaces.add(intf);
}
- return interfaces;
+
+ // If there's no superclass, return
+ if (beanClass.getSuperclass() == null)
+ {
+ return interfaces;
+ }
+ else
+ {
+ // Include any superclasses' interfaces
+ return getBusinessInterfaces(beanClass.getSuperclass(), interfaces);
+ }
}
public static Class getLocalHomeInterface(Container container)
@@ -361,7 +475,7 @@
if (ri == null)
{
Class beanClass = container.getBeanClass();
- Class[] intfs = beanClass.getInterfaces();
+ Class[] intfs = ProxyFactoryHelper.getBusinessInterfaces(beanClass).toArray(new Class[]{});
ArrayList<Class> remotes = new ArrayList<Class>();
for (Class clazz : intfs)
{
@@ -385,7 +499,7 @@
// We have an emtpy @Remote annotated bean class
- ArrayList list = getBusinessInterfaces(container.getBeanClass());
+ List list = getBusinessInterfaces(container.getBeanClass());
if (list.size() == 0)
throw new RuntimeException("Use of empty @Remote on bean class and there are no valid business interfaces: " + container.getEjbName());
if (list.size() > 1)
More information about the jboss-cvs-commits
mailing list