Skip to content

Commit

Permalink
Use all api types when looking for observers, support for discovering…
Browse files Browse the repository at this point in the history
… observer methods at bootstrap, initialized event

git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@433 1c488680-804c-0410-94cd-c6b725194a0e
  • Loading branch information
pmuir committed Dec 7, 2008
1 parent b53f749 commit 905822d
Show file tree
Hide file tree
Showing 20 changed files with 226 additions and 42 deletions.
Expand Up @@ -118,6 +118,11 @@ public Set<AnnotatedField<Object>> getEventFields()
{
return getAnnotatedItem().getAnnotatedFields(Observable.class);
}

public Set<AnnotatedMethod<Object>> getObserverMethods()
{
return getAnnotatedItem().getMethodsWithAnnotatedParameters(Observes.class);
}

/**
* Initializes the injection points
Expand Down
@@ -0,0 +1,9 @@
package org.jboss.webbeans.bindings;

import javax.webbeans.AnnotationLiteral;
import javax.webbeans.manager.Initialized;

public class InitializedBinding extends AnnotationLiteral<Initialized> implements Initialized
{

}
Expand Up @@ -19,21 +19,29 @@

import static org.jboss.webbeans.util.BeanFactory.createEnterpriseBean;
import static org.jboss.webbeans.util.BeanFactory.createEventBean;
import static org.jboss.webbeans.util.BeanFactory.createObserver;
import static org.jboss.webbeans.util.BeanFactory.createProducerMethodBean;
import static org.jboss.webbeans.util.BeanFactory.createSimpleBean;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.webbeans.DefinitionException;
import javax.webbeans.Observer;
import javax.webbeans.Observes;

import org.jboss.webbeans.CurrentManager;
import org.jboss.webbeans.ManagerImpl;
import org.jboss.webbeans.MetaDataCache;
import org.jboss.webbeans.bean.AbstractBean;
import org.jboss.webbeans.bean.AbstractClassBean;
import org.jboss.webbeans.bean.EventBean;
import org.jboss.webbeans.bean.ProducerMethodBean;
import org.jboss.webbeans.bindings.InitializedBinding;
import org.jboss.webbeans.bootstrap.spi.WebBeanDiscovery;
import org.jboss.webbeans.event.ObserverImpl;
import org.jboss.webbeans.introspector.AnnotatedField;
import org.jboss.webbeans.introspector.AnnotatedMethod;
import org.jboss.webbeans.log.LogProvider;
Expand Down Expand Up @@ -131,12 +139,27 @@ public void registerBeans(Iterable<Class<?>> classes)
ProducerMethodBean<?> producerMethodBean = createProducerMethodBean(producerMethod, bean);
beans.add(producerMethodBean);
CurrentManager.rootManager().getResolver().addInjectionPoints(producerMethodBean.getInjectionPoints());
log.info("Web Bean: " + producerMethodBean);
}
for (AnnotatedField<Object> eventField : bean.getEventFields())
{
EventBean<?> eventBean = createEventBean(eventField);
beans.add(eventBean);
CurrentManager.rootManager().getResolver().addInjectionPoints(eventBean.getInjectionPoints());
log.info("Web Bean: " + eventBean);
}
for (AnnotatedMethod<Object> observerMethod : bean.getObserverMethods())
{
ObserverImpl<?> observer = createObserver(observerMethod, bean);
if (observerMethod.getAnnotatedParameters(Observes.class).size() == 1)
{
registerObserver(observer, observerMethod.getAnnotatedParameters(Observes.class).get(0).getType(), observerMethod.getAnnotatedParameters(Observes.class).get(0).getBindingTypesAsArray());
}
else
{
throw new DefinitionException("Observer method can only have one parameter annotated @Observes " + observer);
}

}
log.info("Web Bean: " + bean);
}
Expand All @@ -162,6 +185,8 @@ public void boot(WebBeanDiscovery webBeanDiscovery)
registerBeans(webBeanDiscovery.discoverWebBeanClasses());
log.info("Validing Web Bean injection points");
CurrentManager.rootManager().getResolver().resolveInjectionPoints();
CurrentManager.rootManager().fireEvent(CurrentManager.rootManager(), new InitializedBinding());
log.info("Web Beans RI initialized");
}

/**
Expand Down Expand Up @@ -205,5 +230,11 @@ public static Set<Class<? extends WebBeanDiscovery>> getWebBeanDiscoveryClasses(
}
return webBeanDiscoveryClasses;
}

@SuppressWarnings("unchecked")
private static <T> void registerObserver(Observer<T> observer, Class<?> eventType, Annotation[] bindings)
{
CurrentManager.rootManager().addObserver(observer, (Class<T>) eventType, bindings);
}

}
Expand Up @@ -33,6 +33,7 @@
import org.jboss.webbeans.ManagerImpl;
import org.jboss.webbeans.transaction.TransactionListener;
import org.jboss.webbeans.util.JNDI;
import org.jboss.webbeans.util.Reflections;
import org.jboss.webbeans.util.Strings;

import com.google.common.collect.ForwardingMap;
Expand Down Expand Up @@ -176,11 +177,14 @@ public <T> void addObserver(Observer<T> observer, Class<T> eventType, Annotation
public <T> Set<Observer<T>> getObservers(T event, Annotation... bindings)
{
Set<Observer<T>> interestedObservers = new HashSet<Observer<T>>();
for (EventObserver<?> observer : registeredObservers.get(event.getClass()))
for (Class<?> clazz : Reflections.getTypeHierachy(event.getClass()))
{
if (observer.isObserverInterested(bindings))
for (EventObserver<?> observer : registeredObservers.get(clazz))
{
interestedObservers.add((Observer<T>) observer.getObserver());
if (observer.isObserverInterested(bindings))
{
interestedObservers.add((Observer<T>) observer.getObserver());
}
}
}
return interestedObservers;
Expand Down
Expand Up @@ -24,6 +24,7 @@
import javax.webbeans.Observer;

import org.jboss.webbeans.MetaDataCache;
import org.jboss.webbeans.util.Strings;

/**
* <p>
Expand Down Expand Up @@ -183,5 +184,16 @@ else if (!observer.equals(other.observer))
}
return true;
}

@Override
public String toString()
{
StringBuilder buffer = new StringBuilder();
buffer.append("Event Observer:\n");
buffer.append(" Event Type: " + eventType.getName() +"\n");
buffer.append(Strings.collectionToString(" Event Bindings: ", eventBindings));
buffer.append(" Observer: " + observer);
return buffer.toString();
}

}
Expand Up @@ -55,11 +55,11 @@ public class ObserverImpl<T> implements Observer<T>
{
private Bean<?> observerBean;
private final AnnotatedMethod<Object> observerMethod;
private final Class<T> eventType;
private TransactionObservationPhase transactionObservationPhase;
private boolean conditional;
private ManagerImpl manager;


/**
* Creates an Observer which describes and encapsulates an observer method
* (7.5).
Expand All @@ -72,12 +72,11 @@ public class ObserverImpl<T> implements Observer<T>
* @param observer The observer method to notify
* @param eventType The type of event being observed
*/
public ObserverImpl(final ManagerImpl manager, final Bean<?> observerBean, final AnnotatedMethod<Object> observer, final Class<T> eventType)
public ObserverImpl(final AnnotatedMethod<Object> observer, final Bean<?> observerBean, final ManagerImpl manager)
{
this.manager = manager;
this.observerBean = observerBean;
this.observerMethod = observer;
this.eventType = eventType;
initTransactionObservationPhase();
conditional = !observerMethod.getAnnotatedParameters(IfExists.class).isEmpty();
}
Expand Down Expand Up @@ -115,11 +114,6 @@ else if (observationPhases.size() == 1)
}
}

public Class<T> getEventType()
{
return eventType;
}

public void notify(final T event)
{
// Get the most specialized instance of the component
Expand Down Expand Up @@ -176,5 +170,15 @@ public boolean isInterestedInTransactionPhase(TransactionObservationPhase curren
{
return transactionObservationPhase.equals(currentPhase);
}

@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Observer Implentation: \n");
builder.append(" Observer (Declaring) bean: " + observerBean);
builder.append(" Observer method: " + observerMethod);
return builder.toString();
}

}
Expand Up @@ -81,13 +81,22 @@ public interface AnnotatedClass<T> extends AnnotatedType<T>
public AnnotatedConstructor<T> getConstructor(List<Class<?>> arguments);

/**
* Gets all members annotated with annotationType
* Gets all methods annotated with annotationType
*
* @param annotationType The annotation to match
* @return A set of abstracted methods with the given annotation. Returns an
* empty set if there are no matches
*/
public Set<AnnotatedMethod<Object>> getAnnotatedMethods(Class<? extends Annotation> annotationType);

/**
* Gets all with parameters annotated with annotationType
*
* @param annotationType The annotation to match
* @return A set of abstracted methods with the given annotation. Returns an
* empty set if there are no matches
*/
public Set<AnnotatedMethod<Object>> getMethodsWithAnnotatedParameters(Class<? extends Annotation> annotationType);

/**
* Gets the superclass
Expand Down
Expand Up @@ -19,8 +19,15 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.webbeans.BindingType;
import javax.webbeans.DeploymentType;
import javax.webbeans.ScopeType;
import javax.webbeans.Stereotype;

/**
* AnnotatedItem provides a uniform access to the annotations on an annotated
* item defined either in Java or XML
Expand All @@ -30,6 +37,11 @@
*/
public interface AnnotatedItem<T, S>
{

// The set of meta-annotations to map
@SuppressWarnings("unchecked")
public static final Set<Class<? extends Annotation>> MAPPED_METAANNOTATIONS = new HashSet<Class<? extends Annotation>>(Arrays.asList(BindingType.class, DeploymentType.class, Stereotype.class, ScopeType.class));

/**
* Gets all annotations on the item
*
Expand Down
Expand Up @@ -19,8 +19,18 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.webbeans.AfterTransactionCompletion;
import javax.webbeans.AfterTransactionFailure;
import javax.webbeans.AfterTransactionSuccess;
import javax.webbeans.BeforeTransactionCompletion;
import javax.webbeans.Disposes;
import javax.webbeans.IfExists;
import javax.webbeans.Observes;
import javax.webbeans.manager.Manager;

/**
Expand All @@ -32,6 +42,8 @@
*/
public interface AnnotatedMethod<T> extends AnnotatedItem<T, Method>
{

public static final Set<Class<? extends Annotation>> MAPPED_PARAMETER_ANNOTATIONS = new HashSet<Class<? extends Annotation>>(Arrays.asList(Disposes.class, Observes.class, IfExists.class, BeforeTransactionCompletion.class, AfterTransactionCompletion.class, AfterTransactionFailure.class, AfterTransactionSuccess.class));

/**
* Gets the abstracted parameters of the method
Expand All @@ -42,9 +54,9 @@ public interface AnnotatedMethod<T> extends AnnotatedItem<T, Method>
public List<AnnotatedParameter<Object>> getParameters();

/**
* Gets the list of annotated parameters for a given meta annotation
* Gets the list of annotated parameters for a given annotation
*
* @param metaAnnotationType The meta annotation to match
* @param metaAnnotationType The annotation to match
* @return A set of matching parameter abstractions. Returns an empty list if
* there are no matches.
*/
Expand Down
Expand Up @@ -30,9 +30,6 @@
import java.util.Set;

import javax.webbeans.BindingType;
import javax.webbeans.DeploymentType;
import javax.webbeans.ScopeType;
import javax.webbeans.Stereotype;
import javax.webbeans.manager.Manager;

import org.jboss.webbeans.bindings.CurrentAnnotationLiteral;
Expand Down Expand Up @@ -162,10 +159,6 @@ public String toString()
// The set of default binding types
private static final Set<Annotation> DEFAULT_BINDING = new HashSet<Annotation>(Arrays.asList(DEFAULT_BINDING_ARRAY));

// The set of meta-annotations to map
@SuppressWarnings("unchecked")
private static final Set<Class<? extends Annotation>> MAPPED_METAANNOTATIONS = new HashSet<Class<? extends Annotation>>(Arrays.asList(BindingType.class, DeploymentType.class, Stereotype.class, ScopeType.class));

// Cached string representation
private String toString;

Expand Down
Expand Up @@ -137,6 +137,7 @@ public void put(Class<? extends Annotation> key, AnnotatedMethod<Object> value)
}
methods.add(value);
}

}

/**
Expand Down Expand Up @@ -224,6 +225,8 @@ public String toString()
private final Set<AnnotatedMethod<Object>> methods;
// The map from annotation type to abstracted method with annotation
private final AnnotatedMethodMap annotatedMethods;
// The map from annotation type to method with a parameter with annotation
private final AnnotatedMethodMap methodsByAnnotatedParameters;

// The set of abstracted constructors
private final Set<AnnotatedConstructor<T>> constructors;
Expand All @@ -234,6 +237,7 @@ public String toString()

// Cached string representation
private String toString;


/**
* Constructor
Expand Down Expand Up @@ -309,6 +313,7 @@ public AnnotatedClassImpl(Class<T> rawType, Type type, Annotation[] annotations)

this.methods = new HashSet<AnnotatedMethod<Object>>();
this.annotatedMethods = new AnnotatedMethodMap();
this.methodsByAnnotatedParameters = new AnnotatedMethodMap();
for (Class<?> c = clazz; c != Object.class && c != null; c = c.getSuperclass())
{
for (Method method : clazz.getDeclaredMethods())
Expand All @@ -328,6 +333,13 @@ public AnnotatedClassImpl(Class<T> rawType, Type type, Annotation[] annotations)
}
annotatedMethods.get(annotation.annotationType()).add(annotatedMethod);
}
for (Class<? extends Annotation> annotationType : AnnotatedMethod.MAPPED_PARAMETER_ANNOTATIONS)
{
if (annotatedMethod.getAnnotatedParameters(annotationType).size() > 0)
{
methodsByAnnotatedParameters.put(annotationType, annotatedMethod);
}
}
}
}
}
Expand Down Expand Up @@ -485,6 +497,11 @@ public AnnotatedConstructor<T> getConstructor(List<Class<?>> arguments)
{
return constructorsByArgumentMap.get(arguments);
}

public Set<AnnotatedMethod<Object>> getMethodsWithAnnotatedParameters(Class<? extends Annotation> annotationType)
{
return methodsByAnnotatedParameters.get(annotationType);
}

/**
* Gets a string representation of the constructor
Expand Down

0 comments on commit 905822d

Please sign in to comment.