Permalink
Browse files

WELD-1148 Custom transactional observer not deferred for later invoca…

…tion

Conflicts:

	impl/src/main/java/org/jboss/weld/bootstrap/WeldBootstrap.java
	impl/src/main/java/org/jboss/weld/event/GlobalObserverNotifierService.java
	impl/src/main/java/org/jboss/weld/event/ObserverFactory.java
	impl/src/main/java/org/jboss/weld/event/ObserverMethodImpl.java
	impl/src/main/java/org/jboss/weld/event/ObserverNotifier.java
	impl/src/main/java/org/jboss/weld/event/TransactionalObserverMethodImpl.java
	impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java
	jboss-tck-runner/1.1/src/test/resources/tck-tests.xml
  • Loading branch information...
1 parent a794311 commit 8a2b5d7c44b6079c558ac936fea21bb18fb0a2f7 @jharting jharting committed Jun 26, 2012
Showing with 809 additions and 192 deletions.
  1. +2 −2 impl/src/main/java/org/jboss/weld/bootstrap/WeldBootstrap.java
  2. +2 −2 impl/src/main/java/org/jboss/weld/bootstrap/events/AbstractContainerEvent.java
  3. +11 −8 impl/src/main/java/org/jboss/weld/event/DeferredEventNotification.java
  4. +1 −1 impl/src/main/java/org/jboss/weld/event/EventImpl.java
  5. +1 −9 impl/src/main/java/org/jboss/weld/event/ObserverFactory.java
  6. +1 −1 impl/src/main/java/org/jboss/weld/event/ObserverMethodImpl.java
  7. +119 −0 impl/src/main/java/org/jboss/weld/event/ObserverNotifier.java
  8. +0 −84 impl/src/main/java/org/jboss/weld/event/TransactionalObserverMethodImpl.java
  9. +74 −0 impl/src/main/java/org/jboss/weld/event/TransactionalObserverNotifier.java
  10. +34 −73 impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java
  11. +8 −8 impl/src/main/java/org/jboss/weld/resolution/ResolvableBuilder.java
  12. +7 −4 impl/src/main/java/org/jboss/weld/util/Observers.java
  13. +223 −0 ...c/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/ActionSequence.java
  14. +85 −0 ...boss/weld/tests/cditck11/event/observer/transactional/custom/CustomTransactionalObserverTest.java
  15. +21 −0 ...lian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/Giraffe.java
  16. +91 −0 ...java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeCustomObserver.java
  17. +47 −0 .../test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeObserver.java
  18. +45 −0 ...c/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeService.java
  19. +37 −0 ...est/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/ObserverExtension.java
@@ -393,12 +393,12 @@ public Bootstrap endInitialization() {
// clear the TypeSafeResolvers, so data that is only used at startup
// is not kept around using up memory
deploymentManager.getBeanResolver().clear();
- deploymentManager.getObserverResolver().clear();
+ deploymentManager.getAccessibleObserverNotifier().clear();
deploymentManager.getDecoratorResolver().clear();
for (Entry<BeanDeploymentArchive, BeanDeployment> entry : beanDeployments.entrySet()) {
BeanManagerImpl beanManager = entry.getValue().getBeanManager();
beanManager.getBeanResolver().clear();
- beanManager.getObserverResolver().clear();
+ beanManager.getAccessibleObserverNotifier().clear();
beanManager.getDecoratorResolver().clear();
for (Bean<?> bean : beanManager.getBeans()) {
if (bean instanceof RIBean<?>) {
@@ -57,7 +57,7 @@ protected BeanManagerImpl getBeanManager() {
protected void fire() {
Type eventType = new ParameterizedTypeImpl(getRawType(), getActualTypeArguments(), null);
try {
- beanManager.fireEvent(eventType, this);
+ beanManager.getAccessibleObserverNotifier().fireEvent(eventType, this);
} catch (Exception e) {
getErrors().add(e);
}
@@ -69,7 +69,7 @@ protected void fire(Map<BeanDeploymentArchive, BeanDeployment> beanDeployments)
Set<ObserverMethod<Object>> observers = new HashSet<ObserverMethod<Object>>();
Type eventType = new ParameterizedTypeImpl(getRawType(), getActualTypeArguments(), null);
for (BeanDeployment beanDeployment : beanDeployments.values()) {
- observers.addAll(beanDeployment.getBeanManager().resolveObserverMethods(eventType));
+ observers.addAll(beanDeployment.getBeanManager().getAccessibleObserverNotifier().resolveObserverMethods(eventType));
}
for (ObserverMethod<Object> observerMethod : observers) {
observerMethod.notify(this);
@@ -16,29 +16,32 @@
*/
package org.jboss.weld.event;
+import static org.jboss.weld.logging.Category.EVENT;
+import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
+import static org.jboss.weld.logging.messages.EventMessage.ASYNC_FIRE;
+import static org.jboss.weld.logging.messages.EventMessage.ASYNC_OBSERVER_FAILURE;
+
+import javax.enterprise.inject.spi.ObserverMethod;
+
import org.jboss.weld.Container;
import org.jboss.weld.context.RequestContext;
import org.jboss.weld.context.unbound.UnboundLiteral;
import org.slf4j.cal10n.LocLogger;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLogger.Level;
-import static org.jboss.weld.logging.Category.EVENT;
-import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
-import static org.jboss.weld.logging.messages.EventMessage.ASYNC_FIRE;
-import static org.jboss.weld.logging.messages.EventMessage.ASYNC_OBSERVER_FAILURE;
-
/**
* A task that will notify the observer of a specific event at some future time.
*
* @author David Allen
+ * @author Jozef Hartinger
*/
public class DeferredEventNotification<T> implements Runnable {
private static final LocLogger log = loggerFactory().getLogger(EVENT);
private static final XLogger xLog = loggerFactory().getXLogger(EVENT);
// The observer
- protected final ObserverMethodImpl<T, ?> observer;
+ protected final ObserverMethod<? super T> observer;
// The event object
protected final T event;
@@ -48,7 +51,7 @@
* @param observer The observer to be notified
* @param event The event being fired
*/
- public DeferredEventNotification(T event, ObserverMethodImpl<T, ?> observer) {
+ public DeferredEventNotification(T event, ObserverMethod<? super T> observer) {
this.observer = observer;
this.event = event;
}
@@ -60,7 +63,7 @@ public void run() {
@Override
protected void execute() {
- observer.sendEvent(event);
+ observer.notify(event);
}
}.run();
@@ -66,7 +66,7 @@ public String toString() {
}
public void fire(T event) {
- getBeanManager().fireEvent(getType(), event, getQualifiers());
+ getBeanManager().getAccessibleObserverNotifier().fireEvent(getType(), event, getQualifiers());
}
public Event<T> select(Annotation... qualifiers) {
@@ -20,7 +20,6 @@
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.introspector.WeldParameter;
import org.jboss.weld.manager.BeanManagerImpl;
-import org.jboss.weld.transaction.spi.TransactionServices;
import javax.enterprise.event.Observes;
import javax.enterprise.event.TransactionPhase;
@@ -40,14 +39,7 @@
* @return An observer implementation built from the method abstraction
*/
public static <T, X> ObserverMethodImpl<T, X> create(WeldMethod<T, ? super X> method, RIBean<X> declaringBean, BeanManagerImpl manager) {
- ObserverMethodImpl<T, X> result = null;
- TransactionPhase transactionPhase = getTransactionalPhase(method);
- if (manager.getServices().contains(TransactionServices.class) && !transactionPhase.equals(TransactionPhase.IN_PROGRESS)) {
- result = new TransactionalObserverMethodImpl<T, X>(method, declaringBean, transactionPhase, manager);
- } else {
- result = new ObserverMethodImpl<T, X>(method, declaringBean, manager);
- }
- return result;
+ return new ObserverMethodImpl<T, X>(method, declaringBean, manager);
}
/**
@@ -106,7 +106,7 @@ protected ObserverMethodImpl(final WeldMethod<T, ? super X> observer, final RIBe
this.id = ID_PREFIX + ID_SEPARATOR + /*manager.getId() + ID_SEPARATOR +*/ ObserverMethod.class.getSimpleName() + ID_SEPARATOR + declaringBean.getBeanClass().getName() + "." + observer.getSignature();
this.bindings = new HashSet<Annotation>(eventArgument.getMetaAnnotations(Qualifier.class));
this.reception = eventArgument.getAnnotation(Observes.class).notifyObserver();
- transactionPhase = TransactionPhase.IN_PROGRESS;
+ transactionPhase = ObserverFactory.getTransactionalPhase(observer);
this.injectionPoints = new HashSet<WeldInjectionPoint<?, ?>>();
this.newInjectionPoints = new HashSet<WeldInjectionPoint<?, ?>>();
@@ -0,0 +1,119 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.event;
+
+import static org.jboss.weld.util.reflection.Reflections.cast;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.jboss.weld.bootstrap.api.ServiceRegistry;
+import org.jboss.weld.literal.AnyLiteral;
+import org.jboss.weld.metadata.cache.MetaAnnotationStore;
+import org.jboss.weld.resolution.Resolvable;
+import org.jboss.weld.resolution.ResolvableBuilder;
+import org.jboss.weld.resolution.TypeSafeObserverResolver;
+import org.jboss.weld.resources.SharedObjectCache;
+import org.jboss.weld.transaction.spi.TransactionServices;
+import org.jboss.weld.util.Observers;
+
+/**
+ * Provides event-related operations such sa observer method resolution and event delivery.
+ *
+ * @author Jozef Hartinger
+ * @author David Allen
+ *
+ */
+public class ObserverNotifier {
+
+ public static ObserverNotifier of(TypeSafeObserverResolver resolver, ServiceRegistry services) {
+ if (services.contains(TransactionServices.class)) {
+ return new TransactionalObserverNotifier(resolver, services);
+ } else {
+ return new ObserverNotifier(resolver, services);
+ }
+ }
+
+ private final TypeSafeObserverResolver resolver;
+ private final SharedObjectCache sharedObjectCache;
+ private final MetaAnnotationStore store;
+
+ protected ObserverNotifier(TypeSafeObserverResolver resolver, ServiceRegistry services) {
+ this.resolver = resolver;
+ this.sharedObjectCache = services.get(SharedObjectCache.class);
+ this.store = services.get(MetaAnnotationStore.class);
+ }
+
+ public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... bindings) {
+ Observers.checkEventObjectType(sharedObjectCache, event);
+ return this.<T>resolveObserverMethods(event.getClass(), bindings);
+ }
+
+ public void fireEvent(Object event, Annotation... qualifiers) {
+ fireEvent(event.getClass(), event, qualifiers);
+ }
+
+ public void fireEvent(Type eventType, Object event, Annotation... qualifiers) {
+ Observers.checkEventObjectType(sharedObjectCache, event);
+ notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
+ }
+
+ public void fireEvent(Type eventType, Object event, Set<Annotation> qualifiers) {
+ Observers.checkEventObjectType(sharedObjectCache, event);
+ notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
+ }
+
+ private <T> void notifyObservers(final T event, final Set<ObserverMethod<? super T>> observers) {
+ for (ObserverMethod<? super T> observer : observers) {
+ notifyObserver(event, observer);
+ }
+ }
+
+ public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Annotation... qualifiers) {
+ // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
+ Resolvable resolvable = new ResolvableBuilder(store)
+ .addTypes(sharedObjectCache.getTypeClosure(eventType))
+ .addType(Object.class)
+ .addQualifiers(qualifiers)
+ .addQualifierIfAbsent(AnyLiteral.INSTANCE)
+ .create();
+ return cast(resolver.resolve(resolvable, true));
+ }
+
+ public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Set<Annotation> qualifiers) {
+ // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
+ Set<Type> typeClosure = sharedObjectCache.getTypeClosure(eventType);
+ Resolvable resolvable = new ResolvableBuilder(store)
+ .addTypes(typeClosure)
+ .addType(Object.class)
+ .addQualifiers(qualifiers)
+ .addQualifierIfAbsent(AnyLiteral.INSTANCE)
+ .create();
+ return cast(resolver.resolve(resolvable, true));
+ }
+
+ public void clear() {
+ resolver.clear();
+ }
+
+ protected <T> void notifyObserver(final T event, final ObserverMethod<? super T> observer) {
+ observer.notify(event);
+ }
+}
@@ -1,84 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jboss.weld.event;
-
-import org.jboss.weld.bean.RIBean;
-import org.jboss.weld.introspector.WeldMethod;
-import org.jboss.weld.manager.BeanManagerImpl;
-import org.jboss.weld.transaction.spi.TransactionServices;
-
-import javax.enterprise.event.TransactionPhase;
-import javax.transaction.Synchronization;
-
-/**
- * @author David Allen
- */
-class TransactionalObserverMethodImpl<T, X> extends ObserverMethodImpl<T, X> {
-
- /**
- * Creates a new instance of a transactional observer method implicit object.
- *
- * @param observer The observer method
- * @param observerBean The bean declaring the observer method
- * @param manager The JCDI manager in use
- */
- protected TransactionalObserverMethodImpl(WeldMethod<T, ? super X> observer, RIBean<X> observerBean, TransactionPhase transactionPhase, BeanManagerImpl manager) {
- super(observer, observerBean, manager);
- this.transactionPhase = transactionPhase;
- }
-
- @Override
- public void initialize() {
- super.initialize();
- }
-
- @Override
- public void notify(T event) {
- if (ignore(event)) {
- return;
- }
- TransactionServices txs = beanManager.getServices().get(TransactionServices.class);
- if (txs != null && txs.isTransactionActive()) {
- deferEvent(event);
- } else {
- sendEvent(event);
- }
- }
-
- /**
- * Defers an event for processing in a later phase of the current
- * transaction.
- *
- * @param event The event object
- */
- private void deferEvent(T event) {
- DeferredEventNotification<T> deferredEvent = new DeferredEventNotification<T>(event, this);
-
- Synchronization synchronization = null;
- if (transactionPhase.equals(TransactionPhase.BEFORE_COMPLETION)) {
- synchronization = new TransactionSynchronizedRunnable(deferredEvent, true);
- } else if (transactionPhase.equals(TransactionPhase.AFTER_COMPLETION)) {
- synchronization = new TransactionSynchronizedRunnable(deferredEvent, false);
- } else if (transactionPhase.equals(TransactionPhase.AFTER_SUCCESS)) {
- synchronization = new TransactionSynchronizedRunnable(deferredEvent, Status.SUCCESS);
- } else if (transactionPhase.equals(TransactionPhase.AFTER_FAILURE)) {
- synchronization = new TransactionSynchronizedRunnable(deferredEvent, Status.FAILURE);
- }
- beanManager.getServices().get(TransactionServices.class).registerSynchronization(synchronization);
- }
-
-}
Oops, something went wrong.

0 comments on commit 8a2b5d7

Please sign in to comment.