[webbeans-commits] Webbeans SVN: r907 - in ri/trunk: webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy and 2 other directories.
webbeans-commits at lists.jboss.org
webbeans-commits at lists.jboss.org
Mon Jan 12 15:01:29 EST 2009
Author: pete.muir at jboss.org
Date: 2009-01-12 15:01:29 -0500 (Mon, 12 Jan 2009)
New Revision: 907
Added:
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/ForwardingEjbDescriptor.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/InternalEjbDescriptor.java
Modified:
ri/trunk/webbeans-ri-spi/src/main/java/org/jboss/webbeans/ejb/spi/EjbDescriptor.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/EnterpriseBean.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/SimpleBean.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/ClientProxyMethodHandler.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/EnterpriseBeanProxyMethodHandler.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/EjbDescriptorCache.java
Log:
WBRI-68, no tests :-(
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/EnterpriseBean.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/EnterpriseBean.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/EnterpriseBean.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -18,9 +18,13 @@
package org.jboss.webbeans.bean;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.ProxyObject;
+
import javax.webbeans.ApplicationScoped;
import javax.webbeans.CreationException;
import javax.webbeans.Decorator;
@@ -35,8 +39,10 @@
import javax.webbeans.Specializes;
import org.jboss.webbeans.ManagerImpl;
+import org.jboss.webbeans.bean.proxy.EnterpriseBeanProxyMethodHandler;
import org.jboss.webbeans.context.DependentContext;
-import org.jboss.webbeans.ejb.spi.EjbDescriptor;
+import org.jboss.webbeans.ejb.InternalEjbDescriptor;
+import org.jboss.webbeans.ejb.spi.BusinessInterfaceDescriptor;
import org.jboss.webbeans.introspector.AnnotatedClass;
import org.jboss.webbeans.introspector.AnnotatedField;
import org.jboss.webbeans.introspector.AnnotatedMethod;
@@ -44,6 +50,7 @@
import org.jboss.webbeans.introspector.jlr.AnnotatedClassImpl;
import org.jboss.webbeans.log.LogProvider;
import org.jboss.webbeans.log.Logging;
+import org.jboss.webbeans.util.Proxies;
/**
* An enterprise bean representation
@@ -57,7 +64,9 @@
private LogProvider log = Logging.getLogProvider(EnterpriseBean.class);
// The EJB descriptor
- private EjbDescriptor<T> ejbDescriptor;
+ private InternalEjbDescriptor<T> ejbDescriptor;
+
+ private Class<T> proxyClass;
// The remove method on the bean class (do not call!)
private AnnotatedMethod<?> removeMethod;
@@ -99,12 +108,12 @@
protected void init()
{
super.init();
- Iterable<EjbDescriptor<T>> ejbDescriptors = manager.getEjbDescriptorCache().get(getType());
+ Iterable<InternalEjbDescriptor<T>> ejbDescriptors = manager.getEjbDescriptorCache().get(getType());
if (ejbDescriptors == null)
{
throw new DefinitionException("Not an EJB " + toString());
}
- for (EjbDescriptor<T> ejbDescriptor : ejbDescriptors)
+ for (InternalEjbDescriptor<T> ejbDescriptor : ejbDescriptors)
{
if (this.ejbDescriptor == null)
{
@@ -115,6 +124,8 @@
throw new RuntimeException("TODO Multiple EJBs have the same bean class! " + getType());
}
}
+ initTypesFromLocalInterfaces();
+ initProxyClass();
initRemoveMethod();
initInjectionPoints();
checkEnterpriseBeanTypeAllowed();
@@ -139,6 +150,32 @@
}
}
}
+
+ protected void initTypes()
+ {
+ // Noop, occurs too early
+ // TODO points at class hierachy problem :-(
+ }
+
+ protected void initTypesFromLocalInterfaces()
+ {
+ types = new HashSet<Type>();
+ for (BusinessInterfaceDescriptor<?> businessInterfaceDescriptor : ejbDescriptor.getLocalBusinessInterfaces())
+ {
+ types.add(businessInterfaceDescriptor.getInterface());
+ }
+ types.add(Object.class);
+ }
+
+ protected void initProxyClass()
+ {
+ ProxyFactory proxyFactory = Proxies.getProxyFactory(getTypes());
+
+ @SuppressWarnings("unchecked")
+ Class<T> proxyClass = proxyFactory.createClass();
+
+ this.proxyClass = proxyClass;
+ }
/**
* Validates for non-conflicting roles
@@ -275,13 +312,21 @@
try
{
DependentContext.INSTANCE.setActive(true);
- // TODO Implement enterprise bean proxies and select the correct
- // jndiName
- return (T) manager.getNaming().lookup(ejbDescriptor.getLocalJndiName(), getType());
+ T instance = proxyClass.newInstance();
+ ((ProxyObject) instance).setHandler(new EnterpriseBeanProxyMethodHandler(this));
+ return instance;
}
+ catch (InstantiationException e)
+ {
+ throw new RuntimeException("Could not instantiate enterprise proxy for " + toString(), e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException("Could not access bean correctly when creating enterprise proxy for " + toString(), e);
+ }
catch (Exception e)
{
- throw new CreationException("could not find the name in JNDI " + ejbDescriptor.getLocalJndiName(), e);
+ throw new CreationException("could not find the EJB in JNDI " + proxyClass, e);
}
finally
{
@@ -448,7 +493,7 @@
return injectionPointsAreSerializable();
}
- public EjbDescriptor<T> getEjbDescriptor()
+ public InternalEjbDescriptor<T> getEjbDescriptor()
{
return ejbDescriptor;
}
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/SimpleBean.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/SimpleBean.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/SimpleBean.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -34,8 +34,8 @@
import org.jboss.webbeans.ManagerImpl;
import org.jboss.webbeans.MetaDataCache;
import org.jboss.webbeans.context.DependentContext;
+import org.jboss.webbeans.injection.InjectionPointImpl;
import org.jboss.webbeans.injection.InjectionPointProvider;
-import org.jboss.webbeans.injection.InjectionPointImpl;
import org.jboss.webbeans.introspector.AnnotatedClass;
import org.jboss.webbeans.introspector.AnnotatedConstructor;
import org.jboss.webbeans.introspector.AnnotatedField;
@@ -418,6 +418,15 @@
return;
}
}
+
+ /**
+ * Initializes the bean type
+ */
+ protected void initType()
+ {
+ log.trace("Bean type specified in Java");
+ this.type = getAnnotatedItem().getType();
+ }
/**
* Returns the constructor
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/ClientProxyMethodHandler.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/ClientProxyMethodHandler.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/ClientProxyMethodHandler.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -63,15 +63,23 @@
}
/**
- * The method proxy
+ * Invokes the method on the correct version of the instance as obtained by
+ * a context lookup
*
- * Uses reflection to look up the corresponding method on the proxy and
- * executes that method with the same parameters.
- *
- * @param self A reference to the proxy
- * @param proxiedMethod The method to execute
- * @param proceed The next method to proceed to
- * @param args The method calling arguments
+ * @param self the proxy instance.
+ * @param thisMethod the overridden method declared in the super
+ * class or interface.
+ * @param proceed the forwarder method for invoking the overridden
+ * method. It is null if the overridden mehtod is
+ * abstract or declared in the interface.
+ * @param args an array of objects containing the values of
+ * the arguments passed in the method invocation
+ * on the proxy instance. If a parameter type is
+ * a primitive type, the type of the array element
+ * is a wrapper class.
+ * @return the resulting value of the method invocation.
+ *
+ * @throws Throwable if the method invocation fails.
*/
public Object invoke(Object self, Method proxiedMethod, Method proceed, Object[] args) throws Throwable
{
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/EnterpriseBeanProxyMethodHandler.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/EnterpriseBeanProxyMethodHandler.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/bean/proxy/EnterpriseBeanProxyMethodHandler.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -18,9 +18,13 @@
package org.jboss.webbeans.bean.proxy;
import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
import javassist.util.proxy.MethodHandler;
+import org.jboss.webbeans.CurrentManager;
+import org.jboss.webbeans.bean.EnterpriseBean;
import org.jboss.webbeans.log.LogProvider;
import org.jboss.webbeans.log.Logging;
import org.jboss.webbeans.util.Reflections;
@@ -29,42 +33,65 @@
* Method handler for enterprise bean client proxies
*
* @author Nicklas Karlsson
+ * @author Pete Muir
*
*/
public class EnterpriseBeanProxyMethodHandler implements MethodHandler
{
// The log provider
- private LogProvider log = Logging.getLogProvider(EnterpriseBeanProxyMethodHandler.class);
+ private static final transient LogProvider log = Logging.getLogProvider(EnterpriseBeanProxyMethodHandler.class);
+
// The container provided proxy that implements all interfaces
- private Object proxy;
+ private final Map<Class<?>, Object> proxiedInstances;
+ private final Map<Class<?>, String> jndiNames;
/**
* Constructor
*
* @param proxy The generic proxy
*/
- public EnterpriseBeanProxyMethodHandler(Object proxy)
+ public EnterpriseBeanProxyMethodHandler(EnterpriseBean<?> bean)
{
- this.proxy = proxy;
- log.trace("Created enterprise bean proxy method handler for " + proxy);
+ this.proxiedInstances = new HashMap<Class<?>, Object>();
+ this.jndiNames = bean.getEjbDescriptor().getLocalBusinessInterfacesJndiNames();
+ log.trace("Created enterprise bean proxy method handler for " + bean);
}
/**
- * The method proxy
+ * Lookups the EJB in the container and executes the method on it
*
- * Executes the corresponding method on the proxy
- *
- * @param self A reference to the proxy
- * @param method The method to execute
- * @param process The next method to proceed to
- * @param args The method calling arguments
+ * @param self the proxy instance.
+ * @param method the overridden method declared in the super
+ * class or interface.
+ * @param proceed the forwarder method for invoking the overridden
+ * method. It is null if the overridden method is
+ * abstract or declared in the interface.
+ * @param args an array of objects containing the values of
+ * the arguments passed in the method invocation
+ * on the proxy instance. If a parameter type is
+ * a primitive type, the type of the array element
+ * is a wrapper class.
+ * @return the resulting value of the method invocation.
+ *
+ * @throws Throwable if the method invocation fails.
*/
- //@Override
public Object invoke(Object self, Method method, Method proceed, Object[] args) throws Throwable
{
- Method proxiedMethod = Reflections.lookupMethod(method, proxy);
- Object returnValue = Reflections.invokeAndWrap(proxiedMethod, proxy, args);
- log.trace("Executed " + method + " on " + proxy + " with parameters " + args + " and got return value " + returnValue);
+ Class<?> businessInterface = method.getDeclaringClass();
+ Object proxiedInstance = proxiedInstances.get(businessInterface);
+ if (proxiedInstance == null)
+ {
+ String jndiName = jndiNames.get(businessInterface);
+ if (jndiName == null)
+ {
+ throw new IllegalStateException("Unable to establish jndi name to use to lookup EJB");
+ }
+ proxiedInstance = CurrentManager.rootManager().getNaming().lookup(jndiName, businessInterface);
+ proxiedInstances.put(businessInterface, proxiedInstance);
+ }
+ Method proxiedMethod = Reflections.lookupMethod(method, proxiedInstance);
+ Object returnValue = Reflections.invokeAndWrap(proxiedMethod, proxiedInstance, args);
+ log.trace("Executed " + method + " on " + proxiedInstance + " with parameters " + args + " and got return value " + returnValue);
return returnValue;
}
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/EjbDescriptorCache.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/EjbDescriptorCache.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/EjbDescriptorCache.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -36,17 +36,17 @@
private static final long serialVersionUID = 1L;
// EJB name -> EJB descriptor map
- private ConcurrentMap<String, EjbDescriptor<?>> ejbsByName;
+ private ConcurrentMap<String, InternalEjbDescriptor<?>> ejbsByName;
// EJB implementation class -> EJB descriptors map
- private ConcurrentMap<Class<?>, Set<EjbDescriptor<?>>> ejbsByBeanClass;
+ private ConcurrentMap<Class<?>, Set<InternalEjbDescriptor<?>>> ejbsByBeanClass;
/**
* Constructor
*/
public EjbDescriptorCache()
{
- this.ejbsByName = new ConcurrentHashMap<String, EjbDescriptor<?>>();
- this.ejbsByBeanClass = new ConcurrentHashMap<Class<?>, Set<EjbDescriptor<?>>>();
+ this.ejbsByName = new ConcurrentHashMap<String, InternalEjbDescriptor<?>>();
+ this.ejbsByBeanClass = new ConcurrentHashMap<Class<?>, Set<InternalEjbDescriptor<?>>>();
}
/**
@@ -55,7 +55,7 @@
* @param ejbName The EJB name
* @return The EJB descriptor
*/
- public EjbDescriptor<?> get(String ejbName)
+ public InternalEjbDescriptor<?> get(String ejbName)
{
return ejbsByName.get(ejbName);
}
@@ -67,7 +67,7 @@
* @return An iterator
*/
@SuppressWarnings("unchecked")
- public <T> Iterable<EjbDescriptor<T>> get(Class<T> beanClass)
+ public <T> Iterable<InternalEjbDescriptor<T>> get(Class<T> beanClass)
{
return (Iterable) ejbsByBeanClass.get(beanClass);
}
@@ -77,11 +77,12 @@
*
* @param ejbDescriptor The EJB descriptor to add
*/
- public void add(EjbDescriptor<?> ejbDescriptor)
+ public <T> void add(EjbDescriptor<T> ejbDescriptor)
{
- ejbsByName.put(ejbDescriptor.getEjbName(), ejbDescriptor);
- ejbsByBeanClass.putIfAbsent(ejbDescriptor.getType(), new CopyOnWriteArraySet<EjbDescriptor<?>>());
- ejbsByBeanClass.get(ejbDescriptor.getType()).add(ejbDescriptor);
+ InternalEjbDescriptor<T> internalEjbDescriptor = new InternalEjbDescriptor<T>(ejbDescriptor);
+ ejbsByName.put(ejbDescriptor.getEjbName(), internalEjbDescriptor);
+ ejbsByBeanClass.putIfAbsent(ejbDescriptor.getType(), new CopyOnWriteArraySet<InternalEjbDescriptor<?>>());
+ ejbsByBeanClass.get(ejbDescriptor.getType()).add(internalEjbDescriptor);
}
/**
Added: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/ForwardingEjbDescriptor.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/ForwardingEjbDescriptor.java (rev 0)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/ForwardingEjbDescriptor.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -0,0 +1,58 @@
+package org.jboss.webbeans.ejb;
+
+import java.lang.reflect.Method;
+
+import org.jboss.webbeans.ejb.spi.BusinessInterfaceDescriptor;
+import org.jboss.webbeans.ejb.spi.EjbDescriptor;
+
+public abstract class ForwardingEjbDescriptor<T> implements EjbDescriptor<T>
+{
+
+ protected abstract EjbDescriptor<T> delegate();
+
+ public String getEjbName()
+ {
+ return delegate().getEjbName();
+ }
+
+ public Iterable<BusinessInterfaceDescriptor<?>> getLocalBusinessInterfaces()
+ {
+ return delegate().getLocalBusinessInterfaces();
+ }
+
+ public Iterable<BusinessInterfaceDescriptor<?>> getRemoteBusinessInterfaces()
+ {
+ return delegate().getRemoteBusinessInterfaces();
+ }
+
+ public Iterable<Method> getRemoveMethods()
+ {
+ return delegate().getRemoveMethods();
+ }
+
+ public Class<T> getType()
+ {
+ return delegate().getType();
+ }
+
+ public boolean isMessageDriven()
+ {
+ return delegate().isMessageDriven();
+ }
+
+ public boolean isSingleton()
+ {
+ return delegate().isSingleton();
+ }
+
+ public boolean isStateful()
+ {
+ return delegate().isStateful();
+ }
+
+ public boolean isStateless()
+ {
+ return delegate().isStateless();
+ }
+
+}
Property changes on: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/ForwardingEjbDescriptor.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/InternalEjbDescriptor.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/InternalEjbDescriptor.java (rev 0)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/InternalEjbDescriptor.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -0,0 +1,41 @@
+package org.jboss.webbeans.ejb;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.webbeans.ejb.spi.BusinessInterfaceDescriptor;
+import org.jboss.webbeans.ejb.spi.EjbDescriptor;
+
+public class InternalEjbDescriptor<T> extends ForwardingEjbDescriptor<T> implements EjbDescriptor<T>
+{
+
+ private final Map<Class<?>, String> localBusinessInterfacesJndiNames;
+ private final EjbDescriptor<T> delegate;
+
+ public InternalEjbDescriptor(EjbDescriptor<T> ejbDescriptor)
+ {
+ this.delegate = ejbDescriptor;
+ this.localBusinessInterfacesJndiNames = new HashMap<Class<?>, String>();
+ for (BusinessInterfaceDescriptor<?> businessInterfaceDescriptor : ejbDescriptor.getLocalBusinessInterfaces())
+ {
+ localBusinessInterfacesJndiNames.put(businessInterfaceDescriptor.getInterface(), businessInterfaceDescriptor.getJndiName());
+ }
+ // Internally, Object.class is added to the type hierachy of an
+ // EnterpriseBean, so we need to represent that here. We can just use any
+ // of the local business interfaces
+ localBusinessInterfacesJndiNames.put(Object.class, ejbDescriptor.getLocalBusinessInterfaces().iterator().next().getJndiName());
+ }
+
+ public Map<Class<?>, String> getLocalBusinessInterfacesJndiNames()
+ {
+ return Collections.unmodifiableMap(localBusinessInterfacesJndiNames);
+ }
+
+ @Override
+ protected EjbDescriptor<T> delegate()
+ {
+ return delegate;
+ }
+
+}
Property changes on: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/ejb/InternalEjbDescriptor.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: ri/trunk/webbeans-ri-spi/src/main/java/org/jboss/webbeans/ejb/spi/EjbDescriptor.java
===================================================================
--- ri/trunk/webbeans-ri-spi/src/main/java/org/jboss/webbeans/ejb/spi/EjbDescriptor.java 2009-01-12 17:43:26 UTC (rev 906)
+++ ri/trunk/webbeans-ri-spi/src/main/java/org/jboss/webbeans/ejb/spi/EjbDescriptor.java 2009-01-12 20:01:29 UTC (rev 907)
@@ -93,11 +93,4 @@
*/
public String getEjbName();
- /**
- * @return The JNDI string which can be used to lookup a proxy which
- * implements all local business interfaces
- *
- */
- public String getLocalJndiName();
-
}
More information about the weld-commits
mailing list