Skip to content

Commit

Permalink
check return type of producer
Browse files Browse the repository at this point in the history
  • Loading branch information
pmuir committed Jul 28, 2010
1 parent e36d9ec commit 73ed468
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 3 deletions.
56 changes: 56 additions & 0 deletions impl/src/main/java/org/jboss/weld/extensions/bean/Beans.java
@@ -1,10 +1,20 @@
package org.jboss.weld.extensions.bean;

import static org.jboss.weld.extensions.util.Reflections.isSerializable;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;

public class Beans
{
Expand Down Expand Up @@ -44,5 +54,51 @@ public static Set<Annotation> getQualifiers(BeanManager beanManager, Annotation[
}
return qualifiers;
}

public static void checkReturnValue(Object instance, Bean<?> bean, InjectionPoint injectionPoint, BeanManager beanManager)
{
if (instance == null && !Dependent.class.equals(bean.getScope()))
{
throw new IllegalStateException("Cannot return null from a non-dependent producer method: " + bean);
}
else if (instance != null)
{
boolean passivating = beanManager.isPassivatingScope(bean.getScope());
boolean instanceSerializable = isSerializable(instance.getClass());
if (passivating && !instanceSerializable)
{
throw new IllegalStateException("Producers cannot declare passivating scope and return a non-serializable class: " + bean);
}
if (injectionPoint != null && injectionPoint.getBean() != null)
{
if (!instanceSerializable && beanManager.isPassivatingScope(injectionPoint.getBean().getScope()))
{
if (injectionPoint.getMember() instanceof Field)
{
if (!injectionPoint.isTransient() && instance != null && !instanceSerializable)
{
throw new IllegalStateException("Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans. Producer " + bean + "at injection point " + injectionPoint);
}
}
else if (injectionPoint.getMember() instanceof Method)
{
Method method = (Method) injectionPoint.getMember();
if (method.isAnnotationPresent(Inject.class))
{
throw new IllegalStateException("Producers cannot produce non-serializable instances for injection into parameters of initializers of beans declaring passivating scope. Producer " + bean + "at injection point " + injectionPoint);
}
if (method.isAnnotationPresent(Produces.class))
{
throw new IllegalStateException("Producers cannot produce non-serializable instances for injection into parameters of producer methods declaring passivating scope. Producer " + bean + "at injection point " + injectionPoint);
}
}
else if (injectionPoint.getMember() instanceof Constructor<?>)
{
throw new IllegalStateException("Producers cannot produce non-serializable instances for injection into parameters of constructors of beans declaring passivating scope. Producer " + bean + "at injection point " + injectionPoint);
}
}
}
}
}

}
Expand Up @@ -34,7 +34,7 @@ public GenericBeanProducer(Producer<T> originalProducer, Type genericBeanType, A

public void dispose(T instance)
{
// TODO implement
// TODO Support disposer methods for generic producers
}

public T produce(CreationalContext<T> ctx)
Expand All @@ -49,6 +49,8 @@ public T produce(CreationalContext<T> ctx)

@SuppressWarnings("unchecked")
T value = (T) object;

// No need to check the producer return, the CDI impl will do this for us

return value;
}
Expand Down
Expand Up @@ -10,6 +10,8 @@
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

import org.jboss.weld.extensions.bean.Beans;

// TODO make this passivation capable?
public class GenericProducerBean<T> extends AbstactGenericBean<T>
{
Expand Down Expand Up @@ -39,6 +41,7 @@ public Set<Type> getTypes()
@Override
public void destroy(T instance, CreationalContext<T> creationalContext)
{
// TODO Implement support for disposer methods for generic producers
}

@Override
Expand All @@ -54,6 +57,9 @@ public T create(CreationalContext<T> creationalContext)

@SuppressWarnings("unchecked")
T value = (T) object;

// Check the return value, as this is actually a producer method or field
Beans.checkReturnValue(value, this, null, getBeanManager());

return value;
}
Expand Down
Expand Up @@ -11,6 +11,7 @@
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

import org.jboss.weld.extensions.bean.Beans;
import org.jboss.weld.extensions.util.Synthetic;

// TODO Make this passivation capable
Expand All @@ -36,7 +37,9 @@ public T create(CreationalContext<T> creationalContext)
{
Bean<?> declaringBean = getBeanManager().resolve(getBeanManager().getBeans(declaringBeanType, declaringBeanQualifier));
Object receiver = getBeanManager().getReference(declaringBean, declaringBean.getBeanClass(), creationalContext);
return (T) getFieldValue(field.getJavaMember(), receiver, Object.class);
T instance = (T) getFieldValue(field.getJavaMember(), receiver, Object.class);
Beans.checkReturnValue(instance, this, null, getBeanManager());
return instance;
}
finally
{
Expand Down
Expand Up @@ -9,6 +9,7 @@
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;

import org.jboss.weld.extensions.bean.Beans;
import org.jboss.weld.extensions.bean.InjectableMethod;
import org.jboss.weld.extensions.util.Synthetic;

Expand Down Expand Up @@ -42,7 +43,9 @@ public T create(CreationalContext<T> creationalContext)
{
try
{
return producerMethod.invoke(getReceiver(creationalContext), creationalContext);
T instance = producerMethod.invoke(getReceiver(creationalContext), creationalContext);
Beans.checkReturnValue(instance, this, null, getBeanManager());
return instance;
}
finally
{
Expand Down
12 changes: 12 additions & 0 deletions impl/src/main/java/org/jboss/weld/extensions/util/Reflections.java
Expand Up @@ -16,6 +16,7 @@
*/
package org.jboss.weld.extensions.util;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
Expand Down Expand Up @@ -425,5 +426,16 @@ else if (type instanceof ParameterizedType)
}
return null;
}

/**
* Check if a class is serializable.
*
* @param clazz The class to check
* @return true if the class implements serializable or is a primitive
*/
public static boolean isSerializable(Class<?> clazz)
{
return clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz);
}

}

0 comments on commit 73ed468

Please sign in to comment.