Class ServiceResolver

  • All Implemented Interfaces:
    AutoCloseable, BundleActivator

    public class ServiceResolver
    extends Object
    implements AutoCloseable, BundleActivator
    Maintains and attempts to resolve dependencies on services.

    The class supports two usage pattern. The first is to use the ServiceResolver as base class for the bundle's activator. The derived class must override configure() to add at least one dependency.

    The methods onResolved(), onDissolving() and onRebound(String) can be overridden as required.

     public class Activator extends ServiceResolver {
         @Override
         protected void configure() {
             addDependency(...);
         }
         
         @Override
         protected void onResolved() {
             // Enable usage or register as service or start worker thread ...
         }
         
         @Override
         protected void onDissolving() {
             // Disable usage or unregister or stop and join worker thread ...
         }
         
         @Override
         protected void onRebound(String dependency) {
             // Only required if there is a "long term" usage of a dependency.
         }
     }
     
    The second usage pattern is to create a ServiceResolver with a BundleContext, add dependencies and callbacks as required and call open(). When resolving is no longer required, close() must be called.
     // Usually executed during bundle start...
     ServiceResolver resolver = new ServiceResolver(context);
     // Add dependencies
     resolver.addDependency(...);
     resolver.setOnResolved(() -> ...);
     resolver.setOnDissolving(() -> ...);
     resolver.setOnRebound(name -> ...);
     resolver.open();
     
     // Usually executed during bundle stop...
     resolver.close();
     
    In addition to the management of mandatory dependencies, the ServiceResolver can also keep track of optional service dependencies. This allows the ServiceResolver to be provided as unified service access point. Apart from a single open() and close() function, the ServiceProvider does not implement additional functions for optional service dependencies compared to the underlying ServiceCollectors.
    • Field Detail

    • Method Detail

      • configure

        protected void configure()
        Configures the ServiceResolver. Must be overridden by the derived class when using the ServiceResolver as base class for a bundle activator. The derived class must configure the resolver with calls to at least one of the addDependency methods.

        The default implementation does nothing.

      • onResolved

        protected void onResolved()
        Called when all dependencies have been resolved. Overriding this method is an alternative to setting a callback with setOnResolved(Runnable).
      • onDissolving

        protected void onDissolving()
        Called when the resolver is about to leave the resolved state, i.e. when one of the mandatory services is going to be unbound. Overriding this method is an alternative to setting a callback with setOnDissolving(Runnable).
      • onRebound

        protected void onRebound​(String dependency)
        Called when the preferred service of a resolved dependency changes. The change may either be a change of properties reported by the framework or the replacement of the preferred service with another service. Overriding this method is an alternative to setting a callback with setOnRebound(Consumer).
        Parameters:
        dependency - the dependency that has been rebound
      • stop

        public void stop​(BundleContext context)
                  throws Exception
        Called by the framework when using the ServiceResolver as base class for a bundle activator. The implementatoin calls close().
        Specified by:
        stop in interface BundleActivator
        Parameters:
        context - the context
        Throws:
        Exception - if a problem occurs
      • setOnResolved

        public ServiceResolver setOnResolved​(Runnable onResolved)
        Sets the function to called when the resolver has entered the resolved state, i.e. when all mandatory services have been bound.
        Parameters:
        onResolved - the function
        Returns:
        the service resolver
      • setOnDissolving

        public ServiceResolver setOnDissolving​(Runnable onDissolving)
        Sets the function to called when the resolver is about to leave the resolved state, i.e. when one of the mandatory services is going to be unbound.
        Parameters:
        onDissolving - the function
        Returns:
        the service resolver
      • setOnRebound

        public ServiceResolver setOnRebound​(Consumer<String> onRebound)
        Sets the function to be called when the preferred service of a resolved dependency changes. The change may either be a change of properties reported by the framework or the replacement of the preferred service with another service.
        Parameters:
        onRebound - the on rebound
        Returns:
        the service resolver
      • addDependency

        public ServiceResolver addDependency​(Class<?> clazz)
        Adds a mandatory dependency on the service specified by the class. The name of the class is used as name of the dependency.
        Parameters:
        clazz - the class
        Returns:
        the service resolver
      • addDependency

        public ServiceResolver addDependency​(String name,
                                             Filter filter)
        Adds a mandatory dependency on the service specified by the filter.
        Parameters:
        name - the name of the dependency
        filter - the filter
        Returns:
        the service resolver
      • addDependency

        public ServiceResolver addDependency​(String name,
                                             ServiceReference<?> reference)
        Adds a mandatory dependency on the service specified by the service reference.
        Parameters:
        name - the name of the dependency
        reference - the reference
        Returns:
        the service resolver
      • addDependency

        public ServiceResolver addDependency​(String name,
                                             String className)
        Adds a mandatory dependency on the service specified by the service reference.
        Parameters:
        name - the name of the dependency
        className - the class name
        Returns:
        the service resolver
      • addOptionalDependency

        public ServiceResolver addOptionalDependency​(Class<?> clazz)
        Adds an optional dependency on the service specified by the class. The name of the class is used as identifier for the dependency.
        Parameters:
        clazz - the class
        Returns:
        the service resolver
      • addOptionalDependency

        public ServiceResolver addOptionalDependency​(String name,
                                                     Filter filter)
        Adds an optional dependency on the service specified by the filter.
        Parameters:
        name - the name of the dependency
        filter - the filter
        Returns:
        the service resolver
      • addOptionalDependency

        public ServiceResolver addOptionalDependency​(String name,
                                                     ServiceReference<?> reference)
        Adds an optional dependency on the service specified by the service reference.
        Parameters:
        name - the name of the dependency
        reference - the reference
        Returns:
        the service resolver
      • addOptionalDependency

        public ServiceResolver addOptionalDependency​(String name,
                                                     String className)
        Adds an optional dependency on the service specified by the service reference.
        Parameters:
        name - the name of the dependency
        className - the class name
        Returns:
        the service resolver
      • open

        public void open()
        Starts the resolver. While open, the resolver attempts to obtain service implementation for all registered service dependencies.
      • close

        public void close()
        Stops the resolver. All maintained services are released.
        Specified by:
        close in interface AutoCloseable
      • isOpen

        public boolean isOpen()
        Checks if the resolver is open.
        Returns:
        true, if open
      • isResolved

        public boolean isResolved()
        Checks if the resolver is in the resolved state.
        Returns:
        the result
      • get

        public <T> T get​(String name,
                         Class<T> clazz)
        Returns the service found for the mandatory dependency with the given name. This method should only be called when the resolver is in state resolved. Note that due to the threaded nature of the environment, this method can return null, even if the resolver was in state resolved before its invocation, because the service can go away between the check and the invocation of this method. If you want to be sure that services haven't been unregistered concurrently, the check for resolved and the invocation of this method must be in a block synchronized on this resolver. Consider using with(String, Function) or with(Class, Function) as an alternative.
        Type Parameters:
        T - the type of the service
        Parameters:
        name - the name of the dependency
        clazz - the class of the service
        Returns:
        the service or null if called in unresolved state and the dependency is not resolved
      • get

        public <T> T get​(Class<T> clazz)
        Returns the service found for the mandatory dependency using the name of the class as name of the dependency.
        Type Parameters:
        T - the type of the service
        Parameters:
        clazz - the class of the service
        Returns:
        the service or null if called in unresolved state and the dependency is not resolved
        See Also:
        get(String, Class)
      • optional

        public <T> Optional<T> optional​(String name,
                                        Class<T> clazz)
        Returns the service found for the optional dependency with the given name, if it exists.
        Type Parameters:
        T - the type of the service
        Parameters:
        name - the name of the dependency
        clazz - the class of the service
        Returns:
        the result
      • optional

        public <T> Optional<T> optional​(Class<T> clazz)
        Returns the service found for the optional dependency using the name of the class as name of the dependency, if it exists.
        Type Parameters:
        T - the type of the service
        Parameters:
        clazz - the class of the service
        Returns:
        the result
      • with

        public <T,​R> Optional<R> with​(String name,
                                            Function<T,​? extends R> function)
        Convenience method to invoke the a function with the service registered as mandatory or optional dependency while holding a lock on the underlying service collector.
        Type Parameters:
        T - the type of the service
        R - the result type
        Parameters:
        name - the name of the dependency
        function - the function to invoke with the service as argument
        Returns:
        the result or Optional.empty() of the service was not available.
      • with

        public <T,​R> Optional<R> with​(Class<T> clazz,
                                            Function<T,​? extends R> function)
        Convenience method to invoke the a function with the service registered as mandatory or optional dependency while holding a lock on the underlying service collector.
        Type Parameters:
        T - the type of the service
        R - the result type
        Parameters:
        clazz - the class of the service
        function - the function to invoke with the service as argument
        Returns:
        the result or Optional.empty() of the service was not available.