Adding the listener aspect

Listeners are configured via property files:

#net.sourceforge.pebble.event.response.DeleteRejectedListener
#net.sourceforge.pebble.event.comment.EmailAuthorNotificationListener

And added during creation of the domain object Blog like this

if (!classes[i].startsWith("#")) {
    try {
    Class c = Class.forName(classes[i].trim());
    BlogListener listener = (BlogListener)c.newInstance();
    eventListenerList.addBlogListener(listener);

Class.forName will not work in an OSGi environment. Thus requires the Listeners to reside inside the bundle creating them. To use the dynamics of the OSGi runtime Listeners should be deployed in separate bundles. The Listeners are part of the pebble API and the core implementation moved to a separate bundle

<bean id="emailNotificationListener" class="net.sourceforge.pebble.event.blogentry.EmailNotificationListener" autowire="constructor"/>

<!-- OSGi service -->
<osgi:service ref="emailNotificationListener" interface="net.sourceforge.pebble.api.event.blogentry.BlogEntryListener" />
<osgi:service interface="net.sourceforge.pebble.api.event.blogentry.BlogEntryListener">
    <bean class="net.sourceforge.pebble.event.blogentry.EmailSubscriptionListener" autowire="constructor" />
</osgi:service>

<!-- OSGi service -->
<osgi:service ref="emailNotificationListener" interface="net.sourceforge.pebble.api.event.blogentry.BlogEntryListener" />
<osgi:service interface="net.sourceforge.pebble.api.event.blogentry.BlogEntryListener">
    <bean class="net.sourceforge.pebble.event.blogentry.EmailSubscriptionListener" autowire="constructor" />
</osgi:service>

All available implementations are gathered using:

<osgi:set id="blogEntryListenerSet" interface="net.sourceforge.pebble.api.event.blogentry.BlogEntryListener" cardinality="0..N"/>

Additionally the Listeners are now registered by name:

ipAddressListener
linkSpamListener
contentSpamListener
spamScoreListener
markApprovedWhenAuthenticatedListener

Identified using a name, defaulting to:

@Override
public String getName() {
    return getClass().getSimpleName();
}

This post is part of a series about an OSGi experiment: Migrate a monolith to a modular OSGi application architecture.

The Beginning of an OSGi Experiment

Building OSGi ready pebble with Maven

Third time it's a charm

Extracting the first OSGi bundle

Extract the DAO layer

▶︎ Adding the listener aspect

Extracting the E-Mail Service

▷ ...


Header cover Photo by Matthew Henry from Burst