You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2015/11/12 23:26:32 UTC

svn commit: r1714132 [4/5] - in /felix/sandbox/pderop/dependencymanager.builder.java: ./ cnf/ cnf/bin/ cnf/buildrepo/ cnf/buildrepo/biz.aQute.junit/ cnf/buildrepo/biz.aQute.launcher/ cnf/buildrepo/ee.foundation/ cnf/buildrepo/ee.minimum/ cnf/buildrepo/...

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ComponentBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ComponentBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ComponentBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ComponentBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,271 @@
+package org.apache.felix.dm.builder.java;
+
+import java.util.Dictionary;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.apache.felix.dm.Component;
+
+/**
+ * Builds a DependencyManager Component using java8 constructs. This interface provides builder methods used to configure general Component
+ * parameters, like:<p>
+ * 
+ * <ul>
+ * <li> factory parameters
+ * <li> component service properties
+ * <li> component lifecycle callbacks(init/start/stop/destroy)
+ * <li> service dependencies
+ * <li> configuration dependencies
+ * <li> auto-injected OSGi and DM objects (BundleContext, Component, etc ...)
+ * </ul>
+ * 
+ * Code example:
+ * 
+ * <pre> {@code
+ * public class Activator extends DependencyActivatorBase {    
+ *     public void init() throws Exception {
+ *         component(comp -> comp
+ *             .provides(Service.class)
+ *             .factory(ServiceImplFactory::new, ServiceImplFactory::create)            
+ *             .withService(LogService.class, srv -> srv.required().onAdd(ServiceImpl::set))
+ *             .onStart(ServiceImpl::activate));                      
+ *     }
+ * }
+ * }</pre>
+ *
+ * @param <B> This generic parameter is used by interfaces that may extends this builder, like adapters or aspect builders.
+ * The intent of this parameter is to be able to make each component builder method return the type of sub-interfaces. 
+ * 
+ * TODO: add support for reflection for lifecycle callbacks (like in Dependency Manager).
+ */
+public interface ComponentBuilder<B extends ComponentBuilder<B>> {
+	/**
+	 * Configures the services registered by this component in the OSGgi registry
+	 * @param ifaces the OSGi service(s) components.
+	 * @return this builder
+	 */
+	B provides(Class<?> ... ifaces); 
+	
+	/**
+	 * Configures the component implementation. Can be a classname, or a component implementation object.
+	 * @param impl the component implementation (a class, or an Object).
+	 * @return this builder
+	 */
+	B impl(Object impl);   
+	
+	/**
+	 * Configures a factory that can be used to create this component implemention.
+	 * Example: "factory(ComponentImpl::new)", or "factory(() -> new ComponentImpl())".
+	 * 
+	 * @param create the factory used to create the component implemenation.
+	 * @return this builder
+	 */
+    <T> B factory(Supplier<T> create);
+    
+    /**
+     * Configures a factory used to create this component implementation using a Factory object and a method in the Factory object.
+     * Example:
+     * 
+     * factory(Factory::new, Factory::create)
+     * 
+     * @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
+     */
+    <T> B factory(Supplier<T> factory, Function<T, Object> 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:
+     * 
+     * CompositionManager mngr = new CompositionManager();
+     * ...
+     * factory(mngr::create, mngr::getComposition)
+     * 
+     * @param factory
+     * @param getComposition
+     * @return this builder
+     */
+    <T> B factory(Supplier<T> factory, Supplier<Object[]> getComposition);
+    
+    /**
+     * Configures a factory that also returns a composition of objects for this component implemenation.
+     * 
+     * Example:
+     * 
+     * factory(CompositionManager::new, CompositionManager::create, CompositionManager::getComposition).
+     * 
+     * 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 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
+     */
+    <T> B factory(Supplier<T> factory, Function<T, Object> create, Function<T, Object[]> getComposition);
+    
+    /**
+     * 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.
+     * @param properties a varargs representing a list of key-value pairs.
+     * 
+     * Example: properties("param1", "value1", "service.ranking", 3)
+     * @return this builder
+     */
+    B properties(Object ... properties);  
+    
+    /**
+     * Adds a required/autoconfig service dependency.
+     * @param service the dependency that is required and that will be injected in any field with the same dependency type.
+     * @return this builder
+     */
+    <T> B withService(Class<T> service);
+    
+    /**
+     * Adds a service dependency.
+     * @param service the service
+     * @param consumer the lambda for configuring the service dependency
+     * @return this builder.
+     */
+    <T> B withService(Class<T> service, Consumer<ServiceDependencyBuilder<T>> consumer);
+    
+    /**
+     * Adds a configuration dependency.
+     * @param consumer the lambda used to configuration the configuration dependency.
+     * @return this builder.
+     */
+    B withConfiguration(Consumer<ConfigurationDependencyBuilder> consumer);        
+    
+    /**
+     * Sets a reference on an instance method that is called when the component is initialized.
+     * 
+     * Example: onInit(instance::init)
+     * 
+     * @param callback a callback that will be called when the component is initialized
+     * @return this builder
+     */
+    <T> B onInit(Consumer<T> callback);
+    
+    /**
+     * Sets a reference on a component implementation method that is called when the component is initialized.
+     * 
+     * Example: onInit(MyComponentImpl::activate)
+     * 
+     * @param callback a method reference called when the component is started
+     * @return this builder
+     */
+    <T> B onInit(BiConsumer<T, Component> callback);   
+    
+    /**
+     * Sets a reference on an instance method that is called when the component is started.
+     * 
+     * Example: onStart(instance::start)
+     * 
+     * @param callback a callback that will be called when the component is started
+     * @return this builder
+     */
+    <T> B onStart(Consumer<T> callback);    
+   
+    /**
+     * Sets a reference on a component implementation method that is called when the component is started.
+     * 
+     * Example: onStart(MyComponentImpl::started)
+     * 
+     * @param callback a method reference called when the component is started
+     * @return this builder
+     */
+    <T> B onStart(BiConsumer<T, Component> callback);
+    
+    /**
+     * Sets a reference on an instance method that is called when the component is stopped.
+     * 
+     * Example: onStop(instance::stop)
+     * 
+     * @param callback a callback that will be called when the component is stopped
+     * @return this builder
+     */
+    <T> B onStop(Consumer<T> callback);    
+   
+    /**
+     * Sets a reference on a component implementation method that is called when the component is started.
+     * 
+     * Example: onStart(MyComponentImpl::started)
+     * 
+     * @param callback a method reference called when the component is started
+     * @return this builder
+     */
+    <T> B onStop(BiConsumer<T, Component> callback);
+  
+    /**
+     * Sets a reference on an instance method that is called when the component is destroyed.
+     * 
+     * Example: onDestroy(instance::destroy)
+     * 
+     * @param callback a callback that will be called when the component is destroyed
+     * @return this builder
+     */
+    <T> B onDestroy(Consumer<T> callback); 
+    
+    /**
+     * Sets a reference on a component implementation method that is called when the component is destroyed.
+     * 
+     * Example: onDestroy(MyComponentImpl::destroy)
+     * 
+     * @param callback a method reference called when the component is destroyed
+     * @return this builder
+     */
+    <T> B onDestroy(BiConsumer<T, Component> 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
+     */
+    <T> B autoInject(Class<T> 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
+     */
+    <T> B autoInject(Class<T> 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
+     * @param autoAdd true for automatically adding this component to the DependencyManager object, false if not
+     * @return this builder
+     */
+    B autoAdd(boolean autoAdd);
+    
+    /**
+     * Is this component automatically added to its DependencyManager object ?
+     * @return this builder
+     */
+    boolean autoAdd();
+    
+    /**
+     * Builds the real DependencyManager Component from this Component.
+     * @return the real DependencyManager Component.
+     */
+    Component build();
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ConfigurationDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ConfigurationDependencyBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ConfigurationDependencyBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ConfigurationDependencyBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,32 @@
+package org.apache.felix.dm.builder.java;
+
+import java.util.Dictionary;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import org.apache.felix.dm.ConfigurationDependency;
+
+/**
+ * Defines a builder for DependencyManager Configuration Dependency.
+ * 
+ * Code example with a component that defines a Configuration Dependency:
+ * 
+ * <pre> {@code
+ * public class Activator extends DependencyActivatorBase {
+ *     public void init() throws Exception { 
+ *         component(comp -> comp
+ *           .impl(ServiceConsumer.class)
+ *           .withConfiguration(conf -> conf.pid(ServiceConsumer.class).onUpdate(ServiceConsumer::updated)));  
+ *    }
+ * }</pre>
+ *
+ * TODO: javadoc
+ */
+public interface ConfigurationDependencyBuilder extends DependencyBuilder<ConfigurationDependency> {    
+    ConfigurationDependencyBuilder pid(String pid);
+    ConfigurationDependencyBuilder pid(Class<?> pidClass);
+    ConfigurationDependencyBuilder propagate();
+    ConfigurationDependencyBuilder propagate(boolean propagate);
+    <T> ConfigurationDependencyBuilder onUpdate(BiConsumer<T, Dictionary<String, Object>> updated);
+    ConfigurationDependencyBuilder onUpdate(Consumer<Dictionary<String, Object>> updated);       
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyActivatorBase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyActivatorBase.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyActivatorBase.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyActivatorBase.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,199 @@
+package org.apache.felix.dm.builder.java;
+
+import java.util.function.Consumer;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.java.impl.AdapterBuilderImpl;
+import org.apache.felix.dm.builder.java.impl.AspectBuilderImpl;
+import org.apache.felix.dm.builder.java.impl.ComponentBuilderImpl;
+import org.apache.felix.dm.builder.java.impl.FactoryPidAdapterBuilderImpl;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Defines a base for Activators in order to build DependencyManager Components using a java8 style.
+ * Code example:
+ * 
+ * <pre> {@code
+ * public class Activator extends DependencyActivatorBase {    
+ *     public void init() throws Exception {
+ *         component(comp -> comp
+ *             .provides(Provider.class)
+ *             .factory(ProviderFactory::new, ProviderFactory::create)            
+ *             .withService(LogService.class, srv -> srv.required().onAdd(ProviderImpl::set))
+ *             .onStart(ProviderImpl::start));                      
+ *     }
+ * }
+ * }</pre>
+ *
+ */
+public abstract class DependencyActivatorBase implements BundleActivator {
+	/**
+	 * DependencyManager object used to create/register real DM Components that are built by this activator.
+	 */
+    protected DependencyManager m_manager;
+
+    /**
+     * Our Activator is starting.
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        m_manager = new DependencyManager(context);
+        init();
+    }
+
+    /**
+     * Our Activator is stopped.
+     */
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        destroy();
+    }
+
+    /**
+     * Sub classes must override this method in order to build some DM components.
+     * @throws Exception
+     */
+    protected abstract void init() throws Exception;
+
+    /**
+     * Sub classes may override this method that is called when the Activator is stopped.
+     * @param manager
+     * @throws Exception
+     */
+    protected void destroy() throws Exception {
+    }
+    
+    /**
+     * Returns the DependencyManager used to create/managed DM Components
+     * @return the DependencyManager associated to this Activator
+     */
+    protected DependencyManager getDependencyManager() {
+        return m_manager;
+    }
+    
+    /**
+     * Builds a DM Component using a Java8 style ComponentBuilder.
+     * @param consumer the lambda that will use the ComponentBuilder for building the DM component. 
+     * The component is auto-added to the DependencyManager, unless the lambda calls the ComponentBuilder.autoAdd(false) method.
+     * @return a newly built DM component.
+     */
+    protected Component component(Consumer<ComponentBuilder<? extends ComponentBuilder<?>>> consumer) {
+        return component(m_manager, consumer);
+    }
+        
+    /**
+     * Builds a DM Aspect Component using a Java8 style AspectBuilder.
+     * @param consumer the lambda that will use the AspectBuilder for building the DM aspect component. 
+     * The component is auto-added to the DependencyManager, unless the lambda calls the AspectBuilder.autoAdd(false) method.
+     * @return a newly built DM component.
+     */
+    protected <T> Component aspect(Class<T> aspect, Consumer<AspectBuilder<T>> consumer) {
+        return aspect(m_manager, aspect, consumer);
+    }
+
+    /**
+     * Builds a DM Adapter Component using a Java8 style AdapterBuilder.
+     * @param consumer the lambda that will use the AdapterBuilder for building the DM adapter component. 
+     * The component is auto-added to the DependencyManager, unless the lambda calls the AdapterBuilder.autoAdd(false) method.
+     * @return a newly built DM component.
+     */
+    protected <T> Component adapter(Class<T> adaptee, Consumer<AdapterBuilder<T>> consumer) {
+        return adapter(m_manager, adaptee, consumer);
+    }
+    
+    /**
+     * Builds a DM Factory Configuration Adapter Component using a Java8 style FactoryPidAdapterBuilder.
+     * @param consumer the lambda that will use the FactoryPidAdapterBuilder for building the DM factory configuration adapter component. 
+     * The component is auto-added to the DependencyManager, unless the lambda calls the FactoryPidAdapterBuilder.autoAdd(false) method.
+     * @return a newly built DM component.
+     */
+    protected Component factoryPidAdapter(Consumer<FactoryPidAdapterBuilder> consumer) {
+        return factoryPidAdapter(m_manager, consumer);
+    }
+    
+    // These static methods can be used when building DM components outside of an activator.
+	
+    /**
+     * Builds a component using a lambda and a component builder
+     * @param dm the DependencyManager where the component is auto-added (unless the component.autoAdd(false) is called)
+     * @param consumer a lambda that is called to build the component. When the lambda is called, it will be provided with a 
+     * ComponentBuilder object that is used to build the actual DM component.
+     * 
+     * @return the built DM component.
+     */
+    public static Component component(DependencyManager dm, Consumer<ComponentBuilder<? extends ComponentBuilder<?>>> consumer) {
+        ComponentBuilder<?> componentBuilder = new ComponentBuilderImpl(dm);
+        consumer.accept(componentBuilder);
+        Component comp = componentBuilder.build();
+        if (componentBuilder.autoAdd()) {
+        	dm.add(comp);
+        }
+        return comp;
+    }
+
+    /**
+     * Update an existing component. Typically, this method can be used from a Component.init method, where more dependencies has to be added.
+     * @param comp an existing DM component
+     * @param consumer the lambda that will be used to update the component
+     */
+    public static void component(Component comp, Consumer<ComponentBuilder<?>> consumer) {
+        ComponentBuilder<?> componentBuilder = new ComponentBuilderImpl(comp, true /* update component */);
+        consumer.accept(componentBuilder);
+        componentBuilder.build();
+    }
+    
+    /**
+     * Builds an aspect DM Component.
+     * @param dm the DependencyManager object used to register the built component
+     * @param aspect the type of the aspect service
+     * @param consumer a lambda used to build the DM aspect component
+     * @return a new DM aspect component. The aspect component is auto-added into the dm object, unless the lambda calls
+     * the AspectBuilder.autoAdd(false) method.
+     */
+    public static <T> Component aspect(DependencyManager dm, Class<T> aspect, Consumer<AspectBuilder<T>> consumer) {
+        AspectBuilder<T> aspectBuilder = new AspectBuilderImpl<>(dm, aspect);
+        consumer.accept(aspectBuilder);
+        Component comp = aspectBuilder.build();
+        if (aspectBuilder.autoAdd()) {
+        	dm.add(comp);
+        }
+        return comp;
+    }    
+        
+    /**
+     * Builds an adapter DM Component.
+     * @param dm the DependencyManager object used to register the built component
+     * @param aspect the type of the adaptee service
+     * @param consumer a lambda used to build the DM adapter component
+     * @return a new DM adapter component. The adapter component is auto-added into the dm object, unless the lambda calls
+     * the AspectBuilder.autoAdd(false) method is called.
+     */
+    public static <T> Component adapter(DependencyManager dm, Class<T> adaptee, Consumer<AdapterBuilder<T>> consumer) {
+        AdapterBuilder<T> adapterBuilder = new AdapterBuilderImpl<>(dm, adaptee);
+        consumer.accept(adapterBuilder);
+        Component comp = adapterBuilder.build();
+        if (adapterBuilder.autoAdd()) {
+        	dm.add(comp);
+        }
+        return comp;
+    }
+        
+    /**
+     * Builds a DM factory configuration adapter.
+     * @param dm the DependencyManager object used to create DM components.
+     * @param consumer a lambda used to build the DM factory configuration adapter component
+     * @return a new DM factory configuration adapter component. The adapter component is auto-added into the dm object, unless the lambda calls
+     * the FactoryPidAdapterBuilder.autoAdd(false) method is called
+     */
+    public static Component factoryPidAdapter(DependencyManager dm, Consumer<FactoryPidAdapterBuilder> consumer) {
+        FactoryPidAdapterBuilder factoryPidAdapter = new FactoryPidAdapterBuilderImpl(dm);
+        consumer.accept(factoryPidAdapter);
+        Component comp = factoryPidAdapter.build();
+        if (factoryPidAdapter.autoAdd()) {
+        	dm.add(comp);
+        }
+        return comp;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/DependencyBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,15 @@
+package org.apache.felix.dm.builder.java;
+
+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 DependencyManager dependency
+	 */
+    T build();
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/FactoryPidAdapterBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/FactoryPidAdapterBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/FactoryPidAdapterBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/FactoryPidAdapterBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,29 @@
+package org.apache.felix.dm.builder.java;
+
+import java.util.Dictionary;
+import java.util.function.BiConsumer;
+
+/**
+ * Defines the interface for a Dependency Manager Factory Configuration Adapter.
+ * 
+ * Example that defines a factory configuration adapter service for the "foo.bar" factory pid.
+ * 
+ * <pre> {@code
+ * public class Activator extends DependencyActivatorBase {
+ *     public void init() throws Exception { 
+ *         factoryPidAdapter(comp -> comp
+ *             .factoryPid("foo.bar").onUpdate(ServiceImpl::updated).propagate()
+ *             .impl(DictionaryImpl.class)
+ *             .withService(LogService.class, dep -> dep.required(false)));
+ *    }
+ * }</pre>
+ *
+ * TODO: javadoc
+ */
+public interface FactoryPidAdapterBuilder extends ComponentBuilder<FactoryPidAdapterBuilder> {
+    FactoryPidAdapterBuilder factoryPid(String pid);
+    FactoryPidAdapterBuilder factoryPid(Class<?> pidClass);
+    FactoryPidAdapterBuilder propagate();
+    FactoryPidAdapterBuilder propagate(boolean propagate);
+    <T> FactoryPidAdapterBuilder onUpdate(BiConsumer<T, Dictionary<String, Object>> callback);    
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceCallbacksBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceCallbacksBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceCallbacksBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceCallbacksBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,68 @@
+package org.apache.felix.dm.builder.java;
+
+import org.apache.felix.dm.builder.java.Callbacks.DictServiceDictService;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceDictServiceDictService;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceMapServiceMapService;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceRef;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceRefServiceRefService;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceService;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceServiceDict;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceServiceMap;
+import org.apache.felix.dm.builder.java.Callbacks.InstanceServiceRef;
+import org.apache.felix.dm.builder.java.Callbacks.MapServiceMapService;
+import org.apache.felix.dm.builder.java.Callbacks.Ref;
+import org.apache.felix.dm.builder.java.Callbacks.RefServiceRefService;
+import org.apache.felix.dm.builder.java.Callbacks.Service;
+import org.apache.felix.dm.builder.java.Callbacks.ServiceDict;
+import org.apache.felix.dm.builder.java.Callbacks.ServiceMap;
+import org.apache.felix.dm.builder.java.Callbacks.ServiceRef;
+
+/**
+ * Definition of method references for general service dependency callbacks.
+ *
+ * @param <T> a service dependency type
+ * @param <B> the type of a sub interface that may extends this interface
+ * 
+ * TODO: add javadocs
+ */
+public interface ServiceCallbacksBuilder<T, B extends ServiceCallbacksBuilder<T, B>> {
+    <I> B onAdd(InstanceService<I, T> add);
+    B onAdd(Service<T> add);
+    <I> B onAdd(InstanceServiceMap<I, T> add);
+    B onAdd(ServiceMap<T> add);
+    <I> B onAdd(InstanceServiceDict<I, T> add);
+    B onAdd(ServiceDict<T> add);
+    <I> B onAdd(InstanceRef<I, T> add);
+    B onAdd(Ref<T> add);
+    <I> B onAdd(InstanceServiceRef<I, T> add);
+    B onAdd(ServiceRef<T> add);
+   
+    <I> B onChange(InstanceService<I, T> change);
+    B onChange(Service<T> change);
+    <I> B onChange(InstanceServiceMap<I, T> change);
+    B onChange(ServiceMap<T> change);
+    <I> B onChange(InstanceServiceDict<I, T> change);
+    B onChange(ServiceDict<T> change);
+    <I> B onChange(InstanceRef<I, T> change);
+    B onChange(Ref<T> change);
+    <I> B onChange(InstanceServiceRef<I, T> add);
+    B onChange(ServiceRef<T> add);
+
+    <I> B onRemove(InstanceService<I, T> remove);
+    B onRemove(Service<T> remove);
+    <I> B onRemove(InstanceServiceMap<I, T> remove);
+    B onRemove(ServiceMap<T> remove);
+    <I> B onRemove(InstanceServiceDict<I, T> remove);
+    B onRemove(ServiceDict<T> remove);
+    <I> B onRemove(InstanceRef<I, T> remove);
+    B onRemove(Ref<T> remove);
+    <I> B onRemove(InstanceServiceRef<I, T> add);
+    B onRemove(ServiceRef<T> add);
+
+    <I> B onSwap(InstanceRefServiceRefService<I, T> swap);
+    B onSwap(RefServiceRefService<T> swap);
+    <I> B onSwap(InstanceMapServiceMapService<I, T> swap);
+    B onSwap(MapServiceMapService<T> swap);
+    <I> B onSwap(InstanceDictServiceDictService<I, T> swap);
+    B onSwap(DictServiceDictService<T> swap);
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceDependencyBuilder.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceDependencyBuilder.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceDependencyBuilder.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/ServiceDependencyBuilder.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,128 @@
+package org.apache.felix.dm.builder.java;
+
+import org.apache.felix.dm.ServiceDependency;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Defines a Service dependency. Dependency callbacks can be defined using method like (like in DependencyManager), or using method references.
+ *
+ * @param <T> the type of the service dependency
+ */
+public interface ServiceDependencyBuilder<T> extends DependencyBuilder<ServiceDependency>, ServiceCallbacksBuilder<T, ServiceDependencyBuilder<T>> {
+	/**
+	 * Injects this dependency in all fields matching the dependency type.
+	 * @return this builder
+	 */
+	ServiceDependencyBuilder<T> autoConfig();
+	
+	/**
+	 * Configures whether or not the dependency can be injected in all fields matching the dependency type. 
+	 * @param autoConfig true if the dependency can be injected in all fields matching the dependency type
+	 * @return this builder
+	 */
+    ServiceDependencyBuilder<T> autoConfig(boolean autoConfig);
+    
+    /**
+     * Injects this dependency on the field with the given name
+     * @param field the field name where the dependency must be injected
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> autoConfig(String field);
+    
+    /**
+     * Configures the service dependency filter
+     * @param filter the service filter
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> filter(String filter);
+    
+    /**
+     * Configures this dependency with the given ServiceReference.
+     * @param ref the service reference
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> ref(ServiceReference<T> ref);
+    
+    /**
+     * Configures this dependency as required. By default, a dependency is required.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> required();
+    
+    /**
+     * Configures whether this dependency is required or not.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> required(boolean required);
+    
+    /**
+     * Configures the dependency callback instance.
+     * @param instance the dependency callback instance
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> callbackInstance(Object instance);
+    
+    /**
+     * Configures the callback to invoke when the dependency becomes available
+     * @param added the method name to call when the dependency is available
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> onAdd(String added);
+    
+    /**
+     * Configures the callback to invoke when the dependency is changed.
+     * @param changed the method name to call when the dependency is changed
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> onChange(String changed);
+    
+    /**
+     * Configures the callback to invoke when the dependency is removed.
+     * @param changed the method name to call when the dependency is lost
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> onRemove(String removed);
+    
+    /**
+     * Configures the callback to call when the service is swapped by another one
+     * @param swapped the method name to call on swap service event
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> onSwap(String swapped);
+    
+    /**
+     * Configures debug mode
+     * @param label the label used by debug messages
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> debug(String label);
+    
+    /**
+     * Propagates the dependency properties to the component service properties.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> propagate();
+  
+    /**
+     * Configures whether the dependency properties must be propagated or not to the component service properties.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> propagate(boolean propagate);
+    
+    /**
+     * Configures a method that can is called in order to get propagated service properties.
+     * TODO: add support for method reference
+     * 
+     * @param instance an object instance
+     * @param method the method name to call on the object instance. This method returns the propagated service properties.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> propagateTo(Object instance, String method);
+    
+    /**
+     * Sets the default implementation if the service is not available.
+     * @param defaultImpl the implementation used by default when the service is not available.
+	 * @return this builder
+     */
+    ServiceDependencyBuilder<T> defImpl(Object defaultImpl);
+}
\ No newline at end of file

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AdapterBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AdapterBuilderImpl.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AdapterBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AdapterBuilderImpl.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,76 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Objects;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.java.AdapterBuilder;
+
+public class AdapterBuilderImpl<T> extends ExtendedComponentBase<T, AdapterBuilderImpl<T>> implements AdapterBuilder<T> {
+	
+    private final Class<?> m_adapteeType;
+    private String m_adapteeFilter;
+    private boolean m_propagate;
+    private String m_injectField;
+    private final DependencyManager m_dm;
+    private boolean m_autoAdd = true;
+    
+    public <U> AdapterBuilderImpl(DependencyManager dm, Class<U> type) {
+        m_dm = dm;
+        m_adapteeType = type;
+    }    
+
+    @Override
+    public AdapterBuilderImpl<T> autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    public boolean autoAdd() {
+    	return m_autoAdd;
+    }
+
+    @Override
+    public AdapterBuilder<T> filter(String adapteeFilter) {
+        m_adapteeFilter = adapteeFilter;
+        return this;
+    }
+
+    @Override
+    public AdapterBuilder<T> propagate() {
+        m_propagate = true;
+        return this;
+    }
+
+    @Override
+    public AdapterBuilder<T> propagate(boolean propagate) {
+        m_propagate = propagate;
+        return this;
+    }
+
+    @Override
+    public AdapterBuilder<T> inject(String field) {
+        m_injectField = field;
+        return this;
+    }
+
+    @Override
+    public Component build() {
+        Objects.nonNull(m_adapteeFilter);
+        
+        String add = null, change = null, remove = null, swap = null;
+        Object cbInstance = hasCallbacks() ? createCallbackInstance() : null;
+        if (cbInstance != null) {
+            add = "add";
+            change = "change";
+            remove = "remove";
+            swap = "swap";
+        }
+        Component c = m_dm.createAdapterService(m_adapteeType, m_adapteeFilter, m_injectField, cbInstance, add, change, remove, swap,
+            m_propagate);
+        ComponentBuilderImpl cb = new ComponentBuilderImpl(c, false);
+        // m_compBuilder is a composed consumer that calls in sequence all necessary component builder methods. 
+        m_compBuilder.accept (cb);
+        return cb.build();
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AspectBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AspectBuilderImpl.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AspectBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/AspectBuilderImpl.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,60 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Objects;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.java.AspectBuilder;
+
+public class AspectBuilderImpl<T> extends ExtendedComponentBase<T, AspectBuilderImpl<T>> implements AspectBuilder<T> {
+    private final DependencyManager m_dm;
+    private final Class<?> m_aspectType;
+    private String m_aspectFilter;
+    private int m_aspectRanking;
+    private boolean m_autoAdd = true;
+
+    public <U> AspectBuilderImpl(DependencyManager dm, Class<U> type) {
+        m_dm = dm;
+        m_aspectType = type;
+    }
+
+    @Override
+    public AspectBuilderImpl<T> autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    public boolean autoAdd() {
+    	return m_autoAdd;
+    }
+
+    @Override
+    public AspectBuilder<T> filter(String aspectFilter) {
+        m_aspectFilter = aspectFilter;
+        return this;
+    }
+
+    @Override
+    public AspectBuilder<T> rank(int ranking) {
+        m_aspectRanking = ranking;
+        return this;
+    }
+
+    @Override
+    public Component build() {
+        Objects.nonNull(m_aspectType);
+        Object cbInstance = hasCallbacks() ? createCallbackInstance() : null;
+        String add = null, change = null, remove = null, swap = null;
+        if (cbInstance != null) {
+            add = "add";
+            change = "change";
+            remove = "remove";
+            swap = "swap";
+        }
+        Component c = m_dm.createAspectService(m_aspectType, m_aspectFilter, m_aspectRanking, add, change, remove, swap);
+        ComponentBuilderImpl cb = new ComponentBuilderImpl(c, false);
+        // m_compBuilder is a composed consumer that calls in sequence all necessary component builder methods. 
+        m_compBuilder.accept (cb);
+        return cb.build();
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ComponentBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ComponentBuilderImpl.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ComponentBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ComponentBuilderImpl.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,319 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+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.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.java.ComponentBuilder;
+import org.apache.felix.dm.builder.java.ConfigurationDependencyBuilder;
+import org.apache.felix.dm.builder.java.DependencyBuilder;
+import org.apache.felix.dm.builder.java.ServiceDependencyBuilder;
+
+public class ComponentBuilderImpl implements ComponentBuilder<ComponentBuilderImpl> {
+    private final List<DependencyBuilder<?>> m_dependencyBuilders = new ArrayList<>();
+    private final Component m_component;
+    private final boolean m_componentUpdated;
+    private String[] m_serviceNames;
+    private Dictionary<Object, Object> m_properties;
+    private Object m_impl;
+    private Object m_factory;
+    private boolean m_factoryHasComposite;	
+    private boolean m_autoAdd = true;
+
+    /**
+     * Map used to invoke actual lifecycle component method references.
+     * Key = "init" or "start" or "stop" or "destroy".  
+     * Value = list of Consumers for <component.getInstance(), and the Component object itself>.
+     */
+    private final ConcurrentHashMap<String, List<BiConsumer<?, Component>>> m_callbackMethodRefs = new ConcurrentHashMap<>();
+
+    public ComponentBuilderImpl(DependencyManager dm) {
+        m_component = dm.createComponent();
+        m_componentUpdated = false;
+    }
+    
+    public ComponentBuilderImpl(Component component, boolean update) {
+        m_component = component;
+        m_componentUpdated = update;
+    }
+        
+    @Override
+    public <T> ComponentBuilderImpl autoInject(Class<T> clazz, boolean autoConfig) {
+        m_component.setAutoConfig(clazz, autoConfig);
+        return this;
+    }
+
+    @Override
+    public <T> ComponentBuilderImpl autoInject(Class<T> clazz, String instanceName) {
+        m_component.setAutoConfig(clazz, instanceName);
+        return this;
+    }
+
+    @Override
+    public ComponentBuilderImpl provides(Class<?>... ifaces) {
+        m_serviceNames = Stream.of(ifaces).map(c -> c.getName()).toArray(String[]::new);
+        return this;
+    }
+
+    public ComponentBuilderImpl provides(String... ifaces) {
+        m_serviceNames = ifaces;
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public ComponentBuilderImpl properties(Dictionary<?, ?> properties) {
+        m_properties = (Dictionary<Object, Object>) properties;
+        return this;
+    }
+
+    @Override
+    public ComponentBuilderImpl properties(Object ...properties) {
+        Properties props = new Properties();
+        if ((properties.length & 1) != 0) {
+        	throw new IllegalArgumentException("Invalid number of specified properties (number of arguments must be even).");
+        }
+        for (int i = 0; i < properties.length - 1; i += 2) {
+            String key = properties[i].toString().trim();
+            Object value = properties[i+1];
+            props.put(key, value);
+        }
+        m_properties = props;
+        return this;
+    }
+
+    @Override
+    public ComponentBuilderImpl debug(String label) {
+        m_component.setDebug(label);
+        return this;
+    }
+    
+    @Override
+    public ComponentBuilderImpl autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    public boolean autoAdd() {
+    	return m_autoAdd;
+    }
+
+    @Override
+    public <T> ComponentBuilderImpl withService(Class<T> service) {
+        ServiceDependencyBuilder<T> dep = new ServiceDependencyBuilderImpl<T>(m_component, service);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }   
+
+    @Override
+    public <T> ComponentBuilderImpl withService(Class<T> service, Consumer<ServiceDependencyBuilder<T>> consumer) {
+        ServiceDependencyBuilder<T> dep = new ServiceDependencyBuilderImpl<T>(m_component, service);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }   
+    
+    @Override
+    public ComponentBuilderImpl withConfiguration(Consumer<ConfigurationDependencyBuilder> consumer) {
+        ConfigurationDependencyBuilder dep = new ConfigurationDependencyBuilderImpl(m_component);
+        consumer.accept(dep);
+        m_dependencyBuilders.add(dep);
+        return this;
+    }
+       
+    @Override
+    public ComponentBuilderImpl impl(Object instance) {
+        m_impl = instance;
+        return this;
+    }
+    
+    @Override
+    public <T> ComponentBuilderImpl factory(Supplier<T> create) {
+        Objects.nonNull(create);
+        m_factory = new Object() {
+            @SuppressWarnings("unused")
+            public Object create() {
+                return create.get();
+            }
+        };
+        return this;
+    }
+    
+    @Override
+    public <T> ComponentBuilderImpl factory(Supplier<T> supplier, Function<T, Object> create) {
+        Objects.nonNull(supplier);
+        Objects.nonNull(create);
+        
+        m_factory = new Object() {
+            @SuppressWarnings("unused")
+            public Object create() {
+                T factoryImpl = supplier.get();
+                return create.apply(factoryImpl);
+            }
+        }; 
+        return this;
+    }
+
+    @Override
+    public <T> ComponentBuilderImpl factory(Supplier<T> create, Supplier<Object[]> getComposite) {
+        Objects.nonNull(create);
+        Objects.nonNull(getComposite);
+        
+        m_factory = new Object() {
+            @SuppressWarnings("unused")
+            public Object create() { // Create Factory instance
+                return create.get();
+            }
+            
+            @SuppressWarnings("unused")
+            public Object[] getComposite() { // Create Factory instance
+                return getComposite.get();
+            }
+        };
+        m_factoryHasComposite = true;
+        return this;
+    }
+    
+    @Override
+    public <T> ComponentBuilderImpl factory(Supplier<T> factorySupplier, Function<T, Object> factoryCreate, Function<T, Object[]> factoryGetComposite) {
+        Objects.nonNull(factorySupplier);
+        Objects.nonNull(factoryCreate);
+        Objects.nonNull(factoryGetComposite);
+
+        m_factory = new Object() {
+            T m_factoryInstance;
+            
+            @SuppressWarnings("unused")
+            public Object create() { 
+                m_factoryInstance = factorySupplier.get();
+                return factoryCreate.apply(m_factoryInstance);
+            }
+            
+            @SuppressWarnings("unused")
+            public Object[] getComposite() { 
+                return factoryGetComposite.apply(m_factoryInstance);
+            }
+        }; 
+        m_factoryHasComposite = true;
+        return this;
+    }
+    
+    @Override
+    public final <T> ComponentBuilderImpl onInit(Consumer<T> callback) {
+        return setLifecyceMethodRef("init", (T instance, Component comp) -> callback.accept(instance));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onInit(BiConsumer<T, Component> callback) {
+        return setLifecyceMethodRef("init", (T instance, Component comp) -> callback.accept(instance, comp));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onStart(Consumer<T> callback) {
+        return setLifecyceMethodRef("start", (T instance, Component comp) -> callback.accept(instance));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onStart(BiConsumer<T, Component> callback) {
+        return setLifecyceMethodRef("start", (T instance, Component comp) -> callback.accept(instance, comp));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onStop(Consumer<T> callback) {
+        return setLifecyceMethodRef("stop", (T instance, Component comp) -> callback.accept(instance));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onStop(BiConsumer<T, Component> callback) {
+        return setLifecyceMethodRef("stop", (T instance, Component comp) -> callback.accept(instance, comp));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onDestroy(Consumer<T> callback) {
+        return setLifecyceMethodRef("destroy", (T instance, Component comp) -> callback.accept(instance));
+    }
+
+    @Override
+    public final <T> ComponentBuilderImpl onDestroy(BiConsumer<T, Component> callback) {
+        return setLifecyceMethodRef("destroy", (T instance, Component comp) -> callback.accept(instance, comp));
+    }
+
+    public Component build() {
+        if (m_serviceNames != null) {
+            m_component.setInterface(m_serviceNames, m_properties);
+        } 
+        
+        if (m_properties != null) {
+            m_component.setServiceProperties(m_properties);
+        }
+                
+        if (! m_componentUpdated) { // Don't override impl or set callbacks if component is being updated
+           if (m_impl != null) {               
+               m_component.setImplementation(m_impl);
+           } else {
+               Objects.nonNull(m_factory);
+               m_component.setFactory(m_factory, "create");
+               if (m_factoryHasComposite) {
+                   m_component.setComposition(m_factory, "getComposite");
+               }
+           }
+            
+           if (m_callbackMethodRefs.size() > 0) {
+        	   setLifecycleMethodRefs();
+           }            
+        }
+        
+        if (m_dependencyBuilders.size() > 0) {
+            // add atomically in case we are building some component dependencies from a component init method.
+            // We first transform the list of builders into a stream of built Dependencies, then we collect the result 
+            // to an array of Dependency[].
+            m_component.add(m_dependencyBuilders.stream().map(builder -> builder.build()).toArray(Dependency[]::new));
+        }
+        return m_component;
+    }
+
+    private <T> ComponentBuilderImpl setLifecyceMethodRef(String lifecycle,  BiConsumer<T, Component> callback) {
+        m_callbackMethodRefs.computeIfAbsent(lifecycle, l -> new ArrayList<>()).add(callback);
+        return this;
+    }
+
+    @SuppressWarnings("unused")
+    private void setLifecycleMethodRefs() {
+        Object cb = new Object() {
+            void init(Component comp) {
+                invokeLifecycleMethodRefs("init", comp);
+            }
+
+            void start(Component comp) {
+                invokeLifecycleMethodRefs("start", comp);
+            }
+
+            void stop(Component comp) {
+                invokeLifecycleMethodRefs("stop", comp);
+            }
+
+            void destroy(Component comp) {
+                invokeLifecycleMethodRefs("destroy", comp);
+            }
+        };
+        m_component.setCallbacks(cb, "init", "start", "stop", "destroy");
+    }
+
+    void invokeLifecycleMethodRefs(String lifecycle, Component component) {
+        m_callbackMethodRefs.computeIfPresent(lifecycle, (k, refs) -> {
+            refs.stream().forEach(ref -> ref.accept(component.getInstance(), component));
+            return refs;
+        });
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ConfigurationDependencyBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ConfigurationDependencyBuilderImpl.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ConfigurationDependencyBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ConfigurationDependencyBuilderImpl.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,104 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Dictionary;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ConfigurationDependency;
+import org.apache.felix.dm.builder.java.ConfigurationDependencyBuilder;
+import org.apache.felix.dm.context.ComponentContext;
+
+import net.jodah.typetools.TypeResolver;
+
+public class ConfigurationDependencyBuilderImpl  implements ConfigurationDependencyBuilder {
+    private String m_pid;
+    private boolean m_propagate;
+    private Consumer<Dictionary<String, Object>> m_updatedConsumers = (props -> {});
+    private boolean m_updatedConsumersSet;
+    private final Component m_component;
+    
+	/**
+	 * Mapping between component instances and corresponding "updated" method references.
+	 */
+	private final ConcurrentHashMap<Class<?>, BiConsumer<?, Dictionary<String, Object>>> m_componentInstanceCallbackRefs = new ConcurrentHashMap<>();
+
+    public ConfigurationDependencyBuilderImpl(Component component) {
+        m_component = component;
+    }
+
+    @Override
+    public ConfigurationDependencyBuilder pid(String pid) {
+        m_pid = pid;
+        return this;
+    }
+
+    @Override
+    public ConfigurationDependencyBuilder pid(Class<?> pidClass) {
+        m_pid = pidClass.getName();
+        return this;
+    }
+
+    @Override
+    public ConfigurationDependencyBuilder propagate() {
+        m_propagate = true;
+        return this;
+    }
+
+    @Override
+    public ConfigurationDependencyBuilder propagate(boolean propagate) {
+        m_propagate = propagate;
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationDependencyBuilder onUpdate(BiConsumer<T, Dictionary<String, Object>>  updatedRef) {
+        Class<?> instanceType = TypeResolver.resolveRawArguments(BiConsumer.class, updatedRef.getClass())[0];
+        m_componentInstanceCallbackRefs.put(instanceType, updatedRef);        
+        return this;
+    }
+
+    @Override
+    public ConfigurationDependencyBuilder onUpdate(Consumer<Dictionary<String, Object>> updatedConsumer) {
+        m_updatedConsumers = m_updatedConsumers.andThen(props -> updatedConsumer.accept(props));
+        m_updatedConsumersSet = true;
+        return null;
+    }
+
+    @Override
+    public ConfigurationDependency build() {
+        ConfigurationDependency dep = m_component.getDependencyManager().createConfigurationDependency();
+        Objects.nonNull(m_pid);
+        dep.setPid(m_pid);
+        dep.setPropagate(m_propagate);
+                
+        if (m_componentInstanceCallbackRefs.size() > 0) {
+        	// Some method refs have been added on some component instances. 
+            dep.setCallback(new Object() {
+                @SuppressWarnings({ "unused", "unchecked" })
+                void updated(Component comp, Dictionary<String, Object> props) {
+                	((ComponentContext) comp).instantiateComponent();
+            		Stream.of(comp.getInstances()).forEach(instance -> {
+            			BiConsumer<Object, Dictionary<String, Object>> updatedRef = (BiConsumer<Object, Dictionary<String, Object>>) m_componentInstanceCallbackRefs.get(instance.getClass());
+            			if (updatedRef != null) {
+            				updatedRef.accept(instance, props);
+            			}
+            		});
+            		m_updatedConsumers.accept(props);
+                }
+            }, "updated");
+        } else if (m_updatedConsumersSet) {
+        	// Some consumers have been configured, call them on any updated properties.
+        	dep.setCallback(new Object() {
+        		@SuppressWarnings("unused")
+        		void updated(Dictionary<String, Object> props) {
+        			m_updatedConsumers.accept(props);
+        		}
+        	}, "updated");
+        }        
+        return dep;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ExtendedComponentBase.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ExtendedComponentBase.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ExtendedComponentBase.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ExtendedComponentBase.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,144 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Dictionary;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.builder.java.ComponentBuilder;
+import org.apache.felix.dm.builder.java.ConfigurationDependencyBuilder;
+import org.apache.felix.dm.builder.java.ServiceDependencyBuilder;
+
+/**
+ * Methods common to extended components like adapters or aspects.
+ * Two things are provided to sub classes (to adapters/aspects):
+ * 
+ * 1) Dependency callback management (aspect and adapters API both contain service callbacks)
+ * 
+ * 2) This class also implements the ComponentBuilder interface. The ComponentBuilder implemented methods don't do anything, we just
+ *    keep track the list of called methods using a composition of Consumers of ComponentBuilder. This allows to easily 
+ *    cache the list of invoked ComponentBuilder methods, and then later, invoke the methods in one shot.
+ */
+@SuppressWarnings({"unchecked"})
+public abstract class ExtendedComponentBase<T, B extends ExtendedComponentBase<T, B>> extends ServiceCallbacksBuilderImpl<T, B> {
+	
+	/**
+	 * List of invoked ComponentBuilder methods.
+	 */
+    protected Consumer<ComponentBuilder<? extends ComponentBuilder<?>>> m_compBuilder = (componentBuilder -> {});
+
+    // ComponentBuilder methods: we are using Consumer.andThen that allows to maintain the chain of called methods (function composition).
+    
+    public B impl(Object impl) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.impl(impl));
+        return (B) this;
+    }
+    
+    public <U> B factory(Supplier<U> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.factory(create));
+        return (B) this;
+    }
+
+    public <U> B factory(Supplier<U> factory, Function<U, Object> create) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.factory(factory, create));
+        return (B) this;
+    }
+    
+    public <U> B factory(Supplier<U> factory, Supplier<Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.factory(factory, getComposition));
+        return (B) this;
+    }
+    
+    public <U> B factory(Supplier<U> factory, Function<U, Object> create, Function<U, Object[]> getComposition) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.factory(factory, create, getComposition));
+        return (B) this;
+    }
+    
+    public B provides(Class<?> ... ifaces) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.provides(ifaces));
+        return (B) this;
+    }
+
+    public B properties(Dictionary<?, ?> properties) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.properties(properties));
+        return (B) this;
+    }
+
+    public B properties(Object ... properties) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.properties(properties));
+        return (B) this;
+    }
+    
+    public <U> B withService(Class<U> service) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.withService(service));
+        return (B) this;
+    }
+
+    public <U> B withService(Class<U> service, Consumer<ServiceDependencyBuilder<U>> consumer) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.withService(service, consumer));
+        return (B) this;
+    }
+    
+    public B withConfiguration(Consumer<ConfigurationDependencyBuilder> consumer) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.withConfiguration(consumer));
+        return (B) this;
+    }
+    
+    public <U> B onInit(Consumer<U> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onInit(callback));
+        return (B) this;
+    }
+    
+    public <U> B onInit(BiConsumer<U, Component> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onInit(callback));
+        return (B) this;
+    }
+    
+    public <U> B onStart(Consumer<U> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onStart(callback));
+        return (B) this;
+    }
+    
+    public <U> B onStart(BiConsumer<U, Component> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onStart(callback));
+        return (B) this;
+    }
+    
+    public <U> B onStop(Consumer<U> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onStop(callback));
+        return (B) this;
+    }
+    
+    public <U> B onStop(BiConsumer<U, Component> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onStop(callback));
+        return (B) this;
+    }
+    
+    public <U> B onDestroy(Consumer<U> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onDestroy(callback));
+        return (B) this;
+    }
+    
+    public <U> B onDestroy(BiConsumer<U, Component> callback) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.onDestroy(callback));
+        return (B) this;
+    }
+    
+    public <U> B autoInject(Class<U> clazz, boolean autoConfig) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.autoInject(clazz, autoConfig));
+        return (B) this;
+    }
+    
+    public <U> B autoInject(Class<U> clazz, String field) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.autoInject(clazz, field));
+        return (B) this;
+    }
+    
+    public B debug(String label) {
+        m_compBuilder = m_compBuilder.andThen(compBuilder -> compBuilder.debug(label));
+        return (B) this;
+    }
+    
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/FactoryPidAdapterBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/FactoryPidAdapterBuilderImpl.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/FactoryPidAdapterBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/FactoryPidAdapterBuilderImpl.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,99 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Dictionary;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+import java.util.stream.Stream;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.builder.java.FactoryPidAdapterBuilder;
+
+import net.jodah.typetools.TypeResolver;
+
+public class FactoryPidAdapterBuilderImpl 
+	extends ExtendedComponentBase<Object, FactoryPidAdapterBuilderImpl> 
+	implements FactoryPidAdapterBuilder 
+{
+    protected final ConcurrentHashMap<Class<?>, BiConsumer<?, Dictionary<String, Object>>> m_callbacks = new ConcurrentHashMap<>();
+    private String m_factoryPid;
+    private boolean m_propagate;
+    private final DependencyManager m_dm;
+    private boolean m_autoAdd = true;
+
+    public FactoryPidAdapterBuilderImpl(DependencyManager dm) {
+        m_dm = dm;
+    }
+
+    @Override
+    public FactoryPidAdapterBuilderImpl autoAdd(boolean autoAdd) {
+        m_autoAdd = autoAdd;
+        return this;
+    }
+    
+    public boolean autoAdd() {
+    	return m_autoAdd;
+    }
+    
+    @Override
+    public FactoryPidAdapterBuilder factoryPid(String pid) {
+        m_factoryPid = pid;
+        return this;
+    }
+
+    @Override
+    public FactoryPidAdapterBuilder factoryPid(Class<?> pidClass) {
+        m_factoryPid = pidClass.getName();
+        return this;
+    }
+
+    @Override
+    public FactoryPidAdapterBuilder propagate() {
+        m_propagate = true;
+        return this;
+    }
+
+    @Override
+    public FactoryPidAdapterBuilder propagate(boolean propagate) {
+        m_propagate = propagate;
+        return this;
+    }
+
+    @Override
+    public <T> FactoryPidAdapterBuilder onUpdate(BiConsumer<T, Dictionary<String, Object>> callback) {
+        Class<?> instanceType = TypeResolver.resolveRawArguments(BiConsumer.class, callback.getClass())[0];
+        setUpdateRef(instanceType, (T instance, Dictionary<String, Object> conf) -> callback.accept(instance, conf));
+        return this;
+    }
+
+    @Override
+    public Component build() {        
+        Objects.nonNull(m_factoryPid);
+        if (m_callbacks.size() == 0) {
+            throw new IllegalStateException("No callbacks configured in factory pid adapter");
+        }
+        Object wrapCallback = new Object() {
+            @SuppressWarnings({ "unused", "unchecked" })
+            public void updated(Component comp, Dictionary<String, Object> conf) {
+                Stream.of(comp.getInstances()).forEach(instance -> {
+                    BiConsumer<Object, Dictionary<String, Object>> updateCB = 
+                        (BiConsumer<Object, Dictionary<String, Object>>) m_callbacks.get(instance.getClass());
+                    if (updateCB != null) {
+                        updateCB.accept(instance, conf);
+                    }
+                });            
+ 
+            }
+        };
+        Component c = m_dm.createFactoryConfigurationAdapterService(m_factoryPid, "updated", m_propagate, wrapCallback);
+        ComponentBuilderImpl cb = new ComponentBuilderImpl(c, false);
+        m_compBuilder.accept (cb);
+        return cb.build();
+    }
+
+    public <T> FactoryPidAdapterBuilder setUpdateRef(Class<?> instanceType, BiConsumer<T, Dictionary<String, Object>> updateCB) {
+        m_callbacks.put(instanceType, updateCB);
+        return this;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsDictionary.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsDictionary.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsDictionary.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsDictionary.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,94 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Maps a ServiceReference to a Dictionary.
+ */
+public class SRefAsDictionary extends Dictionary<String, Object> {
+    private final ServiceReference<?> m_ref;
+    private volatile int m_size = -1;
+
+    public SRefAsDictionary(ServiceReference<?> ref) {
+        m_ref = ref;
+    }
+    
+    @Override
+    public Object get(Object key) {
+        return m_ref.getProperty(key.toString());
+    }
+    
+    @Override
+    public int size() {
+        return m_size != -1 ? m_size : (m_size = m_ref.getPropertyKeys().length);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    @Override
+    public Enumeration<String> keys() {
+        return Collections.enumeration(Arrays.asList(m_ref.getPropertyKeys())); 
+    }
+
+    @Override
+    public Enumeration<Object> elements() {
+        final String[] keys = m_ref.getPropertyKeys();
+        
+        return new Enumeration<Object>() {
+            int m_index = 0;
+            
+            @Override
+            public boolean hasMoreElements() {
+                return m_index < keys.length;
+            }
+
+            @Override
+            public Object nextElement() {
+                if (m_index >= keys.length) {
+                    throw new NoSuchElementException();
+                }
+                return m_ref.getProperty(keys[m_index ++]);
+            }
+        };
+    }
+
+    @Override
+    public Object remove(Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Object put(String key, Object value) {
+        throw new UnsupportedOperationException();
+    }
+    
+    public String toString() {
+        int max = size() - 1;
+        if (max == -1)
+            return "{}";
+
+        StringBuilder sb = new StringBuilder();
+        String[] keys = m_ref.getPropertyKeys();
+        sb.append('{');
+        for (int i = 0; ; i++) {
+            String key = keys[i];
+            Object value = m_ref.getProperty(key);
+            sb.append(key);
+            sb.append('=');
+            sb.append(value == this ? "(this Dictionary)" : value.toString());
+
+            if (i == max)
+                return sb.append('}').toString();
+            sb.append(", ");
+        }
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsMap.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsMap.java?rev=1714132&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsMap.java (added)
+++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/SRefAsMap.java Thu Nov 12 22:26:29 2015
@@ -0,0 +1,84 @@
+package org.apache.felix.dm.builder.java.impl;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Maps a ServiceReference to a Map.
+ */
+public class SRefAsMap extends AbstractMap<String, Object> {
+    private final ServiceReference<?> m_ref;
+
+    public SRefAsMap(ServiceReference<?> ref) {
+        m_ref = ref;
+    }
+    
+    public Object get(Object key) {
+        return m_ref.getProperty(key.toString());
+    }
+
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        return new AbstractSet<Entry<String, Object>>() {
+            @Override
+            public Iterator<Entry<String, Object>> iterator() {
+                final Enumeration<String> e = Collections.enumeration(Arrays.asList(m_ref.getPropertyKeys()));
+                
+                return new Iterator<Entry<String, Object>>() {
+                    private String key;
+
+                    public boolean hasNext() {
+                        return e.hasMoreElements();
+                    }
+
+                    public Entry<String, Object> next() {
+                        key = e.nextElement();
+                        return new KeyEntry(key);
+                    }
+
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+
+            @Override
+            public int size() {
+                return m_ref.getPropertyKeys().length;
+            }
+        };
+    }
+
+    @Override
+    public Object put(String key, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    class KeyEntry implements Map.Entry<String, Object> {
+        private final String key;
+
+        KeyEntry(String key) {
+            this.key = key;
+        }
+
+        public String getKey() {
+            return key;
+        }
+
+        public Object getValue() {
+            return m_ref.getProperty(key);
+        }
+
+        public Object setValue(Object value) {
+            return SRefAsMap.this.put(key, value);
+        }
+    }
+}