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);
+ }
+ }
+}