Package-level declarations

Provide general utilities to attach many handlers to be applied on events processing. Events can be of any type.

Handlers may or may not be applied to certain events at runtime based on rules provided as a predicate (function).

If an event doesn't match a handler's predicate, that handler is ignored, and the next one will be processed.

When a handler's predicate returns true, its callback will be called. That block will process the event, and return a modified copy with the changes.

The callback block will decide if subsequent handler's will be evaluated by calling the next handler explicitly (if next method is not called, the handlers defined later won't be evaluated).

There are types of handlers like 'After' y 'Before' that call next as part as their operation discharging the user of doing so.

The events are passed to handlers' callbacks wrapped in a 'context'. The context can also pass information among handlers in the attributes field. And store an exception if it is thrown in a previous handler processing.

Concepts:

  • Events

    • Context

  • Handlers

    • Predicates

    • Callbacks

Types of handlers:

  • On Handler: the callback is executed before calling the remaining handlers. next is called after the callback.

  • After Handler: the predicate is evaluated after the remaining handlers return, and the callback is executed after. next is called before the callback

  • Filter Handler: next is not called by this handler, its callback is responsible for doing so if needed.

  • Chain Handler: this handler contains a list of handlers inside.

IMPORTANT: the order is NOT the order, it is the depth. Handlers are not linked, they are NESTED. The next() method passes control to the next level.

This definition:

H1
H2
H3

Is really this execution:

H1 (on)
H2 (on)
H3 (on)
H2 (after)
H1 (after)

Types

Link copied to clipboard
data class AfterHandler<T : Any>(val afterPredicate: (Context<T>) -> Boolean = { true }, val callback: (Context<T>) -> Context<T>) : Handler<T>

After handlers are executed even if a filter don't call next handler (if after was added before filter).

Link copied to clipboard
data class BeforeHandler<T : Any>(val predicate: (Context<T>) -> Boolean = { true }, val callback: (Context<T>) -> Context<T>) : Handler<T>
Link copied to clipboard
data class ChainHandler<T : Any>(val handlers: List<Handler<T>>, val predicate: (Context<T>) -> Boolean = { true }) : Handler<T>
Link copied to clipboard
interface Context<T : Any>

Context for an event.

Link copied to clipboard
data class ExceptionHandler<T : Any, E : Exception>(val exception: KClass<E>, val clear: Boolean = true, val exceptionCallback: (Context<T>, E) -> Context<T>) : Handler<T>

After handlers are executed even if a filter don't call next handler (if after was added before filter).

Link copied to clipboard
data class FilterHandler<T : Any>(val predicate: (Context<T>) -> Boolean = { true }, val callback: (Context<T>) -> Context<T>) : Handler<T>
Link copied to clipboard
interface Handler<T : Any>

Handler for an event.

Link copied to clipboard
data class OnHandler<T : Any>(val predicate: (Context<T>) -> Boolean = { true }, val callback: (Context<T>) -> Context<T>) : Handler<T>