Skip to content

Commit

Permalink
Start work on bean ordering for deployer
Browse files Browse the repository at this point in the history
git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@2132 1c488680-804c-0410-94cd-c6b725194a0e
  • Loading branch information
pmuir committed Mar 22, 2009
1 parent 704bb9e commit 3b5f406
Show file tree
Hide file tree
Showing 17 changed files with 397 additions and 21 deletions.
Expand Up @@ -48,8 +48,6 @@ public Set<? extends Type> getTypes()
{
return DEFAULT_TYPES;
}



@Override
public Set<Annotation> getBindings()
Expand All @@ -69,4 +67,10 @@ protected Set<Class<? extends Annotation>> getFilteredAnnotationTypes()
return FILTERED_ANNOTATION_TYPES;
}

@Override
public String toString()
{
return "Built-in implicit javax.event.Event bean";
}

}
Expand Up @@ -80,4 +80,10 @@ public Set<Type> getTypes()
return TYPES;
}

@Override
public String toString()
{
return "Built-in javax.inject.manager.InjectionPoint bean";
}

}
Expand Up @@ -66,4 +66,10 @@ protected Set<Class<? extends Annotation>> getFilteredAnnotationTypes()
return FILTERED_ANNOTATION_TYPES;
}

@Override
public String toString()
{
return "Built-in implicit javax.inject.Instance bean";
}

}
Expand Up @@ -56,4 +56,11 @@ public boolean isSerializable()
return true;
}

@Override
public String toString()
{
return "Built-in javax.inject.manager.Manager bean";
}


}
55 changes: 37 additions & 18 deletions impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployer.java
Expand Up @@ -3,6 +3,7 @@
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

import javax.event.Observes;
import javax.inject.BindingType;
Expand Down Expand Up @@ -47,33 +48,35 @@ public class BeanDeployer
public BeanDeployer(ManagerImpl manager)
{
this.manager = manager;
this.beans = new HashSet<RIBean<?>>();
this.beans = new TreeSet<RIBean<?>>(new BootstrapOrderingBeanComparator());
this.classes = new HashSet<AnnotatedClass<?>>();
}


public void addBean(RIBean<?> bean)
public BeanDeployer addBean(RIBean<?> bean)
{
this.beans.add(bean);
return this;
}

public void addClass(Class<?> clazz)
public BeanDeployer addClass(Class<?> clazz)
{
if (!clazz.isAnnotation() && !clazz.isEnum())
{
classes.add(AnnotatedClassImpl.of(clazz));
}
return this;
}

public void addClasses(Iterable<Class<?>> classes)
public BeanDeployer addClasses(Iterable<Class<?>> classes)
{
for (Class<?> clazz : classes)
{
addClass(clazz);
}
return this;
}

public void deploy()
public BeanDeployer createBeans()
{
for (AnnotatedClass<?> clazz : classes)
{
Expand All @@ -86,7 +89,27 @@ else if (isTypeSimpleWebBean(clazz))
createSimpleBean(clazz);
}
}
return this;
}

public BeanDeployer deploy()
{
printBeans();
manager.setBeans(beans);
return this;
}

public Set<RIBean<?>> getBeans()
{
return beans;
}

protected void printBeans()
{
for (RIBean<?> bean : beans)
{
log.info("Bean: " + bean);
}
}

/**
Expand All @@ -95,7 +118,8 @@ else if (isTypeSimpleWebBean(clazz))
*
* Also creates the implicit field- and method-level beans, if present
*
* @param bean The bean representation
* @param bean
* The bean representation
*/
protected void createBean(AbstractClassBean<?> bean, final AnnotatedClass<?> annotatedClass)
{
Expand All @@ -114,8 +138,6 @@ protected void createBean(AbstractClassBean<?> bean, final AnnotatedClass<?> ann
createRealizedProducerFields(bean, annotatedClass);
createRealizedObserverMethods(bean, annotatedClass);
}

log.info("Web Bean: " + bean);
}

private void createProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
Expand All @@ -132,14 +154,13 @@ private void createProducerMethod(AbstractClassBean<?> declaringBean, AnnotatedM
ProducerMethodBean<?> bean = ProducerMethodBean.of(annotatedMethod, declaringBean, manager);
beans.add(bean);
manager.getResolver().addInjectionPoints(bean.getInjectionPoints());
log.info("Web Bean: " + bean);
}

private void createRealizedProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
{
AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
for (AnnotatedMethod<?> realizedMethod : realizedClass.getDeclaredAnnotatedMethods(Produces.class))
{
{
createProducerMethod(declaringBean, realizeProducerMethod(realizedMethod, realizingClass));
}
}
Expand All @@ -148,7 +169,7 @@ private void createRealizedProducerFields(AbstractClassBean<?> declaringBean, An
{
AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
for (final AnnotatedField<?> realizedField : realizedClass.getDeclaredAnnotatedFields(Produces.class))
{
{
createProducerField(declaringBean, realizeProducerField(realizedField, realizingClass));
}
}
Expand All @@ -157,7 +178,6 @@ private void createProducerField(AbstractClassBean<?> declaringBean, AnnotatedFi
{
ProducerFieldBean<?> bean = ProducerFieldBean.of(field, declaringBean, manager);
beans.add(bean);
log.info("Web Bean: " + bean);
}

private void createProducerFields(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
Expand All @@ -167,7 +187,7 @@ private void createProducerFields(AbstractClassBean<?> declaringBean, AnnotatedC
createProducerField(declaringBean, field);
}
}

private void createObserverMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
{
for (AnnotatedMethod<?> method : annotatedClass.getDeclaredMethodsWithAnnotatedParameters(Observes.class))
Expand Down Expand Up @@ -205,7 +225,8 @@ private void createEnterpriseBean(AnnotatedClass<?> annotatedClass)
/**
* Indicates if the type is a simple Web Bean
*
* @param type The type to inspect
* @param type
* The type to inspect
* @return True if simple Web Bean, false otherwise
*/
private boolean isTypeSimpleWebBean(AnnotatedClass<?> clazz)
Expand All @@ -218,11 +239,9 @@ private boolean isTypeSimpleWebBean(AnnotatedClass<?> clazz)
return !Reflections.isAbstract(rawType) && !Reflections.isParameterizedType(rawType) && !servletApiAbstraction.SERVLET_CLASS.isAssignableFrom(rawType) && !servletApiAbstraction.FILTER_CLASS.isAssignableFrom(rawType) && !servletApiAbstraction.SERVLET_CONTEXT_LISTENER_CLASS.isAssignableFrom(rawType) && !servletApiAbstraction.HTTP_SESSION_LISTENER_CLASS.isAssignableFrom(rawType) && !servletApiAbstraction.SERVLET_REQUEST_LISTENER_CLASS.isAssignableFrom(rawType) && !ejbApiAbstraction.ENTERPRISE_BEAN_CLASS.isAssignableFrom(rawType) && !jsfApiAbstraction.UICOMPONENT_CLASS.isAssignableFrom(rawType) && hasSimpleWebBeanConstructor(clazz);
}



private static boolean hasSimpleWebBeanConstructor(AnnotatedClass<?> type)
{
return type.getNoArgsConstructor() != null || type.getAnnotatedConstructors(Initializer.class).size() > 0;
return type.getNoArgsConstructor() != null || type.getAnnotatedConstructors(Initializer.class).size() > 0;
}

private static <T> AnnotatedMethod<T> realizeProducerMethod(final AnnotatedMethod<T> method, final AnnotatedClass<?> realizingClass)
Expand Down
@@ -0,0 +1,124 @@
package org.jboss.webbeans.bootstrap;

import java.util.Comparator;

import org.jboss.webbeans.bean.AbstractClassBean;
import org.jboss.webbeans.bean.AbstractProducerBean;
import org.jboss.webbeans.bean.NewBean;
import org.jboss.webbeans.bean.RIBean;
import org.jboss.webbeans.bean.standard.AbstractStandardBean;

public class BootstrapOrderingBeanComparator implements Comparator<RIBean<?>>
{

public int compare(RIBean<?> o1, RIBean<?> o2)
{
if (o1 instanceof AbstractStandardBean && !(o2 instanceof AbstractStandardBean))
{
return -1;
}
else if (!(o1 instanceof AbstractStandardBean) && o2 instanceof AbstractStandardBean)
{
return 1;
}
else if (o1 instanceof AbstractStandardBean && o2 instanceof AbstractStandardBean)
{
return o1.getId().compareTo(o2.getId());
}
else if (o1.getType().getName().startsWith("org.jboss.webbeans") && !o2.getType().getName().startsWith("org.jboss.webbeans"))
{
return -1;
}
else if (!o1.getType().getName().startsWith("org.jboss.webbeans") && o2.getType().getName().startsWith("org.jboss.webbeans"))
{
return 1;
}
else if (o1 instanceof AbstractClassBean)
{
AbstractClassBean<?> b1 = (AbstractClassBean<?>) o1;
if (o2 instanceof NewBean && !(o1 instanceof NewBean))
{
// Always initialize new beans after class beans
return -1;
}
else if (o1 instanceof NewBean && o2 instanceof AbstractClassBean && !(o2 instanceof NewBean))
{
// Always initialize new beans after class beans
return 1;
}
else if (o1 instanceof NewBean && !(o2 instanceof NewBean))
{
// Always initialize new class beans after class beans but before other beans
return -1;
}
else if (o1 instanceof NewBean && o2 instanceof NewBean)
{
return o1.getId().compareTo(o2.getId());
}
else if (o2 instanceof AbstractClassBean)
{
AbstractClassBean<?> b2 = (AbstractClassBean<?>) o2;
if (o1.getTypes().contains(b2.getType()))
{
return 1;
}
else if (b2.getTypes().contains(b1.getType()))
{
return -1;
}
else
{
return o1.getId().compareTo(o2.getId());
}
}
else if (o2 instanceof AbstractProducerBean)
{
// Producer beans are always initialized after class beans
return -1;
}
else
{
// Ordering doesn't matter
return o1.getId().compareTo(o2.getId());
}
}
else if (o1 instanceof AbstractProducerBean)
{
AbstractProducerBean<?, ?> b1 = (AbstractProducerBean<?, ?>) o1;
if (o2 instanceof NewBean)
{
// Always initialize producers beans after new beans
return 1;
}
else if (o2 instanceof AbstractClassBean)
{
if (b1.getDeclaringBean().equals(o2))
{
return 1;
}
else
{
return o1.getId().compareTo(o2.getId());
}
}
else
{
// Ordering doesn't matter
return o1.getId().compareTo(o2.getId());
}
}
else
{
if (o2 instanceof AbstractClassBean || o2 instanceof AbstractProducerBean)
{
// Initialize undefined ordering after defined ordering
return 1;
}
else
{
return o1.getId().compareTo(o2.getId());
}
}
}

}
Expand Up @@ -134,7 +134,7 @@ protected void registerBeans(Iterable<Class<?>> classes)
beanDeployer.addClass(NumericConversationIdGenerator.class);
beanDeployer.addClass(HttpSessionManager.class);
}
beanDeployer.deploy();
beanDeployer.createBeans().deploy();
}

public void boot()
Expand Down
6 changes: 6 additions & 0 deletions tests/src/test/java/com/acme/RoadRunner.java
@@ -0,0 +1,6 @@
package com.acme;

public class RoadRunner
{

}
@@ -0,0 +1,6 @@
package org.jboss.webbeans.test.unit.bootstrap.ordering;

interface Animal
{

}
@@ -0,0 +1,16 @@
package org.jboss.webbeans.test.unit.bootstrap.ordering;

import javax.context.ApplicationScoped;

@ApplicationScoped
class Cow implements Animal
{

public static boolean mooed = false;

public void moo()
{
mooed = true;
}

}

0 comments on commit 3b5f406

Please sign in to comment.