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 2016/01/28 00:27:36 UTC
svn commit: r1727214 [6/6] - in
/felix/sandbox/pderop/dependencymanager-lambda:
org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/builder/lambda/itest/
org.apache.felix.dependencymanager.lambda.samples/src/org/apache/felix/depende...
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceCallbacksBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceCallbacksBuilderImpl.java?rev=1727214&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceCallbacksBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceCallbacksBuilderImpl.java Wed Jan 27 23:27:34 2016
@@ -0,0 +1,626 @@
+package org.apache.felix.dm.lambda.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.lambda.callbacks.CbComponent;
+import org.apache.felix.dm.lambda.callbacks.CbComponentRef;
+import org.apache.felix.dm.lambda.callbacks.CbComponentRefService;
+import org.apache.felix.dm.lambda.callbacks.CbComponentRefServiceRefService;
+import org.apache.felix.dm.lambda.callbacks.CbComponentService;
+import org.apache.felix.dm.lambda.callbacks.CbComponentServiceService;
+import org.apache.felix.dm.lambda.callbacks.CbRef;
+import org.apache.felix.dm.lambda.callbacks.CbRefService;
+import org.apache.felix.dm.lambda.callbacks.CbRefServiceRefService;
+import org.apache.felix.dm.lambda.callbacks.CbService;
+import org.apache.felix.dm.lambda.callbacks.CbServiceDict;
+import org.apache.felix.dm.lambda.callbacks.CbServiceMap;
+import org.apache.felix.dm.lambda.callbacks.CbServiceService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponent;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponentRef;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponentRefService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponentRefServiceRefService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponentService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeComponentServiceService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeRef;
+import org.apache.felix.dm.lambda.callbacks.CbTypeRefService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeRefServiceRefService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeService;
+import org.apache.felix.dm.lambda.callbacks.CbTypeServiceDict;
+import org.apache.felix.dm.lambda.callbacks.CbTypeServiceMap;
+import org.apache.felix.dm.lambda.callbacks.CbTypeServiceService;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Dependency Callbacks management.
+ *
+ * @param <S> the type of the service dependency
+ * @param <T> the type of the implementation class on which the dependency can be applied (using method references).
+ * @param <B> the type of the sub-classes which may extend this class
+ */
+@SuppressWarnings({"unchecked", "unused"})
+public abstract class ServiceCallbacksBuilderImpl<S, B extends ServiceCallbacksBuilderImpl<S, B>> {
+ protected boolean m_autoConfig = true;
+ protected boolean m_autoConfigInvoked = false;
+ protected String m_autoConfigField;
+ protected Object m_callbackInstance;
+ protected String m_added;
+ protected String m_changed;
+ protected String m_removed;
+ protected String m_swapped;
+ protected final Class<S> m_serviceClass;
+
+ enum Cb {
+ ADD,
+ CHG,
+ REM
+ };
+
+ /**
+ * List of service (add/change/remove) callbacks.
+ */
+ protected final Map<Cb, List<MethodRef<Object, S>>> m_refs = new HashMap<>();
+
+ /**
+ * List of swap callbacks
+ */
+ protected final List<SwapMethodRef<?, S>> m_swapRefs = new ArrayList<>();
+
+ /**
+ * This interface (lambda) is called when we want to invoke a method reference. the lambda is called with all necessary service dependency
+ * informations.
+ *
+ * When the lambda is called, it will invoke the proper callback on the given component instance.
+ *
+ * @param <I> type of a component instance
+ * @param <T> service dependency type
+ */
+ @FunctionalInterface
+ interface MethodRef<I, S> {
+ public void accept(I instance, Component c, ServiceReference<S> ref, S service);
+ }
+
+ /**
+ * This interface (lambda) is called when we want to invoke a swap method reference. the lambda is called with all necessary swap info.
+ * When the lambda is called, it will invoke the proper swap callback on the given component instance.
+ *
+ * @param <I> type of a component instance
+ * @param <T> service dependency type
+ */
+ @FunctionalInterface
+ interface SwapMethodRef<I, S> {
+ public void accept(I instance, Component c, ServiceReference<S> oldRef, S oldService, ServiceReference<S> newRef, S newService);
+ }
+
+ public ServiceCallbacksBuilderImpl(Class<S> serviceClass) {
+ m_serviceClass = serviceClass;
+ }
+
+ public B autoConfig() {
+ autoConfig(true);
+ return (B) this;
+ }
+
+ public B autoConfig(String field) {
+ m_autoConfigField = field;
+ m_autoConfigInvoked = true;
+ return (B) this;
+ }
+
+ public B autoConfig(boolean autoConfig) {
+ m_autoConfig = autoConfig;
+ m_autoConfigInvoked = true;
+ return (B) this;
+ }
+
+ public B cb(String ... callbacks) {
+ return cbi(null, callbacks);
+ }
+
+ public B cbi(Object callbackInstance, String ... callbacks) {
+ Objects.nonNull(callbacks);
+ switch (callbacks.length) {
+ case 1:
+ cb(callbackInstance, callbacks[0], null, null, null);
+ break;
+
+ case 2:
+ cb(callbackInstance, callbacks[0], null, callbacks[1], null);
+ break;
+
+ case 3:
+ cb(callbackInstance, callbacks[0], callbacks[1], callbacks[2], null);
+ break;
+
+ case 4:
+ cb(callbackInstance, callbacks[0], callbacks[1], callbacks[2], callbacks[3]);
+ break;
+
+ default:
+ throw new IllegalArgumentException("wrong number of arguments: " + callbacks.length + ". " +
+ "Possible arguments: [add], [add, remove], [add, change, remove], or [add, change, remove, swap]");
+ }
+ return (B) this;
+ }
+
+ private B cb(Object callbackInstance, String added, String changed, String removed, String swapped) {
+ requiresNoMethodRefs();
+ m_callbackInstance = callbackInstance;
+ m_added = added != null ? added : m_added;
+ m_changed = changed != null ? changed : m_changed;
+ m_removed = removed != null ? removed : m_removed;
+ m_swapped = swapped != null ? swapped : m_swapped;
+ if (! m_autoConfigInvoked) m_autoConfig = false;
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeService<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeService<T, S> add, CbTypeService<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeService<T, S> add, CbTypeService<T, S> change, CbTypeService<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, srv));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, srv));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, srv));
+ return (B) this;
+ }
+
+ public B cbi(CbService<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbService<S> add, CbService<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbService<S> add, CbService<S> change, CbService<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(srv));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(srv));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(srv));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeServiceMap<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeServiceMap<T, S> add, CbTypeServiceMap<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeServiceMap<T, S> add, CbTypeServiceMap<T, S> change, CbTypeServiceMap<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, srv, new SRefAsMap(ref)));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, srv, new SRefAsMap(ref)));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, srv, new SRefAsMap(ref)));
+ return (B) this;
+ }
+
+ public B cbi(CbServiceMap<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbServiceMap<S> add, CbServiceMap<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbServiceMap<S> add, CbServiceMap<S> change, CbServiceMap<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(srv, new SRefAsMap(ref)));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(srv, new SRefAsMap(ref)));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(srv, new SRefAsMap(ref)));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeServiceDict<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeServiceDict<T, S> add, CbTypeServiceDict<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeServiceDict<T, S> add, CbTypeServiceDict<T, S> change, CbTypeServiceDict<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, srv, new SRefAsDictionary(ref)));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, srv, new SRefAsDictionary(ref)));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, srv, new SRefAsDictionary(ref)));
+ return (B) this;
+ }
+
+ public B cbi(CbServiceDict<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbServiceDict<S> add, CbServiceDict<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbServiceDict<S> add, CbServiceDict<S> change, CbServiceDict<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(srv, new SRefAsDictionary(ref)));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(srv, new SRefAsDictionary(ref)));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(srv, new SRefAsDictionary(ref)));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeRefService<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeRefService<T, S> add, CbTypeRefService<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeRefService<T, S> add, CbTypeRefService<T, S> change, CbTypeRefService<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, ref, srv));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, ref, srv));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, ref, srv));
+ return (B) this;
+ }
+
+ public B cbi(CbRefService<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbRefService<S> add, CbRefService<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbRefService<S> add, CbRefService<S> change, CbRefService<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(ref, srv));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(ref, srv));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(ref, srv));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeRef<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeRef<T, S> add, CbTypeRef<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeRef<T, S> add, CbTypeRef<T, S> change, CbTypeRef<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, ref));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, ref));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, ref));
+ return (B) this;
+ }
+
+ public B cbi(CbRef<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbRef<S> add, CbRef<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbRef<S> add, CbRef<S> change, CbRef<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(ref));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(ref));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(ref));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeComponent<T> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeComponent<T> add, CbTypeComponent<T> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeComponent<T> add, CbTypeComponent<T> change, CbTypeComponent<T> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, comp));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, comp));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, comp));
+ return (B) this;
+ }
+
+ public B cbi(CbComponent add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbComponent add, CbComponent remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbComponent add, CbComponent change, CbComponent remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(comp));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(comp));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(comp));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeComponentRef<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeComponentRef<T, S> add, CbTypeComponentRef<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeComponentRef<T, S> add, CbTypeComponentRef<T, S> change, CbTypeComponentRef<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, comp, ref));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, comp, ref));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, comp, ref));
+ return (B) this;
+ }
+
+ public B cbi(CbComponentRef<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbComponentRef<S> add, CbComponentRef<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbComponentRef<S> add, CbComponentRef<S> change, CbComponentRef<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(comp, ref));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(comp, ref));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(comp, ref));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeComponentService<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeComponentService<T, S> add, CbTypeComponentService<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeComponentService<T, S> add, CbTypeComponentService<T, S> change, CbTypeComponentService<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, comp, srv));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, comp, srv));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, comp, srv));
+ return (B) this;
+ }
+
+ public B cbi(CbComponentService<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbComponentService<S> add, CbComponentService<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbComponentService<S> add, CbComponentService<S> change, CbComponentService<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(comp, srv));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(comp, srv));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(comp, srv));
+ return (B) this;
+ }
+
+ public <T> B cb(CbTypeComponentRefService<T, S> add) {
+ return cb(add, null, null);
+ }
+
+ public <T> B cb(CbTypeComponentRefService<T, S> add, CbTypeComponentRefService<T, S> remove) {
+ return cb(add, null, remove);
+ }
+
+ public <T> B cb(CbTypeComponentRefService<T, S> add, CbTypeComponentRefService<T, S> change, CbTypeComponentRefService<T, S> remove) {
+ if (add != null)
+ setComponentCallbackRef(Cb.ADD, Helpers.getLambdaArgType(add, 0), (inst, comp, ref, srv) -> add.accept((T) inst, comp, ref, srv));
+ if (change != null)
+ setComponentCallbackRef(Cb.CHG, Helpers.getLambdaArgType(change, 0), (inst, comp, ref, srv) -> change.accept((T) inst, comp, ref, srv));
+ if (remove != null)
+ setComponentCallbackRef(Cb.REM, Helpers.getLambdaArgType(remove, 0), (inst, comp, ref, srv) -> remove.accept((T) inst, comp, ref, srv));
+ return (B) this;
+ }
+
+ public B cbi(CbComponentRefService<S> add) {
+ return cbi(add, null, null);
+ }
+
+ public B cbi(CbComponentRefService<S> add, CbComponentRefService<S> remove) {
+ return cbi(add, null, remove);
+ }
+
+ public B cbi(CbComponentRefService<S> add, CbComponentRefService<S> change, CbComponentRefService<S> remove) {
+ if (add != null)
+ setInstanceCallbackRef(Cb.ADD, (inst, comp, ref, srv) -> add.accept(comp, ref, srv));
+ if (change != null)
+ setInstanceCallbackRef(Cb.CHG, (inst, comp, ref, srv) -> change.accept(comp, ref, srv));
+ if (remove != null)
+ setInstanceCallbackRef(Cb.REM, (inst, comp, ref, srv) -> remove.accept(comp, ref, srv));
+ return (B) this;
+ }
+
+ public <T> B sw(CbTypeServiceService<T, S> swap) {
+ Class<T> type = Helpers.getLambdaArgType(swap, 0);
+ return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) ->
+ swap.accept((T) inst, oserv, nserv));
+ }
+
+ public <T> B sw(CbTypeComponentServiceService<T, S> swap) {
+ Class<T> type = Helpers.getLambdaArgType(swap, 0);
+ return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) ->
+ swap.accept((T) inst, component, oserv, nserv));
+ }
+
+ public <T> B sw(CbTypeRefServiceRefService<T, S> swap) {
+ Class<T> type = Helpers.getLambdaArgType(swap, 0);
+ return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) ->
+ swap.accept((T) inst, oref, oserv, nref, nserv));
+ }
+
+ public <T> B sw(CbTypeComponentRefServiceRefService<T, S> swap) {
+ Class<T> type = Helpers.getLambdaArgType(swap, 0);
+ return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) ->
+ swap.accept((T) inst, component, oref, oserv, nref, nserv));
+ }
+
+ public B swi(CbServiceService<S> swap) {
+ return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(oserv, nserv));
+ }
+
+ public B swi(CbComponentServiceService<S> swap) {
+ return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(component, oserv, nserv));
+ }
+
+ public B swi(CbRefServiceRefService<S> swap) {
+ return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(oref, oserv, nref, nserv));
+ }
+
+ public B swi(CbComponentRefServiceRefService<S> swap) {
+ return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(component, oref, oserv, nref, nserv));
+ }
+
+ protected <I> B setComponentCallbackRef(Cb cbType, Class<I> type, MethodRef<I, S> ref) {
+ requiresNoCallbacks();
+ if (! m_autoConfigInvoked) m_autoConfig = false;
+ List<MethodRef<Object, S>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>());
+ list.add((instance, component, sref, service) -> {
+ Stream.of(component.getInstances()).forEach(inst -> {
+ if (Helpers.getClass(inst).equals(type)) {
+ ref.accept((I) inst, component, sref, service);
+ }
+ });
+ });
+ return (B) this;
+ }
+
+ protected <T> B setInstanceCallbackRef(Cb cbType, MethodRef<T, S> ref) {
+ requiresNoCallbacks();
+ if (! m_autoConfigInvoked) m_autoConfig = false;
+ List<MethodRef<Object, S>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>());
+ list.add((instance, component, sref, service) -> {
+ ref.accept((T) component.getInstance(), component, sref, service);
+ });
+ return (B) this;
+ }
+
+ public <I> B setComponentSwapCallbackRef(Class<I> type, SwapMethodRef<I, S> ref) {
+ requiresNoCallbacks();
+ if (! m_autoConfigInvoked) m_autoConfig = false;
+ m_swapRefs.add((instance, component, oref, oservice, nref, nservice) -> {
+ Stream.of(component.getInstances()).forEach(componentInstance -> {
+ if (Helpers.getClass(componentInstance).equals(type)) {
+ ref.accept((I) componentInstance, component, oref, oservice, nref, nservice);
+ }
+ });
+ });
+ return (B) this;
+ }
+
+ public <I> B setInstanceSwapCallbackRef(SwapMethodRef<I, S> ref) {
+ requiresNoCallbacks();
+ if (! m_autoConfigInvoked) m_autoConfig = false;
+ m_swapRefs.add((instance, component, oref, oservice, nref, nservice) -> {
+ ref.accept((I) component.getInstance(), component, oref, oservice, nref, nservice);
+ });
+ return (B) this;
+ }
+
+ protected Object createCallbackInstance() {
+ Object cb = null;
+
+ cb = new Object() {
+ void add(Component c, ServiceReference<S> ref, Object service) {
+ invokeMethodRefs(Cb.ADD, c, ref, (S) service);
+ }
+
+ void change(Component c, ServiceReference<S> ref, Object service) {
+ invokeMethodRefs(Cb.CHG, c, ref, (S) service);
+ }
+
+ void remove(Component c, ServiceReference<S> ref, Object service) {
+ invokeMethodRefs(Cb.REM, c, ref, (S) service);
+ }
+
+ void swap(Component c, ServiceReference<S> oldRef, Object oldSrv, ServiceReference<S> newRef, Object newSrv) {
+ invokeSwapMethodRefs(c, oldRef, (S) oldSrv, newRef, (S) newSrv);
+ }
+ };
+
+ return cb;
+ }
+
+ protected boolean hasRefs() {
+ return m_refs.size() > 0 || m_swapRefs.size() > 0;
+ }
+
+ protected boolean hasCallbacks() {
+ return m_callbackInstance != null || m_added != null || m_changed != null || m_removed != null || m_swapped != null;
+ }
+
+ private void invokeMethodRefs(Cb cbType, Component comp, ServiceReference<S> ref, S service) {
+ m_refs.computeIfPresent(cbType, (k, mrefs) -> {
+ mrefs.forEach(mref -> mref.accept(null, comp, ref, service));
+ return mrefs;
+ });
+ }
+
+ private void invokeSwapMethodRefs(Component c, ServiceReference<S> oref, S osrv, ServiceReference<S> nref, S nsrv) {
+ m_swapRefs.forEach(ref -> ref.accept(null, c, oref, osrv, nref, nsrv));
+ }
+
+ private void requiresNoCallbacks() {
+ if (hasCallbacks()) {
+ throw new IllegalStateException("can't mix method references and string callbacks.");
+ }
+ }
+
+ private void requiresNoMethodRefs() {
+ if (hasRefs()) {
+ throw new IllegalStateException("can't mix method references and string callbacks.");
+ }
+ }
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java?rev=1727214&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java Wed Jan 27 23:27:34 2016
@@ -0,0 +1,148 @@
+package org.apache.felix.dm.lambda.impl;
+
+import java.util.Dictionary;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.lambda.ServiceDependencyBuilder;
+import org.osgi.framework.ServiceReference;
+
+public class ServiceDependencyBuilderImpl<S> extends ServiceCallbacksBuilderImpl<S, ServiceDependencyBuilderImpl<S>> implements ServiceDependencyBuilder<S> {
+ private final Class<S> m_serviceIface;
+ private final Component m_component;
+ private String m_filter;
+ private ServiceReference<S> m_ref;
+ private boolean m_required = true;
+ private String m_debug;
+ private boolean m_propagate;
+ private Object m_propagateInstance;
+ private String m_propagateMethod;
+ private Object m_defaultImpl;
+ private long m_timeout = -1;
+
+ public ServiceDependencyBuilderImpl(Component component, Class<S> service) {
+ super(service);
+ m_serviceIface = service;
+ m_component = component;
+ }
+
+ public ServiceDependencyBuilder<S> filter(String filter) {
+ m_filter = filter;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> ref(ServiceReference<S> ref) {
+ m_ref = ref;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> optional() {
+ return required(false);
+ }
+
+ public ServiceDependencyBuilder<S> required() {
+ return required(true);
+ }
+
+ public ServiceDependencyBuilder<S> required(boolean required) {
+ m_required = required;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> debug(String label) {
+ m_debug = label;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> propagate() {
+ return propagate(true);
+ }
+
+ public ServiceDependencyBuilder<S> propagate(boolean propagate) {
+ m_propagate = propagate;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> propagate(Object instance, String method) {
+ m_propagateInstance = instance;
+ m_propagateMethod = method;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> propagate(Function<ServiceReference<S>, Dictionary<String, Object>> propagate) {
+ Object wrappedCallback = new Object() {
+ @SuppressWarnings("unused")
+ Dictionary<String, Object> propagate(ServiceReference<S> ref) {
+ return propagate.apply(ref);
+ }
+ };
+ propagate(wrappedCallback, "propagate");
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> propagate(BiFunction<ServiceReference<S>, S, Dictionary<String, Object>> propagate) {
+ Object wrappedCallback = new Object() {
+ @SuppressWarnings("unused")
+ Dictionary<String, Object> propagate(ServiceReference<S> ref, S service) {
+ return propagate.apply(ref, service);
+ }
+ };
+ propagate(wrappedCallback, "propagate");
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> defImpl(Object defaultImpl) {
+ m_defaultImpl = defaultImpl;
+ return this;
+ }
+
+ public ServiceDependencyBuilder<S> timeout(long timeout) {
+ m_timeout = timeout;
+ return this;
+ }
+
+ // Build final ServiceDependency object.
+ @Override
+ public ServiceDependency build() {
+ DependencyManager dm = m_component.getDependencyManager();
+ if (m_ref != null && m_filter != null) {
+ throw new IllegalArgumentException("Can not set ref and filter at the same time");
+ }
+ ServiceDependency sd = m_timeout > -1 ? dm.createTemporalServiceDependency(m_timeout) : dm.createServiceDependency();
+ if (m_ref != null) {
+ sd.setService(m_serviceIface, m_ref);
+ } else {
+ sd.setService(m_serviceIface, m_filter);
+ }
+ sd.setRequired(m_required);
+ sd.setDefaultImplementation(m_defaultImpl);
+ if (m_debug != null) {
+ sd.setDebug(m_debug);
+ }
+ if (m_propagate) {
+ sd.setPropagate(true);
+ } else if (m_propagateInstance != null) {
+ if (m_propagateMethod == null) {
+ throw new IllegalArgumentException("propagate instance can't be null");
+ }
+ sd.setPropagate(m_propagateInstance, m_propagateMethod);
+ }
+ if (hasCallbacks()) {
+ sd.setCallbacks(m_callbackInstance, m_added, m_changed, m_removed, m_swapped);
+ } else if (hasRefs()) {
+ Object cb = createCallbackInstance();
+ sd.setCallbacks(cb, "add", "change", "remove", m_swapRefs.size() > 0 ? "swap" : null);
+ }
+
+ if (m_autoConfigField != null) {
+ sd.setAutoConfig(m_autoConfigField);
+ } else {
+ sd.setAutoConfig(m_autoConfig);
+ }
+ return sd;
+ }
+
+}
Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/packageinfo
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/packageinfo?rev=1727214&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/packageinfo (added)
+++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/packageinfo Wed Jan 27 23:27:34 2016
@@ -0,0 +1 @@
+version 1.0.0
\ No newline at end of file