domino.java.ServiceWatcherCapsule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of domino-java Show documentation
Show all versions of domino-java Show documentation
A lightweight Java library for writing elegant OSGi bundle activators
package domino.java;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import de.tototec.utils.functional.Optional;
import de.tototec.utils.functional.Procedure1;
import domino.java.capsule.Capsule;
import domino.java.internal.Logger;
import domino.java.internal.LoggerFactory;
/**
* A capsule which executes the given event handlers on service state
* transitions while the current scope is active. Tracks all state transitions
* and services visible to the class loader. The custom object facility of the
* service tracker is not used.
*
* @param filter
* Filter expression restricting the set of services to be tracked
* @param f
* Event handlers
* @param bundleContext
* Bundle context
* @tparam S Service type to be tracked
*/
public class ServiceWatcherCapsule implements Capsule {
private final Logger log = LoggerFactory.getLogger(ServiceWatcherCapsule.class);
private final Filter filter;
private final Procedure1> f;
private final BundleContext bundleContext;
private Optional> tracker = Optional.none();
public ServiceWatcherCapsule(
final Filter filter,
final Procedure1> f,
final BundleContext bundleContext) {
this.filter = filter;
this.f = f;
this.bundleContext = bundleContext;
}
public Optional> tracker() {
return tracker;
}
@Override
public void start() {
log.debug("About to create service tracker with filter: {}", filter);
// Create tracker matching this filter
final ServiceTracker t = new ServiceTracker(bundleContext, filter, null) {
@Override
public S addingService(final ServiceReference reference) {
final S service = context.getService(reference);
final ServiceWatcherEvent event = new ServiceWatcherEvent(
service,
new ServiceWatcherContext<>(tracker().orNull(), reference),
ServiceWatcherEvent.EventType.ADDING);
f.apply(event);
return service;
}
@Override
public void modifiedService(final ServiceReference reference, final S service) {
final ServiceWatcherEvent event = new ServiceWatcherEvent(
service,
new ServiceWatcherContext<>(tracker().orNull(), reference),
ServiceWatcherEvent.EventType.MODIFIED);
f.apply(event);
}
@Override
public void removedService(final ServiceReference reference, final S service) {
final ServiceWatcherEvent event = new ServiceWatcherEvent(
service,
new ServiceWatcherContext<>(tracker().orNull(), reference),
ServiceWatcherEvent.EventType.REMOVED);
try {
f.apply(event);
} finally {
context.ungetService(reference);
}
}
};
tracker = Optional.some(t);
t.open();
}
@Override
public void stop() {
tracker.foreach(t -> {
t.close();
tracker = Optional.none();
});
}
}