Class ServiceCollector<S,​T>

  • Type Parameters:
    S - the type of the service
    T - the type of service instances returned by queries, usually the same type as the type of the service (see setServiceGetter(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 Detail

      • ServiceCollector

        public ServiceCollector​(BundleContext context,
                                Class<S> clazz)
        Instantiates a new ServiceCollector that collects services of the specified class.
        Parameters:
        context - the bundle context used to interact with the framework
        clazz - the clazz
      • ServiceCollector

        public ServiceCollector​(BundleContext context,
                                Filter filter)
        Instantiates a new ServiceCollector that collects services matches by the specified filter.
        Parameters:
        context - the bundle context used to interact with the framework
        filter - the filter
      • ServiceCollector

        public ServiceCollector​(BundleContext context,
                                ServiceReference<S> reference)
        Instantiates a new ServiceCollector that collects services on the specified service reference.
        Parameters:
        context - the bundle context used to interact with the framework
        reference - the reference
      • ServiceCollector

        public ServiceCollector​(BundleContext context,
                                String className)
        Instantiates a new ServiceCollector that collects services on the specified class name.
        Parameters:
        context - the bundle context used to interact with the framework
        className - the class name
    • Method Detail

      • setServiceGetter

        public ServiceCollector<S,​TsetServiceGetter​(BiFunction<BundleContext,​ServiceReference<S>,​T> serviceGetter)
        Sets the service getter function. Instead of simply getting the service from the bundle using the given ServiceReference 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,​TsetOnBound​(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,​TsetOnAdded​(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,​TsetOnRemoving​(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,​TsetOnUnbinding​(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,​TsetOnModfied​(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 calling open(false).
        Throws:
        IllegalStateException - If the BundleConetxt with which this ServiceCollector was created is no longer valid.
      • open

        public void open​(boolean collectAllServices)
                  throws IllegalStateException
        Starts collecting services. Short for calling open(false).
        Parameters:
        collectAllServices - if true, then this ServiceCollector will collect all matching services regardless of class loader accessibility. If false, then this ServiceCollector will only collect matching services which are class loader accessible to the bundle whose BundleContext is used by this ServiceCollector.
        Throws:
        IllegalStateException - If the BundleConetxt with which this ServiceCollector was created is no longer valid.
      • waitForService

        public Optional<TwaitForService​(long timeout)
                                   throws InterruptedException
        Wait for at least one service to be collected by this ServiceCollector. This method will also return when this ServiceCollector is closed from another thread.

        It is strongly recommended that waitForService is not used during the calling of the BundleActivator 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.
      • serviceReference

        public Optional<ServiceReference<S>> serviceReference()
        Returns a ServiceReference for one of the services collected by this ServiceCollector.

        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 its service.id property); that is, the service that was registered first is returned. This is the same algorithm used by BundleContext.getServiceReference.

        Returns:
        an optional ServiceReference
      • service

        public Optional<Tservice​(ServiceReference<S> reference)
        Returns the service object for the specified ServiceReference if the specified referenced service has been collected by this ServiceCollector.
        Parameters:
        reference - the reference to the desired service.
        Returns:
        an optional service object
      • service

        public Optional<Tservice()
        Returns a service object for one of the services collected by this ServiceCollector. This is effectively the same as serviceReference().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 from service() (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<Tservices()
        Return the list of service objects for all services collected by this ServiceCollector. This is effectively a mapping of serviceReferences() to services.
        Returns:
        a list of service objects which may be empty
      • size

        public int size()
        Return the number of services collected by this ServiceCollector. 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 this ServiceCollector. The modification count is initialized to 0 when this ServiceCollector is opened. Every time a service is added, modified or removed from this ServiceCollector, 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 this ServiceCollector since the previous modification count was collected.

        Returns:
        The modification count for this ServiceCollector or -1 if this ServiceCollector is not open.
      • isOpen

        public boolean isOpen()
        Checks if this ServiceCollector is open.
        Returns:
        true, if is open
      • collected

        public SortedMap<ServiceReference<S>,​Tcollected()
        Return a SortedMap of the ServiceReferences and service objects for all services collected by this ServiceCollector. The map is sorted in reverse natural order of ServiceReference. That is, the first entry is the service with the highest ranking and the lowest service id.
        Returns:
        A SortedMap with the ServiceReferences and service objects for all services collected by this ServiceCollector. If no services have been collected, then the returned map is empty.
      • isEmpty

        public boolean isEmpty()
        Return if this ServiceCollector is empty.
        Returns:
        true if this ServiceCollector has not collected any services.
      • remove

        public void remove​(ServiceReference<S> reference)
        Remove a service from this ServiceCollector. The specified service will be removed from this ServiceCollector.
        Parameters:
        reference - The reference to the service to be removed.