Author: dallen6
Date: 2008-10-27 05:59:35 -0400 (Mon, 27 Oct 2008)
New Revision: 172
Added:
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventObserver.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventBusTest.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventObserverTest.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/annotations/Role.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/bindings/RoleBinding.java
Modified:
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventBus.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventImpl.java
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/ObserverImpl.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventTest.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/ObserverTest.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockManagerImpl.java
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockObserverImpl.java
Log:
Added new data structures for observers and observer resolution.
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventBus.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventBus.java 2008-10-26
20:39:54 UTC (rev 171)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventBus.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -1,8 +1,7 @@
package org.jboss.webbeans.event;
import java.lang.annotation.Annotation;
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -20,106 +19,114 @@
* The event bus is where observers are registered and events are fired.
*
* @author David Allen
- *
+ *
*/
public class EventBus
{
- private final Map<Integer, Set<Observer<?>>> registeredObservers;
- private final TransactionManager tm;
- private String tmName =
"java:/TransactionManager";
-
+ private final Map<Class<?>, ArrayList<EventObserver<?>>>
registeredObservers;
+ private final TransactionManager tm;
+ private String tmName = "java:/TransactionManager";
+
/**
- * Initializes a new instance of the EventBus. This includes looking up the
+ * Initializes a new instance of the EventBus. This includes looking up the
* transaction manager which is needed to defer events till the end of a
- * transaction.
- * TODO Should be able to configure JNDI name of transaction manager
+ * transaction. TODO Should be able to configure JNDI name of transaction
+ * manager
*
*/
public EventBus()
{
- registeredObservers = new HashMap<Integer, Set<Observer<?>>>();
+ registeredObservers = new HashMap<Class<?>,
ArrayList<EventObserver<?>>>();
tm = JNDI.lookup(tmName, TransactionManager.class);
}
/**
- * Adds an observer to the event bus so that it receives event notifications. The
- * event information is already encapsulated as part of the observer.
- * @param o The observer that should receive events
+ * Adds an observer to the event bus so that it receives event notifications.
+ * The event information is already encapsulated as part of the observer.
+ *
+ * @param o
+ * The observer that should receive events
*/
- public void addObserver(Observer<?> o)
+ public <T> void addObserver(Observer<T> o, Class<T> eventType,
+ Annotation... bindings)
{
- int key = 1 /*TODO generateKey(o.getEventType(), o.get)*/;
- Set<Observer<?>> l = registeredObservers.get(key);
+ ArrayList<EventObserver<?>> l = registeredObservers.get(eventType);
if (l == null)
- l = new HashSet<Observer<?>>();
- l.add(o);
- registeredObservers.put(key, l);
+ {
+ l = new ArrayList<EventObserver<?>>();
+ registeredObservers.put(eventType, l);
+ }
+ EventObserver<T> eventObserver = new EventObserver<T>(o, eventType,
bindings);
+ if (!l.contains(eventObserver))
+ l.add(eventObserver);
}
/**
- * Defers delivery of an event till the end of the currently active transaction.
+ * Defers delivery of an event till the end of the currently active
+ * transaction.
*
- * @param container The WebBeans container
- * @param event The event object to deliver
- * @param o The observer to receive the event
+ * @param container
+ * The WebBeans container
+ * @param event
+ * The event object to deliver
+ * @param o
+ * The observer to receive the event
* @throws SystemException
* @throws IllegalStateException
* @throws RollbackException
*/
- public void deferEvent(Object event, Observer<Object> o) throws SystemException,
IllegalStateException, RollbackException
+ public void deferEvent(Object event, Observer<Object> o)
+ throws SystemException, IllegalStateException, RollbackException
{
- if (tm != null) {
+ if (tm != null)
+ {
// Get the current transaction associated with the thread
Transaction t = tm.getTransaction();
if (t != null)
- t.registerSynchronization(new DeferredEventNotification<Object>(event,
o));
+ t.registerSynchronization(new DeferredEventNotification<Object>(
+ event, o));
}
}
/**
* Resolves the list of observers to be notified for a given event and
* optional event bindings.
- * @param event The event object
- * @param bindings Optional event bindings
+ *
+ * @param event
+ * The event object
+ * @param bindings
+ * Optional event bindings
* @return A set of Observers
*/
+ @SuppressWarnings("unchecked")
public <T> Set<Observer<T>> getObservers(T event, Annotation...
bindings)
{
Set<Observer<T>> results = new HashSet<Observer<T>>();
- for (Observer<?> observer :
registeredObservers.get(generateKey(event.getClass(), Arrays.asList(bindings))))
+ for (EventObserver<?> observer : registeredObservers.get(event.getClass()))
{
- results.add((Observer<T>) observer);
+ // TODO Verify bindings match before adding
+ results.add((Observer<T>) observer.getObserver());
}
return results;
}
/**
* Removes an observer from the event bus.
- * @param o The observer to remove
+ *
+ * @param observer
+ * The observer to remove
*/
- public void removeObserver(Observer<?> o)
+ public <T> void removeObserver(Observer<T> observer, Class<T>
eventType)
{
- // TODO fix
- // Set<Observer<?>> l =
registeredObservers.get(generateKey(o.getEventType(), o.getEventBindingTypes()));
- //if (l != null) {
- // l.remove(o);
- //}
+ ArrayList<EventObserver<?>> observers =
registeredObservers.get(eventType);
+ for (int i = 0; i < observers.size(); i++)
+ {
+ EventObserver<?> eventObserver = observers.get(i);
+ if (eventObserver.getObserver().equals(observer))
+ {
+ observers.remove(i);
+ break;
+ }
+ }
}
-
- /**
- * Creates a key that can be used in a map for an observer that is notified of
- * events of a specific type with optional event bindings.
- * @param eventType The class of the event being observed
- * @param eventBindings An optional set of event bindings
- * @return
- */
- public int generateKey(Class<?> eventType, Collection<Annotation>
eventBindings)
- {
- // Produce the sum of the hash codes for the event type and the set of
- // event bindings.
- int key = eventType.hashCode();
- if (eventBindings != null)
- key += eventBindings.hashCode();
- return key;
- }
}
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventImpl.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventImpl.java 2008-10-26
20:39:54 UTC (rev 171)
+++ ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventImpl.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -1,6 +1,9 @@
package org.jboss.webbeans.event;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -11,6 +14,7 @@
import javax.webbeans.DuplicateBindingTypeException;
import javax.webbeans.Event;
import javax.webbeans.Observer;
+import javax.webbeans.TypeLiteral;
import javax.webbeans.manager.Manager;
/**
@@ -24,21 +28,26 @@
public class EventImpl<T> implements Event<T>
{
private Collection<? extends Annotation> eventBindings;
+ private Class<T> eventType;
// The current WB manager
@Current
protected Manager webBeansManager;
/**
- * Used to set the event bindings for this type of event after it is constructed
- * with the default constructor.
- * @param eventBindings Annotations that are bindings for the event
+ * Used to set the event bindings for this type of event after it is
+ * constructed with the default constructor.
+ *
+ * @param eventBindings
+ * Annotations that are bindings for the event
*/
public void setEventBindings(Annotation... eventBindings)
{
- this.eventBindings = Arrays.asList(eventBindings);
+ Set<Annotation> newEventBindings = new HashSet<Annotation>();
+ addAnnotationBindings(newEventBindings, eventBindings);
+ this.eventBindings = newEventBindings;
}
-
+
/*
* (non-Javadoc)
*
@@ -60,10 +69,31 @@
.fireEvent(event, eventBindings.toArray(new Annotation[0]));
}
- public void observe(Observer<T> observe, Annotation... bindings)
+ public void observe(Observer<T> observer, Annotation... bindings)
{
- // TODO Auto-generated method stub
-
+ // Register the observer with the web beans manager
+ Class<T> eventArgumentClazz = null;
+ try
+ {
+ // TODO Fix me: Reflection can only get type variables, not the arguments used
elsewhere
+ Field eventTypeField = this.getClass().getDeclaredField("eventType");
+ ParameterizedType genericType = (ParameterizedType)
eventTypeField.getGenericType();
+ Type[] eventTypeArguments = genericType.getActualTypeArguments();
+ eventArgumentClazz = (Class<T>) eventTypeArguments[0];
+ } catch (SecurityException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchFieldException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ Set<Annotation> eventBindings = new HashSet<Annotation>();
+ eventBindings.addAll(this.getBindingTypes());
+ addAnnotationBindings(eventBindings, bindings);
+ webBeansManager.addObserver(observer, eventArgumentClazz, bindings);
}
/**
@@ -72,9 +102,13 @@
* thrown.
*
* @param bindingsSet
+ * The set of annotation binding objects
* @param bindings
+ * An array of annotation bindings to add to the set
* @throws DuplicateBindingTypeException
* if any of bindings are duplicates
+ * @throws IllegalArgumentException
+ * if any annotation is not a binding type
*/
private void addAnnotationBindings(Set<Annotation> bindingsSet,
Annotation[] bindings)
@@ -82,6 +116,15 @@
if (bindings != null)
{
Set<Class<? extends Annotation>> bindingTypes = new
HashSet<Class<? extends Annotation>>();
+ // Add the bindings types that are already in the set being added to. This
will
+ // provide detection of duplicates across construction and later invocations.
+ for (Annotation annotation : bindingsSet)
+ {
+ bindingTypes.add(annotation.annotationType());
+ }
+
+ // Now go through the new annotations being added to make sure these are
binding
+ // types and are not duplicates
for (Annotation annotation : bindings)
{
// Check that the binding type is indeed a binding type
Added: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventObserver.java
===================================================================
--- ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventObserver.java
(rev 0)
+++
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventObserver.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -0,0 +1,134 @@
+package org.jboss.webbeans.event;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.webbeans.Observer;
+
+/**
+ * <p>
+ * EventObserver wraps various {@link Observer} objects created by application
+ * code or by the Web Beans Manager for annotated observer methods. In all
+ * cases, this wrapper provides consistent object identification and hashing
+ * based on the type of event being observed and any event binding types
+ * specified.
+ *
+ * @author David Allen
+ *
+ */
+public class EventObserver<T>
+{
+ private final Class<T> eventType;
+ private final Annotation[] eventBindings;
+ private final Observer<T> observer;
+
+ /**
+ * Constructs a new wrapper for an observer.
+ *
+ * @param observer
+ * The observer
+ * @param eventType
+ * The class of event being observed
+ * @param eventBindings
+ * The array of annotation event bindings, if any
+ */
+ public EventObserver(final Observer<T> observer, final Class<T>
eventType,
+ final Annotation... eventBindings)
+ {
+ this.observer = observer;
+ this.eventType = eventType;
+ this.eventBindings = eventBindings;
+ }
+
+ /**
+ * @return the eventType
+ */
+ public final Class<T> getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * @return the eventBindings
+ */
+ public final Annotation[] getEventBindings()
+ {
+ return eventBindings;
+ }
+
+ /**
+ * @return the observer
+ */
+ public final Observer<T> getObserver()
+ {
+ return observer;
+ }
+
+ /**
+ * Query method to determine if this observer should be notified of an event
+ * based on the event bindings and any member values thereof.
+ *
+ * @param bindings The event bindings
+ * @return true only if all required bindings match
+ */
+ public boolean isObserverInterested(Annotation... bindings)
+ {
+ boolean result = true;
+ // Check each binding specified by this observer against those provided
+ if (this.eventBindings != null)
+ {
+ if ((bindings != null) && (bindings.length > 0))
+ {
+ List<Annotation> bindingsArray = Arrays.asList(bindings);
+ for (Annotation annotation : this.eventBindings)
+ {
+ int eventBindingIndex = bindingsArray.indexOf(annotation);
+ if (eventBindingIndex >= 0)
+ {
+ result = annotationsMatch(annotation,
bindingsArray.get(eventBindingIndex));
+ } else
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Compares two annotation bindings for equivalence. This means that all member
values, if any,
+ * must match.
+ * @param annotation The first annotation to compare
+ * @param annotation2 The second annotation to compare
+ * @return
+ */
+ private boolean annotationsMatch(Annotation annotation,
+ Annotation annotation2)
+ {
+ boolean result = true;
+ if (annotation.getClass().getDeclaredMethods().length > 0)
+ {
+ for (Method annotationValue : annotation.getClass().getDeclaredMethods())
+ {
+ try
+ {
+ if
(!annotationValue.invoke(annotation).equals(annotationValue.invoke(annotation2)))
+ {
+ result = false;
+ break;
+ }
+ } catch (Exception e)
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+}
Property changes on:
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/EventObserver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/ObserverImpl.java
===================================================================
---
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/ObserverImpl.java 2008-10-26
20:39:54 UTC (rev 171)
+++
ri/trunk/webbeans-ri/src/main/java/org/jboss/webbeans/event/ObserverImpl.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -2,9 +2,8 @@
import java.lang.annotation.Annotation;
+import javax.webbeans.Current;
import javax.webbeans.Observer;
-import javax.webbeans.manager.Manager;
-
import org.jboss.webbeans.ManagerImpl;
import org.jboss.webbeans.injectable.InjectableMethod;
import org.jboss.webbeans.injectable.InjectableParameter;
@@ -14,17 +13,11 @@
/**
* <p>
* Reference implementation for the Observer interface, which represents an
- * observer method. Each observer method has an event type, the class of the
- * event object being observed, and event binding types, annotations applied to
+ * observer method. Each observer method has an event type which is the class of the
+ * event object being observed, and event binding types that are annotations applied to
* the event parameter to narrow the event notifications delivered.
* </p>
*
- * <p>
- * The hash code for each observer method includes all the information
- * contained. The data structure used to lookup observers must account for an
- * arbitrary number of observers of the same event.
- * </p>
- *
* @author David Allen
*
*/
@@ -36,14 +29,30 @@
private final Class<T> eventType;
/**
- * Creates an Observer which describes and encapsulates an observer method (7.3).
+ * Injected before notify is called. This can only work with the RI since
+ * InjectableMethod requires this specific implementation.
+ * TODO Determine if the impl can be injected here.
+ */
+ @Current
+ protected ManagerImpl manager;
+
+ /**
+ * Creates an Observer which describes and encapsulates an observer method
+ * (7.5).
*
+ * @param componentModel
+ * The model for the component which defines the observer method
+ * @param observer
+ * The observer method to notify
+ * @param eventType
+ * The type of event being observed
* @param beanModel The model for the bean which defines the
* observer method
* @param observer The observer method to notify
* @param eventType The type of event being observed
*/
- public ObserverImpl(BeanModel<?, ?> beanModel, InjectableMethod<?>
observer, Class<T> eventType)
+ public ObserverImpl(final BeanModel<?, ?> beanModel,
+ final InjectableMethod<?> observer, final Class<T> eventType)
{
this.beanModel = beanModel;
this.observerMethod = observer;
@@ -68,18 +77,20 @@
*/
public void notify(final T event)
{
- // Get the most specialized instance of the bean
- Object instance = null /*getInstance(manager)*/;
+ // Get the most specialized instance of the component
+ Object instance = getInstance();
if (instance != null)
{
// Let the super class get the parameter values, but substitute the event
// object so that we know for certain it is the correct one.
for (int i = 0; i < observerMethod.getParameters().size(); i++)
{
- InjectableParameter<? extends Object> parameter =
observerMethod.getParameters().get(i);
+ InjectableParameter<? extends Object> parameter = observerMethod
+ .getParameters().get(i);
if (parameter.getType().isAssignableFrom(event.getClass()))
{
- InjectableParameter<?> newParameter = new
InjectableParameterWrapper<Object>(parameter)
+ InjectableParameter<?> newParameter = new
InjectableParameterWrapper<Object>(
+ parameter)
{
@Override
public Object getValue(ManagerImpl manager)
@@ -90,21 +101,21 @@
observerMethod.getParameters().set(i, newParameter);
}
}
- // this.observerMethod.invoke(manager, instance);
+ this.observerMethod.invoke(manager, instance);
}
-
+
}
/**
* Uses the container to retrieve the most specialized instance of this
* observer.
*
- * @param container The WebBeans manager
* @return the most specialized instance
*/
- protected Object getInstance(Manager manager)
+ protected Object getInstance()
{
- // Return the most specialized instance of the bean
- return manager.getInstanceByType(beanModel.getType(),
beanModel.getBindingTypes().toArray(new Annotation[0]));
+ // Return the most specialized instance of the component
+ return manager.getInstanceByType(beanModel.getType(), beanModel
+ .getBindingTypes().toArray(new Annotation[0]));
}
}
Added: ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventBusTest.java
===================================================================
--- ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventBusTest.java
(rev 0)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventBusTest.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -0,0 +1,12 @@
+package org.jboss.webbeans.test;
+
+/**
+ * Tests for the EventBus implementation used by the Web Beans RI.
+ *
+ * @author David Allen
+ *
+ */
+public class EventBusTest extends AbstractTest
+{
+
+}
Property changes on:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventBusTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventObserverTest.java
===================================================================
--- ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventObserverTest.java
(rev 0)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventObserverTest.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -0,0 +1,52 @@
+package org.jboss.webbeans.test;
+
+import javax.webbeans.Observer;
+
+import org.jboss.webbeans.event.EventObserver;
+import org.jboss.webbeans.test.bindings.AnimalStereotypeAnnotationLiteral;
+import org.jboss.webbeans.test.bindings.RoleBinding;
+import org.jboss.webbeans.test.bindings.TameAnnotationLiteral;
+import org.jboss.webbeans.test.beans.DangerCall;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for the wrapper class {@link EventObserverTest} which implements some of
+ * the observer resolution behavior specified in 7.7.1 and 7.7.2 of the Web Beans
+ * Specification.
+ *
+ * @author David Allen
+ *
+ */
+@SpecVersion("20081024-PDR")
+public class EventObserverTest
+{
+ public class AnObserver<T> implements Observer<T>
+ {
+ public void notify(T event)
+ {
+ }
+ }
+
+
+ /**
+ * Tests different annotation literals as event bindings to make sure the wrapper
+ * properly detects when an observer matches the given event bindings.
+ */
+ @Test(groups = "eventbus")
+ @SpecAssertion(section = "7.7.1")
+ public void testIsObserverInterested()
+ {
+ Observer<DangerCall> observer = new AnObserver<DangerCall>();
+ EventObserver<DangerCall> wrappedObserver = new
EventObserver<DangerCall>(observer, DangerCall.class, new TameAnnotationLiteral());
+ assert wrappedObserver.getEventBindings().length == 1;
+ assert wrappedObserver.isObserverInterested(new TameAnnotationLiteral());
+ assert !wrappedObserver.isObserverInterested(new
AnimalStereotypeAnnotationLiteral());
+ assert wrappedObserver.isObserverInterested(new TameAnnotationLiteral(), new
RoleBinding("Admin"));
+
+ // Perform some tests with binding values (7.7.1)
+ wrappedObserver = new EventObserver<DangerCall>(observer, DangerCall.class,
new RoleBinding("Admin"));
+ assert wrappedObserver.getEventBindings().length == 1;
+ assert wrappedObserver.isObserverInterested(new RoleBinding("Admin"));
+ assert !wrappedObserver.isObserverInterested(new RoleBinding("User"));
+ }
+}
Property changes on:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventObserverTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventTest.java
===================================================================
--- ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventTest.java 2008-10-26
20:39:54 UTC (rev 171)
+++ ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/EventTest.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -6,34 +6,48 @@
import javax.webbeans.DuplicateBindingTypeException;
import javax.webbeans.Event;
+import javax.webbeans.Observer;
import javax.webbeans.Standard;
import org.jboss.webbeans.event.EventImpl;
-import org.jboss.webbeans.test.annotations.AnimalStereotype;
import org.jboss.webbeans.test.annotations.AnotherDeploymentType;
import org.jboss.webbeans.test.annotations.Synchronous;
import org.jboss.webbeans.test.annotations.Tame;
-import org.jboss.webbeans.test.beans.DangerCall;
-import org.jboss.webbeans.test.bindings.AnimalStereotypeAnnotationLiteral;
import org.jboss.webbeans.test.bindings.FishStereotypeAnnotationLiteral;
+import org.jboss.webbeans.test.bindings.RiverFishStereotypeAnnotationLiteral;
import org.jboss.webbeans.test.bindings.SynchronousAnnotationLiteral;
import org.jboss.webbeans.test.bindings.TameAnnotationLiteral;
+import org.jboss.webbeans.test.beans.DangerCall;
import org.jboss.webbeans.test.mock.MockManagerImpl;
import org.jboss.webbeans.util.Reflections;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
- * Tests for the implementation of an Event bean
+ * Tests for the implementation of an Event component.
*
* @author David Allen
*
*/
-@SpecVersion("20081012")
+@SpecVersion("20081024-PDR")
public class EventTest
{
private MockManagerImpl manager = null;
+ /**
+ * Test class used as an observer.
+ *
+ */
+ public class AnObserver<T> implements Observer<T>
+ {
+ protected boolean notified = false;
+
+ public void notify(T event)
+ {
+ this.notified = true;
+ }
+ }
+
@BeforeMethod
public void before() throws Exception
{
@@ -48,45 +62,87 @@
* instantiated implementation.
*/
@SuppressWarnings("unchecked")
- @Test(groups = "eventbus") @SpecAssertion(section="7.4")
+ @Test(groups = "eventbus")
+ @SpecAssertion(section = "7.6")
public void testFireEvent()
{
DangerCall anEvent = new DangerCall();
// Create a test annotation for the event and use it to construct the
// event object
- Annotation[] annotations = new Annotation[] { new
AnimalStereotypeAnnotationLiteral() };
- EventImpl<DangerCall> eventBean = new EventImpl<DangerCall>();
- eventBean.setEventBindings(annotations);
- eventBean.setManager(manager);
- eventBean.fire(anEvent, new TameAnnotationLiteral(),
- new SynchronousAnnotationLiteral());
+ Annotation[] annotations = new Annotation[] { new TameAnnotationLiteral() };
+ EventImpl<DangerCall> eventComponent = new EventImpl<DangerCall>();
+ eventComponent.setEventBindings(annotations);
+ eventComponent.setManager(manager);
+ eventComponent.fire(anEvent, new SynchronousAnnotationLiteral());
assert anEvent.equals(manager.getEvent());
assert Reflections.annotationSetMatches(manager.getEventBindings(),
- AnimalStereotype.class, Tame.class,
- Synchronous.class);
+ Tame.class, Synchronous.class);
// Test duplicate annotations on the fire method call
boolean duplicateDetected = false;
try
{
- eventBean.fire(anEvent, new TameAnnotationLiteral(),
+ eventComponent.fire(anEvent, new TameAnnotationLiteral(),
new TameAnnotationLiteral());
} catch (DuplicateBindingTypeException e)
{
duplicateDetected = true;
}
assert duplicateDetected;
-
+
// Test annotations that are not binding types
boolean nonBindingTypeDetected = false;
try
{
- eventBean.fire(anEvent, new FishStereotypeAnnotationLiteral());
+ eventComponent.fire(anEvent, new FishStereotypeAnnotationLiteral());
+ } catch (IllegalArgumentException e)
+ {
+ nonBindingTypeDetected = true;
}
- catch (IllegalArgumentException e)
+ assert nonBindingTypeDetected;
+ }
+
+ /**
+ * Tests the {@link Event#observe(javax.webbeans.Observer, Annotation...)}
+ * method with a locally instantiated implementation.
+ */
+ @Test(groups = "eventbus")
+ @SpecAssertion(section = "7.6")
+ public void testObserve()
+ {
+ // Create a test annotation for the event and use it to construct the
+ // event object
+ Annotation[] annotations = new Annotation[] { new TameAnnotationLiteral() };
+ EventImpl<DangerCall> eventComponent = new EventImpl<DangerCall>();
+ eventComponent.setEventBindings(annotations);
+ eventComponent.setManager(manager);
+ Observer<DangerCall> observer = new AnObserver<DangerCall>();
+ eventComponent.observe(observer, new SynchronousAnnotationLiteral());
+ assert manager.getEventType().equals(DangerCall.class);
+
+ // Try duplicate annotation bindings
+ boolean duplicateDetected = false;
+ try
{
+ eventComponent.observe(observer,
+ new TameAnnotationLiteral());
+ } catch (DuplicateBindingTypeException e)
+ {
+ duplicateDetected = true;
+ }
+ assert duplicateDetected;
+
+ // Try an invalid binding type
+ boolean nonBindingTypeDetected = false;
+ try
+ {
+ eventComponent.observe(observer,
+ new RiverFishStereotypeAnnotationLiteral());
+ } catch (IllegalArgumentException e)
+ {
nonBindingTypeDetected = true;
}
assert nonBindingTypeDetected;
}
+
}
Modified: ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/ObserverTest.java
===================================================================
---
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/ObserverTest.java 2008-10-26
20:39:54 UTC (rev 171)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/ObserverTest.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -11,7 +11,6 @@
import javax.webbeans.Standard;
import org.jboss.webbeans.ManagerImpl;
-import org.jboss.webbeans.event.ObserverImpl;
import org.jboss.webbeans.injectable.InjectableMethod;
import org.jboss.webbeans.introspector.AnnotatedType;
import org.jboss.webbeans.introspector.SimpleAnnotatedType;
@@ -31,14 +30,14 @@
* @author David Allen
*
*/
-@SpecVersion("20081012")
+@SpecVersion("20081024-PDR")
public class ObserverTest
{
private ManagerImpl manager;
private SimpleBeanModel<Tuna> tuna;
private InjectableMethod<?> om;
- public class Event
+ public class SampleEvent
{
// Simple class used for testing
}
@@ -47,7 +46,7 @@
{
protected boolean notified = false;
- public void observe(@Observes @Asynchronous Event e)
+ public void observe(@Observes @Asynchronous SampleEvent e)
{
// An observer method
this.notified = true;
@@ -67,49 +66,21 @@
annotations.put(Asynchronous.class, new AsynchronousAnnotationLiteral());
AnnotatedType<Tuna> annotatedItem = new
SimpleAnnotatedType<Tuna>(Tuna.class, annotations);
tuna = new SimpleBeanModel<Tuna>(new
SimpleAnnotatedType<Tuna>(Tuna.class), annotatedItem, manager);
- om = new
InjectableMethod<Object>(AnObserver.class.getMethod("observe", new Class[]
{ Event.class }));
+ om = new
InjectableMethod<Object>(AnObserver.class.getMethod("observe", new Class[]
{ SampleEvent.class }));
}
/**
* Test method for
- * {@link org.jboss.webbeans.event.ObserverImpl#getEventBindingTypes()}.
- */
- @SuppressWarnings("unchecked")
- @Test(groups = "eventbus") @SpecAssertion(section="7.3")
- public final void testGetEventBindingTypes() throws Exception
- {
- Observer<Event> o = new ObserverImpl<Event>(tuna, om, Event.class);
- //assert o.getEventBindingTypes().size() == 1;
- //assert Reflections.annotationSetMatches(o.getEventBindingTypes(),
Asynchronous.class);
- //assert o.getEventType().equals(Event.class);
- }
-
- /**
- * Test method for
- * {@link org.jboss.webbeans.event.ObserverImpl#getEventType()}.
- *
- * @throws
- * @throws Exception
- */
- @Test(groups = "eventbus") @SpecAssertion(section="7.3")
- public final void testGetEventType() throws Exception
- {
- Observer<Event> o = new ObserverImpl<Event>(tuna, om, Event.class);
- //assert o.getEventType().equals(Event.class);
- }
-
- /**
- * Test method for
* {@link org.jboss.webbeans.event.ObserverImpl#notify(javax.webbeans.Container,
java.lang.Object)}
* .
*/
- @Test(groups = "eventbus")
@SpecAssertion(section={"7.2","7.3"})
+ @Test(groups = "eventbus") @SpecAssertion(section={"7.5.7"})
public final void testNotify() throws Exception
{
AnObserver observerInstance = new AnObserver();
- Observer<Event> observer = new MockObserverImpl<Event>(tuna, om,
Event.class);
- ((MockObserverImpl<Event>) observer).setInstance(observerInstance);
- Event event = new Event();
+ Observer<SampleEvent> observer = new
MockObserverImpl<SampleEvent>(tuna, om, SampleEvent.class);
+ ((MockObserverImpl<SampleEvent>) observer).setInstance(observerInstance);
+ SampleEvent event = new SampleEvent();
observer.notify(event);
assert observerInstance.notified;
}
Added: ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/annotations/Role.java
===================================================================
--- ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/annotations/Role.java
(rev 0)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/annotations/Role.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -0,0 +1,6 @@
+package org.jboss.webbeans.test.annotations;
+
+public @interface Role
+{
+ String value();
+}
Property changes on:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/annotations/Role.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/bindings/RoleBinding.java
===================================================================
--- ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/bindings/RoleBinding.java
(rev 0)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/bindings/RoleBinding.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -0,0 +1,21 @@
+package org.jboss.webbeans.test.bindings;
+
+import javax.webbeans.AnnotationLiteral;
+
+import org.jboss.webbeans.test.annotations.Role;
+
+public class RoleBinding extends AnnotationLiteral<Role> implements Role
+{
+ private String value = null;
+
+ public RoleBinding(String value)
+ {
+ this.value = value;
+ }
+
+ public String value()
+ {
+ return value;
+ }
+
+}
Property changes on:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/bindings/RoleBinding.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockManagerImpl.java
===================================================================
---
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockManagerImpl.java 2008-10-26
20:39:54 UTC (rev 171)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockManagerImpl.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -6,12 +6,18 @@
import java.util.List;
import java.util.Set;
+import javax.webbeans.Observer;
+import javax.webbeans.TypeLiteral;
+import javax.webbeans.manager.Manager;
+
import org.jboss.webbeans.ManagerImpl;
public class MockManagerImpl extends ManagerImpl
{
private Object event = null;
+ private Class<? extends Object> eventType = null;
private Annotation[] eventBindings = null;
+ private Observer<?> observer = null;
public MockManagerImpl(List<Class<? extends Annotation>>
enabledDeploymentTypes)
{
@@ -29,6 +35,33 @@
this.eventBindings = bindings;
}
+ /* (non-Javadoc)
+ * @see org.jboss.webbeans.ManagerImpl#addObserver(javax.webbeans.Observer,
java.lang.Class, java.lang.annotation.Annotation[])
+ */
+ @Override
+ public <T> Manager addObserver(Observer<T> observer, Class<T>
eventType,
+ Annotation... bindings)
+ {
+ this.observer = observer;
+ this.eventType = eventType;
+ this.eventBindings = bindings;
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.webbeans.ManagerImpl#addObserver(javax.webbeans.Observer,
javax.webbeans.TypeLiteral, java.lang.annotation.Annotation[])
+ */
+ @Override
+ public <T> Manager addObserver(Observer<T> observer,
+ TypeLiteral<T> eventType, Annotation... bindings)
+ {
+ this.observer = observer;
+ // TODO Fix the event type based on the type literal being passed. Not clear how
to get the actual T.
+ this.eventType = null;
+ this.eventBindings = bindings;
+ return this;
+ }
+
/**
* Retrieves the event which was last fired with this manager.
* @return the event
@@ -49,4 +82,20 @@
return null;
}
+ /**
+ * @return the eventType
+ */
+ public final Class<?> getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * @return the observer
+ */
+ public final Observer<?> getObserver()
+ {
+ return observer;
+ }
+
}
Modified:
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockObserverImpl.java
===================================================================
---
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockObserverImpl.java 2008-10-26
20:39:54 UTC (rev 171)
+++
ri/trunk/webbeans-ri/src/test/java/org/jboss/webbeans/test/mock/MockObserverImpl.java 2008-10-27
09:59:35 UTC (rev 172)
@@ -1,7 +1,5 @@
package org.jboss.webbeans.test.mock;
-import javax.webbeans.manager.Manager;
-
import org.jboss.webbeans.event.ObserverImpl;
import org.jboss.webbeans.injectable.InjectableMethod;
import org.jboss.webbeans.model.bean.BeanModel;
@@ -24,7 +22,7 @@
}
@Override
- protected final Object getInstance(Manager manager) {
+ protected final Object getInstance() {
return specializedInstance;
}