Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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...
commit 8a2b5d7c44b6079c558ac936fea21bb18fb0a2f7 1 parent a794311
Jozef Hartinger jharting authored

Showing 19 changed files with 809 additions and 192 deletions. Show diff stats Hide diff stats

  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 ...uillian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/ActionSequence.java
  14. +85 0 ...java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/CustomTransactionalObserverTest.java
  15. +21 0 tests-arquillian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/Giraffe.java
  16. +91 0 .../src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeCustomObserver.java
  17. +47 0 ...illian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeObserver.java
  18. +45 0 ...uillian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/GiraffeService.java
  19. +37 0 ...lian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/ObserverExtension.java
4 impl/src/main/java/org/jboss/weld/bootstrap/WeldBootstrap.java
@@ -393,12 +393,12 @@ public Bootstrap endInitialization() {
393 393 // clear the TypeSafeResolvers, so data that is only used at startup
394 394 // is not kept around using up memory
395 395 deploymentManager.getBeanResolver().clear();
396   - deploymentManager.getObserverResolver().clear();
  396 + deploymentManager.getAccessibleObserverNotifier().clear();
397 397 deploymentManager.getDecoratorResolver().clear();
398 398 for (Entry<BeanDeploymentArchive, BeanDeployment> entry : beanDeployments.entrySet()) {
399 399 BeanManagerImpl beanManager = entry.getValue().getBeanManager();
400 400 beanManager.getBeanResolver().clear();
401   - beanManager.getObserverResolver().clear();
  401 + beanManager.getAccessibleObserverNotifier().clear();
402 402 beanManager.getDecoratorResolver().clear();
403 403 for (Bean<?> bean : beanManager.getBeans()) {
404 404 if (bean instanceof RIBean<?>) {
4 impl/src/main/java/org/jboss/weld/bootstrap/events/AbstractContainerEvent.java
@@ -57,7 +57,7 @@ protected BeanManagerImpl getBeanManager() {
57 57 protected void fire() {
58 58 Type eventType = new ParameterizedTypeImpl(getRawType(), getActualTypeArguments(), null);
59 59 try {
60   - beanManager.fireEvent(eventType, this);
  60 + beanManager.getAccessibleObserverNotifier().fireEvent(eventType, this);
61 61 } catch (Exception e) {
62 62 getErrors().add(e);
63 63 }
@@ -69,7 +69,7 @@ protected void fire(Map<BeanDeploymentArchive, BeanDeployment> beanDeployments)
69 69 Set<ObserverMethod<Object>> observers = new HashSet<ObserverMethod<Object>>();
70 70 Type eventType = new ParameterizedTypeImpl(getRawType(), getActualTypeArguments(), null);
71 71 for (BeanDeployment beanDeployment : beanDeployments.values()) {
72   - observers.addAll(beanDeployment.getBeanManager().resolveObserverMethods(eventType));
  72 + observers.addAll(beanDeployment.getBeanManager().getAccessibleObserverNotifier().resolveObserverMethods(eventType));
73 73 }
74 74 for (ObserverMethod<Object> observerMethod : observers) {
75 75 observerMethod.notify(this);
19 impl/src/main/java/org/jboss/weld/event/DeferredEventNotification.java
@@ -16,6 +16,13 @@
16 16 */
17 17 package org.jboss.weld.event;
18 18
  19 +import static org.jboss.weld.logging.Category.EVENT;
  20 +import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
  21 +import static org.jboss.weld.logging.messages.EventMessage.ASYNC_FIRE;
  22 +import static org.jboss.weld.logging.messages.EventMessage.ASYNC_OBSERVER_FAILURE;
  23 +
  24 +import javax.enterprise.inject.spi.ObserverMethod;
  25 +
19 26 import org.jboss.weld.Container;
20 27 import org.jboss.weld.context.RequestContext;
21 28 import org.jboss.weld.context.unbound.UnboundLiteral;
@@ -23,22 +30,18 @@
23 30 import org.slf4j.ext.XLogger;
24 31 import org.slf4j.ext.XLogger.Level;
25 32
26   -import static org.jboss.weld.logging.Category.EVENT;
27   -import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
28   -import static org.jboss.weld.logging.messages.EventMessage.ASYNC_FIRE;
29   -import static org.jboss.weld.logging.messages.EventMessage.ASYNC_OBSERVER_FAILURE;
30   -
31 33 /**
32 34 * A task that will notify the observer of a specific event at some future time.
33 35 *
34 36 * @author David Allen
  37 + * @author Jozef Hartinger
35 38 */
36 39 public class DeferredEventNotification<T> implements Runnable {
37 40 private static final LocLogger log = loggerFactory().getLogger(EVENT);
38 41 private static final XLogger xLog = loggerFactory().getXLogger(EVENT);
39 42
40 43 // The observer
41   - protected final ObserverMethodImpl<T, ?> observer;
  44 + protected final ObserverMethod<? super T> observer;
42 45 // The event object
43 46 protected final T event;
44 47
@@ -48,7 +51,7 @@
48 51 * @param observer The observer to be notified
49 52 * @param event The event being fired
50 53 */
51   - public DeferredEventNotification(T event, ObserverMethodImpl<T, ?> observer) {
  54 + public DeferredEventNotification(T event, ObserverMethod<? super T> observer) {
52 55 this.observer = observer;
53 56 this.event = event;
54 57 }
@@ -60,7 +63,7 @@ public void run() {
60 63
61 64 @Override
62 65 protected void execute() {
63   - observer.sendEvent(event);
  66 + observer.notify(event);
64 67 }
65 68
66 69 }.run();
2  impl/src/main/java/org/jboss/weld/event/EventImpl.java
@@ -66,7 +66,7 @@ public String toString() {
66 66 }
67 67
68 68 public void fire(T event) {
69   - getBeanManager().fireEvent(getType(), event, getQualifiers());
  69 + getBeanManager().getAccessibleObserverNotifier().fireEvent(getType(), event, getQualifiers());
70 70 }
71 71
72 72 public Event<T> select(Annotation... qualifiers) {
10 impl/src/main/java/org/jboss/weld/event/ObserverFactory.java
@@ -20,7 +20,6 @@
20 20 import org.jboss.weld.introspector.WeldMethod;
21 21 import org.jboss.weld.introspector.WeldParameter;
22 22 import org.jboss.weld.manager.BeanManagerImpl;
23   -import org.jboss.weld.transaction.spi.TransactionServices;
24 23
25 24 import javax.enterprise.event.Observes;
26 25 import javax.enterprise.event.TransactionPhase;
@@ -40,14 +39,7 @@
40 39 * @return An observer implementation built from the method abstraction
41 40 */
42 41 public static <T, X> ObserverMethodImpl<T, X> create(WeldMethod<T, ? super X> method, RIBean<X> declaringBean, BeanManagerImpl manager) {
43   - ObserverMethodImpl<T, X> result = null;
44   - TransactionPhase transactionPhase = getTransactionalPhase(method);
45   - if (manager.getServices().contains(TransactionServices.class) && !transactionPhase.equals(TransactionPhase.IN_PROGRESS)) {
46   - result = new TransactionalObserverMethodImpl<T, X>(method, declaringBean, transactionPhase, manager);
47   - } else {
48   - result = new ObserverMethodImpl<T, X>(method, declaringBean, manager);
49   - }
50   - return result;
  42 + return new ObserverMethodImpl<T, X>(method, declaringBean, manager);
51 43 }
52 44
53 45 /**
2  impl/src/main/java/org/jboss/weld/event/ObserverMethodImpl.java
@@ -106,7 +106,7 @@ protected ObserverMethodImpl(final WeldMethod<T, ? super X> observer, final RIBe
106 106 this.id = ID_PREFIX + ID_SEPARATOR + /*manager.getId() + ID_SEPARATOR +*/ ObserverMethod.class.getSimpleName() + ID_SEPARATOR + declaringBean.getBeanClass().getName() + "." + observer.getSignature();
107 107 this.bindings = new HashSet<Annotation>(eventArgument.getMetaAnnotations(Qualifier.class));
108 108 this.reception = eventArgument.getAnnotation(Observes.class).notifyObserver();
109   - transactionPhase = TransactionPhase.IN_PROGRESS;
  109 + transactionPhase = ObserverFactory.getTransactionalPhase(observer);
110 110
111 111 this.injectionPoints = new HashSet<WeldInjectionPoint<?, ?>>();
112 112 this.newInjectionPoints = new HashSet<WeldInjectionPoint<?, ?>>();
119 impl/src/main/java/org/jboss/weld/event/ObserverNotifier.java
... ... @@ -0,0 +1,119 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + * http://www.apache.org/licenses/LICENSE-2.0
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS,
  13 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + * See the License for the specific language governing permissions and
  15 + * limitations under the License.
  16 + */
  17 +package org.jboss.weld.event;
  18 +
  19 +import static org.jboss.weld.util.reflection.Reflections.cast;
  20 +
  21 +import java.lang.annotation.Annotation;
  22 +import java.lang.reflect.Type;
  23 +import java.util.Set;
  24 +
  25 +import javax.enterprise.inject.spi.ObserverMethod;
  26 +
  27 +import org.jboss.weld.bootstrap.api.ServiceRegistry;
  28 +import org.jboss.weld.literal.AnyLiteral;
  29 +import org.jboss.weld.metadata.cache.MetaAnnotationStore;
  30 +import org.jboss.weld.resolution.Resolvable;
  31 +import org.jboss.weld.resolution.ResolvableBuilder;
  32 +import org.jboss.weld.resolution.TypeSafeObserverResolver;
  33 +import org.jboss.weld.resources.SharedObjectCache;
  34 +import org.jboss.weld.transaction.spi.TransactionServices;
  35 +import org.jboss.weld.util.Observers;
  36 +
  37 +/**
  38 + * Provides event-related operations such sa observer method resolution and event delivery.
  39 + *
  40 + * @author Jozef Hartinger
  41 + * @author David Allen
  42 + *
  43 + */
  44 +public class ObserverNotifier {
  45 +
  46 + public static ObserverNotifier of(TypeSafeObserverResolver resolver, ServiceRegistry services) {
  47 + if (services.contains(TransactionServices.class)) {
  48 + return new TransactionalObserverNotifier(resolver, services);
  49 + } else {
  50 + return new ObserverNotifier(resolver, services);
  51 + }
  52 + }
  53 +
  54 + private final TypeSafeObserverResolver resolver;
  55 + private final SharedObjectCache sharedObjectCache;
  56 + private final MetaAnnotationStore store;
  57 +
  58 + protected ObserverNotifier(TypeSafeObserverResolver resolver, ServiceRegistry services) {
  59 + this.resolver = resolver;
  60 + this.sharedObjectCache = services.get(SharedObjectCache.class);
  61 + this.store = services.get(MetaAnnotationStore.class);
  62 + }
  63 +
  64 + public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... bindings) {
  65 + Observers.checkEventObjectType(sharedObjectCache, event);
  66 + return this.<T>resolveObserverMethods(event.getClass(), bindings);
  67 + }
  68 +
  69 + public void fireEvent(Object event, Annotation... qualifiers) {
  70 + fireEvent(event.getClass(), event, qualifiers);
  71 + }
  72 +
  73 + public void fireEvent(Type eventType, Object event, Annotation... qualifiers) {
  74 + Observers.checkEventObjectType(sharedObjectCache, event);
  75 + notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
  76 + }
  77 +
  78 + public void fireEvent(Type eventType, Object event, Set<Annotation> qualifiers) {
  79 + Observers.checkEventObjectType(sharedObjectCache, event);
  80 + notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
  81 + }
  82 +
  83 + private <T> void notifyObservers(final T event, final Set<ObserverMethod<? super T>> observers) {
  84 + for (ObserverMethod<? super T> observer : observers) {
  85 + notifyObserver(event, observer);
  86 + }
  87 + }
  88 +
  89 + public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Annotation... qualifiers) {
  90 + // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
  91 + Resolvable resolvable = new ResolvableBuilder(store)
  92 + .addTypes(sharedObjectCache.getTypeClosure(eventType))
  93 + .addType(Object.class)
  94 + .addQualifiers(qualifiers)
  95 + .addQualifierIfAbsent(AnyLiteral.INSTANCE)
  96 + .create();
  97 + return cast(resolver.resolve(resolvable, true));
  98 + }
  99 +
  100 + public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Set<Annotation> qualifiers) {
  101 + // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
  102 + Set<Type> typeClosure = sharedObjectCache.getTypeClosure(eventType);
  103 + Resolvable resolvable = new ResolvableBuilder(store)
  104 + .addTypes(typeClosure)
  105 + .addType(Object.class)
  106 + .addQualifiers(qualifiers)
  107 + .addQualifierIfAbsent(AnyLiteral.INSTANCE)
  108 + .create();
  109 + return cast(resolver.resolve(resolvable, true));
  110 + }
  111 +
  112 + public void clear() {
  113 + resolver.clear();
  114 + }
  115 +
  116 + protected <T> void notifyObserver(final T event, final ObserverMethod<? super T> observer) {
  117 + observer.notify(event);
  118 + }
  119 +}
84 impl/src/main/java/org/jboss/weld/event/TransactionalObserverMethodImpl.java
... ... @@ -1,84 +0,0 @@
1   -/*
2   - * JBoss, Home of Professional Open Source
3   - * Copyright 2008, Red Hat, Inc., and individual contributors
4   - * by the @authors tag. See the copyright.txt in the distribution for a
5   - * full listing of individual contributors.
6   - *
7   - * Licensed under the Apache License, Version 2.0 (the "License");
8   - * you may not use this file except in compliance with the License.
9   - * You may obtain a copy of the License at
10   - * http://www.apache.org/licenses/LICENSE-2.0
11   - * Unless required by applicable law or agreed to in writing, software
12   - * distributed under the License is distributed on an "AS IS" BASIS,
13   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   - * See the License for the specific language governing permissions and
15   - * limitations under the License.
16   - */
17   -package org.jboss.weld.event;
18   -
19   -import org.jboss.weld.bean.RIBean;
20   -import org.jboss.weld.introspector.WeldMethod;
21   -import org.jboss.weld.manager.BeanManagerImpl;
22   -import org.jboss.weld.transaction.spi.TransactionServices;
23   -
24   -import javax.enterprise.event.TransactionPhase;
25   -import javax.transaction.Synchronization;
26   -
27   -/**
28   - * @author David Allen
29   - */
30   -class TransactionalObserverMethodImpl<T, X> extends ObserverMethodImpl<T, X> {
31   -
32   - /**
33   - * Creates a new instance of a transactional observer method implicit object.
34   - *
35   - * @param observer The observer method
36   - * @param observerBean The bean declaring the observer method
37   - * @param manager The JCDI manager in use
38   - */
39   - protected TransactionalObserverMethodImpl(WeldMethod<T, ? super X> observer, RIBean<X> observerBean, TransactionPhase transactionPhase, BeanManagerImpl manager) {
40   - super(observer, observerBean, manager);
41   - this.transactionPhase = transactionPhase;
42   - }
43   -
44   - @Override
45   - public void initialize() {
46   - super.initialize();
47   - }
48   -
49   - @Override
50   - public void notify(T event) {
51   - if (ignore(event)) {
52   - return;
53   - }
54   - TransactionServices txs = beanManager.getServices().get(TransactionServices.class);
55   - if (txs != null && txs.isTransactionActive()) {
56   - deferEvent(event);
57   - } else {
58   - sendEvent(event);
59   - }
60   - }
61   -
62   - /**
63   - * Defers an event for processing in a later phase of the current
64   - * transaction.
65   - *
66   - * @param event The event object
67   - */
68   - private void deferEvent(T event) {
69   - DeferredEventNotification<T> deferredEvent = new DeferredEventNotification<T>(event, this);
70   -
71   - Synchronization synchronization = null;
72   - if (transactionPhase.equals(TransactionPhase.BEFORE_COMPLETION)) {
73   - synchronization = new TransactionSynchronizedRunnable(deferredEvent, true);
74   - } else if (transactionPhase.equals(TransactionPhase.AFTER_COMPLETION)) {
75   - synchronization = new TransactionSynchronizedRunnable(deferredEvent, false);
76   - } else if (transactionPhase.equals(TransactionPhase.AFTER_SUCCESS)) {
77   - synchronization = new TransactionSynchronizedRunnable(deferredEvent, Status.SUCCESS);
78   - } else if (transactionPhase.equals(TransactionPhase.AFTER_FAILURE)) {
79   - synchronization = new TransactionSynchronizedRunnable(deferredEvent, Status.FAILURE);
80   - }
81   - beanManager.getServices().get(TransactionServices.class).registerSynchronization(synchronization);
82   - }
83   -
84   -}
74 impl/src/main/java/org/jboss/weld/event/TransactionalObserverNotifier.java
... ... @@ -0,0 +1,74 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + * http://www.apache.org/licenses/LICENSE-2.0
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS,
  13 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + * See the License for the specific language governing permissions and
  15 + * limitations under the License.
  16 + */
  17 +package org.jboss.weld.event;
  18 +
  19 +import javax.enterprise.event.TransactionPhase;
  20 +import javax.enterprise.inject.spi.ObserverMethod;
  21 +
  22 +import org.jboss.weld.bootstrap.api.ServiceRegistry;
  23 +import org.jboss.weld.resolution.TypeSafeObserverResolver;
  24 +import org.jboss.weld.transaction.spi.TransactionServices;
  25 +
  26 +/**
  27 + * {@link ObserverNotifier} whith support for transactional observer methods.
  28 + *
  29 + * @author Jozef Hartinger
  30 + *
  31 + */
  32 +public class TransactionalObserverNotifier extends ObserverNotifier {
  33 +
  34 + private final TransactionServices transactionServices;
  35 +
  36 + protected TransactionalObserverNotifier(TypeSafeObserverResolver resolver, ServiceRegistry services) {
  37 + super(resolver, services);
  38 + this.transactionServices = services.get(TransactionServices.class);
  39 + }
  40 +
  41 + @Override
  42 + protected <T> void notifyObserver(final T event, final ObserverMethod<? super T> observer) {
  43 + if (immediateDispatch(observer)) {
  44 + super.notifyObserver(event, observer);
  45 + } else {
  46 + deferNotification(event, observer);
  47 + }
  48 + }
  49 +
  50 + private boolean immediateDispatch(ObserverMethod<?> observer) {
  51 + return TransactionPhase.IN_PROGRESS.equals(observer.getTransactionPhase()) || transactionServices == null || !transactionServices.isTransactionActive();
  52 + }
  53 +
  54 + /**
  55 + * Defers an event for processing in a later phase of the current
  56 + * transaction.
  57 + *
  58 + * @param event The event object
  59 + */
  60 + private <T> void deferNotification(final T event, final ObserverMethod<? super T> observer) {
  61 + DeferredEventNotification<T> deferredEvent = new DeferredEventNotification<T>(event, observer);
  62 + TransactionPhase transactionPhase = observer.getTransactionPhase();
  63 +
  64 + if (transactionPhase.equals(TransactionPhase.BEFORE_COMPLETION)) {
  65 + transactionServices.registerSynchronization(new TransactionSynchronizedRunnable(deferredEvent, true));
  66 + } else if (transactionPhase.equals(TransactionPhase.AFTER_COMPLETION)) {
  67 + transactionServices.registerSynchronization(new TransactionSynchronizedRunnable(deferredEvent, false));
  68 + } else if (transactionPhase.equals(TransactionPhase.AFTER_SUCCESS)) {
  69 + transactionServices.registerSynchronization(new TransactionSynchronizedRunnable(deferredEvent, Status.SUCCESS));
  70 + } else if (transactionPhase.equals(TransactionPhase.AFTER_FAILURE)) {
  71 + transactionServices.registerSynchronization(new TransactionSynchronizedRunnable(deferredEvent, Status.FAILURE));
  72 + }
  73 + }
  74 +}
107 impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java
@@ -16,6 +16,26 @@
16 16 */
17 17 package org.jboss.weld.manager;
18 18
  19 +import static org.jboss.weld.logging.messages.BeanManagerMessage.AMBIGUOUS_BEANS_FOR_DEPENDENCY;
  20 +import static org.jboss.weld.logging.messages.BeanManagerMessage.CONTEXT_NOT_ACTIVE;
  21 +import static org.jboss.weld.logging.messages.BeanManagerMessage.DUPLICATE_ACTIVE_CONTEXTS;
  22 +import static org.jboss.weld.logging.messages.BeanManagerMessage.DUPLICATE_INTERCEPTOR_BINDING;
  23 +import static org.jboss.weld.logging.messages.BeanManagerMessage.INTERCEPTOR_BINDINGS_EMPTY;
  24 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NON_NORMAL_SCOPE;
  25 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NOT_INTERCEPTOR_BINDING_TYPE;
  26 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NOT_STEREOTYPE;
  27 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NO_DECORATOR_TYPES;
  28 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_BEAN_ARGUMENT;
  29 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_BEAN_TYPE_ARGUMENT;
  30 +import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_CREATIONAL_CONTEXT_ARGUMENT;
  31 +import static org.jboss.weld.logging.messages.BeanManagerMessage.SPECIFIED_TYPE_NOT_BEAN_TYPE;
  32 +import static org.jboss.weld.logging.messages.BeanManagerMessage.TOO_MANY_ACTIVITIES;
  33 +import static org.jboss.weld.logging.messages.BeanManagerMessage.UNPROXYABLE_RESOLUTION;
  34 +import static org.jboss.weld.logging.messages.BeanManagerMessage.UNRESOLVABLE_ELEMENT;
  35 +import static org.jboss.weld.manager.BeanManagers.buildAccessibleClosure;
  36 +import static org.jboss.weld.util.reflection.Reflections.cast;
  37 +import static org.jboss.weld.util.reflection.Reflections.isCacheable;
  38 +
19 39 import java.io.Serializable;
20 40 import java.lang.annotation.Annotation;
21 41 import java.lang.reflect.Member;
@@ -50,7 +70,6 @@
50 70 import javax.enterprise.inject.spi.PassivationCapable;
51 71 import javax.enterprise.util.TypeLiteral;
52 72
53   -import com.google.common.collect.Iterators;
54 73 import org.jboss.weld.Container;
55 74 import org.jboss.weld.bean.NewBean;
56 75 import org.jboss.weld.bean.RIBean;
@@ -71,6 +90,7 @@
71 90 import org.jboss.weld.el.Namespace;
72 91 import org.jboss.weld.el.WeldELResolver;
73 92 import org.jboss.weld.el.WeldExpressionFactory;
  93 +import org.jboss.weld.event.ObserverNotifier;
74 94 import org.jboss.weld.exceptions.AmbiguousResolutionException;
75 95 import org.jboss.weld.exceptions.DeploymentException;
76 96 import org.jboss.weld.exceptions.IllegalArgumentException;
@@ -104,36 +124,15 @@
104 124 import org.jboss.weld.resolution.TypeSafeObserverResolver;
105 125 import org.jboss.weld.resolution.TypeSafeResolver;
106 126 import org.jboss.weld.resources.ClassTransformer;
107   -import org.jboss.weld.resources.SharedObjectCache;
108 127 import org.jboss.weld.serialization.spi.ContextualStore;
109 128 import org.jboss.weld.util.Beans;
110 129 import org.jboss.weld.util.BeansClosure;
111   -import org.jboss.weld.util.Observers;
112 130 import org.jboss.weld.util.Proxies;
113   -import org.jboss.weld.util.Types;
114 131 import org.jboss.weld.util.collections.Arrays2;
115 132 import org.jboss.weld.util.collections.IterableToIteratorFunction;
116 133 import org.jboss.weld.util.reflection.Reflections;
117 134
118   -import static org.jboss.weld.logging.messages.BeanManagerMessage.AMBIGUOUS_BEANS_FOR_DEPENDENCY;
119   -import static org.jboss.weld.logging.messages.BeanManagerMessage.CONTEXT_NOT_ACTIVE;
120   -import static org.jboss.weld.logging.messages.BeanManagerMessage.DUPLICATE_ACTIVE_CONTEXTS;
121   -import static org.jboss.weld.logging.messages.BeanManagerMessage.DUPLICATE_INTERCEPTOR_BINDING;
122   -import static org.jboss.weld.logging.messages.BeanManagerMessage.INTERCEPTOR_BINDINGS_EMPTY;
123   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NON_NORMAL_SCOPE;
124   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NOT_INTERCEPTOR_BINDING_TYPE;
125   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NOT_STEREOTYPE;
126   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NO_DECORATOR_TYPES;
127   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_BEAN_ARGUMENT;
128   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_BEAN_TYPE_ARGUMENT;
129   -import static org.jboss.weld.logging.messages.BeanManagerMessage.NULL_CREATIONAL_CONTEXT_ARGUMENT;
130   -import static org.jboss.weld.logging.messages.BeanManagerMessage.SPECIFIED_TYPE_NOT_BEAN_TYPE;
131   -import static org.jboss.weld.logging.messages.BeanManagerMessage.TOO_MANY_ACTIVITIES;
132   -import static org.jboss.weld.logging.messages.BeanManagerMessage.UNPROXYABLE_RESOLUTION;
133   -import static org.jboss.weld.logging.messages.BeanManagerMessage.UNRESOLVABLE_ELEMENT;
134   -import static org.jboss.weld.manager.BeanManagers.buildAccessibleClosure;
135   -import static org.jboss.weld.util.reflection.Reflections.cast;
136   -import static org.jboss.weld.util.reflection.Reflections.isCacheable;
  135 +import com.google.common.collect.Iterators;
137 136
138 137 /**
139 138 * Implementation of the Bean Manager.
@@ -195,11 +194,12 @@
195 194 private final transient TypeSafeBeanResolver<Bean<?>> beanResolver;
196 195 private final transient TypeSafeResolver<Resolvable, Decorator<?>> decoratorResolver;
197 196 private final transient TypeSafeResolver<InterceptorResolvable, Interceptor<?>> interceptorResolver;
198   - private final transient TypeSafeResolver<Resolvable, ObserverMethod<?>> observerResolver;
199 197 private final transient NameBasedResolver nameBasedResolver;
200 198 private final transient ELResolver weldELResolver;
201 199 private transient Namespace rootNamespace;
202 200
  201 + private final transient ObserverNotifier accessibleObserverNotifier;
  202 +
203 203 /*
204 204 * Activity scoped data structures
205 205 * ********************************
@@ -358,10 +358,11 @@ private BeanManagerImpl(
358 358 this.beanResolver = new TypeSafeBeanResolver<Bean<?>>(this, createDynamicAccessibleIterable(beanTransform));
359 359 this.decoratorResolver = new TypeSafeDecoratorResolver(this, createDynamicAccessibleIterable(DecoratorTransform.INSTANCE));
360 360 this.interceptorResolver = new TypeSafeInterceptorResolver(this, createDynamicAccessibleIterable(InterceptorTransform.INSTANCE));
361   - this.observerResolver = new TypeSafeObserverResolver(this, createDynamicAccessibleIterable(ObserverMethodTransform.INSTANCE));
362 361 this.nameBasedResolver = new NameBasedResolver(this, createDynamicAccessibleIterable(beanTransform));
363 362 this.weldELResolver = new WeldELResolver(this);
364 363 this.childActivities = new CopyOnWriteArraySet<BeanManagerImpl>();
  364 + TypeSafeObserverResolver observerResolver = new TypeSafeObserverResolver(this, createDynamicAccessibleIterable(ObserverMethodTransform.INSTANCE));
  365 + this.accessibleObserverNotifier = ObserverNotifier.of(observerResolver, getServices());
365 366 }
366 367
367 368
@@ -381,7 +382,7 @@ public void addAccessibleBeanManager(BeanManagerImpl accessibleBeanManager) {
381 382 beanResolver.clear();
382 383 interceptorResolver.clear();
383 384 decoratorResolver.clear();
384   - observerResolver.clear();
  385 + accessibleObserverNotifier.clear();
385 386 }
386 387
387 388 public HashSet<BeanManagerImpl> getAccessibleManagers() {
@@ -418,8 +419,7 @@ public void addDecorator(Decorator<?> bean) {
418 419 }
419 420
420 421 public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... bindings) {
421   - Observers.checkEventObjectType(this, event);
422   - return this.<T>resolveObserverMethods(event.getClass(), bindings);
  422 + return accessibleObserverNotifier.resolveObserverMethods(event, bindings);
423 423 }
424 424
425 425 public void addInterceptor(Interceptor<?> bean) {
@@ -428,29 +428,6 @@ public void addInterceptor(Interceptor<?> bean) {
428 428 interceptorResolver.clear();
429 429 }
430 430
431   - public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Annotation... qualifiers) {
432   - // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
433   - Resolvable resolvable = new ResolvableBuilder(this)
434   - .addTypes(services.get(SharedObjectCache.class).getTypeClosure(eventType))
435   - .addType(Object.class)
436   - .addQualifiers(qualifiers)
437   - .addQualifierIfAbsent(AnyLiteral.INSTANCE)
438   - .create();
439   - return cast(observerResolver.resolve(resolvable, true));
440   - }
441   -
442   - public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType, Set<Annotation> qualifiers) {
443   - // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
444   - Set<Type> typeClosure = services.get(SharedObjectCache.class).getTypeClosure(eventType);
445   - Resolvable resolvable = new ResolvableBuilder(this)
446   - .addTypes(typeClosure)
447   - .addType(Object.class)
448   - .addQualifiers(qualifiers)
449   - .addQualifierIfAbsent(AnyLiteral.INSTANCE)
450   - .create();
451   - return cast(observerResolver.resolve(resolvable, true));
452   - }
453   -
454 431 /**
455 432 * Enabled Alternatives, Interceptors and Decorators
456 433 *
@@ -571,23 +548,7 @@ public void addObserver(ObserverMethod<?> observer) {
571 548 * java.lang.annotation.Annotation[])
572 549 */
573 550 public void fireEvent(Object event, Annotation... qualifiers) {
574   - fireEvent(event.getClass(), event, qualifiers);
575   - }
576   -
577   - public void fireEvent(Type eventType, Object event, Annotation... qualifiers) {
578   - Observers.checkEventObjectType(this, event);
579   - notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
580   - }
581   -
582   - public void fireEvent(Type eventType, Object event, Set<Annotation> qualifiers) {
583   - Observers.checkEventObjectType(this, event);
584   - notifyObservers(event, resolveObserverMethods(eventType, qualifiers));
585   - }
586   -
587   - private <T> void notifyObservers(final T event, final Set<ObserverMethod<? super T>> observers) {
588   - for (ObserverMethod<? super T> observer : observers) {
589   - observer.notify(event);
590   - }
  551 + accessibleObserverNotifier.fireEvent(event, qualifiers);
591 552 }
592 553
593 554 /**
@@ -818,12 +779,12 @@ private void checkResolveDecoratorsArguments(Set<Type> types) {
818 779 }
819 780
820 781 /**
821   - * Get the observer resolver. For internal use
  782 + * Get the observer notifier for accessible observer methods. For internal use
822 783 *
823   - * @return The resolver
  784 + * @return The {@link ObserverNotifier}
824 785 */
825   - public TypeSafeResolver<Resolvable, ObserverMethod<?>> getObserverResolver() {
826   - return observerResolver;
  786 + public ObserverNotifier getAccessibleObserverNotifier() {
  787 + return accessibleObserverNotifier;
827 788 }
828 789
829 790 /**
@@ -1093,7 +1054,7 @@ public void cleanup() {
1093 1054 this.interceptors.clear();
1094 1055 this.nameBasedResolver.clear();
1095 1056 this.namespaces.clear();
1096   - this.observerResolver.clear();
  1057 + this.accessibleObserverNotifier.clear();
1097 1058 this.observers.clear();
1098 1059 BeansClosure.removeClosure(this);
1099 1060 }
16 impl/src/main/java/org/jboss/weld/resolution/ResolvableBuilder.java
@@ -54,16 +54,20 @@
54 54 protected final Set<QualifierInstance> qualifierInstances;
55 55 protected final Map<Class<? extends Annotation>, Annotation> mappedQualifiers;
56 56 protected Bean<?> declaringBean;
57   - private final BeanManagerImpl beanManager;
  57 + private final MetaAnnotationStore store;
58 58
59   - public ResolvableBuilder(final BeanManagerImpl beanManager) {
60   - this.beanManager = beanManager;
  59 + public ResolvableBuilder(final MetaAnnotationStore store) {
  60 + this.store = store;
61 61 this.types = new HashSet<Type>();
62 62 this.qualifiers = new HashSet<Annotation>();
63 63 this.mappedQualifiers = new HashMap<Class<? extends Annotation>, Annotation>();
64 64 this.qualifierInstances = new HashSet<QualifierInstance>();
65 65 }
66 66
  67 + public ResolvableBuilder(final BeanManagerImpl beanManager) {
  68 + this(beanManager.getServices().get(MetaAnnotationStore.class));
  69 + }
  70 +
67 71 public ResolvableBuilder(Type type, final BeanManagerImpl beanManager) {
68 72 this(beanManager);
69 73 if (type != null) {
@@ -79,7 +83,6 @@ public ResolvableBuilder(InjectionPoint injectionPoint, final BeanManagerImpl ma
79 83 this(injectionPoint.getType(), manager);
80 84 addQualifiers(injectionPoint.getQualifiers());
81 85 if (mappedQualifiers.containsKey(Named.class) && injectionPoint.getMember() instanceof Field) {
82   - final MetaAnnotationStore store = beanManager.getServices().get(MetaAnnotationStore.class);
83 86 Named named = (Named) mappedQualifiers.get(Named.class);
84 87 QualifierInstance qualifierInstance = new QualifierInstance(named, store);
85 88 if (named.value().equals("")) {
@@ -113,7 +116,6 @@ public ResolvableBuilder addTypes(Set<Type> types) {
113 116
114 117 public Resolvable create() {
115 118 if (qualifiers.size() == 0) {
116   - final MetaAnnotationStore store = beanManager.getServices().get(MetaAnnotationStore.class);
117 119 this.qualifierInstances.add(new QualifierInstance(DefaultLiteral.INSTANCE, store));
118 120 }
119 121 if (Reflections.isAssignableFrom(Event.class, types)) {
@@ -128,7 +130,6 @@ public Resolvable create() {
128 130 }
129 131
130 132 private Resolvable createFacade(Class<?> rawType) {
131   - final MetaAnnotationStore store = beanManager.getServices().get(MetaAnnotationStore.class);
132 133 Set<QualifierInstance> qualifiers = Collections.<QualifierInstance>singleton(new QualifierInstance(AnyLiteral.INSTANCE, store));
133 134 Set<Type> types = Collections.<Type>singleton(rawType);
134 135 return new ResolvableImpl(rawType, types, mappedQualifiers, declaringBean, qualifiers);
@@ -136,7 +137,6 @@ private Resolvable createFacade(Class<?> rawType) {
136 137
137 138 public ResolvableBuilder addQualifier(Annotation qualifier) {
138 139 // Handle the @New qualifier special case
139   - final MetaAnnotationStore store = beanManager.getServices().get(MetaAnnotationStore.class);
140 140 QualifierInstance qualifierInstance = new QualifierInstance(qualifier, store);
141 141 final Class<? extends Annotation> annotationType = qualifierInstance.getAnnotationClass();
142 142 if (annotationType.equals(New.class)) {
@@ -187,7 +187,7 @@ public ResolvableBuilder addQualifiers(Set<Annotation> qualifiers) {
187 187 }
188 188
189 189 protected void checkQualifier(Annotation qualifier, final QualifierInstance qualifierInstance, Class<? extends Annotation> annotationType) {
190   - if (!beanManager.getServices().get(MetaAnnotationStore.class).getBindingTypeModel(annotationType).isValid()) {
  190 + if (!store.getBindingTypeModel(annotationType).isValid()) {
191 191 throw new IllegalArgumentException(INVALID_QUALIFIER, qualifier);
192 192 }
193 193 if (qualifierInstances.contains(qualifierInstance)) {
11 impl/src/main/java/org/jboss/weld/util/Observers.java
@@ -37,9 +37,12 @@
37 37 */
38 38 public class Observers {
39 39
40   - public static void checkEventObjectType(final BeanManagerImpl beanManager, Type eventType) {
  40 + public static void checkEventObjectType(BeanManagerImpl manager, Type eventType) {
  41 + checkEventObjectType(manager.getServices().get(SharedObjectCache.class), eventType);
  42 + }
  43 +
  44 + public static void checkEventObjectType(final SharedObjectCache cache, Type eventType) {
41 45 Type[] types;
42   - final SharedObjectCache cache = beanManager.getServices().get(SharedObjectCache.class);
43 46 final Type resolvedType = cache.getResolvedType(eventType);
44 47 if (resolvedType instanceof Class<?>) {
45 48 types = new Type[0];
@@ -55,8 +58,8 @@ public static void checkEventObjectType(final BeanManagerImpl beanManager, Type
55 58 }
56 59 }
57 60
58   - public static void checkEventObjectType(final BeanManagerImpl beanManager, Object event) {
59   - checkEventObjectType(beanManager, event.getClass());
  61 + public static void checkEventObjectType(final SharedObjectCache cache, Object event) {
  62 + checkEventObjectType(cache, event.getClass());
60 63
61 64 }
62 65
223 ...lian/src/test/java/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/ActionSequence.java
... ... @@ -0,0 +1,223 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright 2010, Red Hat, Inc., and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + * http://www.apache.org/licenses/LICENSE-2.0
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS,
  13 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + * See the License for the specific language governing permissions and
  15 + * limitations under the License.
  16 + */
  17 +package org.jboss.weld.tests.cditck11.event.observer.transactional.custom;
  18 +
  19 +import java.util.ArrayList;
  20 +import java.util.Arrays;
  21 +import java.util.Collections;
  22 +import java.util.HashMap;
  23 +import java.util.List;
  24 +import java.util.Map;
  25 +
  26 +/**
  27 + * Simple data holder for sequence of actions identified with {@link String}.
  28 + *
  29 + * @author Martin Kouba
  30 + */
  31 +public final class ActionSequence {
  32 +
  33 + /**
  34 + * Name of sequence
  35 + */
  36 + private String name;
  37 +
  38 + /**
  39 + * Data - list of actions
  40 + */
  41 + private List<String> data = Collections.synchronizedList(new ArrayList<String>());
  42 +
  43 + public ActionSequence() {
  44 + super();
  45 + this.name = DEFAULT_SEQUENCE;
  46 + }
  47 +
  48 + public ActionSequence(String name) {
  49 + super();
  50 + this.name = name;
  51 + }
  52 +
  53 + /**
  54 + * @param actionId
  55 + * @return data holder
  56 + */
  57 + public ActionSequence add(String actionId) {
  58 + this.data.add(actionId);
  59 + return this;
  60 + }
  61 +
  62 + /**
  63 + * @return read-only copy of sequence data
  64 + */
  65 + public List<String> getData() {
  66 + return Collections.unmodifiableList(new ArrayList<String>(this.data));
  67 + }
  68 +
  69 + /**
  70 + * @return name of sequence
  71 + */
  72 + public String getName() {
  73 + return name;
  74 + }
  75 +
  76 + /**
  77 + *
  78 + * @param actions
  79 + * @return <code>true</code> if sequence data contain all of the specified actions, <code>false</code> otherwise
  80 + */
  81 + public boolean containsAll(String... actions) {
  82 + return getData().containsAll(Arrays.asList(actions));
  83 + }
  84 +
  85 + /**
  86 + *
  87 + * @param actions
  88 + * @return <code>true</code> if sequence data begins with the specified actions, <code>false</code> otherwise
  89 + */
  90 + public boolean beginsWith(String... actions) {
  91 +
  92 + List<String> sequenceData = getData();
  93 + List<String> matchData = Arrays.asList(actions);
  94 +
  95 + if (sequenceData.size() < matchData.size())
  96 + return false;
  97 +
  98 + return sequenceData.subList(0, matchData.size()).equals(matchData);
  99 + }
  100 +
  101 + /**
  102 + *
  103 + * @param actions
  104 + * @return <code>true</code> if sequence data ends with the specified actions, <code>false</code> otherwise
  105 + */
  106 + public boolean endsWith(String... actions) {
  107 +
  108 + List<String> sequenceData = getData();
  109 + List<String> matchData = Arrays.asList(actions);
  110 +
  111 + if (sequenceData.size() < matchData.size())
  112 + return false;
  113 +
  114 + return sequenceData.subList(sequenceData.size() - matchData.size(), sequenceData.size()).equals(matchData);
  115 + }
  116 +
  117 + @Override
  118 + public String toString() {
  119 + return String.format("ActionSequence [name=%s, data=%s]", name, getData());
  120 + }
  121 +
  122 + // Static members
  123 +
  124 + private static final String DEFAULT_SEQUENCE = "default";
  125 +
  126 + /**
  127 + * Static sequence map
  128 + */
  129 + private static Map<String, ActionSequence> sequences = new HashMap<String, ActionSequence>();
  130 +
  131 + /**
  132 + * Remove all sequences.
  133 + */
  134 + public static void reset() {
  135 + synchronized (sequences) {
  136 + sequences.clear();
  137 + }
  138 + }
  139 +
  140 + /**
  141 + * Add actionId to specified sequence. Add new sequence if needed.
  142 + *
  143 + * @param sequence
  144 + * @param actionId
  145 + * @return <code>true</code> if a new sequence was added, <code>false</code> otherwise
  146 + */
  147 + public static boolean addAction(String sequenceName, String actionId) {
  148 +
  149 + boolean newSequenceAdded = false;
  150 +
  151 + synchronized (sequences) {
  152 +
  153 + if (!sequences.containsKey(sequenceName)) {
  154 + sequences.put(sequenceName, new ActionSequence(sequenceName));
  155 + newSequenceAdded = true;
  156 + }
  157 + sequences.get(sequenceName).add(actionId);
  158 + }
  159 + return newSequenceAdded;
  160 + }
  161 +
  162 + /**
  163 + * Add actionId to default sequence.
  164 + *
  165 + * @param actionId
  166 + * @return <code>true</code> if a new sequence was added, <code>false</code> otherwise
  167 + */
  168 + public static boolean addAction(String actionId) {
  169 + return addAction(DEFAULT_SEQUENCE, actionId);
  170 + }
  171 +
  172 + /**
  173 + * @return default sequence or <code>null</code> if no such sequence exists
  174 + */
  175 + public static ActionSequence getSequence() {
  176 + return getSequence(DEFAULT_SEQUENCE);
  177 + }
  178 +
  179 + /**
  180 + * @param name
  181 + * @return specified sequence or <code>null</code> if no such sequence exists
  182 + */
  183 + public static ActionSequence getSequence(String sequenceName) {
  184 + synchronized (sequences) {
  185 + return sequences.get(sequenceName);
  186 + }
  187 + }
  188 +
  189 + /**
  190 + * @return data of default sequence or <code>null</code> if no such sequence exists
  191 + */
  192 + public static List<String> getSequenceData() {
  193 + return getSequenceData(DEFAULT_SEQUENCE);
  194 + }
  195 +
  196 + /**
  197 + * @param sequenceName
  198 + * @return data of specified sequence or <code>null</code> if no such sequence exists
  199 + */
  200 + public static List<String> getSequenceData(String sequenceName) {
  201 + synchronized (sequences) {
  202 + return sequences.containsKey(sequenceName) ? sequences.get(sequenceName).getData() : null;
  203 + }
  204 + }
  205 +
  206 + /**
  207 + * @return size of default sequence
  208 + */
  209 + public static int getSequenceSize() {
  210 + return getSequenceSize(DEFAULT_SEQUENCE);
  211 + }
  212 +
  213 + /**
  214 + * @param sequence
  215 + * @return size of specified sequence
  216 + */
  217 + public static int getSequenceSize(String sequenceName) {
  218 + synchronized (sequences) {
  219 + return sequences.containsKey(sequenceName) ? sequences.get(sequenceName).getData().size() : 0;
  220 + }
  221 + }
  222 +
  223 +}
85 ...a/org/jboss/weld/tests/cditck11/event/observer/transactional/custom/CustomTransactionalObserverTest.java
... ... @@ -0,0 +1,85 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + * http://www.apache.org/licenses/LICENSE-2.0
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS,
  13 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + * See the License for the specific language governing permissions and
  15 + * limitations under the License.
  16 + */
  17 +
  18 +package org.jboss.weld.tests.cditck11.event.observer.transactional.custom;
  19 +
  20 +import static org.junit.Assert.assertEquals;
  21 +import static org.junit.Assert.assertNotNull;
  22 +import static org.junit.Assert.assertTrue;
  23 +
  24