Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd Sun Jan 31 23:27:05 2016 @@ -0,0 +1,13 @@ +javac.source: 1.8 +javac.target: 1.8 +Bundle-Version: 1.0.0 +-buildpath: \ + org.apache.felix.dependencymanager;version=latest,\ + osgi.core;version=6.0,\ + osgi.cmpn;version=6.0 +Export-Package: \ + org.apache.felix.dm.lambda,\ + org.apache.felix.dm.lambda.callbacks +-runfw: org.apache.felix.framework;version='[4.4.1,4.4.1]' +-runee: JavaSE-1.8 +Private-Package: org.apache.felix.dm.lambda.impl \ No newline at end of file
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/.gitignore URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/.gitignore?rev=1727869&view=auto ============================================================================== (empty) Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleAdapterBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleAdapterBuilder.java?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleAdapterBuilder.java (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleAdapterBuilder.java Sun Jan 31 23:27:05 2016 @@ -0,0 +1,243 @@ +package org.apache.felix.dm.lambda; + +import org.apache.felix.dm.lambda.callbacks.CbBundle; +import org.apache.felix.dm.lambda.callbacks.CbComponentBundle; +import org.apache.felix.dm.lambda.callbacks.CbTypeBundle; +import org.apache.felix.dm.lambda.callbacks.CbTypeComponentBundle; + +/** + * Builds a Dependency Manager bundle adapter. The adapter created by this builder will be applied to any bundle that matches the specified + * bundle state mask and filter condition. For each matching bundle an adapter service will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties from the original bundle plus any extra properties + * you supply here. The bundle is injected by reflection in adapter class fields having a Bundle type, or using a callback method that you can + * specify. + * + * <p> Example which creates a BundleAdapter service for each started bundle (the bundle is added by reflection on + * a class field that has a "Bundle" type): + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * bundleAdapter(adapt -> adapt + * .impl(BundleAdapterImpl.class) + * .provides(BundleAdapter.class) + * .mask(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE)); + * } + * } + * } </pre> + * + * Example that creates a BundleAdapter service for each started bundle (the bundle is added using a method reference): + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * bundleAdapter(adapt -> adapt + * .impl(BundleAdapterImpl.class) + * .provides(BundleAdapter.class) + * .mask(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE) + * .cb(BundleAdapterImpl::setBundle)); + * } + * } + * }</pre> + * + * Example that creates a BundleAdapter service for each started bundle (the bundle is added using a method name): + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * bundleAdapter(adapt -> adapt + * .impl(BundleAdapterImpl.class) + * .provides(BundleAdapter.class) + * .mask(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE) + * .cb("setBundle")); + * } + * } + * }</pre> + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public interface BundleAdapterBuilder extends ComponentBuilder<BundleAdapterBuilder> { + /** + * Sets the bundle state mask to depend on. The OSGi BundleTracker explains this mask in more detail, but + * it is basically a mask with flags for each potential state a bundle can be in. + * + * @param mask the mask to use + * @return this builder + */ + BundleAdapterBuilder mask(int mask); + + /** + * Sets the filter condition to depend on. Filters are matched against the full manifest of a bundle. + * + * @param filter the filter condition + * @return this builder + */ + BundleAdapterBuilder filter(String filter); + + /** + * Sets property propagation. If set to <code>true</code> any bundle manifest properties will be added + * to the service properties of the component that has this dependency (if it registers as a service). + * + * @param propagate <code>true</code> to propagate the bundle manifest properties + * @return this builder + */ + BundleAdapterBuilder propagate(boolean propagate); + + /** + * Enables property propagation. Any bundle manifest properties will be added + * to the service properties of the component that has this dependency (if it registers as a service). + * + * @return this builder + */ + BundleAdapterBuilder propagate(); + + /** + * Sets some <code>callbacks</code> invoked on the component implementation instances. When a bundle state matches the bundle + * adapter filter, then the bundle is injected using the specified callback methods. When you specify one callback, it stands for the "add" callback. + * When you specify two callbacks, the first one corresponds to the "add" callback, and the second one to the "remove" callback. When you specify three + * callbacks, the first one stands for the "add" callback, the second one for the "change" callback, and the third one for the "remove" callback. + * + * @param callbacks a list of callbacks (1 param : "add", 2 params : "add"/remove", 3 params : "add"/"change"/"remove"). + * @return this builder + */ + BundleAdapterBuilder cb(String ... callbacks); + + /** + * Sets some <code>callback instance</code> methods invoked on a given Object instance. When a bundle state matches the bundle + * adapter filter, then the bundle is injected using the specified callback methods. When you specify one callback, it stands for the "add" callback. + * When you specify two callbacks, the first one corresponds to the "add" callback, and the second one to the "remove" callback. + * When you specify three callbacks, the first one stands for the "add" callback, the second one for the "change" callback, and the third one for + * the "remove" callback. + * + * @param callbackInstance the Object instance where the callbacks are invoked on + * @param callbacks a list of callbacks (1 param : "add", 2 params : "add"/remove", 3 params : "add"/"change"/"remove"). + * @return this builder + */ + BundleAdapterBuilder cbi(Object callbackInstance, String ... callbacks); + + /** + * Sets a <code>callback</code> invoked on a component implementation instance when a bundle is added. + * The method reference must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeBundle<T> add); + + /** + * Sets some <code>callbacks</code> invoked on a component implementation instance when a bundle is added/removed. + * The method references must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeBundle<T> add, CbTypeBundle<T> remove); + + /** + * Sets some <code>callbacks</code> invoked on a component implementation instance when a bundle is added, changed or removed. + * The method references must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeBundle<T> add, CbTypeBundle<T> change, CbTypeBundle<T> remove); + + /** + * Sets a <code>callback</code> invoked on a component implementation instance when a bundle is added. + * The method reference must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeComponentBundle<T> add); + + /** + * Sets some <code>callbacks</code> invoked on a component implementation instance when a bundle is added, or removed. + * The method references must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeComponentBundle<T> add, CbTypeComponentBundle<T> remove); + + /** + * Sets some <code>callbacks</code> invoked on a component implementation instance when a bundle is added, changed or removed. + * The method references must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component instance class on which the callback is invoked. + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleAdapterBuilder cb(CbTypeComponentBundle<T> add, CbTypeComponentBundle<T> change, CbTypeComponentBundle<T> remove); + + /** + * Sets a <code>callback instance</code> invoked on a given Object instance when a bundle is added. + * The method reference must point to an Object instance method, and takes as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + BundleAdapterBuilder cbi(CbBundle add); + + /** + * Sets some <code>callback instance</code> invoked on a given Object instance when a bundle is added or removed. + * The method references must point to an Object instance method, and take as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleAdapterBuilder cbi(CbBundle add, CbBundle remove); + + /** + * Sets some <code>callback instance</code> invoked on a given Object instance when a bundle is added, changed or removed. + * The method references must point to an Object instance method, and take as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleAdapterBuilder cbi(CbBundle add, CbBundle change, CbBundle remove); + + /** + * Sets a <code>callback instance</code> invoked on a given Object instance when a bundle is added. + * The method reference must point to an Object instance method, and takes as arguments a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + BundleAdapterBuilder cbi(CbComponentBundle add); + + /** + * Sets some <code>callback instance</code> invoked on a given Object instance when a bundle is added or removed. + * The method references must point to an Object instance method, and take as argument a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleAdapterBuilder cbi(CbComponentBundle add, CbComponentBundle remove); + + /** + * Sets some <code>callback instance</code> invoked on a given Object instance when a bundle is added, changed or removed. + * The method references must point to an Object instance method, and take as argument a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleAdapterBuilder cbi(CbComponentBundle add, CbComponentBundle change, CbComponentBundle remove); +} Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleDependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleDependencyBuilder.java?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleDependencyBuilder.java (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/BundleDependencyBuilder.java Sun Jan 31 23:27:05 2016 @@ -0,0 +1,279 @@ +package org.apache.felix.dm.lambda; + +import java.util.Dictionary; +import java.util.function.Supplier; + +import org.apache.felix.dm.BundleDependency; +import org.apache.felix.dm.lambda.callbacks.CbBundle; +import org.apache.felix.dm.lambda.callbacks.CbComponentBundle; +import org.apache.felix.dm.lambda.callbacks.CbTypeBundle; +import org.apache.felix.dm.lambda.callbacks.CbTypeComponentBundle; +import org.osgi.framework.Bundle; + +/** + * Builds a Dependency Manager Bundle Dependency. The Dependency is required by default (unlike in the original Dependency Manager API). + * + * <p> Example of a Component which tracks a started bundle having a given bundle symbolic name: + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * String BSN = "org.apache.felix.dependencymanager"; + * component(comp -> comp + * .impl(MyComponent.class) + * .withBundle(b -> b.mask(Bundle.ACTIVE).filter("(Bundle-SymbolicName=" + BSN + ")").cb(MyComponent::add, MyComponent::remove))); + * + * } + * } + * } </pre> + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public interface BundleDependencyBuilder extends DependencyBuilder<BundleDependency> { + /** + * Enables auto configuration for this dependency. This means the component implementation (composition) will be + * injected with this bundle dependency automatically. + * + * @param autoConfig <code>true</code> to enable auto configuration + * @return the bundle dependency builder + */ + public BundleDependencyBuilder autoConfig(boolean autoConfig); + + /** + * Enables auto configuration for this dependency. This means the component implementation (composition) will be + * injected with this bundle dependency automatically. + * + * @return the bundle dependency builder + */ + public BundleDependencyBuilder autoConfig(); + + /** + * Sets the dependency to be required. By default, the dependency is required. + * + * @param required <code>true</code> if this bundle dependency is required (true by default). + * @return the bundle dependency builder + */ + public BundleDependencyBuilder required(boolean required); + + /** + * Sets the dependency to be required. + * + * @return the bundle dependency builder + */ + public BundleDependencyBuilder required(); + + /** + * Sets the bundle to depend on directly. + * + * @param bundle the bundle to depend on + * @return the bundle dependency builder + */ + public BundleDependencyBuilder bundle(Bundle bundle); + + /** + * Sets the filter condition to depend on. Filters are matched against the full manifest of a bundle. + * + * @param filter the filter condition + * @return the bundle dependency builder + */ + public BundleDependencyBuilder filter(String filter); + + /** + * Sets the bundle state mask to depend on. The OSGi BundleTracker explains this mask in more detail, but + * it is basically a mask with flags for each potential state a bundle can be in. + * + * @param mask the mask to use + * @return the bundle dependency builder + */ + public BundleDependencyBuilder mask(int mask); + + /** + * Sets property propagation. If set to <code>true</code> any bundle manifest properties will be added + * to the service properties of the component that has this dependency (if it registers as a service). + * + * @param propagate <code>true</code> to propagate the bundle manifest properties + * @return the bundle dependency builder + */ + public BundleDependencyBuilder propagate(boolean propagate); + + /** + * Sets property propagation. any bundle manifest properties will be added + * to the service properties of the component that has this dependency (if it registers as a service). + * + * @return the bundle dependency builder + */ + public BundleDependencyBuilder propagate(); + + /** + * Sets an Object instance and a callback method used to propagate some properties to the provided service properties. + * The method will be invoked on the specified object instance and must have one of the following signatures: + * <ul><li>Dictionary callback(ServiceReference, Object service) + * <li>Dictionary callback(ServiceReference) + * </ul> + * @param instance the Object instance which is used to retrieve propagated service properties + * @param method the method to invoke for retrieving the properties to be propagated to the service properties. + * @return this service dependency. builder + */ + public BundleDependencyBuilder propagate(Object instance, String method); + + /** + * Sets an Object instance and a callback method used to propagate some properties to the provided service properties. + * The method will be invoked on the specified object instance and must have one of the following signatures: + * <ul><li>Dictionary callback(ServiceReference, Object service) + * <li>Dictionary callback(ServiceReference) + * </ul> + * @param instance the Object instance which is used to retrieve propagated service properties + * @return this service dependency. builder + */ + public BundleDependencyBuilder propagate(Supplier<Dictionary<?, ?>> instance); + + /** + * Sets some <code>callback</code> methods to invoke on the component instance(s). When a bundle state matches the bundle + * filter, then the bundle is injected using the specified callback methods. When you specify one callback, it stands for the "add" callback. + * When you specify two callbacks, the first one corresponds to the "add" callback, and the second one to the "remove" callback. When you specify three + * callbacks, the first one stands for the "add" callback, the second one for the "change" callback, and the third one for the "remove" callback. + * + * @param callbacks a list of callbacks (1 param: "add", 2 params: "add"/remove", 3 params: "add"/"change"/"remove" callbacks). + * @return this builder + */ + BundleDependencyBuilder cb(String ... callbacks); + + /** + * Sets some <code>callback instance</code> methods to invoke on a given Object instance. When a bundle state matches the bundle + * filter, then the bundle is injected using the specified callback methods. When you specify one callback, it stands for the "add" callback. + * When you specify two callbacks, the first one corresponds to the "add" callback, and the second one to the "remove" callback. + * When you specify three callbacks, the first one stands for the "add" callback, the second one for the "change" callback, and the third one for + * the "remove" callback. + * + * @param callbackInstance the Object instance where the callbacks are invoked on + * @param callbacks a list of callbacks (1 param: "add", 2 params: "add/remove", 3 params: "add/change/remove" callbacks). + * @return this builder + */ + BundleDependencyBuilder cb(Object callbackInstance, String ... callbacks); + + /** + * Sets a <code>callback</code> method reference which is invoked when a bundle is added. + * The method reference must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeBundle<T> add); + + /** + * Sets some <code>callback</code> method references which are invoked when a bundle is added, or removed. + * The method references must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeBundle<T> add, CbTypeBundle<T> remove); + + /** + * Sets some <code>callback</code> method references which are invoked when a bundle is added, changed or removed. + * The method references must point to a Component implementation class method, and take as argument a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeBundle<T> add, CbTypeBundle<T> change, CbTypeBundle<T> remove); + + /** + * Sets a <code>callback</code> method reference which is invoked when a bundle is added. + * The method reference must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeComponentBundle<T> add); + + /** + * Sets some <code>callback</code> method references which are invoked when a bundle is added, or removed. + * The method references must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeComponentBundle<T> add, CbTypeComponentBundle<T> remove); + + /** + * Sets some <code>callback</code> method references which are invoked when a bundle is added, changed or removed. + * The method references must point to a Component implementation class method, and take as argument a Component and a Bundle. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + <T> BundleDependencyBuilder cb(CbTypeComponentBundle<T> add, CbTypeComponentBundle<T> change, CbTypeComponentBundle<T> remove); + + /** + * Sets a <code>callback instance</code> method reference which is invoked when a bundle is added. + * The method reference must point to an Object instance method, and takes as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + BundleDependencyBuilder cbi(CbBundle add); + + /** + * Sets some <code>callback instance</code> method references which are invoked when a bundle is added or removed. + * The method references must point to an Object instance method, and take as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleDependencyBuilder cbi(CbBundle add, CbBundle remove); + + /** + * Sets some <code>callback instance</code> method references which are invoked when a bundle is added, changed or removed. + * The method references must point to an Object instance method, and take as argument a Bundle parameter. + * + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleDependencyBuilder cbi(CbBundle add, CbBundle change, CbBundle remove); + + /** + * Sets a <code>callback instance</code> method reference which is invoked when a bundle is added. + * The method reference must point to an Object instance method, and takes as arguments a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @return this builder + */ + BundleDependencyBuilder cbi(CbComponentBundle add); + + /** + * Sets some <code>callback instance</code> method references which are invoked when a bundle is added or removed. + * The method references must point to an Object instance method, and take as argument a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleDependencyBuilder cbi(CbComponentBundle add, CbComponentBundle remove); + + /** + * Sets some <code>callback instance</code> method references which are invoked when a bundle is added, changed or removed. + * The method references must point to an Object instance method, and take as argument a Component and a Bundle. + * + * @param add the method reference invoked when a bundle is added. + * @param change the method reference invoked when a bundle has changed. + * @param remove the method reference invoked when a bundle is removed. + * @return this builder + */ + BundleDependencyBuilder cbi(CbComponentBundle add, CbComponentBundle change, CbComponentBundle remove); +} Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ComponentBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ComponentBuilder.java?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ComponentBuilder.java (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ComponentBuilder.java Sun Jan 31 23:27:05 2016 @@ -0,0 +1,791 @@ +package org.apache.felix.dm.lambda; + +import java.util.Dictionary; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.apache.felix.dm.Component; +import org.apache.felix.dm.lambda.callbacks.CbComponent; +import org.apache.felix.dm.lambda.callbacks.CbConsumer; +import org.apache.felix.dm.lambda.callbacks.CbTypeComponent; + +/** + * Builds a Dependency Manager Component. Components are the main building blocks for OSGi applications. + * They can publish themselves as a service, and they can have dependencies. + * These dependencies will influence their life cycle as component will only be activated when all + * required dependencies are available. + * + * <p> This interface is also the base interface for extended components like aspects, adapters, etc ... + * + * <p> Example of a component that depends on a ConfigurationAdmin service. The dependency is injected by reflection + * on a class field which type matches the ConfigurationAdmin interface: + * + * <pre>{@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * component(comp -> comp.impl(Configurator.class).withSrv(ConfigurationAdmin.class)); + * } + * } + * } </pre> + * + * @param <B> the type of a builder that may extends this builder interface (aspect/adapter). + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public interface ComponentBuilder<B extends ComponentBuilder<B>> { + /** + * Configures the component implementation. Can be a class name, or a component implementation object. + * + * @param impl the component implementation (a class, or an Object). + * @return this builder + */ + B impl(Object impl); + + /** + * Sets the factory to use to create the implementation. You can specify both the factory class and method to invoke. The method should return the implementation, + * and can use any method to create it. Actually, this can be used together with setComposition to create a composition of instances that work together to implement + * a component. The factory itself can also be instantiated lazily by not specifying an instance, but a Class. + * + * @param factory the factory instance, or the factory class. + * @param createMethod the create method called on the factory in order to instantiate the component instance. + * @return this builder + */ + B factory(Object factory, String createMethod); + + /** + * Configures a factory that can be used to create this component implementation. + * Example: + * + * <pre> {@code + * factory(ComponentImpl::new)", or "factory(() -> new ComponentImpl()) + * }</pre> + * + * @param create the factory used to create the component implementation. + * @return this builder + */ + B factory(Supplier<?> create); + + /** + * Configures a factory used to create this component implementation using a Factory object and a method in the Factory object. + * Example: + * + * <pre> {@code + * factory(Factory::new, Factory::create) + * }</pre> + * + * @param <U> the type of the factory returned by the supplier + * @param <V> the type of the object that is returned by the factory create method. + * @param factory the function used to create the Factory itself + * @param create the method reference on the Factory method that is used to create the Component implementation + * @return this builder + */ + <U, V> B factory(Supplier<U> factory, Function<U, V> create); + + /** + * Configures a factory used to create this component implementation using a Factory object and a "getComponent" factory method. + * the Factory method may then return multiple objects that will be part of this component implementation. + * + * Example: + * + * <pre> {@code + * CompositionManager mngr = new CompositionManager(); + * ... + * factory(mngr::create, mngr::getComposition) + * }</pre> + * + * @param factory the supplier used to return the main component implementation instance + * @param getComposition the supplier that returns the list of instances that are part of the component implementation classes. + * @return this builder + */ + B factory(Supplier<?> factory, Supplier<Object[]> getComposition); + + /** + * Configures a factory that also returns a composition of objects for this component implemenation. + * + * Example: + * + * <pre> {@code + * factory(CompositionManager::new, CompositionManager::create, CompositionManager::getComposition). + * }</pre> + * + * Here, the CompositionManager will act as a factory (the create method will return the component implementation object), and the + * CompositionManager.getComposition() method will return all the objects that are also part of the component implementation. + * + * @param <U> the type of the object returned by the supplier factory + * @param factory the function used to create the Factory itself + * @param create the Factory method used to create the main component implementation object + * @param getComposition the Factory method used to return the list of objects that are also part of the component implementation. + * @return this builder + */ + <U> B factory(Supplier<U> factory, Function<U, ?> create, Function<U, Object[]> getComposition); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * + * @param iface the public interfaces to register in the OSGI service registry. + * @return this builder + */ + B provides(Class<?> iface); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * + * @param iface the public interfaces to register in the OSGI service registry. + * @param name a property name for the provided service + * @param value a property value for the provided service + * @param rest the rest of property name/value pairs. + * @return this builder. + */ + B provides(Class<?> iface, String name, Object value, Object ... rest); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * Warning: you can only use this method if you compile your application using the "-parameters" javac option. + * + * code example: + * + * <pre> {@code + * provides(MyService.class, property1 -> "value1", property2 -> 123); + * }</pre> + * + * @param iface the public interfaces to register in the OSGI service registry. + * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the + * {@link FluentProperties} interface that allows to define a property name using a lambda parameter. + * @return this builder. + */ + B provides(Class<?> iface, FluentProperties ... properties); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * @param iface the public interfaces to register in the OSGI service registry. + * @param properties the properties for the provided service + * @return this builder. + */ + B provides(Class<?> iface, Dictionary<?,?> properties); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * + * @param ifaces list of services provided by the component. + * @return this builder. + */ + B provides(Class<?>[] ifaces); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param name a property name for the provided service + * @param value a property value for the provided service + * @param rest the rest of property name/value pairs. + * @return this builder. + */ + B provides(Class<?>[] ifaces, String name, Object value, Object ... rest); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * Warning: you can only use this method if you compile your application using the "-parameters" javac option. + * code example: + * + * <pre> {@code + * provides(new Class[] { MyService.class, MyService2.class }, property1 -> "value1", property2 -> 123); + * }</pre> + * + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the + * {@link FluentProperties} interface that allows to define a property name using a lambda parameter. + * @return this builder. + */ + B provides(Class<?>[] ifaces, FluentProperties ... properties); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param properties the properties for the provided service + * @return this builder. + */ + B provides(Class<?>[] ifaces, Dictionary<?,?> properties); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * + * @param iface the service provided by this component. + * @return this builder. + */ + B provides(String iface); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * + * @param iface the public interfaces to register in the OSGI service registry. + * @param name a property name for the provided service + * @param value a property value for the provided service + * @param rest the rest of property name/value pairs. + * @return this builder. + */ + B provides(String iface, String name, Object value, Object ... rest); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * Warning: you can only use this method if you compile your application using the "-parameters" javac option. + * code example: + * + * <pre> {@code + * provides(MyService.class, property1 -> "value1", property2 -> 123); + * }</pre> + * + * @param iface the public interfaces to register in the OSGI service registry. + * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the + * {@link FluentProperties} interface that allows to define a property name using a lambda parameter. + * @return this builder. + */ + B provides(String iface, FluentProperties ... properties); + + /** + * Sets the public interface under which this component should be registered in the OSGi service registry. + * @param iface the public interfaces to register in the OSGI service registry. + * @param properties the properties for the provided service + * @return this builder. + */ + B provides(String iface, Dictionary<?,?> properties); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * + * @param ifaces the list of services provided by the component. + * @return this builder. + */ + B provides(String[] ifaces); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param name a property name for the provided service + * @param value a property value for the provided service + * @param rest the rest of property name/value pairs. + * @return this builder. + */ + B provides(String[] ifaces, String name, Object value, Object ... rest); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * Warning: you can only use this method if you compile your application using the "-parameters" javac option. + * + * code example: + * <pre> {@code + * provides(new Class[] { MyService.class, MyService2.class }, property1 -> "value1", property2 -> 123); + * }</pre> + * + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the + * {@link FluentProperties} interface that allows to define a property name using a lambda parameter. + * @return this builder. + */ + B provides(String[] ifaces, FluentProperties ... properties); + + /** + * Sets the public interfaces under which this component should be registered in the OSGi service registry. + * @param ifaces the public interfaces to register in the OSGI service registry. + * @param properties the properties for the provided service + * @return this builder. + */ + B provides(String[] ifaces, Dictionary<?,?> properties); + + /** + * Sets the component's service properties + * @param properties the component's service properties + * @return this builder + */ + B properties(Dictionary<?,?> properties); + + /** + * Sets the components's service properties using varargs. The number of parameters must be even, representing a list of pair property key-value. + * + * <pre> {@code + * Example: properties("param1", "value1", "service.ranking", 3) + * }</pre> + * + * @param name the first property name + * @param value the first property value + * @param rest the rest of properties key/value pairs. + * @return this builder + */ + B properties(String name, Object value, Object ... rest); + + /** + * Sets the components's service properties using List of lamda properties. + * + * Example: + * + * <pre> {@code + * properties(param1 -> "value1, param2 -> 2); + * }</pre> + * + * When you use this method, you must compile your source code using the "-parameters" option, and the "arg0" parameter + * name is now allowed. + * + * @param properties the fluent properties + * @return this builder + */ + B properties(FluentProperties ... properties); + + /** + * Adds a required/autoconfig service dependency. + * + * @param service the service dependency filter + * @param filter the service filter + * @return this builder + */ + B withSrv(Class<?> service, String filter); + + /** + * Adds in one shot multiple required/autoconfig service dependencies. + * @param services the dependencies that are required and that will be injected in any field with the same dependency type. + * @return this builder + */ + B withSrv(Class<?> ... services); + + /** + * Adds a service dependency built using a Consumer lambda that is provided with a ServiceDependencyBuilder. + * + * @param <U> the type of the dependency service + * @param service the service + * @param consumer the lambda for building the service dependency + * @return this builder. + */ + <U> B withSrv(Class<U> service, Consumer<ServiceDependencyBuilder<U>> consumer); + + /** + * Adds a configuration dependency. + * @param consumer the lambda used to build the configuration dependency. + * @return this builder. + */ + B withCnf(Consumer<ConfigurationDependencyBuilder> consumer); + + /** + * Adds multiple configuration dependencies in one single call. All configurations are injected by default in the "updated" callback. + * @param pids list of configuration pids. + * @return this builder + */ + @SuppressWarnings("unchecked") + default B withCnf(String ... pids) { + Stream.of(pids).forEach(pid -> withCnf(cnf -> cnf.pid(pid))); + return (B) this; + } + + /** + * Adds multiple configuration dependencies in one single call. + * @param pids list of configuration pids + * @return this builder + */ + @SuppressWarnings("unchecked") + default B withCnf(Class<?> ... pids) { + Stream.of(pids).forEach(pid -> withCnf(cnf -> cnf.pid(pid))); + return (B) this; + } + + /** + * Adds a bundle dependency. + * @param consumer the lambda used to build the bundle dependency. + * @return this builder. + */ + B withBundle(Consumer<BundleDependencyBuilder> consumer); + + /** + * Adds a CompletableFuture dependency. + * + * @param <U> the type of the result of the CompletableFuture. + * @param future a CompletableFuture on which the dependency will wait for + * @param consumer the builder used to build the dependency + * @return this builder. + */ + <U> B withFuture(CompletableFuture<U> future, Consumer<FutureDependencyBuilder<U>> consumer); + + /** + * Sets the name of the method used as the "init" callback. This method, when found, is + * invoked as part of the life cycle management of the component implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The dependency manager will look for a method of this name with the following signatures, + * in this order: + * <ol> + * <li>method(Component component)</li> + * <li>method()</li> + * </ol> + * + * @param callback the callback name + * @return this builder. + */ + B init(String callback); + + /** + * Sets the name of the method used as the "start" callback. This method, when found, is + * invoked as part of the life cycle management of the component implementation. The + * dependency manager will look for a method of this name with the following signatures, + * in this order: + * <ol> + * <li>method(Component component)</li> + * <li>method()</li> + * </ol> + * + * @param callback the callback name + * @return this builder. + */ + B start(String callback); + + /** + * Sets the name of the method used as the "stop" callback. This method, when found, is + * invoked as part of the life cycle management of the component implementation. The + * dependency manager will look for a method of this name with the following signatures, + * in this order: + * <ol> + * <li>method(Component component)</li> + * <li>method()</li> + * </ol> + * + * @param callback the callback name + * @return this builder. + */ + B stop(String callback); + + /** + * Sets the name of the method used as the "destroy" callback. This method, when found, is + * invoked as part of the life cycle management of the component implementation. The + * dependency manager will look for a method of this name with the following signatures, + * in this order: + * <ol> + * <li>method(Component component)</li> + * <li>method()</li> + * </ol> + * + * @param callback the callback name + * @return this builder. + */ + B destroy(String callback); + + /** + * Sets the name of the methods used as init callback that is invoked on a given Object instance. + * These methods, when found, are invoked on the specified instance as part of the life cycle management + * of the component implementation. + * <p> + * Specifying an instance means you can create a manager + * that will be invoked whenever the life cycle of a component changes and this manager + * can then decide how to expose this life cycle to the actual component, offering an + * important indirection when developing your own component models. + * + * @see #init(String) + * @param callbackInstance the instance the callback will be invoked on. + * @param callback the callback name + * @return this builder. + */ + B init(Object callbackInstance, String callback); + + /** + * Sets the name of the methods used as start callback that is invoked on a given Object instance. + * These methods, when found, are invoked on the specified instance as part of the life cycle management + * of the component implementation. + * <p> + * Specifying an instance means you can create a manager + * that will be invoked whenever the life cycle of a component changes and this manager + * can then decide how to expose this life cycle to the actual component, offering an + * important indirection when developing your own component models. + * + * @see #start(String) + * @param callbackInstance the instance the callback will be invoked on. + * @param callback the name of the start method + * @return this builder. + */ + B start(Object callbackInstance, String callback); + + /** + * Sets the name of the methods used as stop callback that is invoked on a given Object instance. + * These methods, when found, are invoked on the specified instance as part of the life cycle management + * of the component implementation. + * <p> + * Specifying an instance means you can create a manager + * that will be invoked whenever the life cycle of a component changes and this manager + * can then decide how to expose this life cycle to the actual component, offering an + * important indirection when developing your own component models. + * + * @see #stop(String) + * @param callbackInstance the instance the callback will be invoked on. + * @param callback the name of the stop method + * @return this builder. + */ + B stop(Object callbackInstance, String callback); + + /** + * Sets the name of the methods used as destroy callback that is invoked on a given Object instance. + * These methods, when found, are invoked on the specified instance as part of the life cycle management + * of the component implementation. + * <p> + * Specifying an instance means you can create a manager + * that will be invoked whenever the life cycle of a component changes and this manager + * can then decide how to expose this life cycle to the actual component, offering an + * important indirection when developing your own component models. + * + * @see #destroy(String) + * @param callbackInstance the instance the callback will be invoked on. + * @param callback the name of the destroy method + * @return this builder. + */ + B destroy(Object callbackInstance, String callback); + + /** + * Sets a method reference used as the "init" callback. This method reference must point to method from one + * of the component instance classes. It is invoked as part of the life cycle management of the component implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method does not take any parameters. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. + * @return this builder + */ + <U> B init(CbConsumer<U> callback); + + /** + * Sets a method reference used as the "start" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. + * @return this builder. + */ + <U> B start(CbConsumer<U> callback); + + /** + * Sets a method reference used as the "stop" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. + * @return this builder. + */ + <U> B stop(CbConsumer<U> callback); + + /** + * Sets a method reference used as the "destroy" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. + * @return this builder. + */ + <U> B destroy(CbConsumer<U> callback); + + /** + * Sets a method reference used as the "init" callback. This method reference must point to method from one + * of the component instance classes. It is invoked as part of the life cycle management of the component implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method takes as argument a Component parameter. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. The method takes as argument a Component parameter. + * @return this builder + */ + <U> B init(CbTypeComponent<U> callback); + + /** + * Sets a method reference used as the "start" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. The method takes as argument a Component parameter. + * @return this builder. + */ + <U> B start(CbTypeComponent<U> callback); + + /** + * Sets a method reference used as the "stop" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. The method takes as argument a Component parameter. + * @return this builder. + */ + <U> B stop(CbTypeComponent<U> callback); + + /** + * Sets a method reference used as the "destroy" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param <U> the type of the component class on which the callback is invoked on. + * @param callback a method reference must point to method from one of the component instance classes. The method takes as argument a Component parameter. + * @return this builder. + */ + <U> B destroy(CbTypeComponent<U> callback); + + /** + * Sets an Object instance method reference used as the "init" callback. It is invoked as part of the life cycle management of the component + * implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method does not take any parameters. + * + * @param callback an Object instance method reference. The method does not take any parameters. + * @return this builder + */ + B initInstance(Runnable callback); + + /** + * Sets an Object instance method reference used as the "start" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method does not take any parameters. + * + * @param callback an Object instance method reference. The method does not take any parameters. + * @return this builder. + */ + B startInstance(Runnable callback); + + /** + * Sets an Object instance method reference used as the "stop" callback. It is invoked as part of the life cycle management of the component + * implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method does not take any parameters. + * + * @param callback an Object instance method reference. The method does not take any parameters. + * @return this builder + */ + B stopInstance(Runnable callback); + + /** + * Sets an Object instance method reference used as the "destroy" callback. It is invoked as part of the life cycle management of the component + * implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method does not take any parameters. + * + * @param callback an Object instance method reference. The method does not take any parameters. + * @return this builder + */ + B destroyInstance(Runnable callback); + + /** + * Sets an Object instance method reference used as the "init" callback. It is invoked as part of the life cycle management of the component + * implementation. + * This method is useful because when it is invoked, all required dependencies defines in the Activator + * are already injected, and you can then add more extra dependencies from the init() method. + * And once all extra dependencies will be available and injected, then the "start" callback will be invoked. + * The method takes as argument a Component parameter. + * + * @param callback an Object instance method reference. + * @return this builder + */ + B initInstance(CbComponent callback); + + /** + * Sets an Object instance method reference used as the "start" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param callback an Object instance method reference. The method takes as argument a Component parameter. + * @return this builder. + */ + B startInstance(CbComponent callback); + + /** + * Sets an Object instance method reference used as the "stop" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param callback an Object instance method reference. The method takes as argument a Component parameter. + * @return this builder. + */ + B stopInstance(CbComponent callback); + + /** + * Sets an Object instance method reference used as the "destroy" callback. This method reference must point to method from one + * of the component instance classes. This method is invoked as part of the life cycle management of the component implementation. + * The method takes as argument a Component parameter. + * + * @param callback an Object instance method reference. The method takes as argument a Component parameter. + * @return this builder. + */ + B destroyInstance(CbComponent callback); + + /** + * Configures OSGi object (BundleContext, Component, etc ...) that will be injected in any field having the same OSGi object type. + * @param clazz the OSGi object type (BundleContext, Component, DependencyManager). + * @param autoConfig true if the OSGi object has to be injected, false if not + * @return this builder + */ + B autoConfig(Class<?> clazz, boolean autoConfig); + + /** + * Configures OSGi object (BundleContext, Component, etc ...) that will be injected in a given field. + * @param clazz the OSGi object type (BundleContext, Component, DependencyManager). + * @param field the field that will be injected with the OSGI object + * @return this builder + */ + B autoConfig(Class<?> clazz, String field); + + /** + * Activates debug mode + * @param label the debug label + * @return this builder + */ + B debug(String label); + + /** + * Automatically adds this component to its DependencyManager object. When a lambda builds a Component using this builder, by default + * the built component is auto added to its DependencyManager object, unless you invoke autoAdd(false). + * + * @param autoAdd true for automatically adding this component to the DependencyManager object, false if not + * @return this builder + */ + B autoAdd(boolean autoAdd); + + /** + * Sets the method to invoke on the service implementation to get back all + * instances that are part of a composition and need dependencies injected. + * All of them will be searched for any of the dependencies. The method that + * is invoked must return an <code>Object[]</code>. + * + * @param getCompositionMethod the method to invoke + * @return this builder + */ + B composition(String getCompositionMethod); + + /** + * Sets the instance and method to invoke to get back all instances that + * are part of a composition and need dependencies injected. All of them + * will be searched for any of the dependencies. The method that is + * invoked must return an <code>Object[]</code>. + * + * @param instance the instance that has the method + * @param getCompositionMethod the method to invoke + * @return this builder + */ + B composition(Object instance, String getCompositionMethod); + + /** + * Sets a java8 method reference to a Supplier that returns all instances that are part of a composition and need dependencies injected. + * All of them will be searched for any of the dependencies. The method that + * is invoked must return an <code>Object[]</code>. + * + * @param getCompositionMethod the method to invoke + * @return this builder + */ + B composition(Supplier<Object[]> getCompositionMethod); + + /** + * Builds the real DependencyManager Component. + * @return the real DependencyManager Component. + */ + Component build(); +} Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ConfigurationDependencyBuilder.java Sun Jan 31 23:27:05 2016 @@ -0,0 +1,129 @@ +package org.apache.felix.dm.lambda; + +import org.apache.felix.dm.ConfigurationDependency; +import org.apache.felix.dm.lambda.callbacks.CbComponentDictionary; +import org.apache.felix.dm.lambda.callbacks.CbDictionary; +import org.apache.felix.dm.lambda.callbacks.CbTypeComponentDictionary; +import org.apache.felix.dm.lambda.callbacks.CbTypeDictionary; + +/** + * Builds a Dependency Manager Configuration Dependency. + * By default, the updated callback is "updated", like in original DM API. + * + * <p> Code example with a component that defines a Configuration Dependency. the ServiceImpl modified method + * callback is declared using a method reference (see the "cb(ServiceImpl::modified)" code): + * + * <pre> {@code + * public class Activator extends DependencyManagerActivator { + * public void activate() throws Exception { + * component(comp -> comp + * .impl(ServiceImpl.class) + * .withConf(conf -> conf.pid(ServiceConsumer.class).cb(ServiceImpl::modified))); + * } + * } + * }</pre> + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public interface ConfigurationDependencyBuilder extends DependencyBuilder<ConfigurationDependency> { + /** + * Sets the pid for this configuration dependency. + * + * @param pid the configuration dependendency pid. + * @return this builder + */ + ConfigurationDependencyBuilder pid(String pid); + + /** + * Sets the class which fqdn represents the pid for this configuration dependency. Usually, this class can optionally be annotated with metatypes bnd annotations. + * + * @param pidClass the class which fqdn represents the pid for this configuration dependency. + * @return this builder + */ + ConfigurationDependencyBuilder pid(Class<?> pidClass); + + /** + * Sets propagation of the configuration properties to the service properties (false by default). + * All public configuration properties (not starting with a dot) will be propagated to the component service properties. + * + * @return this builder + */ + ConfigurationDependencyBuilder propagate(); + + /** + * Sets propagation of the configuration properties to the service properties (false by default). + * + * @param propagate true if all public configuration properties (not starting with a dot) must be propagated to the component service properties (false by default) + * @return this builder + */ + ConfigurationDependencyBuilder propagate(boolean propagate); + + /** + * Configures whether or not the component instance should be instantiated at the time the updated callback is invoked. + * By default, when the callback is applied on an external object instance, the component is not instantiated, but in this case + * you can force the creation of the component instances by calling this method. + * + * @param needsInstance true if the component instance should be instantiated at the time the updated callback is invoked on an external object instance. + * @return this builder + */ + ConfigurationDependencyBuilder needsInstance(boolean needsInstance); + + /** + * Sets a <code>callback</code> to call on the component instance(s) when the configuration is updated. + * + * @param updateMethod the callback to call on the component instance(s) when the configuration is updated. + * @return this builder + */ + ConfigurationDependencyBuilder cb(String updateMethod); + + /** + * Sets a <code>callback instance</code> to call on a given object instance when the configuration is updated. + * When the updated method is invoked, the Component implementation has not yet been instantiated, unless you have called + * the @link {@link #needsInstance(boolean)} method with "true". + * + * @param callbackInstance the object instance on which the updatedMethod is invoked + * @param updateMethod the callback to call on the callbackInstance when the configuration is updated. + * @return this builder + */ + ConfigurationDependencyBuilder cbi(Object callbackInstance, String updateMethod); + + /** + * Sets a <code>callback</code> method reference used to invoke an update method. The method reference must point to a method from one of the component + * implementation classes, and is invoked when the configuration is updated. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param callback the callback method reference which must point to a method from one of the component implementation classes. The method + * takes as argument a Dictionary. + * @return this builder + */ + <T> ConfigurationDependencyBuilder cb(CbTypeDictionary<T> callback); + + /** + * Sets the <code>callback</code> method reference used to invoke an update method. The method reference must point to a method from one of the + * component implementation classes, and is invoked when the configuration is updated. + * + * @param <T> the type of the component implementation class on which the callback is invoked on. + * @param callback the callback method reference used to invoke an update method on the component instance(s) when the configuration is updated. + * The method takes as argument a Component and a Dictionary. + * @return this builder + */ + <T> ConfigurationDependencyBuilder cb(CbTypeComponentDictionary<T> callback); + + /** + * Sets a <code>callback instance</code> method reference used to invoke the update method. The method reference must point to an Object instance + * method which takes as argument a Dictionary. + * + * @param updated a method reference that points to an Object instance method which takes as argument a Dictionary. + * @return this builder + */ + ConfigurationDependencyBuilder cbi(CbDictionary updated); + + /** + * Sets a <code>callback instance</code> method reference used to invoke the update method. The method reference must point to an Object instance method + * which takes as argument a Component and a Dictionary. + * + * @param updated a method reference that points to an Object instance method which takes as argument a Component and a Dictionary. + * @return this builder + */ + ConfigurationDependencyBuilder cbi(CbComponentDictionary updated); +} Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyBuilder.java?rev=1727869&view=auto ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyBuilder.java (added) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/DependencyBuilder.java Sun Jan 31 23:27:05 2016 @@ -0,0 +1,15 @@ +package org.apache.felix.dm.lambda; + +import org.apache.felix.dm.Dependency; + +/** + * Base class for all dependency builders + * @param <T> the dependency type. + */ +public interface DependencyBuilder<T extends Dependency> { + /** + * Builds a DependencyManager dependency. + * @return a real DependencyManager dependency + */ + T build(); +}
