diff --git a/README.md b/README.md index 80e8dd5..99ee3e2 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ MBassador is a very light-weight message (event) bus implementation following th for ease of use and aims to be feature rich and extensible while preserving resource efficiency and performance. It uses a specialized data structure to allow high throughput for concurrent access. -Read this documentation to get an overview of its features and how cool this message (event) bus actually is. -You can also check out the performance comparison +Read this documentation to get an overview of its features. You can also check out the performance comparison which also contains a partial list of the features of the compared implementations. The current version is 1.1.1 and it is available from the Maven Central Repository. See the release notes for more details. @@ -15,6 +14,7 @@ Table of contents: + [Features](#features) + [Usage](#usage) + [Installation](#installation) ++ [Wiki](#wiki) + [Release Notes](#releasenotes) + [Roadmap](#roadmap) + [Credits](#credits) @@ -26,26 +26,33 @@ Table of contents: At its core MBassador offers the following features: -+ Annotation driven: To define and customize a message handler simply mark it with @Listener annotation -+ Delivers everything: Messages must not implement any interface and can be of any type (-> message bus is typed using generics with upper -bound being Object.class). The class hierarchy of a message is considered during message delivery. This means that listeners will also receive -subtypes of the message type they are listening for, e.g. a listener for Object.class receives everything. ++ Annotation driven: To define and customize a message handler simply mark it with @Handler annotation ++ Delivers everything: Messages must not implement any interface and can be of any type. It is +possible though to define an upper bound of the message type using generics. The class hierarchy of a message is considered during message delivery. +This means that listeners will also receivesubtypes of the message type they are listening for, e.g. a listener for Object.class receives everything. + Synchronous and asynchronous message delivery: A handler can be invoked to handle a message either synchronously or asynchronously. This is configurable for each handler via annotations. Message publication itself supports synchronous (method blocks until messages are delivered to all handlers) or asynchronous (fire and forget) dispatch -+ Weak references: Mbassador uses weak references to all listening objects to relieve the programmer of the burden to explicitly unregister ++ Weak references: MBassador uses weak references to all listening objects to relieve the programmer of the burden to explicitly unregister listeners that are not used anymore (of course it is also possible to explicitly unregister a listener if needed). This is very comfortable -in certain environments where objects are created by frameworks, i.e. spring, guice etc. Just stuff everything into the message bus, it will +in certain environments where listeners are managed by frameworks, i.e. spring, guice etc. Just stuff everything into the message bus, it will ignore objects without message handlers and automatically clean-up orphaned weak references after the garbage collector has done its job. -+ Filtering: Mbassador offers static message filtering. Filters are configured using annotations and multiple filters can be attached to ++ Filtering: MBassador offers static message filtering. Filters are configured using annotations and multiple filters can be attached to a single message handler -+ Message envelopes: Message handlers can declare to receive an enveloped message. The envelope can wrap around different -types of messages. This allows for a single handler to handle multiple message types -+ Handler priorities: A listener can be associated with a priority to influence the order of the message delivery -+ Error handling: Errors during message delivery are sent to an error handler of which a custom implementation can easily be plugged-in. -+ Ease of Use: Using Mbassador in your project is very easy. Create as many instances of Mbassador as you like (usually a singleton will do), -mark and configure your message handlers with @Listener annotations and finally register the listeners at any Mbassador instance. Start -sending messages to your listeners using one of Mbassador's publication methods (sync or async). Done! ++ Message envelopes: Message handlers can declare to receive an enveloped message. The envelope can wrap different +types of messages. This allows for a single handler to handle multiple (unrelated) message types. ++ Handler priorities: A listener can be associated with a priority to influence the order in which messages are delivered when multiple handlers exist ++ Custom error handling: Errors during message delivery are sent to all registered error handlers which can be added to the bus as necessary. ++ Dead Event: Messages that do not match any handler result in the publication of a DeadEvent object which wraps the original message. Dead events +can be handled by registering listeners that handle DeadEvent. ++ Dead Event: Messages that have matching handlers but do not pass the configured filters result in the publication of a FilteredEvent object which wraps the original message. +Filtered events can be handled by registering listeners that handle FilteredEvent. ++ Extensibility:MBassador is designed to be extensible with custom implementations of various components like message +dispatchers and handler invocations (using the decorator pattern), metadata reader (you can add your own annotations) and factories for different + kinds of object.A configuration object can be passed to on instance creation to specify the different configurable parts ++ Ease of Use: Using MBassador in your project is very easy. Create as many instances of MBassador as you like (usually a singleton will do), +mark and configure your message handlers with @Handler annotations and finally register the listeners at any MBassador instance. Start +sending messages to your listeners using one of MBassador's publication methods (sync or async). Done! @@ -53,33 +60,33 @@ sending messages to your listeners using one of Mbassador's publication methods Listener definition (in any bean): - // every event of type TestEvent or any subtype will be delivered + // every event of type TestMessage or any subtype will be delivered // to this handler - @Listener - public void handleTestEvent(TestEvent event) { + @Handler + public void handleTestMessage(TestMessage event) { // do something } // this handler will be invoked concurrently - @Listener(delivery = Mode.Concurrent) - public void handleSubTestEvent(SubTestEvent event) { + @Handler(delivery = Mode.Concurrent) + public void handleSubTestMessage(SubTestMessage event) { // do something more expensive here } - // this handler will receive messages of type SubTestEvent + // this handler will receive messages of type SubTestMessage // or any of its sub types that passe the given filter(s) - @Listener(priority = 10, + @Handler(priority = 10, delivery = Mode.Sequential, - filters = {@Filter(Filters.SpecialEvent.class)}) - public void handleFiltered(SubTestEvent event) { + filters = {@Filter(Filters.SpecialMessage.class)}) + public void handleFiltered(SubTestMessage event) { //do something special here } - @Listener(delivery = Mode.Sequential, rejectSubtypes = true) - @Enveloped(messages = {TestEvent.class, TestEvent2.class}) + @Handler(delivery = Mode.Sequential, rejectSubtypes = true) + @Enveloped(messages = {TestMessage.class, TestMessage2.class}) public void handleVariousEvents(MessageEnvelope envelope) { - // the envelope will contain either an instance of TestEvent or TestEvent2 - // if rejectSubtypes were set to 'false' (default) also subtypes of TestEvent or TestEvent2 would be allowed + // the envelope will contain either an instance of TestMessage or TestMessage2 + // if rejectSubtypes were set to 'false' (default) also subtypes of TestMessage or TestMessage2 would be allowed } @@ -87,7 +94,7 @@ Creation of message bus and registration of listeners: // create as many instances as necessary // bind it to any upper bound - MBassador bus = new MBassador(BusConfiguration.Default()); + MBassador bus = new MBassador(BusConfiguration.Default()); ListeningBean listener = new ListeningBean(); // the listener will be registered using a weak-reference bus.subscribe(listener); @@ -97,18 +104,18 @@ Creation of message bus and registration of listeners: Message publication: - TestEvent event = new TestEvent(); - TestEvent subEvent = new SubTestEvent(); + TestMessage message = new TestMessage(); + TestMessage subMessage = new SubTestMessage(); - bus.publishAsync(event); //returns immediately, publication will continue asynchronously - bus.post(event).asynchronously(); // same as above - bus.publish(subEvent); // will return after each handler has been invoked - bus.post(subEvent).now(); // same as above + bus.publishAsync(message); //returns immediately, publication will continue asynchronously + bus.post(message).asynchronously(); // same as above + bus.publish(subMessage); // will return after each handler has been invoked + bus.post(subMessage).now(); // same as above

Installation

Beginning with version 1.1.0 MBassador is available from the Maven Central Repository (Hooray!). Older versions are still available from the included maven repository in this github repo but will be deleted in the future. -The preferred way of using MBassador is to simply add the dependency as shown in step two. Step one is only necessary +The recommended way of using MBassador in your project is to add the dependency as shown in step two. Step one is only necessary if you want to use an older version that is not available in the central repository. 1. Add the repository location to your pom.xml @@ -131,17 +138,31 @@ if you want to use an older version that is not available in the central reposit 3. Run mvn clean package to have maven download and install the required version into your local repository -Of course you can always clone the repository and build from source +Of course you can always clone the repository and build from source. + +

Wiki

+There is ongoing afford to extend documentation and provide code samples and detailed explanations of how the message bus +works. Code samples can also be found in the various test cases. Please read about the terminology used in this project +to avoid confusion and misunderstanding.

Release Notes

+

1.1.2

+ + + Added support for FilteredMessage event + + Renamed @Listener to @Handler and DeadEvent to DeadMessage to increase alignment with the established terminology. + Sorry for the inconvenience since this will lead to compile errors but good old find&replace will do + + Repackaging and refactoring of some parts + + Introduced message publication factories as configurable components to make MBassador more extensible/customizable + + Added more documentation and unit tests +

1.1.1

- + Added support for DeadEvent - + Introduced new property to @Listener annotation that allows to activate/deactivate any message handler + + Added support for DeadMessage event + + Introduced new property to @Handler annotation that allows to activate/deactivate any message handler + Full support of proxies created by cglib + Message handler inheritance changed! See wiki page about handler definition for more details. - + Changed @Listener property "dispatch" to "delivery" and renamed the associated enumeration values to + + Changed @Handler property "dispatch" to "delivery" and renamed the associated enumeration values to more precisely indicate their meaning + Added more unit tests @@ -163,7 +184,7 @@ First stable release!

1.0.5.RC

+ Added MessageEnvelope and @Enveloped annotation to configure handlers that might receive arbitrary message type - + Added handler configuration property to @Listener annotation to move from message filtering to more specific implementation + + Added handler configuration property to @Handler annotation to move from message filtering to more specific implementation of this feature

1.0.4.RC

@@ -177,9 +198,12 @@ successful commit etc.). Currently in beta, see A removed listener will under no circumstances receive any message publications. +A listener is considered removed after the unsubscribe(Object) call returned.Any running message publication that has not yet delivered +the message to the recently removed listener will not see the listener after the remove operation completed. diff --git a/wiki-listener-def.md b/src/docs/wiki-listener-def.md similarity index 93% rename from wiki-listener-def.md rename to src/docs/wiki-listener-def.md index 566474e..1bde8d0 100644 --- a/wiki-listener-def.md +++ b/src/docs/wiki-listener-def.md @@ -52,7 +52,7 @@ receive all messages of type TestEvent or any subtype sequentially. // every message of type TestEvent or any subtype will be delivered // to this handler - @Listener + @Handler public void handleTestEvent(TestEvent event) { // do something } @@ -62,7 +62,7 @@ receive all messages of type TestEvent or any subtype sequentially. This handler will receive all messages of type SubTestEvent or any subtype concurrently // this handler will be invoked concurrently - @Listener(delivery = Mode.Concurrent) + @Handler(delivery = Mode.Concurrent) public void handleSubTestEvent(SubTestEvent event) { // do something more expensive here } @@ -73,7 +73,7 @@ defined one, since it specifies a higher priority // this handler will receive messages of type SubTestEvent // or any of its sub types that passe the given filter(s) - @Listener(priority = 10, + @Handler(priority = 10, dispatch = Mode.Synchronous, filters = {@Filter(Filters.SpecialEvent.class)}) public void handleFiltered(SubTestEvent event) { @@ -81,7 +81,7 @@ defined one, since it specifies a higher priority } - @Listener(dispatch = Mode.Synchronous, rejectSubtypes = true) + @Handler(dispatch = Mode.Synchronous, rejectSubtypes = true) @Enveloped(messages = {TestEvent.class, TestEvent2.class}) public void handleVariousEvents(MessageEnvelope envelope) { // the envelope will contain either an instance of TestEvent or TestEvent2 @@ -95,10 +95,10 @@ defined one, since it specifies a higher priority Since one parameter (the message) does not offer a great deal of flexibility if different types of messages should be consumed, there exists the possibility to wrap a message inside an envelope. An enveloped message handler specifies the message type it consumes by using the @Enveloped annotation -in addition to the @Listener annotation. All configurations of @Listener apply to each of the specified +in addition to the @Handler annotation. All configurations of @Handler apply to each of the specified message types. - @Listener(dispatch = Mode.Synchronous, rejectSubtypes = true) + @Handler(dispatch = Mode.Synchronous, rejectSubtypes = true) @Enveloped(messages = {TestEvent.class, TestEvent2.class}) public void handleVariousEvents(MessageEnvelope envelope) { // the envelope will contain either an instance of TestEvent or TestEvent2 diff --git a/src/docs/wiki-terminology.md b/src/docs/wiki-terminology.md new file mode 100644 index 0000000..31b796a --- /dev/null +++ b/src/docs/wiki-terminology.md @@ -0,0 +1,39 @@ +

Terminology

+To avoid confusion and increase precision of the available documentation a common vocabulary of the most relevant concepts is necessary. +Specifically, the terms "event" and "message" have their own definition within the context of the message bus system and as such require +some clarification. + +

Message

+A message is an object used for communication between multiple other objects.Other libraries established the term "event" which essentially +refers to the same idea (an event occurs at some point in the system and is published to other components such that they might react to it). +MBassador uses the term message instead of event since the object sent through it does not necessarily represent an event. It might merely represent +data to be processed, e.g. stored or transformed. + +A message can be any object, no restrictions or assumptions are made. A message can be sent by any object that has access to the bus +and is delivered to all registered listeners that consume the type of message. + +

Message handler

+A message handler is a method that defines exactly one parameter (the message) and is marked with @Handler. A handler has a message type +that is implicitly defined in the method signature (the parameter type). A message handler will be invoked for each message that has a compatible +type. + +

Message listener

+An object that defines one or more message handlers and that has been subscribed at the message bus is referred to as (message) listener. + +

Subscription

+Subscription is the process of adding a listener to the message bus, such that it might receive messages. It is used interchangeably with the +term "registration" + +

Message publication|Message dispatch

+The process of delivering a message from the sender to all registered listeners is called message publication. +The initial phase of this process, that lasts until the message is actually delivered to the handlers is called message dispatch. +The distinction is necessarily drawn as all method publications share a common scheme but may vary in the way how the dispatching works. + +

Event

+The term "event" refers to events that can occur during message publication. Currently there are two types of events: + + + DeadMessage: Whenever a message is published and no listeners exist that defined matching handlers, a DeadMessage event will be created and published + using the common message publication mechanism. Listeners with handlers for DeadEvent can be subscribed to listen for and react to dead + + FilteredMessage: Since handlers can define filters to narrow the set of messages it consumes, it is possible that a message is not delivered + to any handler. In such a case the FilteredMessage event is published, + diff --git a/src/main/java/net/engio/mbassy/AbstractMessageBus.java b/src/main/java/net/engio/mbassy/bus/AbstractMessageBus.java similarity index 95% rename from src/main/java/net/engio/mbassy/AbstractMessageBus.java rename to src/main/java/net/engio/mbassy/bus/AbstractMessageBus.java index 2a4500b..37c6459 100644 --- a/src/main/java/net/engio/mbassy/AbstractMessageBus.java +++ b/src/main/java/net/engio/mbassy/bus/AbstractMessageBus.java @@ -1,7 +1,9 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; +import net.engio.mbassy.IPublicationErrorHandler; +import net.engio.mbassy.PublicationError; import net.engio.mbassy.common.ReflectionUtils; -import net.engio.mbassy.dispatch.SubscriptionContext; +import net.engio.mbassy.subscription.SubscriptionContext; import net.engio.mbassy.listener.MessageHandlerMetadata; import net.engio.mbassy.listener.MetadataReader; import net.engio.mbassy.subscription.Subscription; @@ -50,12 +52,14 @@ public abstract class AbstractMessageBus // it can be customized by implementing the getSubscriptionFactory() method private final SubscriptionFactory subscriptionFactory; + private final MessagePublication.Factory publicationFactory; public AbstractMessageBus(BusConfiguration configuration) { this.executor = configuration.getExecutor(); subscriptionFactory = configuration.getSubscriptionFactory(); this.metadataReader = configuration.getMetadataReader(); + this.publicationFactory = configuration.getMessagePublicationFactory(); pendingMessages = new LinkedBlockingQueue(configuration.getMaximumNumberOfPendingMessages()); initDispatcherThreads(configuration.getNumberOfMessageDispatchers()); addErrorHandler(new IPublicationErrorHandler.ConsoleLogger()); @@ -85,6 +89,10 @@ public abstract class AbstractMessageBus } } + protected MessagePublication.Factory getPublicationFactory(){ + return publicationFactory; + } + @Override public Collection getRegisteredErrorHandlers() { return Collections.unmodifiableCollection(errorHandlers); diff --git a/src/main/java/net/engio/mbassy/BusConfiguration.java b/src/main/java/net/engio/mbassy/bus/BusConfiguration.java similarity index 84% rename from src/main/java/net/engio/mbassy/BusConfiguration.java rename to src/main/java/net/engio/mbassy/bus/BusConfiguration.java index 696890d..3b49fca 100644 --- a/src/main/java/net/engio/mbassy/BusConfiguration.java +++ b/src/main/java/net/engio/mbassy/bus/BusConfiguration.java @@ -1,4 +1,4 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; import net.engio.mbassy.listener.MetadataReader; import net.engio.mbassy.subscription.SubscriptionFactory; @@ -6,7 +6,7 @@ import net.engio.mbassy.subscription.SubscriptionFactory; import java.util.concurrent.*; /** - * The bus configuration holds various parameters that can be used to customize the bus' runtime behaviour. * + * The bus configuration holds various parameters that can be used to customize the bus' runtime behaviour. * * @author bennidi * Date: 12/8/12 @@ -36,13 +36,23 @@ public class BusConfiguration { private MetadataReader metadataReader; + private MessagePublication.Factory messagePublicationFactory; + public BusConfiguration() { this.numberOfMessageDispatchers = 2; this.maximumNumberOfPendingMessages = Integer.MAX_VALUE; this.subscriptionFactory = new SubscriptionFactory(); this.executor = new ThreadPoolExecutor(10, 10, 1, TimeUnit.MINUTES, new LinkedBlockingQueue(), DaemonThreadFactory); this.metadataReader = new MetadataReader(); + this.messagePublicationFactory = new MessagePublication.Factory(); + } + public MessagePublication.Factory getMessagePublicationFactory() { + return messagePublicationFactory; + } + + public void setMessagePublicationFactory(MessagePublication.Factory messagePublicationFactory) { + this.messagePublicationFactory = messagePublicationFactory; } public MetadataReader getMetadataReader() { diff --git a/src/main/java/net/engio/mbassy/IMessageBus.java b/src/main/java/net/engio/mbassy/bus/IMessageBus.java similarity index 97% rename from src/main/java/net/engio/mbassy/IMessageBus.java rename to src/main/java/net/engio/mbassy/bus/IMessageBus.java index 06fbb12..8bb2e48 100644 --- a/src/main/java/net/engio/mbassy/IMessageBus.java +++ b/src/main/java/net/engio/mbassy/bus/IMessageBus.java @@ -1,4 +1,6 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; + +import net.engio.mbassy.IPublicationErrorHandler; import java.util.Collection; import java.util.concurrent.Executor; @@ -17,7 +19,7 @@ import java.util.concurrent.TimeUnit; *

* A listener is any object that defines at least one message handler and that has been subscribed to at least * one message bus. A message handler can be any method that accepts exactly one parameter (the message) and is marked - * as a message handler using the @Listener annotation. + * as a message handler using the @Handler annotation. *

* The bus uses weak references to all listeners such that registered listeners do not need to * be explicitly unregistered to be eligible for garbage collection. Dead (garbage collected) listeners are @@ -145,7 +147,7 @@ public interface IMessageBus { * * If an unbound queuing strategy is used the call returns immediately. * If a bounded queue is used the call will block until the message can be placed in the queue - * or the timeout r + * or the timeout is reached. * * @return A message publication that wraps up the publication request */ diff --git a/src/main/java/net/engio/mbassy/MBassador.java b/src/main/java/net/engio/mbassy/bus/MBassador.java similarity index 76% rename from src/main/java/net/engio/mbassy/MBassador.java rename to src/main/java/net/engio/mbassy/bus/MBassador.java index 20ff8bd..b9d4f1d 100644 --- a/src/main/java/net/engio/mbassy/MBassador.java +++ b/src/main/java/net/engio/mbassy/bus/MBassador.java @@ -1,6 +1,7 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; -import net.engio.mbassy.common.DeadEvent; +import net.engio.mbassy.PublicationError; +import net.engio.mbassy.common.DeadMessage; import net.engio.mbassy.subscription.Subscription; import java.util.Collection; @@ -24,12 +25,12 @@ public class MBassador extends AbstractMessageBus> private MessagePublication createMessagePublication(T message) { Collection subscriptions = getSubscriptionsByMessageType(message.getClass()); - if (subscriptions == null || subscriptions.isEmpty()) { + if ((subscriptions == null || subscriptions.isEmpty()) && !message.getClass().equals(DeadMessage.class)) { // Dead Event - subscriptions = getSubscriptionsByMessageType(DeadEvent.class); - return MessagePublication.Create(this, subscriptions, new DeadEvent(message)); + subscriptions = getSubscriptionsByMessageType(DeadMessage.class); + return getPublicationFactory().createPublication(this, subscriptions, new DeadMessage(message)); } - else return MessagePublication.Create(this, subscriptions, message); + else return getPublicationFactory().createPublication(this, subscriptions, message); } diff --git a/src/main/java/net/engio/mbassy/MessagePublication.java b/src/main/java/net/engio/mbassy/bus/MessagePublication.java similarity index 67% rename from src/main/java/net/engio/mbassy/MessagePublication.java rename to src/main/java/net/engio/mbassy/bus/MessagePublication.java index 7a3d60e..025e3a3 100644 --- a/src/main/java/net/engio/mbassy/MessagePublication.java +++ b/src/main/java/net/engio/mbassy/bus/MessagePublication.java @@ -1,7 +1,7 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; -import net.engio.mbassy.common.DeadEvent; -import net.engio.mbassy.common.FilteredEvent; +import net.engio.mbassy.common.DeadMessage; +import net.engio.mbassy.common.FilteredMessage; import net.engio.mbassy.subscription.Subscription; import java.util.Collection; @@ -19,8 +19,12 @@ import java.util.Collection; */ public class MessagePublication { - public static MessagePublication Create(IMessageBus bus, Collection subscriptions, Object message){ - return new MessagePublication(bus,subscriptions, message, State.Initial); + public static class Factory{ + + public MessagePublication createPublication(IMessageBus owningBus, Collection subscriptions, Object message){ + return new MessagePublication(owningBus, subscriptions, message, State.Initial); + } + } private Collection subscriptions; @@ -33,7 +37,7 @@ public class MessagePublication { private IMessageBus bus; - private MessagePublication(IMessageBus bus, Collection subscriptions, Object message, State initialState) { + public MessagePublication(IMessageBus bus, Collection subscriptions, Object message, State initialState) { this.bus = bus; this.subscriptions = subscriptions; this.message = message; @@ -50,8 +54,14 @@ public class MessagePublication { sub.publish(this, message); } state = State.Finished; - if(!delivered && !isFilteredEvent() && !isDeadEvent()){ - bus.post(new FilteredEvent(message)).now(); + // if the message has not been marked delivered by the dispatcher + if(!delivered){ + if(!isFilteredEvent() && !isDeadEvent()){ + bus.post(new FilteredMessage(message)).now(); + }else if(!isDeadEvent()){ + bus.post(new DeadMessage(message)).now(); + } + } } @@ -84,11 +94,11 @@ public class MessagePublication { } public boolean isDeadEvent(){ - return DeadEvent.class.isAssignableFrom(message.getClass()); + return DeadMessage.class.isAssignableFrom(message.getClass()); } public boolean isFilteredEvent(){ - return FilteredEvent.class.isAssignableFrom(message.getClass()); + return FilteredMessage.class.isAssignableFrom(message.getClass()); } private enum State{ diff --git a/src/main/java/net/engio/mbassy/SyncAsyncPostCommand.java b/src/main/java/net/engio/mbassy/bus/SyncAsyncPostCommand.java similarity index 96% rename from src/main/java/net/engio/mbassy/SyncAsyncPostCommand.java rename to src/main/java/net/engio/mbassy/bus/SyncAsyncPostCommand.java index d29396b..7ac4aca 100644 --- a/src/main/java/net/engio/mbassy/SyncAsyncPostCommand.java +++ b/src/main/java/net/engio/mbassy/bus/SyncAsyncPostCommand.java @@ -1,4 +1,4 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/net/engio/mbassy/common/DeadEvent.java b/src/main/java/net/engio/mbassy/common/DeadMessage.java similarity index 73% rename from src/main/java/net/engio/mbassy/common/DeadEvent.java rename to src/main/java/net/engio/mbassy/common/DeadMessage.java index 4878646..abd83d4 100644 --- a/src/main/java/net/engio/mbassy/common/DeadEvent.java +++ b/src/main/java/net/engio/mbassy/common/DeadMessage.java @@ -7,9 +7,9 @@ package net.engio.mbassy.common; * @author bennidi * Date: 1/18/13 */ -public class DeadEvent extends PublicationEvent { +public final class DeadMessage extends PublicationEvent { - public DeadEvent(Object message) { + public DeadMessage(Object message) { super(message); } diff --git a/src/main/java/net/engio/mbassy/common/FilteredEvent.java b/src/main/java/net/engio/mbassy/common/FilteredMessage.java similarity index 76% rename from src/main/java/net/engio/mbassy/common/FilteredEvent.java rename to src/main/java/net/engio/mbassy/common/FilteredMessage.java index 98bdddb..65a284f 100644 --- a/src/main/java/net/engio/mbassy/common/FilteredEvent.java +++ b/src/main/java/net/engio/mbassy/common/FilteredMessage.java @@ -8,10 +8,10 @@ package net.engio.mbassy.common; * @author bennidi * Date: 3/1/13 */ -public class FilteredEvent extends PublicationEvent { +public class FilteredMessage extends PublicationEvent { - public FilteredEvent(Object event) { + public FilteredMessage(Object event) { super(event); } } diff --git a/src/main/java/net/engio/mbassy/common/PublicationEvent.java b/src/main/java/net/engio/mbassy/common/PublicationEvent.java index cefcfae..a3eb191 100644 --- a/src/main/java/net/engio/mbassy/common/PublicationEvent.java +++ b/src/main/java/net/engio/mbassy/common/PublicationEvent.java @@ -15,7 +15,7 @@ public abstract class PublicationEvent { this.event = message; } - public Object getEvent() { + public Object getMessage() { return event; } } diff --git a/src/main/java/net/engio/mbassy/dispatch/AsynchronousHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/AsynchronousHandlerInvocation.java index 31273e0..40403a6 100644 --- a/src/main/java/net/engio/mbassy/dispatch/AsynchronousHandlerInvocation.java +++ b/src/main/java/net/engio/mbassy/dispatch/AsynchronousHandlerInvocation.java @@ -1,6 +1,5 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.MessagePublication; import net.engio.mbassy.subscription.AbstractSubscriptionContextAware; /** diff --git a/src/main/java/net/engio/mbassy/dispatch/EnvelopedMessageDispatcher.java b/src/main/java/net/engio/mbassy/dispatch/EnvelopedMessageDispatcher.java index 8df3774..e4aed51 100644 --- a/src/main/java/net/engio/mbassy/dispatch/EnvelopedMessageDispatcher.java +++ b/src/main/java/net/engio/mbassy/dispatch/EnvelopedMessageDispatcher.java @@ -1,6 +1,6 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.MessagePublication; +import net.engio.mbassy.bus.MessagePublication; import net.engio.mbassy.common.ConcurrentSet; import net.engio.mbassy.subscription.MessageEnvelope; diff --git a/src/main/java/net/engio/mbassy/dispatch/FilteredMessageDispatcher.java b/src/main/java/net/engio/mbassy/dispatch/FilteredMessageDispatcher.java index 1bd1a3a..685e484 100644 --- a/src/main/java/net/engio/mbassy/dispatch/FilteredMessageDispatcher.java +++ b/src/main/java/net/engio/mbassy/dispatch/FilteredMessageDispatcher.java @@ -1,6 +1,6 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.MessagePublication; +import net.engio.mbassy.bus.MessagePublication; import net.engio.mbassy.common.ConcurrentSet; import net.engio.mbassy.listener.IMessageFilter; diff --git a/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java index c449403..f9bc39a 100644 --- a/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java +++ b/src/main/java/net/engio/mbassy/dispatch/IHandlerInvocation.java @@ -1,7 +1,5 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.MessagePublication; - /** * A handler invocation encapsulates the logic that is used to invoke a single * message handler to process a given message. diff --git a/src/main/java/net/engio/mbassy/dispatch/IMessageBusAware.java b/src/main/java/net/engio/mbassy/dispatch/IMessageBusAware.java index 9e3260e..6c71b0f 100644 --- a/src/main/java/net/engio/mbassy/dispatch/IMessageBusAware.java +++ b/src/main/java/net/engio/mbassy/dispatch/IMessageBusAware.java @@ -1,6 +1,6 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.IMessageBus; +import net.engio.mbassy.bus.IMessageBus; /** * This interface marks components that have access to the message bus that they belong to. diff --git a/src/main/java/net/engio/mbassy/dispatch/IMessageDispatcher.java b/src/main/java/net/engio/mbassy/dispatch/IMessageDispatcher.java index 41f5eb2..b74f8e0 100644 --- a/src/main/java/net/engio/mbassy/dispatch/IMessageDispatcher.java +++ b/src/main/java/net/engio/mbassy/dispatch/IMessageDispatcher.java @@ -1,6 +1,6 @@ package net.engio.mbassy.dispatch; -import net.engio.mbassy.MessagePublication; +import net.engio.mbassy.bus.MessagePublication; import net.engio.mbassy.common.ConcurrentSet; /** diff --git a/src/main/java/net/engio/mbassy/dispatch/ISubscriptionContextAware.java b/src/main/java/net/engio/mbassy/dispatch/ISubscriptionContextAware.java index c16ae5b..636f21f 100644 --- a/src/main/java/net/engio/mbassy/dispatch/ISubscriptionContextAware.java +++ b/src/main/java/net/engio/mbassy/dispatch/ISubscriptionContextAware.java @@ -1,5 +1,7 @@ package net.engio.mbassy.dispatch; +import net.engio.mbassy.subscription.SubscriptionContext; + /** * This interface marks components that have access to the subscription context. * diff --git a/src/main/java/net/engio/mbassy/dispatch/MessageDispatcher.java b/src/main/java/net/engio/mbassy/dispatch/MessageDispatcher.java index 6c69dc1..968eebb 100644 --- a/src/main/java/net/engio/mbassy/dispatch/MessageDispatcher.java +++ b/src/main/java/net/engio/mbassy/dispatch/MessageDispatcher.java @@ -1,11 +1,9 @@ package net.engio.mbassy.dispatch; -import java.lang.reflect.Method; - -import net.engio.mbassy.IMessageBus; -import net.engio.mbassy.MessagePublication; +import net.engio.mbassy.bus.MessagePublication; import net.engio.mbassy.common.ConcurrentSet; import net.engio.mbassy.subscription.AbstractSubscriptionContextAware; +import net.engio.mbassy.subscription.SubscriptionContext; /** * Standard implementation for direct, unfiltered message delivery. diff --git a/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java b/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java index ee75da5..844ad45 100644 --- a/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java +++ b/src/main/java/net/engio/mbassy/dispatch/ReflectiveHandlerInvocation.java @@ -1,9 +1,9 @@ package net.engio.mbassy.dispatch; import net.engio.mbassy.IPublicationErrorHandler; -import net.engio.mbassy.MessagePublication; import net.engio.mbassy.PublicationError; import net.engio.mbassy.subscription.AbstractSubscriptionContextAware; +import net.engio.mbassy.subscription.SubscriptionContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/main/java/net/engio/mbassy/listener/Enveloped.java b/src/main/java/net/engio/mbassy/listener/Enveloped.java index 4307e91..aea0e53 100644 --- a/src/main/java/net/engio/mbassy/listener/Enveloped.java +++ b/src/main/java/net/engio/mbassy/listener/Enveloped.java @@ -4,7 +4,7 @@ import java.lang.annotation.*; /** * Configure a handler to receive an enveloped message as a wrapper around the source - * message. An enveloped message can be + * message. An enveloped message can contain any type of message * * @author bennidi * Date: 2/8/12 diff --git a/src/main/java/net/engio/mbassy/listener/Filter.java b/src/main/java/net/engio/mbassy/listener/Filter.java index ec69f05..75d0364 100644 --- a/src/main/java/net/engio/mbassy/listener/Filter.java +++ b/src/main/java/net/engio/mbassy/listener/Filter.java @@ -6,10 +6,10 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * THe filter annotation is used to add filters to message listeners. - * It references a class that implements the MessageFilter interface. - * The object filter will be used to check whether a message should be delivered - * to the message listener or not. + * The filter annotation is used to add filters to message listeners. + * It references a class that implements the IMessageFilter interface. + * The filter will be used to check whether a message should be delivered + * to the listener or not. * *

* @author bennidi @@ -19,5 +19,10 @@ import java.lang.annotation.Target; @Target(value = {ElementType.ANNOTATION_TYPE}) public @interface Filter { + /** + * The class that implements the filter. + * Note: A filter always needs to provide a non-arg constructor + * @return + */ Class value(); } diff --git a/src/main/java/net/engio/mbassy/listener/Filters.java b/src/main/java/net/engio/mbassy/listener/Filters.java index fb53820..0bb23fa 100644 --- a/src/main/java/net/engio/mbassy/listener/Filters.java +++ b/src/main/java/net/engio/mbassy/listener/Filters.java @@ -1,7 +1,8 @@ package net.engio.mbassy.listener; /** - * Todo: Add javadoc + * Some sample filters that are not particularly useful in production environment + * but illustrate how filters are meant to be used. * * @author bennidi * Date: 12/12/12 diff --git a/src/main/java/net/engio/mbassy/listener/Handler.java b/src/main/java/net/engio/mbassy/listener/Handler.java new file mode 100644 index 0000000..7664f89 --- /dev/null +++ b/src/main/java/net/engio/mbassy/listener/Handler.java @@ -0,0 +1,51 @@ +package net.engio.mbassy.listener; + +import java.lang.annotation.*; + +/** + * Mark any method of any object(=listener) as a message handler and configure the handler + * using different properties. + * + * @author bennidi + * Date: 2/8/12 + */ +@Retention(value = RetentionPolicy.RUNTIME) +@Inherited +@Target(value = {ElementType.METHOD}) +public @interface Handler { + + /** + * Add any numbers of filters to the handler. All filters are evaluated before the handler + * is actually invoked, which is only if all the filters accept the message. + */ + Filter[] filters() default {}; + + /** + * Define the mode in which a message is delivered to each listener. Listeners can be notified + * sequentially or concurrently. + * + */ + Mode delivery() default Mode.Sequential; + + /** + * Handlers are ordered by priority and handlers with higher priority are processed before + * those with lower priority, i.e. Influence the order in which different handlers that consume + * the same message type are invoked. + */ + int priority() default 0; + + /** + * Define whether or not the handler accepts sub types of the message type it declares in its + * signature. + */ + boolean rejectSubtypes() default false; + + + /** + * Enable or disable the handler. Disabled handlers do not receive any messages. + * This property is useful for quick changes in configuration and necessary to disable + * handlers that have been declared by a superclass but do not apply to the subclass + */ + boolean enabled() default true; + +} diff --git a/src/main/java/net/engio/mbassy/listener/Listener.java b/src/main/java/net/engio/mbassy/listener/Listener.java deleted file mode 100644 index b214283..0000000 --- a/src/main/java/net/engio/mbassy/listener/Listener.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.engio.mbassy.listener; - -import java.lang.annotation.*; - -/** - * Mark any method of any object as a message handler and configure the handler - * using different properties. - * - * @author bennidi - * Date: 2/8/12 - */ -@Retention(value = RetentionPolicy.RUNTIME) -@Inherited -@Target(value = {ElementType.METHOD}) -public @interface Listener { - - - Filter[] filters() default {}; // no filters by default - - Mode delivery() default Mode.Sequential; - - int priority() default 0; - - boolean rejectSubtypes() default false; - - boolean enabled() default true; - -} diff --git a/src/main/java/net/engio/mbassy/listener/MessageHandlerMetadata.java b/src/main/java/net/engio/mbassy/listener/MessageHandlerMetadata.java index bb819c5..0f8d110 100644 --- a/src/main/java/net/engio/mbassy/listener/MessageHandlerMetadata.java +++ b/src/main/java/net/engio/mbassy/listener/MessageHandlerMetadata.java @@ -16,7 +16,7 @@ public class MessageHandlerMetadata { private IMessageFilter[] filter; - private Listener listenerConfig; + private Handler handlerConfig; private boolean isAsynchronous = false; @@ -27,13 +27,13 @@ public class MessageHandlerMetadata { private boolean acceptsSubtypes = true; - public MessageHandlerMetadata(Method handler, IMessageFilter[] filter, Listener listenerConfig) { + public MessageHandlerMetadata(Method handler, IMessageFilter[] filter, Handler handlerConfig) { this.handler = handler; this.filter = filter; - this.listenerConfig = listenerConfig; - this.isAsynchronous = listenerConfig.delivery().equals(Mode.Concurrent); + this.handlerConfig = handlerConfig; + this.isAsynchronous = handlerConfig.delivery().equals(Mode.Concurrent); this.envelope = handler.getAnnotation(Enveloped.class); - this.acceptsSubtypes = !listenerConfig.rejectSubtypes(); + this.acceptsSubtypes = !handlerConfig.rejectSubtypes(); if(this.envelope != null){ for(Class messageType : envelope.messages()) handledMessages.add(messageType); @@ -54,7 +54,7 @@ public class MessageHandlerMetadata { } public int getPriority(){ - return listenerConfig.priority(); + return handlerConfig.priority(); } public Method getHandler() { @@ -87,6 +87,6 @@ public class MessageHandlerMetadata { public boolean isEnabled() { - return listenerConfig.enabled(); + return handlerConfig.enabled(); } } diff --git a/src/main/java/net/engio/mbassy/listener/MetadataReader.java b/src/main/java/net/engio/mbassy/listener/MetadataReader.java index d06f67f..0e4aa86 100644 --- a/src/main/java/net/engio/mbassy/listener/MetadataReader.java +++ b/src/main/java/net/engio/mbassy/listener/MetadataReader.java @@ -16,11 +16,11 @@ import java.util.*; */ public class MetadataReader { - // This predicate is used to find all message listeners (methods annotated with @Listener) + // This predicate is used to find all message listeners (methods annotated with @Handler) private static final IPredicate AllMessageHandlers = new IPredicate() { @Override public boolean apply(Method target) { - return target.getAnnotation(Listener.class) != null; + return target.getAnnotation(Handler.class) != null; } }; @@ -28,7 +28,7 @@ public class MetadataReader { private final Map, IMessageFilter> filterCache = new HashMap, IMessageFilter>(); // retrieve all instances of filters associated with the given subscription - private IMessageFilter[] getFilter(Listener subscription){ + private IMessageFilter[] getFilter(Handler subscription){ if (subscription.filters().length == 0) return null; IMessageFilter[] filters = new IMessageFilter[subscription.filters().length]; int i = 0; @@ -52,14 +52,14 @@ public class MetadataReader { public MessageHandlerMetadata getHandlerMetadata(Method messageHandler){ - Listener config = messageHandler.getAnnotation(Listener.class); + Handler config = messageHandler.getAnnotation(Handler.class); return new MessageHandlerMetadata(messageHandler, getFilter(config), config); } // get all listeners defined by the given class (includes // listeners defined in super classes) public List getMessageHandlers(Class target) { - // get all handlers (this will include all (inherited) methods directly annotated using @Listener) + // get all handlers (this will include all (inherited) methods directly annotated using @Handler) List allHandlers = ReflectionUtils.getMethods(AllMessageHandlers, target); // retain only those that are at the bottom of their respective class hierarchy (deepest overriding method) List bottomMostHandlers = new LinkedList(); @@ -71,15 +71,15 @@ public class MetadataReader { List filteredHandlers = new LinkedList(); - // for each handler there will be no overriding method that specifies @Listener annotation + // for each handler there will be no overriding method that specifies @Handler annotation // but an overriding method does inherit the listener configuration of the overwritten method for(Method handler : bottomMostHandlers){ - Listener listener = handler.getAnnotation(Listener.class); - if(!listener.enabled() || !isValidMessageHandler(handler)) continue; // disabled or invalid listeners are ignored + Handler handle = handler.getAnnotation(Handler.class); + if(!handle.enabled() || !isValidMessageHandler(handler)) continue; // disabled or invalid listeners are ignored Method overriddenHandler = ReflectionUtils.getOverridingMethod(handler, target); // if a handler is overwritten it inherits the configuration of its parent method MessageHandlerMetadata handlerMetadata = new MessageHandlerMetadata(overriddenHandler == null ? handler : overriddenHandler, - getFilter(listener), listener); + getFilter(handle), handle); filteredHandlers.add(handlerMetadata); } @@ -94,7 +94,7 @@ public class MetadataReader { private boolean isValidMessageHandler(Method handler) { - if(handler == null || handler.getAnnotation(Listener.class) == null){ + if(handler == null || handler.getAnnotation(Handler.class) == null){ return false; } if (handler.getParameterTypes().length != 1) { diff --git a/src/main/java/net/engio/mbassy/subscription/AbstractSubscriptionContextAware.java b/src/main/java/net/engio/mbassy/subscription/AbstractSubscriptionContextAware.java index e2fbaf9..f41fab5 100644 --- a/src/main/java/net/engio/mbassy/subscription/AbstractSubscriptionContextAware.java +++ b/src/main/java/net/engio/mbassy/subscription/AbstractSubscriptionContextAware.java @@ -1,8 +1,7 @@ package net.engio.mbassy.subscription; -import net.engio.mbassy.IMessageBus; +import net.engio.mbassy.bus.IMessageBus; import net.engio.mbassy.dispatch.ISubscriptionContextAware; -import net.engio.mbassy.dispatch.SubscriptionContext; /** * The base implementation for subscription context aware objects (mightily obvious :) diff --git a/src/main/java/net/engio/mbassy/subscription/Subscription.java b/src/main/java/net/engio/mbassy/subscription/Subscription.java index 7dc9e5d..5b5f5b3 100644 --- a/src/main/java/net/engio/mbassy/subscription/Subscription.java +++ b/src/main/java/net/engio/mbassy/subscription/Subscription.java @@ -3,10 +3,9 @@ package net.engio.mbassy.subscription; import java.util.Comparator; import java.util.UUID; -import net.engio.mbassy.MessagePublication; +import net.engio.mbassy.bus.MessagePublication; import net.engio.mbassy.common.ConcurrentSet; import net.engio.mbassy.dispatch.IMessageDispatcher; -import net.engio.mbassy.dispatch.SubscriptionContext; /** * A subscription is a thread safe container for objects that contain message handlers diff --git a/src/main/java/net/engio/mbassy/dispatch/SubscriptionContext.java b/src/main/java/net/engio/mbassy/subscription/SubscriptionContext.java similarity index 93% rename from src/main/java/net/engio/mbassy/dispatch/SubscriptionContext.java rename to src/main/java/net/engio/mbassy/subscription/SubscriptionContext.java index 6926bca..0d2a678 100644 --- a/src/main/java/net/engio/mbassy/dispatch/SubscriptionContext.java +++ b/src/main/java/net/engio/mbassy/subscription/SubscriptionContext.java @@ -1,6 +1,6 @@ -package net.engio.mbassy.dispatch; +package net.engio.mbassy.subscription; -import net.engio.mbassy.IMessageBus; +import net.engio.mbassy.bus.IMessageBus; import net.engio.mbassy.listener.MessageHandlerMetadata; /** diff --git a/src/main/java/net/engio/mbassy/subscription/SubscriptionFactory.java b/src/main/java/net/engio/mbassy/subscription/SubscriptionFactory.java index f0e8f53..b90c634 100644 --- a/src/main/java/net/engio/mbassy/subscription/SubscriptionFactory.java +++ b/src/main/java/net/engio/mbassy/subscription/SubscriptionFactory.java @@ -1,7 +1,6 @@ package net.engio.mbassy.subscription; import net.engio.mbassy.dispatch.*; -import net.engio.mbassy.dispatch.SubscriptionContext; /** * Created with IntelliJ IDEA. diff --git a/src/test/java/net/engio/mbassy/AllTests.java b/src/test/java/net/engio/mbassy/AllTests.java index 7dd199d..58bc64c 100644 --- a/src/test/java/net/engio/mbassy/AllTests.java +++ b/src/test/java/net/engio/mbassy/AllTests.java @@ -1,5 +1,6 @@ package net.engio.mbassy; +import net.engio.mbassy.bus.ListenerSubscriptionTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; diff --git a/src/test/java/net/engio/mbassy/DeadEventTest.java b/src/test/java/net/engio/mbassy/DeadEventTest.java index b509a59..f1b3ddb 100644 --- a/src/test/java/net/engio/mbassy/DeadEventTest.java +++ b/src/test/java/net/engio/mbassy/DeadEventTest.java @@ -1,9 +1,11 @@ package net.engio.mbassy; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.MBassador; import net.engio.mbassy.common.ConcurrentSet; -import net.engio.mbassy.common.DeadEvent; -import net.engio.mbassy.common.UnitTest; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.common.DeadMessage; +import net.engio.mbassy.common.MessageBusTest; +import net.engio.mbassy.listener.Handler; import org.junit.Test; /** @@ -12,12 +14,12 @@ import org.junit.Test; * @author bennidi * Date: 1/18/13 */ -public class DeadEventTest extends UnitTest{ +public class DeadEventTest extends MessageBusTest{ @Test public void testDeadEvent(){ - MBassador bus = new MBassador(BusConfiguration.Default()); + MBassador bus = getBus(BusConfiguration.Default()); DeadEventHandler deadEventHandler = new DeadEventHandler(); bus.subscribe(deadEventHandler); assertEquals(0, deadEventHandler.getDeadEventCount()); @@ -33,9 +35,9 @@ public class DeadEventTest extends UnitTest{ private ConcurrentSet deadEvents = new ConcurrentSet(); - @Listener - public void handle(DeadEvent event){ - deadEvents.add(event); + @Handler + public void handle(DeadMessage message){ + deadEvents.add(message); } diff --git a/src/test/java/net/engio/mbassy/FilterTest.java b/src/test/java/net/engio/mbassy/FilterTest.java index 58586a8..e20d3b0 100644 --- a/src/test/java/net/engio/mbassy/FilterTest.java +++ b/src/test/java/net/engio/mbassy/FilterTest.java @@ -1,17 +1,19 @@ package net.engio.mbassy; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.MBassador; +import net.engio.mbassy.common.DeadMessage; +import net.engio.mbassy.common.FilteredMessage; +import net.engio.mbassy.common.MessageBusTest; +import net.engio.mbassy.events.SubTestMessage; +import net.engio.mbassy.listener.*; import org.junit.Test; import net.engio.mbassy.common.TestUtil; -import net.engio.mbassy.common.UnitTest; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.events.TestEvent; -import net.engio.mbassy.listener.Filter; -import net.engio.mbassy.listener.Filters; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.events.TestMessage; import net.engio.mbassy.listeners.ListenerFactory; -import net.engio.mbassy.listeners.NonListeningBean; /** * Testing of filter functionality @@ -19,42 +21,94 @@ import net.engio.mbassy.listeners.NonListeningBean; * @author bennidi * Date: 11/26/12 */ -public class FilterTest extends UnitTest { +public class FilterTest extends MessageBusTest { + + private static final AtomicInteger FilteredEventCounter = new AtomicInteger(0); + private static final AtomicInteger DeadEventCounter = new AtomicInteger(0); @Test public void testSubclassFilter() throws Exception { - MBassador bus = new MBassador(new BusConfiguration()); + MBassador bus = getBus(new BusConfiguration()); ListenerFactory listenerFactory = new ListenerFactory() - .create(100, FilteredMessageListener.class) - .create(100, Object.class) - .create(100, NonListeningBean.class); + .create(100, FilteredMessageListener.class); List listeners = listenerFactory.build(); // this will subscribe the listeners concurrently to the bus TestUtil.setup(bus, listeners, 10); - TestEvent event = new TestEvent(); - TestEvent subTestEvent = new SubTestEvent(); + TestMessage message = new TestMessage(); + TestMessage subTestMessage = new SubTestMessage(); - bus.post(event).now(); - bus.post(subTestEvent).now(); - - assertEquals(100, event.counter.get()); - assertEquals(0, subTestEvent.counter.get()); + bus.post(message).now(); + bus.post(subTestMessage).now(); + assertEquals(100, message.counter.get()); + assertEquals(0, subTestMessage.counter.get()); + assertEquals(100, FilteredEventCounter.get()); } + @Test + public void testFilteredFilteredEvent() throws Exception { + FilteredEventCounter.set(0); + DeadEventCounter.set(0); + + MBassador bus = getBus(new BusConfiguration()); + ListenerFactory listenerFactory = new ListenerFactory() + .create(100, FilteredMessageListener.class); + + List listeners = listenerFactory.build(); + + // this will subscribe the listeners concurrently to the bus + TestUtil.setup(bus, listeners, 10); + + bus.post(new Object()).now(); + bus.post(new SubTestMessage()).now(); + + assertEquals(100, FilteredEventCounter.get()); // the SubTestMessage should have been republished as a filtered event + assertEquals(100, DeadEventCounter.get()); // Object.class was filtered and the fil + } public static class FilteredMessageListener{ - @Listener(filters = {@Filter(Filters.RejectSubtypes.class)}) - public void handleTestEvent(TestEvent event){ - event.counter.incrementAndGet(); + // NOTE: Use rejectSubtypes property of @Handler to achieve the same functionality but with better performance + // and more concise syntax + @Handler(filters = {@Filter(Filters.RejectSubtypes.class)}) + public void handleTestMessage(TestMessage message){ + message.counter.incrementAndGet(); + } + + // FilteredEvents that contain messages of class Object will be filtered (again) and should cause a DeadEvent to be thrown + @Handler(filters = {@Filter(RejectFilteredObjects.class)}) + public void handleFilteredEvent(FilteredMessage filtered){ + FilteredEventCounter.incrementAndGet(); + } + + // will cause republication of a FilteredEvent + @Handler(filters = {@Filter(Filters.RejectAll.class)}) + public void handleNone(Object any){ + FilteredEventCounter.incrementAndGet(); + } + + // will cause republication of a FilteredEvent + @Handler + public void handleDead(DeadMessage dead){ + DeadEventCounter.incrementAndGet(); } } + public static class RejectFilteredObjects implements IMessageFilter{ + + @Override + public boolean accepts(Object message, MessageHandlerMetadata metadata) { + if(message.getClass().equals(FilteredMessage.class) && ((FilteredMessage)message).getMessage().getClass().equals(Object.class)){ + return false; + } + return true; + } + } + } diff --git a/src/test/java/net/engio/mbassy/MessagePublicationTest.java b/src/test/java/net/engio/mbassy/MessagePublicationTest.java index 22fb1da..d3dd9a6 100644 --- a/src/test/java/net/engio/mbassy/MessagePublicationTest.java +++ b/src/test/java/net/engio/mbassy/MessagePublicationTest.java @@ -3,13 +3,15 @@ package net.engio.mbassy; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.MBassador; +import net.engio.mbassy.common.MessageBusTest; +import net.engio.mbassy.events.SubTestMessage; import org.junit.Test; import net.engio.mbassy.common.ConcurrentExecutor; import net.engio.mbassy.common.TestUtil; -import net.engio.mbassy.common.UnitTest; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.events.TestEvent; -import net.engio.mbassy.events.TestEvent2; +import net.engio.mbassy.events.TestMessage; +import net.engio.mbassy.events.TestMessage2; import net.engio.mbassy.listeners.EventingTestBean; import net.engio.mbassy.listeners.EventingTestBean2; import net.engio.mbassy.listeners.EventingTestBean3; @@ -23,7 +25,7 @@ import net.engio.mbassy.listeners.NonListeningBean; * @author bennidi * Date: 2/8/12 */ -public class MessagePublicationTest extends UnitTest { +public class MessagePublicationTest extends MessageBusTest { // this value probably needs to be adjusted depending on the performance of the underlying plattform // otherwise the tests will fail since asynchronous processing might not have finished when @@ -34,7 +36,7 @@ public class MessagePublicationTest extends UnitTest { @Test public void testAsynchronousMessagePublication() throws Exception { - MBassador bus = new MBassador(new BusConfiguration()); + MBassador bus = getBus(new BusConfiguration()); ListenerFactory listenerFactory = new ListenerFactory() .create(10000, EventingTestBean.class) .create(10000, EventingTestBean2.class) @@ -48,26 +50,26 @@ public class MessagePublicationTest extends UnitTest { // this will subscribe the listeners concurrently to the bus TestUtil.setup(bus, listeners, 10); - TestEvent event = new TestEvent(); - TestEvent subEvent = new SubTestEvent(); - TestEvent2 event2 = new TestEvent2(); + TestMessage message = new TestMessage(); + TestMessage subMessage = new SubTestMessage(); + TestMessage2 message2 = new TestMessage2(); - bus.publishAsync(event); - bus.publishAsync(subEvent); - bus.publishAsync(event2); + bus.publishAsync(message); + bus.publishAsync(subMessage); + bus.publishAsync(message2); pause(processingTimeInMS); - assertEquals(50000, event.counter.get()); - assertEquals(80000, subEvent.counter.get()); - assertEquals(20000, event2.counter.get()); + assertEquals(50000, message.counter.get()); + assertEquals(80000, subMessage.counter.get()); + assertEquals(20000, message2.counter.get()); } @Test public void testSynchronousMessagePublication() throws Exception { - MBassador bus = new MBassador(new BusConfiguration()); + MBassador bus = getBus(new BusConfiguration()); ListenerFactory listenerFactory = new ListenerFactory() .create(10000, EventingTestBean.class) .create(10000, EventingTestBean2.class) @@ -80,27 +82,27 @@ public class MessagePublicationTest extends UnitTest { // this will subscribe the listeners concurrently to the bus TestUtil.setup(bus, listeners, 10); - TestEvent event = new TestEvent(); - TestEvent subEvent = new SubTestEvent(); + TestMessage message = new TestMessage(); + TestMessage subMessage = new SubTestMessage(); - bus.publish(event); - bus.publish(subEvent); + bus.publish(message); + bus.publish(subMessage); pause(processingTimeInMS); - assertEquals(30000, event.counter.get()); - assertEquals(70000, subEvent.counter.get()); + assertEquals(30000, message.counter.get()); + assertEquals(70000, subMessage.counter.get()); } @Test public void testConcurrentMixedMessagePublication() throws Exception { - final CopyOnWriteArrayList testEvents = new CopyOnWriteArrayList(); - final CopyOnWriteArrayList subtestEvents = new CopyOnWriteArrayList(); + final CopyOnWriteArrayList testMessages = new CopyOnWriteArrayList(); + final CopyOnWriteArrayList subtestMessages = new CopyOnWriteArrayList(); final int eventLoopsPerTHread = 100; - final MBassador bus = new MBassador(new BusConfiguration()); + final MBassador bus = getBus(new BusConfiguration()); ListenerFactory listenerFactory = new ListenerFactory() .create(10000, EventingTestBean.class) .create(10000, EventingTestBean2.class) @@ -117,25 +119,25 @@ public class MessagePublicationTest extends UnitTest { @Override public void run() { for (int i = 0; i < eventLoopsPerTHread; i++) { - TestEvent event = new TestEvent(); - SubTestEvent subEvent = new SubTestEvent(); - testEvents.add(event); - subtestEvents.add(subEvent); + TestMessage message = new TestMessage(); + SubTestMessage subMessage = new SubTestMessage(); + testMessages.add(message); + subtestMessages.add(subMessage); - bus.publishAsync(event); - bus.publish(subEvent); + bus.publishAsync(message); + bus.publish(subMessage); } } }, 10); pause(processingTimeInMS); - for (TestEvent event : testEvents) { - assertEquals(30000, event.counter.get()); + for (TestMessage message : testMessages) { + assertEquals(30000, message.counter.get()); } - for (SubTestEvent event : subtestEvents) { - assertEquals(70000, event.counter.get()); + for (SubTestMessage message : subtestMessages) { + assertEquals(70000, message.counter.get()); } } diff --git a/src/test/java/net/engio/mbassy/MetadataReaderTest.java b/src/test/java/net/engio/mbassy/MetadataReaderTest.java index 6f7f7df..99b345a 100644 --- a/src/test/java/net/engio/mbassy/MetadataReaderTest.java +++ b/src/test/java/net/engio/mbassy/MetadataReaderTest.java @@ -3,7 +3,7 @@ package net.engio.mbassy; import org.junit.Test; import net.engio.mbassy.common.UnitTest; import net.engio.mbassy.listener.Enveloped; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.listener.Handler; import net.engio.mbassy.listener.MessageListenerMetadata; import net.engio.mbassy.listener.MetadataReader; import net.engio.mbassy.subscription.MessageEnvelope; @@ -112,18 +112,18 @@ public class MetadataReaderTest extends UnitTest { // a simple event listener public class EventListener1 { - @Listener(rejectSubtypes = true) + @Handler(rejectSubtypes = true) public void handleObject(Object o) { } - @Listener + @Handler public void handleAny(Object o) { } - @Listener + @Handler public void handleString(String s) { } @@ -143,12 +143,12 @@ public class MetadataReaderTest extends UnitTest { public class EventListener3 extends EventListener2 { // narrow the handler - @Listener(rejectSubtypes = true) + @Handler(rejectSubtypes = true) public void handleAny(Object o) { } - @Listener(enabled = false) + @Handler(enabled = false) public void handleString(String s) { } @@ -158,13 +158,13 @@ public class MetadataReaderTest extends UnitTest { public class EnvelopedListener{ - @Listener(rejectSubtypes = true) + @Handler(rejectSubtypes = true) @Enveloped(messages = {String.class, Integer.class, Long.class}) public void handleEnveloped(MessageEnvelope o) { } - @Listener + @Handler @Enveloped(messages = {Number.class}) public void handleEnveloped2(MessageEnvelope o) { @@ -175,7 +175,7 @@ public class MetadataReaderTest extends UnitTest { public class EnvelopedListenerSubclass extends EnvelopedListener{ // narrow to integer - @Listener + @Handler @Enveloped(messages = {Integer.class}) public void handleEnveloped2(MessageEnvelope o) { diff --git a/src/test/java/net/engio/mbassy/MethodDispatchTest.java b/src/test/java/net/engio/mbassy/MethodDispatchTest.java index 8b0f60b..8af0426 100644 --- a/src/test/java/net/engio/mbassy/MethodDispatchTest.java +++ b/src/test/java/net/engio/mbassy/MethodDispatchTest.java @@ -1,7 +1,9 @@ package net.engio.mbassy; -import net.engio.mbassy.common.UnitTest; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.IMessageBus; +import net.engio.mbassy.common.MessageBusTest; +import net.engio.mbassy.listener.Handler; import org.junit.Test; /** @@ -10,7 +12,7 @@ import org.junit.Test; * @author bennidi * Date: 1/17/13 */ -public class MethodDispatchTest extends UnitTest{ +public class MethodDispatchTest extends MessageBusTest{ private boolean listener1Called = false; private boolean listener2Called = false; @@ -20,7 +22,7 @@ public class MethodDispatchTest extends UnitTest{ // a simple event listener public class EventListener1 { - @Listener + @Handler public void handleString(String s) { listener1Called = true; } @@ -39,7 +41,7 @@ public class MethodDispatchTest extends UnitTest{ @Test public void testDispatch1(){ - MBassador bus = new MBassador(BusConfiguration.Default()); + IMessageBus bus = getBus(BusConfiguration.Default()); EventListener2 listener2 = new EventListener2(); bus.subscribe(listener2); bus.post("jfndf").now(); diff --git a/src/test/java/net/engio/mbassy/ListenerSubscriptionTest.java b/src/test/java/net/engio/mbassy/bus/ListenerSubscriptionTest.java similarity index 84% rename from src/test/java/net/engio/mbassy/ListenerSubscriptionTest.java rename to src/test/java/net/engio/mbassy/bus/ListenerSubscriptionTest.java index 815c989..7b7830c 100644 --- a/src/test/java/net/engio/mbassy/ListenerSubscriptionTest.java +++ b/src/test/java/net/engio/mbassy/bus/ListenerSubscriptionTest.java @@ -1,10 +1,12 @@ -package net.engio.mbassy; +package net.engio.mbassy.bus; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.MBassador; +import net.engio.mbassy.common.MessageBusTest; +import net.engio.mbassy.events.SubTestMessage; import org.junit.Test; import net.engio.mbassy.common.TestUtil; -import net.engio.mbassy.common.UnitTest; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.events.TestEvent; +import net.engio.mbassy.events.TestMessage; import net.engio.mbassy.listeners.*; import net.engio.mbassy.subscription.Subscription; @@ -18,13 +20,13 @@ import java.util.List; * @author bennidi * Date: 1/9/13 */ -public class ListenerSubscriptionTest extends UnitTest{ +public class ListenerSubscriptionTest extends MessageBusTest{ // this is a single threaded test for subscribing and unsubscribing of a single listener @Test public void testSubscribeSimple() throws InterruptedException { - MBassador bus = new MBassador(new BusConfiguration()); + MBassador bus = getBus(new BusConfiguration()); List listeners = new LinkedList(); int listenerCount = 200000; @@ -43,11 +45,11 @@ public class ListenerSubscriptionTest extends UnitTest{ } // check the generated subscriptions for existence of all previously subscribed valid listeners - Collection testEventsubscriptions = bus.getSubscriptionsByMessageType(TestEvent.class); + Collection testEventsubscriptions = bus.getSubscriptionsByMessageType(TestMessage.class); assertEquals(1, testEventsubscriptions.size()); assertEquals(listenerCount, getNumberOfSubscribedListeners(testEventsubscriptions)); - Collection subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestEvent.class); + Collection subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestMessage.class); assertEquals(3, subTestEventsubscriptions.size()); assertEquals(3 * listenerCount, getNumberOfSubscribedListeners(subTestEventsubscriptions)); @@ -57,11 +59,11 @@ public class ListenerSubscriptionTest extends UnitTest{ } // no listener should be left - testEventsubscriptions = bus.getSubscriptionsByMessageType(TestEvent.class); + testEventsubscriptions = bus.getSubscriptionsByMessageType(TestMessage.class); assertEquals(1, testEventsubscriptions.size()); assertEquals(0, getNumberOfSubscribedListeners(testEventsubscriptions)); - subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestEvent.class); + subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestMessage.class); assertEquals(3, subTestEventsubscriptions.size()); assertEquals(0, getNumberOfSubscribedListeners(subTestEventsubscriptions)); @@ -78,7 +80,7 @@ public class ListenerSubscriptionTest extends UnitTest{ @Test public void testConcurrentSubscription() throws Exception { - MBassador bus = new MBassador(new BusConfiguration()); + MBassador bus = getBus(new BusConfiguration()); ListenerFactory listenerFactory = new ListenerFactory() .create(10000, EventingTestBean.class) .create(10000, EventingTestBean2.class) @@ -92,11 +94,11 @@ public class ListenerSubscriptionTest extends UnitTest{ TestUtil.setup(bus, listeners, 10); // check the generated subscriptions for existence of all previously subscribed valid listeners - Collection testEventsubscriptions = bus.getSubscriptionsByMessageType(TestEvent.class); + Collection testEventsubscriptions = bus.getSubscriptionsByMessageType(TestMessage.class); assertEquals(3, testEventsubscriptions.size()); assertEquals(30000, getNumberOfSubscribedListeners(testEventsubscriptions)); - Collection subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestEvent.class); + Collection subTestEventsubscriptions = bus.getSubscriptionsByMessageType(SubTestMessage.class); assertEquals(10, subTestEventsubscriptions.size()); assertEquals(100000, getNumberOfSubscribedListeners(subTestEventsubscriptions)); diff --git a/src/test/java/net/engio/mbassy/common/MessageBusTest.java b/src/test/java/net/engio/mbassy/common/MessageBusTest.java new file mode 100644 index 0000000..9a708b0 --- /dev/null +++ b/src/test/java/net/engio/mbassy/common/MessageBusTest.java @@ -0,0 +1,31 @@ +package net.engio.mbassy.common; + +import junit.framework.Assert; +import net.engio.mbassy.*; +import net.engio.mbassy.bus.BusConfiguration; +import net.engio.mbassy.bus.MBassador; + +/** + * A base test that provides a factory for message bus that makes tests fail if any + * publication error occurs + * + * @author bennidi + * Date: 3/2/13 + */ +public class MessageBusTest extends UnitTest{ + + private static final IPublicationErrorHandler TestFailingHandler = new IPublicationErrorHandler() { + @Override + public void handleError(PublicationError error) { + Assert.fail(); + } + }; + + public MBassador getBus(BusConfiguration configuration){ + MBassador bus = new MBassador(configuration); + bus.addErrorHandler(TestFailingHandler); + return bus; + } + + +} diff --git a/src/test/java/net/engio/mbassy/common/TestUtil.java b/src/test/java/net/engio/mbassy/common/TestUtil.java index 0e89d60..6a7edc0 100644 --- a/src/test/java/net/engio/mbassy/common/TestUtil.java +++ b/src/test/java/net/engio/mbassy/common/TestUtil.java @@ -1,6 +1,6 @@ package net.engio.mbassy.common; -import net.engio.mbassy.IMessageBus; +import net.engio.mbassy.bus.IMessageBus; import java.util.List; diff --git a/src/test/java/net/engio/mbassy/events/SubTestEvent.java b/src/test/java/net/engio/mbassy/events/SubTestMessage.java similarity index 65% rename from src/test/java/net/engio/mbassy/events/SubTestEvent.java rename to src/test/java/net/engio/mbassy/events/SubTestMessage.java index 5af6b30..ef295ec 100644 --- a/src/test/java/net/engio/mbassy/events/SubTestEvent.java +++ b/src/test/java/net/engio/mbassy/events/SubTestMessage.java @@ -5,6 +5,6 @@ package net.engio.mbassy.events; * @author bennidi * Date: 11/22/12 */ -public class SubTestEvent extends TestEvent { +public class SubTestMessage extends TestMessage { } diff --git a/src/test/java/net/engio/mbassy/events/TestEvent2.java b/src/test/java/net/engio/mbassy/events/TestMessage.java similarity index 87% rename from src/test/java/net/engio/mbassy/events/TestEvent2.java rename to src/test/java/net/engio/mbassy/events/TestMessage.java index 3b0c83f..12e69dd 100644 --- a/src/test/java/net/engio/mbassy/events/TestEvent2.java +++ b/src/test/java/net/engio/mbassy/events/TestMessage.java @@ -8,7 +8,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @author bennidi * Date: 11/22/12 */ -public class TestEvent2 { +public class TestMessage { public AtomicInteger counter = new AtomicInteger(); diff --git a/src/test/java/net/engio/mbassy/events/TestEvent.java b/src/test/java/net/engio/mbassy/events/TestMessage2.java similarity index 87% rename from src/test/java/net/engio/mbassy/events/TestEvent.java rename to src/test/java/net/engio/mbassy/events/TestMessage2.java index 237f4d3..1270529 100644 --- a/src/test/java/net/engio/mbassy/events/TestEvent.java +++ b/src/test/java/net/engio/mbassy/events/TestMessage2.java @@ -8,7 +8,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @author bennidi * Date: 11/22/12 */ -public class TestEvent { +public class TestMessage2 { public AtomicInteger counter = new AtomicInteger(); diff --git a/src/test/java/net/engio/mbassy/listeners/EventingTestBean.java b/src/test/java/net/engio/mbassy/listeners/EventingTestBean.java index df28db6..f0ff5b1 100644 --- a/src/test/java/net/engio/mbassy/listeners/EventingTestBean.java +++ b/src/test/java/net/engio/mbassy/listeners/EventingTestBean.java @@ -1,7 +1,7 @@ package net.engio.mbassy.listeners; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.events.TestEvent; +import net.engio.mbassy.events.SubTestMessage; +import net.engio.mbassy.events.TestMessage; import net.engio.mbassy.listener.*; /** @@ -14,25 +14,25 @@ public class EventingTestBean { // every event of type TestEvent or any subtype will be delivered // to this listener - @Listener - public void handleTestEvent(TestEvent event) { - event.counter.incrementAndGet(); + @Handler + public void handleTestEvent(TestMessage message) { + message.counter.incrementAndGet(); } // this handler will be invoked asynchronously - @Listener(priority = 0, delivery = Mode.Concurrent) - public void handleSubTestEvent(SubTestEvent event) { - event.counter.incrementAndGet(); + @Handler(priority = 0, delivery = Mode.Concurrent) + public void handleSubTestEvent(SubTestMessage message) { + message.counter.incrementAndGet(); } // this handler will receive events of type SubTestEvent // or any subtabe and that passes the given filter - @Listener( + @Handler( priority = 10, delivery = Mode.Sequential, filters = {@Filter(Filters.RejectAll.class), @Filter(Filters.AllowAll.class)}) - public void handleFiltered(SubTestEvent event) { - event.counter.incrementAndGet(); + public void handleFiltered(SubTestMessage message) { + message.counter.incrementAndGet(); } diff --git a/src/test/java/net/engio/mbassy/listeners/EventingTestBean2.java b/src/test/java/net/engio/mbassy/listeners/EventingTestBean2.java index bad7c1a..a21abbf 100644 --- a/src/test/java/net/engio/mbassy/listeners/EventingTestBean2.java +++ b/src/test/java/net/engio/mbassy/listeners/EventingTestBean2.java @@ -1,7 +1,7 @@ package net.engio.mbassy.listeners; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.events.SubTestMessage; +import net.engio.mbassy.listener.Handler; import net.engio.mbassy.listener.Mode; /** @@ -11,8 +11,8 @@ import net.engio.mbassy.listener.Mode; public class EventingTestBean2 extends EventingTestBean{ // redefine the configuration for this handler - @Listener(delivery = Mode.Sequential) - public void handleSubTestEvent(SubTestEvent event) { - super.handleSubTestEvent(event); + @Handler(delivery = Mode.Sequential) + public void handleSubTestEvent(SubTestMessage message) { + super.handleSubTestEvent(message); } } diff --git a/src/test/java/net/engio/mbassy/listeners/EventingTestBean3.java b/src/test/java/net/engio/mbassy/listeners/EventingTestBean3.java index 8b053d2..3df3c5f 100644 --- a/src/test/java/net/engio/mbassy/listeners/EventingTestBean3.java +++ b/src/test/java/net/engio/mbassy/listeners/EventingTestBean3.java @@ -1,7 +1,7 @@ package net.engio.mbassy.listeners; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.events.SubTestMessage; +import net.engio.mbassy.listener.Handler; import net.engio.mbassy.listener.Mode; /** @@ -12,9 +12,9 @@ public class EventingTestBean3 extends EventingTestBean2{ // this handler will be invoked asynchronously - @Listener(priority = 0, delivery = Mode.Sequential) - public void handleSubTestEventAgain(SubTestEvent event) { - event.counter.incrementAndGet(); + @Handler(priority = 0, delivery = Mode.Sequential) + public void handleSubTestEventAgain(SubTestMessage message) { + message.counter.incrementAndGet(); } } diff --git a/src/test/java/net/engio/mbassy/listeners/MultiEventHandler.java b/src/test/java/net/engio/mbassy/listeners/MultiEventHandler.java index 7545935..b6d7478 100644 --- a/src/test/java/net/engio/mbassy/listeners/MultiEventHandler.java +++ b/src/test/java/net/engio/mbassy/listeners/MultiEventHandler.java @@ -1,11 +1,11 @@ package net.engio.mbassy.listeners; -import net.engio.mbassy.events.TestEvent; -import net.engio.mbassy.events.TestEvent2; +import net.engio.mbassy.events.TestMessage; +import net.engio.mbassy.events.TestMessage2; import net.engio.mbassy.listener.Enveloped; import net.engio.mbassy.listener.Filter; import net.engio.mbassy.listener.Filters; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.listener.Handler; import net.engio.mbassy.listener.Mode; import net.engio.mbassy.subscription.MessageEnvelope; @@ -18,29 +18,29 @@ import net.engio.mbassy.subscription.MessageEnvelope; public class MultiEventHandler { - @Listener(delivery = Mode.Sequential) - @Enveloped(messages = {TestEvent.class, TestEvent2.class}) + @Handler(delivery = Mode.Sequential) + @Enveloped(messages = {TestMessage.class, TestMessage2.class}) public void handleEvents(MessageEnvelope envelope) { - if(TestEvent.class.isAssignableFrom(envelope.getMessage().getClass())){ - TestEvent event = envelope.getMessage(); - event.counter.incrementAndGet(); + if(TestMessage.class.isAssignableFrom(envelope.getMessage().getClass())){ + TestMessage message = envelope.getMessage(); + message.counter.incrementAndGet(); } - if(envelope.getMessage().getClass().equals(TestEvent2.class)){ - TestEvent2 event = envelope.getMessage(); - event.counter.incrementAndGet(); + if(envelope.getMessage().getClass().equals(TestMessage2.class)){ + TestMessage2 message = envelope.getMessage(); + message.counter.incrementAndGet(); } } - @Listener(delivery = Mode.Sequential, filters = @Filter(Filters.RejectSubtypes.class)) - @Enveloped(messages = {TestEvent.class, TestEvent2.class}) + @Handler(delivery = Mode.Sequential, filters = @Filter(Filters.RejectSubtypes.class)) + @Enveloped(messages = {TestMessage.class, TestMessage2.class}) public void handleSuperTypeEvents(MessageEnvelope envelope) { - if(TestEvent.class.isAssignableFrom(envelope.getMessage().getClass())){ - TestEvent event = envelope.getMessage(); - event.counter.incrementAndGet(); + if(TestMessage.class.isAssignableFrom(envelope.getMessage().getClass())){ + TestMessage message = envelope.getMessage(); + message.counter.incrementAndGet(); } - if(envelope.getMessage().getClass().equals(TestEvent2.class)){ - TestEvent2 event = envelope.getMessage(); - event.counter.incrementAndGet(); + if(envelope.getMessage().getClass().equals(TestMessage2.class)){ + TestMessage2 message = envelope.getMessage(); + message.counter.incrementAndGet(); } } diff --git a/src/test/java/net/engio/mbassy/listeners/NonListeningBean.java b/src/test/java/net/engio/mbassy/listeners/NonListeningBean.java index c7f519a..6537b4c 100644 --- a/src/test/java/net/engio/mbassy/listeners/NonListeningBean.java +++ b/src/test/java/net/engio/mbassy/listeners/NonListeningBean.java @@ -1,8 +1,8 @@ package net.engio.mbassy.listeners; -import net.engio.mbassy.events.SubTestEvent; -import net.engio.mbassy.events.TestEvent; -import net.engio.mbassy.listener.Listener; +import net.engio.mbassy.events.SubTestMessage; +import net.engio.mbassy.events.TestMessage; +import net.engio.mbassy.listener.Handler; /** * This bean overrides all the handlers defined in its superclass. Since it does not specify any annotations @@ -15,20 +15,20 @@ public class NonListeningBean extends EventingTestBean{ @Override - @Listener(enabled = false) - public void handleTestEvent(TestEvent event) { - event.counter.incrementAndGet(); // should never be called + @Handler(enabled = false) + public void handleTestEvent(TestMessage message) { + message.counter.incrementAndGet(); // should never be called } @Override - @Listener(enabled = false) - public void handleSubTestEvent(SubTestEvent event) { - event.counter.incrementAndGet(); // should never be called + @Handler(enabled = false) + public void handleSubTestEvent(SubTestMessage message) { + message.counter.incrementAndGet(); // should never be called } @Override - @Listener(enabled = false) - public void handleFiltered(SubTestEvent event) { - event.counter.incrementAndGet(); // should never be called + @Handler(enabled = false) + public void handleFiltered(SubTestMessage message) { + message.counter.incrementAndGet(); // should never be called } }