Author: swd847
Date: 2010-04-22 08:20:07 -0400 (Thu, 22 Apr 2010)
New Revision: 6149
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/annotations/
extensions/trunk/src/main/java/org/jboss/weld/extensions/annotations/ManagedProducer.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/beans/CustomInjectionPoint.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerBean.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerExtension.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerInvocationHandler.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/BeanProducer.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/MPType.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedProducerTest.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedReciever.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedBean.java
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedInterface.java
Modified:
extensions/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
Log:
Initial implementation of managed producers
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/annotations/ManagedProducer.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/annotations/ManagedProducer.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/annotations/ManagedProducer.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,13 @@
+package org.jboss.weld.extensions.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+(a)Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.METHOD })
+public @interface ManagedProducer
+{
+
+}
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/beans/CustomInjectionPoint.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/beans/CustomInjectionPoint.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/beans/CustomInjectionPoint.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,132 @@
+package org.jboss.weld.extensions.beans;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+/**
+ * implementation of InjectionPoint that can be used by other extensions
+ *
+ * @author stuart
+ *
+ */
+public class CustomInjectionPoint implements InjectionPoint
+{
+
+ public CustomInjectionPoint(AnnotatedField<?> field, Set<Annotation>
qualifiers, Bean<?> bean, boolean trans, boolean delegate)
+ {
+ this.annotated = field;
+ this.member = field.getJavaMember();
+ this.qualifiers = new HashSet<Annotation>(qualifiers);
+ this.type = field.getJavaMember().getGenericType();
+ this.trans = trans;
+ this.delegate = delegate;
+ this.bean = bean;
+ }
+
+ public CustomInjectionPoint(AnnotatedField<?> field, BeanManager beanManager,
Bean<?> bean, boolean trans, boolean delegate)
+ {
+ this.annotated = field;
+ this.member = field.getJavaMember();
+ this.qualifiers = new HashSet<Annotation>();
+ this.type = field.getJavaMember().getGenericType();
+ this.trans = trans;
+ this.delegate = delegate;
+ this.bean = bean;
+ for (Annotation a : field.getAnnotations())
+ {
+ if (beanManager.isQualifier(a.annotationType()))
+ {
+ qualifiers.add(a);
+ }
+ }
+ }
+
+ public CustomInjectionPoint(AnnotatedParameter<?> param, Set<Annotation>
qualifiers, Bean<?> bean, boolean trans, boolean delegate)
+ {
+ this.annotated = param;
+ this.member = param.getDeclaringCallable().getJavaMember();
+ this.qualifiers = new HashSet<Annotation>(qualifiers);
+ this.trans = trans;
+ this.delegate = delegate;
+ this.bean = bean;
+ this.type = param.getBaseType();
+ }
+
+ public CustomInjectionPoint(AnnotatedParameter<?> param, BeanManager
beanManager, Bean<?> bean, boolean trans, boolean delegate)
+ {
+ this.annotated = param;
+ this.member = param.getDeclaringCallable().getJavaMember();
+ this.qualifiers = new HashSet<Annotation>();
+ this.trans = trans;
+ this.delegate = delegate;
+ this.bean = bean;
+ this.type = param.getBaseType();
+ for (Annotation a : annotated.getAnnotations())
+ {
+ if (beanManager.isQualifier(a.annotationType()))
+ {
+ qualifiers.add(a);
+ }
+ }
+ }
+
+ private final Annotated annotated;
+
+ private final Member member;
+
+ private final Bean<?> bean;
+
+ private final Set<Annotation> qualifiers;
+
+ private final Type type;
+
+ private final boolean trans;
+
+ private final boolean delegate;
+
+ public Annotated getAnnotated()
+ {
+ return annotated;
+ }
+
+ public Bean<?> getBean()
+ {
+ return bean;
+ }
+
+ public Member getMember()
+ {
+ return member;
+ }
+
+ public Set<Annotation> getQualifiers()
+ {
+ return qualifiers;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public boolean isDelegate()
+ {
+ return delegate;
+ }
+
+ public boolean isTransient()
+ {
+ return trans;
+ }
+
+}
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerBean.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerBean.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerBean.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,200 @@
+package org.jboss.weld.extensions.managedproducer;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Named;
+
+/**
+ * Bean implementation that produces a JDK proxy
+ *
+ * when a method is invoked on the proxy it calls the managed producer method
+ * and invokes the method on the returned object
+ *
+ * @author stuart
+ *
+ * @param <M>
+ */
+public class ManagedProducerBean<M> implements Bean<M>
+{
+
+ final Class<?> beanClass;
+
+ final String name;
+
+ final Set<Annotation> qualifiers;
+
+ final Set<Type> types;
+
+ final Class<?> proxyClass;
+
+ final BeanManager manager;
+
+ final Constructor<?> proxyConstructor;
+
+
+ final AnnotatedMethod<?> method;
+
+ public ManagedProducerBean(AnnotatedMethod<?> method, BeanManager manager)
+ {
+ this.method = method;
+ beanClass = method.getDeclaringType().getJavaClass();
+ // get the name
+ if (method.isAnnotationPresent(Named.class))
+ {
+ name = method.getAnnotation(Named.class).value();
+ }
+ else
+ {
+ name = null;
+ }
+ // get the qualifiers
+ qualifiers = new HashSet<Annotation>();
+ for (Annotation a : method.getAnnotations())
+ {
+ if (manager.isQualifier(a.annotationType()))
+ {
+ qualifiers.add(a);
+ }
+ }
+ if (qualifiers.isEmpty())
+ {
+ qualifiers.add(new AnnotationLiteral<Default>()
+ {
+ });
+ }
+ // get the bean types
+ types = new HashSet<Type>();
+ Set<Class<?>> interfaces = new HashSet<Class<?>>();
+ for (Type t : method.getTypeClosure())
+ {
+ if (t instanceof Class<?>)
+ {
+ Class<?> c = (Class<?>) t;
+ if (c.isInterface())
+ {
+ types.add(c);
+ interfaces.add(c);
+ }
+ }
+ else if (t instanceof ParameterizedType)
+ {
+ ParameterizedType p = (ParameterizedType) t;
+ Class<?> c = (Class<?>) p.getRawType();
+ if (c.isInterface())
+ {
+ types.add(t);
+ }
+ }
+ }
+ // build the properties
+ Class<?>[] iarray = new Class[interfaces.size()];
+ int count = 0;
+ this.manager = manager;
+ for (Class<?> c : interfaces)
+ {
+ iarray[count++] = c;
+ }
+ proxyClass = Proxy.getProxyClass(beanClass.getClassLoader(), iarray);
+ try
+ {
+ proxyConstructor = proxyClass.getConstructor(new Class[] {
InvocationHandler.class });
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+
+ }
+
+ public Class<?> getBeanClass()
+ {
+ return beanClass;
+ }
+
+ public Set<InjectionPoint> getInjectionPoints()
+ {
+ return Collections.emptySet();
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public Set<Annotation> getQualifiers()
+ {
+ return qualifiers;
+ }
+
+ /**
+ * the proxies that are injected all have Dependant scope
+ */
+ public Class<? extends Annotation> getScope()
+ {
+ return Dependent.class;
+ }
+
+ public Set<Class<? extends Annotation>> getStereotypes()
+ {
+ return Collections.emptySet();
+ }
+
+ public Set<Type> getTypes()
+ {
+ return types;
+ }
+
+ public boolean isAlternative()
+ {
+ return false;
+ }
+
+ public boolean isNullable()
+ {
+ return false;
+ }
+
+ public M create(CreationalContext<M> creationalContext)
+ {
+ Annotation[] quals = { new AnnotationLiteral<Default>()
+ {
+ } };
+ Set<Bean<?>> beans = manager.getBeans(InjectionPoint.class, quals);
+ Bean injectionPointBean = (Bean) beans.iterator().next();
+ InjectionPoint injectionPoint = (InjectionPoint)
manager.getReference(injectionPointBean, InjectionPoint.class, creationalContext);
+ ManagedProducerInvocationHandler<?> hdl = new
ManagedProducerInvocationHandler(manager, this.method, this, injectionPoint);
+ try
+ {
+ M obj = (M) proxyConstructor.newInstance(new Object[] { hdl });
+ creationalContext.push(obj);
+ return obj;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void destroy(M instance, CreationalContext<M> creationalContext)
+ {
+ creationalContext.release();
+ }
+
+}
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerExtension.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerExtension.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerExtension.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,50 @@
+package org.jboss.weld.extensions.managedproducer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+import org.jboss.weld.extensions.annotations.ManagedProducer;
+
+/**
+ * An extension that allows the use of @ManagedProducer methods
+ *
+ * these methods work in a similar manner to @Unwrap methods in seam 2
+ *
+ * @author stuart
+ *
+ */
+public class ManagedProducerExtension implements Extension
+{
+
+ Set<ManagedProducerBean<?>> beans = new
HashSet<ManagedProducerBean<?>>();
+
+ public void processAnnotatedType(@Observes ProcessAnnotatedType<?> type,
BeanManager manager)
+ {
+ for (AnnotatedMethod<?> m : type.getAnnotatedType().getMethods())
+ {
+ if (m.isAnnotationPresent(ManagedProducer.class))
+ {
+ // we have a managed producer
+ // lets make a not of it and register it later
+
+ beans.add(new ManagedProducerBean(m, manager));
+ }
+ }
+ }
+
+ public void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBean)
+ {
+ for (ManagedProducerBean<?> b : beans)
+ {
+ afterBean.addBean(b);
+ }
+ }
+
+}
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerInvocationHandler.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerInvocationHandler.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/managedproducer/ManagedProducerInvocationHandler.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,92 @@
+package org.jboss.weld.extensions.managedproducer;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.AmbiguousResolutionException;
+import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.jboss.weld.extensions.beans.CustomInjectionPoint;
+
+public class ManagedProducerInvocationHandler<T> implements InvocationHandler
+{
+
+ final BeanManager manager;
+ final AnnotatedMethod<?> annotatedMethod;
+ final Method method;
+ final Bean<?> bean;
+ final InjectionPoint[] injectionPoints;
+ final Map<Method, Method> methods = Collections.synchronizedMap(new
HashMap<Method, Method>());
+ final Bean<?> mainClassBean;
+ final InjectionPoint injectionPoint;
+
+
+ public ManagedProducerInvocationHandler(BeanManager manager, AnnotatedMethod<?>
method, Bean<?> bean, InjectionPoint injectionPoint)
+ {
+ this.manager = manager;
+ this.method = method.getJavaMember();
+ this.annotatedMethod = method;
+ this.bean = bean;
+ injectionPoints = new InjectionPoint[this.method.getTypeParameters().length];
+ for (int i = 0; i < injectionPoints.length; ++i)
+ {
+ injectionPoints[i] = new CustomInjectionPoint(method.getParameters().get(i),
manager, bean, false, false);
+ }
+ Type mainType = method.getDeclaringType().getBaseType();
+ HashSet<Annotation> mainClassQualifiers = new HashSet<Annotation>();
+ for (Annotation a : method.getDeclaringType().getAnnotations())
+ {
+ if (manager.isQualifier(a.annotationType()))
+ {
+ mainClassQualifiers.add(a);
+ }
+ }
+ Set<Bean<?>> beans = manager.getBeans(mainType,
mainClassQualifiers.toArray(new Annotation[0]));
+ if (beans.isEmpty())
+ {
+ throw new UnsatisfiedResolutionException("could not find declaring bean for
managed producer method " + method.getDeclaringType().getJavaClass() + "."
+ this.method.getName());
+ }
+ else if (beans.size() > 1)
+ {
+ throw new AmbiguousResolutionException("could not find declaring bean for
managed producer method " + method.getDeclaringType().getJavaClass() + "."
+ this.method.getName());
+ }
+ mainClassBean = beans.iterator().next();
+ this.injectionPoint = injectionPoint;
+ }
+
+ public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
+ {
+ CreationalContext<?> ctx = manager.createCreationalContext(bean);
+ Object[] params = new Object[method.getParameterTypes().length];
+ for (int i = 0; i < this.method.getParameterTypes().length; ++i)
+ {
+ if (InjectionPoint.class.isAssignableFrom(this.method.getParameterTypes()[i]))
+ {
+ params[i] = injectionPoint;
+ }
+ else
+ {
+ params[i] = manager.getInjectableReference(injectionPoints[i], ctx);
+ }
+ }
+ Object base = manager.getReference(mainClassBean,
annotatedMethod.getDeclaringType().getJavaClass(), ctx);
+
+ Object result = method.invoke(base, params);
+ Object ret = m.invoke(result, args);
+ ctx.release();
+ return ret;
+ }
+
+}
Modified:
extensions/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
===================================================================
---
extensions/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension 2010-04-22
09:42:38 UTC (rev 6148)
+++
extensions/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension 2010-04-22
12:20:07 UTC (rev 6149)
@@ -1,3 +1,5 @@
org.jboss.weld.extensions.genericbeans.GenericExtension
org.jboss.weld.extensions.resources.servlet.ServletResourceExtension
-org.jboss.weld.extensions.beanid.IdentifiableBeanExtension
\ No newline at end of file
+org.jboss.weld.extensions.beanid.IdentifiableBeanExtension
+org.jboss.weld.extensions.CoreExtension
+org.jboss.weld.extensions.managedproducer.ManagedProducerExtension
\ No newline at end of file
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/BeanProducer.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/BeanProducer.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/BeanProducer.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,16 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.jboss.weld.extensions.annotations.ManagedProducer;
+
+public class BeanProducer
+{
+ @ManagedProducer
+ public ProducedInterface produce(InjectionPoint injectionPoint)
+ {
+ ProducedBean b = new ProducedBean();
+ b.setValue(injectionPoint.getAnnotated().getAnnotation(MPType.class).value());
+ return b;
+ }
+}
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/MPType.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/MPType.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/MPType.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,10 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface MPType
+{
+ String value();
+}
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedProducerTest.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedProducerTest.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedProducerTest.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,17 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.weld.test.AbstractWeldTest;
+import org.testng.annotations.Test;
+
+@Artifact
+public class ManagedProducerTest extends AbstractWeldTest
+{
+ @Test
+ public void testManagedProducers()
+ {
+ ManagedReciever bean = getReference(ManagedReciever.class);
+ assert bean.bean1.getValue().equals("bean1") : " value: " +
bean.bean1.getValue();
+ assert bean.bean2.getValue().equals("bean2") : " value: " +
bean.bean1.getValue();
+ }
+}
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedReciever.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedReciever.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ManagedReciever.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,15 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+import javax.inject.Inject;
+
+public class ManagedReciever
+{
+ @MPType("bean1")
+ @Inject
+ ProducedInterface bean1;
+
+ @MPType("bean2")
+ @Inject
+ ProducedInterface bean2;
+
+}
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedBean.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedBean.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedBean.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,19 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+import org.jboss.weld.extensions.Veto;
+
+@Veto
+public class ProducedBean implements ProducedInterface
+{
+ String value = "wrong";
+
+ public String getValue()
+ {
+ return value;
+ }
+
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+}
Added:
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedInterface.java
===================================================================
---
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedInterface.java
(rev 0)
+++
extensions/trunk/src/test/java/org/jboss/weld/test/extensions/managedproducer/ProducedInterface.java 2010-04-22
12:20:07 UTC (rev 6149)
@@ -0,0 +1,8 @@
+package org.jboss.weld.test.extensions.managedproducer;
+
+public interface ProducedInterface
+{
+
+ public abstract String getValue();
+
+}
\ No newline at end of file