Class ServiceCollector<S,T>
- java.lang.Object
-
- de.mnl.osgi.coreutils.ServiceCollector<S,T>
-
- Type Parameters:
S
- the type of the serviceT
- the type of service instances returned by queries, usually the same type as the type of the service (seesetServiceGetter(BiFunction)
)
- All Implemented Interfaces:
AutoCloseable
public class ServiceCollector<S,T> extends Object implements AutoCloseable
Maintains a collection of services matching some criteria.An instance can be created with different criteria for matching services of a given type. While the instance is open, it maintains a collection of all matching services provided by the framework. Changes of the collection are reported using the registered handlers.
Because OSGi is a threaded environment, the registered services can vary any time. Results from queries on the collection are therefore only reliable while synchronizing on the
ServiceCollector
instance. The synchronization puts other threads that attempt to change the collection on hold. Note that this implies a certain risk of creating deadlocks. Also note that this does not prevent modifications by the holder of the lock.Callbacks are always synchronized on this collector, else the state of the collector during the execution of the callback might no longer be the state that triggered the callback.
Instead of using the services from the framework directly, they may optionally be adapted to another type by setting a service getter function. The invocation of this function is also synchronized on this collector.
-
-
Constructor Summary
Constructors Constructor Description ServiceCollector(BundleContext context, Class<S> clazz)
Instantiates a newServiceCollector
that collects services of the specified class.ServiceCollector(BundleContext context, String className)
Instantiates a newServiceCollector
that collects services on the specified class name.ServiceCollector(BundleContext context, Filter filter)
Instantiates a newServiceCollector
that collects services matches by the specified filter.ServiceCollector(BundleContext context, ServiceReference<S> reference)
Instantiates a newServiceCollector
that collects services on the specified service reference.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
close()
Stops collecting services.SortedMap<ServiceReference<S>,T>
collected()
Return aSortedMap
of theServiceReference
s and service objects for all services collected by thisServiceCollector
.BundleContext
getContext()
Returns the context passed to the constructor.boolean
isEmpty()
Return if thisServiceCollector
is empty.boolean
isOpen()
Checks if thisServiceCollector
is open.int
modificationCount()
Returns the modification count for thisServiceCollector
.void
open()
Starts collecting of service providers.void
open(boolean collectAllServices)
Starts collecting services.void
remove(ServiceReference<S> reference)
Remove a service from thisServiceCollector
.Optional<T>
service()
Returns a service object for one of the services collected by thisServiceCollector
.Optional<T>
service(ServiceReference<S> reference)
Returns the service object for the specifiedServiceReference
if the specified referenced service has been collected by thisServiceCollector
.Optional<ServiceReference<S>>
serviceReference()
Returns aServiceReference
for one of the services collected by thisServiceCollector
.List<ServiceReference<S>>
serviceReferences()
Return the current set ofServiceReference
s for all services collected by thisServiceCollector
.List<T>
services()
Return the list of service objects for all services collected by thisServiceCollector
.ServiceCollector<S,T>
setOnAdded(BiConsumer<ServiceReference<S>,T> onAdded)
Sets a function to be called when a new service instance was added to the collection.ServiceCollector<S,T>
setOnBound(BiConsumer<ServiceReference<S>,T> onBound)
Sets a function to be called when the first service instance was added to the collection.ServiceCollector<S,T>
setOnModfied(BiConsumer<ServiceReference<S>,T> onModified)
Sets a function to be called when the preferred service changes.ServiceCollector<S,T>
setOnRemoving(BiConsumer<ServiceReference<S>,T> onRemoving)
Sets a function to be called before one of the collected service instances becomes unavailable.ServiceCollector<S,T>
setOnUnbinding(BiConsumer<ServiceReference<S>,T> onUnbinding)
Sets a function to be called before the last of the collected service instances becomes unavailable.ServiceCollector<S,T>
setServiceGetter(BiFunction<BundleContext,ServiceReference<S>,T> serviceGetter)
Sets the service getter function.int
size()
Return the number of services collected by thisServiceCollector
.String
toString()
Optional<T>
waitForService(long timeout)
Wait for at least one service to be collected by thisServiceCollector
.<R> Optional<R>
withService(Function<T,? extends R> function)
Convenience method to invoke the a function with the result fromservice()
(if it is available) while holding a lock on this service collector.
-
-
-
Constructor Detail
-
ServiceCollector
public ServiceCollector(BundleContext context, Class<S> clazz)
Instantiates a newServiceCollector
that collects services of the specified class.- Parameters:
context
- the bundle context used to interact with the frameworkclazz
- the clazz
-
ServiceCollector
public ServiceCollector(BundleContext context, Filter filter)
Instantiates a newServiceCollector
that collects services matches by the specified filter.- Parameters:
context
- the bundle context used to interact with the frameworkfilter
- the filter
-
ServiceCollector
public ServiceCollector(BundleContext context, ServiceReference<S> reference)
Instantiates a newServiceCollector
that collects services on the specified service reference.- Parameters:
context
- the bundle context used to interact with the frameworkreference
- the reference
-
ServiceCollector
public ServiceCollector(BundleContext context, String className)
Instantiates a newServiceCollector
that collects services on the specified class name.- Parameters:
context
- the bundle context used to interact with the frameworkclassName
- the class name
-
-
Method Detail
-
setServiceGetter
public ServiceCollector<S,T> setServiceGetter(BiFunction<BundleContext,ServiceReference<S>,T> serviceGetter)
Sets the service getter function. Instead of simply getting the service from the bundle using the givenServiceReference
some additional processing may be performed such as adapting the service obtained to another interface.A possible use case scenario for this feature consists of two service types with different APIs but overlapping functionality. If the consumer needs only the common functionality, it may collect both service types and adapt the services obtained.
If the function returns
null
, no service is added to the collection. The function can thus also be used as a filter.- Parameters:
serviceGetter
- the function- Returns:
- the service collector
-
setOnBound
public ServiceCollector<S,T> setOnBound(BiConsumer<ServiceReference<S>,T> onBound)
Sets a function to be called when the first service instance was added to the collection. The reference to the new service and the service instance are passed as arguments.The function is called before a callback set by
setOnAdded(BiConsumer)
.- Parameters:
onBound
- the function to be called- Returns:
- the
ServiceCollector
-
setOnAdded
public ServiceCollector<S,T> setOnAdded(BiConsumer<ServiceReference<S>,T> onAdded)
Sets a function to be called when a new service instance was added to the collection. The reference to the new service and the service instance are passed as arguments.- Parameters:
onAdded
- the function to be called- Returns:
- the
ServiceCollector
-
setOnRemoving
public ServiceCollector<S,T> setOnRemoving(BiConsumer<ServiceReference<S>,T> onRemoving)
Sets a function to be called before one of the collected service instances becomes unavailable. The reference to the service to be removed and the service instance are passed as arguments.- Parameters:
onRemoving
- the function to call- Returns:
- the
ServiceCollector
-
setOnUnbinding
public ServiceCollector<S,T> setOnUnbinding(BiConsumer<ServiceReference<S>,T> onUnbinding)
Sets a function to be called before the last of the collected service instances becomes unavailable. The reference to the service to be removed and the service instance are passed as arguments.The function is called after a callback set by
setOnRemoving(BiConsumer)
).- Parameters:
onUnbinding
- the function to call- Returns:
- the
ServiceCollector
-
setOnModfied
public ServiceCollector<S,T> setOnModfied(BiConsumer<ServiceReference<S>,T> onModified)
Sets a function to be called when the preferred service changes. This may either be a change of the preferred service's properties (reported by the framework) or the replacement of the preferred service by another service. The service reference to the modified service and the service are passed as arguments.If the preferred service is replaced by another service, this function is called after the "onAdded" or "onRemoved" callback.
- Parameters:
onModified
- the function to call- Returns:
- the
ServiceCollector
-
getContext
public BundleContext getContext()
Returns the context passed to the constructor.- Returns:
- the context
-
open
public void open() throws IllegalStateException
Starts collecting of service providers. Short for callingopen(false)
.- Throws:
IllegalStateException
- If theBundleConetxt
with which thisServiceCollector
was created is no longer valid.
-
open
public void open(boolean collectAllServices) throws IllegalStateException
Starts collecting services. Short for callingopen(false)
.- Parameters:
collectAllServices
- iftrue
, then thisServiceCollector
will collect all matching services regardless of class loader accessibility. Iffalse
, then thisServiceCollector
will only collect matching services which are class loader accessible to the bundle whoseBundleContext
is used by thisServiceCollector
.- Throws:
IllegalStateException
- If theBundleConetxt
with which thisServiceCollector
was created is no longer valid.
-
close
public void close()
Stops collecting services.- Specified by:
close
in interfaceAutoCloseable
-
waitForService
public Optional<T> waitForService(long timeout) throws InterruptedException
Wait for at least one service to be collected by thisServiceCollector
. This method will also return when thisServiceCollector
is closed from another thread.It is strongly recommended that
waitForService
is not used during the calling of theBundleActivator
methods.BundleActivator
methods are expected to complete in a short period of time.- Parameters:
timeout
- The time interval in milliseconds to wait. If zero, the method will wait indefinitely.- Returns:
- Returns the result of
service()
. - Throws:
InterruptedException
- If another thread has interrupted the current thread.IllegalArgumentException
- If the value of timeout is negative.
-
serviceReferences
public List<ServiceReference<S>> serviceReferences()
Return the current set ofServiceReference
s for all services collected by thisServiceCollector
.- Returns:
- the set.
-
serviceReference
public Optional<ServiceReference<S>> serviceReference()
Returns aServiceReference
for one of the services collected by thisServiceCollector
.If multiple services have been collected, the service with the highest ranking (as specified in its
service.ranking
property) is returned. If there is a tie in ranking, the service with the lowest service id (as specified in itsservice.id
property); that is, the service that was registered first is returned. This is the same algorithm used byBundleContext.getServiceReference
.- Returns:
- an optional
ServiceReference
-
service
public Optional<T> service(ServiceReference<S> reference)
Returns the service object for the specifiedServiceReference
if the specified referenced service has been collected by thisServiceCollector
.- Parameters:
reference
- the reference to the desired service.- Returns:
- an optional service object
-
service
public Optional<T> service()
Returns a service object for one of the services collected by thisServiceCollector
. This is effectively the same asserviceReference().flatMap(ref -> service(ref))
.The result value is cached, so refrain from implementing another cache in the invoking code.
- Returns:
- an optional service object
-
withService
public <R> Optional<R> withService(Function<T,? extends R> function)
Convenience method to invoke the a function with the result fromservice()
(if it is available) while holding a lock on this service collector.- Type Parameters:
R
- the result type- Parameters:
function
- the function to invoke with the service as argument- Returns:
- the result or
Optional.empty()
of the service was not available.
-
services
public List<T> services()
Return the list of service objects for all services collected by thisServiceCollector
. This is effectively a mapping ofserviceReferences()
to services.- Returns:
- a list of service objects which may be empty
-
size
public int size()
Return the number of services collected by thisServiceCollector
. This value may not be correct during the execution of handlers.- Returns:
- The number of services collected
-
modificationCount
public int modificationCount()
Returns the modification count for thisServiceCollector
. The modification count is initialized to 0 when thisServiceCollector
is opened. Every time a service is added, modified or removed from thisServiceCollector
, the modification count is incremented.The modification count can be used to determine if this
ServiceCollector
has added, modified or removed a service by comparing a modification count value previously collected with the current modification count value. If the value has not changed, then no service has been added, modified or removed from thisServiceCollector
since the previous modification count was collected.- Returns:
- The modification count for this
ServiceCollector
or -1 if thisServiceCollector
is not open.
-
isOpen
public boolean isOpen()
Checks if thisServiceCollector
is open.- Returns:
- true, if is open
-
collected
public SortedMap<ServiceReference<S>,T> collected()
Return aSortedMap
of theServiceReference
s and service objects for all services collected by thisServiceCollector
. The map is sorted in reverse natural order ofServiceReference
. That is, the first entry is the service with the highest ranking and the lowest service id.- Returns:
- A
SortedMap
with theServiceReference
s and service objects for all services collected by thisServiceCollector
. If no services have been collected, then the returned map is empty.
-
isEmpty
public boolean isEmpty()
Return if thisServiceCollector
is empty.- Returns:
true
if thisServiceCollector
has not collected any services.
-
remove
public void remove(ServiceReference<S> reference)
Remove a service from thisServiceCollector
. The specified service will be removed from thisServiceCollector
.- Parameters:
reference
- The reference to the service to be removed.
-
-