Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java?rev=1725147&r1=1725146&r2=1725147&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ComponentBuilderImpl.java Sun Jan 17 23:38:55 2016 @@ -9,7 +9,6 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -27,7 +26,6 @@ import org.apache.felix.dm.builder.lambd import org.apache.felix.dm.builder.lambda.Functions.CbComponent; import org.apache.felix.dm.builder.lambda.Functions.CbConsumer; import org.apache.felix.dm.builder.lambda.Functions.FluentProperties; -import org.apache.felix.dm.builder.lambda.impl.ServiceCallbacksBuilderImpl.MethodRef; import org.apache.felix.dm.builder.lambda.FutureDependencyBuilder; import org.apache.felix.dm.builder.lambda.ServiceDependencyBuilder; @@ -43,7 +41,15 @@ public class ComponentBuilderImpl implem private boolean m_autoAdd = true; protected final Map<Cb, List<MethodRef<Object>>> m_refs = new HashMap<>(); private Object m_compositionInstance; - private String m_compositionMethod; + private String m_compositionMethod; + private String m_init; + private String m_stop; + private String m_start; + private String m_destroy; + private Object m_callbackInstance; + private String m_factoryCreateMethod; + private boolean m_hasFactoryRef; + private boolean m_hasFactory; @FunctionalInterface interface MethodRef<I> { @@ -254,8 +260,24 @@ public class ComponentBuilderImpl implem } @Override + public ComponentBuilderImpl factory(Object factory, String createMethod) { + m_factory = factory; + m_factoryCreateMethod = createMethod; + ensureHasNoFactoryRef(); + m_hasFactory = true; + return this; + } + + @Override + public ComponentBuilderImpl factory(String createMethod) { + return factory(null, createMethod); + } + + @Override public <U> ComponentBuilderImpl factory(Supplier<U> create) { Objects.nonNull(create); + ensureHasNoFactory(); + m_hasFactoryRef = true; m_factory = new Object() { @SuppressWarnings("unused") public Object create() { @@ -269,7 +291,9 @@ public class ComponentBuilderImpl implem public <U, V> ComponentBuilderImpl factory(Supplier<U> supplier, Function<U, V> create) { Objects.nonNull(supplier); Objects.nonNull(create); - + ensureHasNoFactory(); + m_hasFactoryRef = true; + m_factory = new Object() { @SuppressWarnings("unused") public Object create() { @@ -284,7 +308,9 @@ public class ComponentBuilderImpl implem public <U> ComponentBuilderImpl factory(Supplier<U> create, Supplier<Object[]> getComposite) { Objects.nonNull(create); Objects.nonNull(getComposite); - + ensureHasNoFactory(); + m_hasFactoryRef = true; + m_factory = new Object() { @SuppressWarnings("unused") public Object create() { // Create Factory instance @@ -305,6 +331,8 @@ public class ComponentBuilderImpl implem Objects.nonNull(factorySupplier); Objects.nonNull(factoryCreate); Objects.nonNull(factoryGetComposite); + ensureHasNoFactory(); + m_hasFactoryRef = true; m_factory = new Object() { U m_factoryInstance; @@ -336,6 +364,7 @@ public class ComponentBuilderImpl implem public ComponentBuilderImpl composition(Supplier<Object[]> getCompositionMethod) { m_compositionInstance = new Object() { + @SuppressWarnings("unused") public Object[] getComposition() { return getCompositionMethod.get(); } @@ -345,6 +374,11 @@ public class ComponentBuilderImpl implem } @Override + public ComponentBuilderImpl withService(Class<?> service, String filter) { + return withService(service, srv->srv.filter(filter)); + } + + @Override public ComponentBuilderImpl withService(Class<?> service, Class<?> ... services) { doWithService(service); for (Class<?> s : services) { @@ -389,6 +423,20 @@ public class ComponentBuilderImpl implem m_dependencyBuilders.add(dep); return this; } + + public ComponentBuilderImpl cb(String init, String start, String stop, String destroy) { + ensureHasNoLifecycleMethodRefs(); + m_init = init; + m_start = start; + m_stop = stop; + m_destroy = destroy; + return this; + } + + public ComponentBuilderImpl cb(Object callbackInstance, String init, String start, String stop, String destroy) { + m_callbackInstance = callbackInstance; + return cb(init, start, stop, destroy); + } @Override public <U> ComponentBuilderImpl cb(Cb callbackType, CbConsumer<U> callback) { @@ -427,15 +475,21 @@ public class ComponentBuilderImpl implem m_component.setComposition(m_compositionInstance, m_compositionMethod); } else { Objects.nonNull(m_factory); - m_component.setFactory(m_factory, "create"); - if (m_factoryHasComposite) { - m_component.setComposition(m_factory, "getComposite"); + if (m_hasFactoryRef) { + m_component.setFactory(m_factory, "create"); + if (m_factoryHasComposite) { + m_component.setComposition(m_factory, "getComposite"); + } + } else { + m_component.setFactory(m_factory, m_factoryCreateMethod); } } if (m_refs.size() > 0) { setLifecycleMethodRefs(); - } + } else if (hasLifecleMethods()) { + m_component.setCallbacks(m_callbackInstance, m_init, m_start, m_stop, m_destroy); + } } if (m_dependencyBuilders.size() > 0) { @@ -447,7 +501,28 @@ public class ComponentBuilderImpl implem return m_component; } + private boolean hasLifecleMethods() { + return m_init != null || m_start != null || m_stop != null || m_destroy != null; + } + + private boolean hasLifecleMethodRefs() { + return m_refs.size() > 0; + } + + private void ensureHasNoLifecycleMethods() { + if (hasLifecleMethods()) { + throw new IllegalStateException("Can't mix method references and name names for lifecycle callbacks"); + } + } + + private void ensureHasNoLifecycleMethodRefs() { + if (hasLifecleMethodRefs()) { + throw new IllegalStateException("Can't mix method references and name names for lifecycle callbacks"); + } + } + protected <U> ComponentBuilderImpl setInstanceCallbackRef(Cb cbType, MethodRef<U> ref) { + ensureHasNoLifecycleMethods(); cbType.ensureLifecyleCallback(); List<MethodRef<Object>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>()); list.add((instance, component) -> { @@ -457,6 +532,7 @@ public class ComponentBuilderImpl implem } private <U> ComponentBuilderImpl setComponentCallbackRef(Cb cbType, Class<U> type, MethodRef<U> callback) { + ensureHasNoLifecycleMethods(); cbType.ensureLifecyleCallback(); List<MethodRef<Object>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>()); list.add((instance, component) -> { @@ -498,4 +574,15 @@ public class ComponentBuilderImpl implem }); } + private void ensureHasNoFactoryRef() { + if (m_hasFactoryRef) { + throw new IllegalStateException("Can't mix factory method name and factory method reference"); + } + } + + private void ensureHasNoFactory() { + if (m_hasFactory) { + throw new IllegalStateException("Can't mix factory method name and factory method reference"); + } + } }
Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java?rev=1725147&r1=1725146&r2=1725147&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ConfigurationDependencyBuilderImpl.java Sun Jan 17 23:38:55 2016 @@ -23,6 +23,8 @@ public class ConfigurationDependencyBuil private boolean m_hasMethodRefs; private boolean m_hasReflectionCallback; private final List<MethodRef<Object>> m_refs = new ArrayList<>(); + private boolean m_hasComponentCallbackRefs; + private boolean m_needsInstance = false; @FunctionalInterface interface MethodRef<I> { @@ -70,6 +72,11 @@ public class ConfigurationDependencyBuil return this; } + public ConfigurationDependencyBuilder needsInstance(boolean needsInstance) { + m_needsInstance = needsInstance; + return this; + } + @Override public <T> ConfigurationDependencyBuilder cb(CbTypeDictionary<T> callback) { Class<T> type = Helpers.getLambdaGenericType(callback, 0); @@ -99,14 +106,22 @@ public class ConfigurationDependencyBuil dep.setPid(m_pid); dep.setPropagate(m_propagate); if (m_updateMethodName != null) { - dep.setCallback(m_updateCallbackInstance, m_updateMethodName); - } else { + if (m_updateCallbackInstance != null) { + dep.setCallback(m_updateCallbackInstance, m_updateMethodName, m_needsInstance); + } else { + dep.setCallback(m_updateMethodName); + } + } else if (m_refs.size() > 0) { + // setup an internal callback object. When config is updated, we have to call each registered + // method references. + // Notice that we need the component to be instantiated in case there is a mref on one of the component instances (unbound method ref), or is used + // called "needsInstance(true)". dep.setCallback(new Object() { @SuppressWarnings("unused") void updated(Component comp, Dictionary<String, Object> props) { m_refs.forEach(mref -> mref.accept(null, comp, props)); } - }, "updated", true /* we need component instances before updated is called */); + }, "updated", m_hasComponentCallbackRefs||m_needsInstance); } return dep; } @@ -122,6 +137,7 @@ public class ConfigurationDependencyBuil private <T> ConfigurationDependencyBuilder setComponentCallbackRef(Class<T> type, MethodRef<T> ref) { checkHasNoReflectionCallbacks(); m_hasMethodRefs = true; + m_hasComponentCallbackRefs = true; m_refs.add((instance, component, props) -> { Stream.of(component.getInstances()).forEach(inst -> { if (Helpers.getClass(inst).equals(type)) { Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/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/builder/lambda/impl/ServiceCallbacksBuilderImpl.java?rev=1725147&r1=1725146&r2=1725147&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceCallbacksBuilderImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceCallbacksBuilderImpl.java Sun Jan 17 23:38:55 2016 @@ -9,11 +9,15 @@ import java.util.stream.Stream; import org.apache.felix.dm.Component; import org.apache.felix.dm.builder.lambda.Cb; import org.apache.felix.dm.builder.lambda.Functions.CbComponent; +import org.apache.felix.dm.builder.lambda.Functions.CbComponentDictServiceDictService; +import org.apache.felix.dm.builder.lambda.Functions.CbComponentMapServiceMapService; import org.apache.felix.dm.builder.lambda.Functions.CbComponentRef; import org.apache.felix.dm.builder.lambda.Functions.CbComponentRefService; +import org.apache.felix.dm.builder.lambda.Functions.CbComponentRefServiceRefService; import org.apache.felix.dm.builder.lambda.Functions.CbComponentService; import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceDict; import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceMap; +import org.apache.felix.dm.builder.lambda.Functions.CbComponentServiceService; import org.apache.felix.dm.builder.lambda.Functions.CbDictServiceDictService; import org.apache.felix.dm.builder.lambda.Functions.CbMapServiceMapService; import org.apache.felix.dm.builder.lambda.Functions.CbRef; @@ -26,9 +30,11 @@ import org.apache.felix.dm.builder.lambd import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponent; import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRef; import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRefService; +import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentRefServiceRefService; import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentService; import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceDict; import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceMap; +import org.apache.felix.dm.builder.lambda.Functions.CbTypeComponentServiceService; import org.apache.felix.dm.builder.lambda.Functions.CbTypeDictServiceDictService; import org.apache.felix.dm.builder.lambda.Functions.CbTypeMapServiceMapService; import org.apache.felix.dm.builder.lambda.Functions.CbTypeRef; @@ -272,12 +278,24 @@ public abstract class ServiceCallbacksBu swap.accept((T) inst, oserv, nserv)); } + public <T> B sw(CbTypeComponentServiceService<T, S> swap) { + Class<T> type = Helpers.getLambdaGenericType(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.getLambdaGenericType(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.getLambdaGenericType(swap, 0); + return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) -> + swap.accept((T) inst, component, oref, oserv, nref, nserv)); + } + public <T> B sw(CbTypeMapServiceMapService<T, S> swap) { Class<T> type = Helpers.getLambdaGenericType(swap, 0); return setComponentSwapCallbackRef(type, (inst, component, oref, oserv, nref, nserv) -> @@ -294,20 +312,38 @@ public abstract class ServiceCallbacksBu 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)); + } + public B swi(CbMapServiceMapService<S> swap) { return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(new SRefAsMap(oref), oserv, new SRefAsMap(nref), nserv)); } + public B swi(CbComponentMapServiceMapService<S> swap) { + return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> + swap.accept(component, new SRefAsMap(oref), oserv, new SRefAsMap(nref), nserv)); + } + public B swi(CbDictServiceDictService<S> swap) { return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> swap.accept(new SRefAsDictionary(oref), oserv, new SRefAsDictionary(nref), nserv)); } + public B swi(CbComponentDictServiceDictService<S> swap) { + return setInstanceSwapCallbackRef((inst, component, oref, oserv, nref, nserv) -> + swap.accept(component, new SRefAsDictionary(oref), oserv, new SRefAsDictionary(nref), nserv)); + } + protected <I> B setComponentCallbackRef(Cb cbType, Class<I> type, MethodRef<I, S> ref) { cbType.ensureServiceCallback(); requiresNoCallbacks(); Modified: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/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/builder/lambda/impl/ServiceDependencyBuilderImpl.java?rev=1725147&r1=1725146&r2=1725147&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java Sun Jan 17 23:38:55 2016 @@ -38,6 +38,10 @@ public class ServiceDependencyBuilderImp return this; } + public ServiceDependencyBuilder<S> optional() { + return required(false); + } + public ServiceDependencyBuilder<S> required() { return required(true); }
