Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceDependencyBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceDependencyBuilder.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceDependencyBuilder.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/ServiceDependencyBuilder.java Sun Feb 28 19:11:09 2016 @@ -27,8 +27,6 @@ import org.osgi.framework.ServiceReferen /** * Builds a Dependency Manager Service Dependency. - * <p> When a service dependency is not explicitly defined as "required" or "optional", then it is assumed to be required by default. - * * <p> Sample code: * * <pre> {@code @@ -36,11 +34,13 @@ import org.osgi.framework.ServiceReferen * public void init(BundleContext ctx, DependencyManager dm) throws Exception { * component(comp -> comp * .impl(Pojo.class) - * .withSrv(ConfigurationAdmin.class, "(vendor=apache)") // required service with a filter, injected in class field - * .withSrv(Coordinator.class, LogService.class) // varargs of required dependencies injected on class fields - * .withSrv(HttpService.class, svc -> srv.add(Pojo::setHttpService)) // required dependency injected using a method ref - * .withSrv(ConnectorService.class, svc -> svc.optional()) // optional dependency, injected in class field with a NullObject if unavailable (before start() callback). - * .withSrv(Tracked.class, srv -> srv.optional().add(Pojo::addTracked)) // optional dependency, injected using method ref, after the start() callback + * .withSvc(ConfigurationAdmin.class, LogService.class) // varargs of optional (possibly NullObjects) dependencies injected in compatible class fields + * .withSvc(true, Coordinator.class, LogService.class) // varargs of required dependencies injected in compatible class fields + * .withSvc(ConfigurationAdmin.class, "(vendor=apache)") // service with a filter, injected in compatible class fields + * .withSvc(ConfigurationAdmin.class, "(vendor=apache)", true) // required service with a filter, injected in compatible class fields + * .withSvc(ConfigurationAdmin.class, "(vendor=apache)", true, "field") // required service with a filter, injected in a given class field name + * .withSvc(HttpService.class, svc -> svc.required().add(Pojo::setHttpService)) // required dependency injected using a method reference + * .withSvc(Tracked.class, svc -> svc.optional().add(Pojo::addTracked)) // optional dependency, injected using method ref, after the start() callback * } * }}</pre> *
Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/CbService.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/CbService.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/CbService.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/CbService.java Sun Feb 28 19:11:09 2016 @@ -35,7 +35,7 @@ public interface CbService<T, S> extends */ void accept(T instance, S service); - default CbFuture<T, S> andThen(CbFuture<? super T, S> after) { + default CbService<T, S> andThen(CbService<? super T, S> after) { Objects.requireNonNull(after); return (T instance, S service) -> { accept(instance, service); Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/InstanceCb.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/InstanceCb.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/InstanceCb.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/callbacks/InstanceCb.java Sun Feb 28 19:11:09 2016 @@ -30,13 +30,13 @@ public interface InstanceCb { /** * Implements the callback method. */ - void cb(); + void callback(); default InstanceCb andThen(InstanceCb after) { Objects.requireNonNull(after); return () -> { - cb(); - after.cb(); + callback(); + after.callback(); }; } } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/AdapterBase.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/AdapterBase.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/AdapterBase.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/AdapterBase.java Sun Feb 28 19:11:09 2016 @@ -30,8 +30,6 @@ import org.apache.felix.dm.lambda.Config import org.apache.felix.dm.lambda.FluentProperty; import org.apache.felix.dm.lambda.FutureDependencyBuilder; import org.apache.felix.dm.lambda.ServiceDependencyBuilder; -import org.apache.felix.dm.lambda.callbacks.Cb; -import org.apache.felix.dm.lambda.callbacks.CbComponent; import org.apache.felix.dm.lambda.callbacks.InstanceCb; import org.apache.felix.dm.lambda.callbacks.InstanceCbComponent; @@ -175,16 +173,6 @@ public interface AdapterBase<B extends C return (B) this; } - default B withSvc(Class<?> service, String filter) { - andThenBuild(compBuilder -> compBuilder.withSvc(service, filter)); - return (B) this; - } - - default B withSvc(Class<?> ... services) { - andThenBuild(compBuilder -> compBuilder.withSvc(services)); - return (B) this; - } - default <U> B withSvc(Class<U> service, Consumer<ServiceDependencyBuilder<U>> consumer) { andThenBuild(compBuilder -> compBuilder.withSvc(service, consumer)); return (B) this; @@ -204,109 +192,84 @@ public interface AdapterBase<B extends C andThenBuild(compBuilder -> compBuilder.withFuture(future, consumer)); return (B) this; } - - default B lifecycleCallbackInstance(Object lifecycleCallbackInstance) { - andThenBuild(compBuilder -> compBuilder.lifecycleCallbackInstance(lifecycleCallbackInstance)); - return (B) this; - } - + default B init(String callback) { andThenBuild(compBuilder -> compBuilder.init(callback)); return (B) this; } - default B start(String callback) { - andThenBuild(compBuilder -> compBuilder.start(callback)); + default B init(Object callbackInstance, String callback) { + andThenBuild(compBuilder -> compBuilder.init(callbackInstance, callback)); return (B) this; } - - default B stop(String callback) { - andThenBuild(compBuilder -> compBuilder.stop(callback)); - return (B) this; - } - - default B destroy(String callback) { - andThenBuild(compBuilder -> compBuilder.destroy(callback)); + + default B init(InstanceCb callback) { + andThenBuild(compBuilder -> compBuilder.init(callback)); return (B) this; } - default <U> B init(Cb<U> callback) { + default B init(InstanceCbComponent callback) { andThenBuild(compBuilder -> compBuilder.init(callback)); return (B) this; } - default <U> B start(Cb<U> callback) { + default B start(String callback) { andThenBuild(compBuilder -> compBuilder.start(callback)); return (B) this; } - default <U> B stop(Cb<U> callback) { - andThenBuild(compBuilder -> compBuilder.stop(callback)); + default B start(Object callbackInstance, String callback) { + andThenBuild(compBuilder -> compBuilder.start(callbackInstance, callback)); return (B) this; } - default <U> B destroy(Cb<U> callback) { - andThenBuild(compBuilder -> compBuilder.destroy(callback)); - return (B) this; - } - - default <U> B init(CbComponent<U> callback) { - andThenBuild(compBuilder -> compBuilder.init(callback)); + default B start(InstanceCb callback) { + andThenBuild(compBuilder -> compBuilder.start(callback)); return (B) this; } - default <U> B start(CbComponent<U> callback) { + default B start(InstanceCbComponent callback) { andThenBuild(compBuilder -> compBuilder.start(callback)); return (B) this; } - - default <U> B stop(CbComponent<U> callback) { + + default B stop(String callback) { andThenBuild(compBuilder -> compBuilder.stop(callback)); return (B) this; } - - default <U> B destroy(CbComponent<U> callback) { - andThenBuild(compBuilder -> compBuilder.destroy(callback)); + + default B stop(Object callbackInstance, String callback) { + andThenBuild(compBuilder -> compBuilder.stop(callbackInstance, callback)); return (B) this; } - - default B initInstance(InstanceCb callback) { - andThenBuild(compBuilder -> compBuilder.initInstance(callback)); + + default B stop(InstanceCb callback) { + andThenBuild(compBuilder -> compBuilder.stop(callback)); return (B) this; } - default B startInstance(InstanceCb callback) { - andThenBuild(compBuilder -> compBuilder.startInstance(callback)); + default B stop(InstanceCbComponent callback) { + andThenBuild(compBuilder -> compBuilder.stop(callback)); return (B) this; } - - default B stopInstance(InstanceCb callback) { - andThenBuild(compBuilder -> compBuilder.stopInstance(callback)); + + default B destroy(String callback) { + andThenBuild(compBuilder -> compBuilder.destroy(callback)); return (B) this; } - default B destroyInstance(InstanceCb callback) { - andThenBuild(compBuilder -> compBuilder.destroyInstance(callback)); + default B destroy(Object callbackInstance, String callback) { + andThenBuild(compBuilder -> compBuilder.destroy(callbackInstance, callback)); return (B) this; } - default B initInstance(InstanceCbComponent callback) { - andThenBuild(compBuilder -> compBuilder.initInstance(callback)); - return (B) this; - } - - default B startInstance(InstanceCbComponent callback) { - andThenBuild(compBuilder -> compBuilder.startInstance(callback)); - return (B) this; - } - - default B stopInstance(InstanceCbComponent callback) { - andThenBuild(compBuilder -> compBuilder.stopInstance(callback)); + default B destroy(InstanceCb callback) { + andThenBuild(compBuilder -> compBuilder.destroy(callback)); return (B) this; } - - default B destroyInstance(InstanceCbComponent callback) { - andThenBuild(compBuilder -> compBuilder.destroyInstance(callback)); + + default B destroy(InstanceCbComponent callback) { + andThenBuild(compBuilder -> compBuilder.destroy(callback)); return (B) this; } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/BundleDependencyBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/BundleDependencyBuilderImpl.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/BundleDependencyBuilderImpl.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/BundleDependencyBuilderImpl.java Sun Feb 28 19:11:09 2016 @@ -45,7 +45,7 @@ public class BundleDependencyBuilderImpl private Object m_instance; private boolean m_autoConfig = true; private boolean m_autoConfigInvoked = false; - private boolean m_required = true; + private boolean m_required; private Bundle m_bundle; private String m_filter; private int m_stateMask = -1; @@ -54,6 +54,7 @@ public class BundleDependencyBuilderImpl private String m_propagateMethod; private Function<Bundle, Dictionary<?, ?>> m_propagateCallback; private final Component m_component; + private boolean m_requiredSet; enum Cb { ADD, @@ -98,8 +99,14 @@ public class BundleDependencyBuilderImpl @Override public BundleDependencyBuilder required(boolean required) { m_required = required; + m_requiredSet = true; return this; } + + @Override + public BundleDependencyBuilder optional() { + return required(false); + } @Override public BundleDependencyBuilder required() { @@ -292,6 +299,9 @@ public class BundleDependencyBuilderImpl DependencyManager dm = m_component.getDependencyManager(); BundleDependency dep = dm.createBundleDependency(); + if (! m_requiredSet) { + m_required = Helpers.isDependencyRequiredByDefault(m_component); + } dep.setRequired(m_required); if (m_filter != null) { Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ComponentBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ComponentBuilderImpl.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ComponentBuilderImpl.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ComponentBuilderImpl.java Sun Feb 28 19:11:09 2016 @@ -40,6 +40,7 @@ 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.context.ComponentContext; import org.apache.felix.dm.lambda.BundleDependencyBuilder; import org.apache.felix.dm.lambda.ComponentBuilder; import org.apache.felix.dm.lambda.ConfigurationDependencyBuilder; @@ -47,8 +48,6 @@ import org.apache.felix.dm.lambda.Depend import org.apache.felix.dm.lambda.FluentProperty; import org.apache.felix.dm.lambda.FutureDependencyBuilder; import org.apache.felix.dm.lambda.ServiceDependencyBuilder; -import org.apache.felix.dm.lambda.callbacks.Cb; -import org.apache.felix.dm.lambda.callbacks.CbComponent; import org.apache.felix.dm.lambda.callbacks.InstanceCb; import org.apache.felix.dm.lambda.callbacks.InstanceCbComponent; @@ -62,23 +61,26 @@ public class ComponentBuilderImpl implem private Object m_factory; private boolean m_factoryHasComposite; private boolean m_autoAdd = true; - protected final Map<ComponentCallback, List<MethodRef<Object>>> m_refs = new HashMap<>(); + protected final Map<ComponentCallback, MethodRef> m_refs = new HashMap<>(); private Object m_compositionInstance; private String m_compositionMethod; private String m_init; - private String m_stop; private String m_start; + private String m_stop; private String m_destroy; - private Object m_callbackInstance; private String m_factoryCreateMethod; private boolean m_hasFactoryRef; - private boolean m_hasFactory; + private boolean m_hasFactory; + private Object m_initCallbackInstance; + private Object m_startCallbackInstance; + private Object m_stopCallbackInstance; + private Object m_destroyCallbackInstance; enum ComponentCallback { INIT, START, STOP, DESTROY }; @FunctionalInterface - interface MethodRef<I> { - public void accept(I instance, Component c); + interface MethodRef { + public void accept(Component c); } public ComponentBuilderImpl(DependencyManager dm) { @@ -297,6 +299,10 @@ public class ComponentBuilderImpl implem public Object create() { return create.get(); } + @Override + public String toString() { + return create.getClass().getName() + " (Factory)"; + } }; return this; } @@ -314,6 +320,10 @@ public class ComponentBuilderImpl implem U factoryImpl = supplier.get(); return create.apply(factoryImpl); } + @Override + public String toString() { + return supplier.getClass().getName() + " (Factory)"; + } }; return this; } @@ -335,6 +345,11 @@ public class ComponentBuilderImpl implem public Object[] getComposite() { // Create Factory instance return getComposite.get(); } + + @Override + public String toString() { + return create.getClass().getName() + " (Factory)"; + } }; m_factoryHasComposite = true; return this; @@ -361,6 +376,11 @@ public class ComponentBuilderImpl implem public Object[] getComposite() { return factoryGetComposite.apply(m_factoryInstance); } + + @Override + public String toString() { + return factorySupplier.getClass().getName() + " (Factory)"; + } }; m_factoryHasComposite = true; return this; @@ -388,31 +408,13 @@ public class ComponentBuilderImpl implem } @Override - public ComponentBuilderImpl withSvc(Class<?> service, String filter) { - return withSvc(service, srv->srv.filter(filter)); - } - - @Override - public ComponentBuilderImpl withSvc(Class<?> ... services) { - for (Class<?> s : services) { - doWithService(s); - } - return this; - } - - private <U> void doWithService(Class<U> service) { - ServiceDependencyBuilder<U> dep = new ServiceDependencyBuilderImpl<>(m_component, service); - m_dependencyBuilders.add(dep); - } - - @Override public <U> ComponentBuilderImpl withSvc(Class<U> service, Consumer<ServiceDependencyBuilder<U>> consumer) { ServiceDependencyBuilder<U> dep = new ServiceDependencyBuilderImpl<>(m_component, service); consumer.accept(dep); m_dependencyBuilders.add(dep); return this; } - + @Override public ComponentBuilderImpl withCnf(Consumer<ConfigurationDependencyBuilder> consumer) { ConfigurationDependencyBuilder dep = new ConfigurationDependencyBuilderImpl(m_component); @@ -437,168 +439,111 @@ public class ComponentBuilderImpl implem return this; } - public ComponentBuilderImpl lifecycleCallbackInstance(Object callbackInstance) { - m_callbackInstance = callbackInstance; - return this; - } - public ComponentBuilderImpl init(String callback) { - ensureHasNoLifecycleMethodRefs(); m_init = callback; return this; } - public ComponentBuilderImpl start(String callback) { - ensureHasNoLifecycleMethodRefs(); - m_start = callback; + public ComponentBuilderImpl init(Object callbackInstance, String callback) { + init(callback); + m_initCallbackInstance = callbackInstance; return this; } - public ComponentBuilderImpl stop(String callback) { - ensureHasNoLifecycleMethodRefs(); - m_stop = callback; + @Override + public ComponentBuilderImpl init(InstanceCb callback) { + setCallbackMethodRef(INIT, component -> callback.callback()); + m_init = null; + m_initCallbackInstance = null; return this; } - public ComponentBuilderImpl destroy(String callback) { - ensureHasNoLifecycleMethodRefs(); - m_destroy = callback; + @Override + public ComponentBuilderImpl init(InstanceCbComponent callback) { + setCallbackMethodRef(INIT, component -> callback.accept(component)); + m_init = null; + m_initCallbackInstance = null; return this; } - - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl init(Cb<T> callback) { - if (callback != null) { - setComponentCallbackRef(INIT, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst)); - } + + public ComponentBuilderImpl start(String callback) { + m_start = callback; return this; } - - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl start(Cb<T> callback) { - if (callback != null) { - setComponentCallbackRef(START, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst)); - } + + public ComponentBuilderImpl start(Object callbackInstance, String callback) { + start(callback); + m_startCallbackInstance = callbackInstance; return this; } - @SuppressWarnings("unchecked") @Override - public <T> ComponentBuilderImpl stop(Cb<T> callback) { - if (callback != null) { - setComponentCallbackRef(STOP, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst)); - } + public ComponentBuilderImpl start(InstanceCb callback) { + setCallbackMethodRef(START, component -> callback.callback()); + m_start = null; + m_startCallbackInstance = null; return this; } - - @SuppressWarnings("unchecked") + @Override - public <T> ComponentBuilderImpl destroy(Cb<T> callback) { - if (callback != null) { - setComponentCallbackRef(DESTROY, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst)); - } + public ComponentBuilderImpl start(InstanceCbComponent callback) { + setCallbackMethodRef(START, component -> callback.accept(component)); + m_start = null; + m_startCallbackInstance = null; return this; } - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl init(CbComponent<T> callback) { - if (callback != null) { - setComponentCallbackRef(INIT, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst, component)); - } - return this; - } - - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl start(CbComponent<T> callback) { - if (callback != null) { - setComponentCallbackRef(START, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst, component)); - } - return this; - } - - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl stop(CbComponent<T> callback) { - if (callback != null) { - setComponentCallbackRef(STOP, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst, component)); - } - return this; - } - - @SuppressWarnings("unchecked") - @Override - public <T> ComponentBuilderImpl destroy(CbComponent<T> callback) { - if (callback != null) { - setComponentCallbackRef(DESTROY, Helpers.getLambdaArgType(callback, 0), (inst, component) -> callback.accept((T) inst, component)); - } - return this; - } - - @Override - public ComponentBuilderImpl initInstance(InstanceCb callback) { - if (callback != null) { - setInstanceCallbackRef(INIT, (inst, component) -> callback.cb()); - } + public ComponentBuilderImpl stop(String callback) { + m_stop = callback; return this; } - @Override - public ComponentBuilderImpl startInstance(InstanceCb callback) { - if (callback != null) { - setInstanceCallbackRef(START, (inst, component) -> callback.cb()); - } + public ComponentBuilderImpl stop(Object callbackInstance, String callback) { + stop(callback); + m_stopCallbackInstance = callbackInstance; return this; } @Override - public ComponentBuilderImpl stopInstance(InstanceCb callback) { - if (callback != null) { - setInstanceCallbackRef(STOP, (inst, component) -> callback.cb()); - } + public ComponentBuilderImpl stop(InstanceCb callback) { + setCallbackMethodRef(STOP, component -> callback.callback()); + m_stop = null; + m_stopCallbackInstance = null; return this; } @Override - public ComponentBuilderImpl destroyInstance(InstanceCb callback) { - if (callback != null) { - setInstanceCallbackRef(DESTROY, (inst, component) -> callback.cb()); - } + public ComponentBuilderImpl stop(InstanceCbComponent callback) { + setCallbackMethodRef(STOP, component -> callback.accept(component)); + m_stop = null; + m_stopCallbackInstance = null; return this; } - - @Override - public ComponentBuilderImpl initInstance(InstanceCbComponent callback) { - if (callback != null) { - setInstanceCallbackRef(INIT, (inst, component) -> callback.accept(component)); - } + + public ComponentBuilderImpl destroy(String callback) { + m_destroy = callback; return this; } - - @Override - public ComponentBuilderImpl startInstance(InstanceCbComponent callback) { - if (callback != null) { - setInstanceCallbackRef(START, (inst, component) -> callback.accept(component)); - } + + public ComponentBuilderImpl destroy(Object callbackInstance, String callback) { + destroy(callback); + m_destroyCallbackInstance = callbackInstance; return this; } @Override - public ComponentBuilderImpl stopInstance(InstanceCbComponent callback) { - if (callback != null) { - setInstanceCallbackRef(STOP, (inst, component) -> callback.accept(component)); - } + public ComponentBuilderImpl destroy(InstanceCb callback) { + setCallbackMethodRef(DESTROY, component -> callback.callback()); + m_destroy = null; + m_destroyCallbackInstance = null; return this; } - + @Override - public ComponentBuilderImpl destroyInstance(InstanceCbComponent callback) { - if (callback != null) { - setInstanceCallbackRef(DESTROY, (inst, component) -> callback.accept(component)); - } + public ComponentBuilderImpl destroy(InstanceCbComponent callback) { + setCallbackMethodRef(DESTROY, component -> callback.accept(component)); + m_destroy = null; + m_destroyCallbackInstance = null; return this; } @@ -625,13 +570,23 @@ public class ComponentBuilderImpl implem } 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 (hasCallbacks()) { // either method refs on some object instances, or a callback (reflection) on some object instances. + if (m_refs.get(INIT) == null) { + setCallbackMethodRef(INIT, component -> invokeCallbacks(component, m_initCallbackInstance, m_init, "init")); + } + if (m_refs.get(START) == null) { + setCallbackMethodRef(START, component -> invokeCallbacks(component, m_startCallbackInstance, m_start, "start")); + } + if (m_refs.get(STOP) == null) { + setCallbackMethodRef(STOP, component -> invokeCallbacks(component, m_stopCallbackInstance, m_stop, "stop")); + } + if (m_refs.get(DESTROY) == null) { + setCallbackMethodRef(DESTROY, component -> invokeCallbacks(component, m_destroyCallbackInstance, m_destroy, "destroy")); + } + setInternalCallbacks(); + } } if (m_dependencyBuilders.size() > 0) { @@ -642,79 +597,54 @@ 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"); - } + + private boolean hasCallbacks() { + return m_refs.size() > 0 || m_init != null || m_start != null || m_stop != null || m_destroy != null; } - protected <U> ComponentBuilderImpl setInstanceCallbackRef(ComponentCallback cbType, MethodRef<U> ref) { - ensureHasNoLifecycleMethods(); - List<MethodRef<Object>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>()); - list.add((instance, component) -> { - ref.accept(null, component); - }); - return this; - } + private void invokeCallbacks(Component component, Object callbackInstance, String callback, String defaultCallback) { + boolean logIfNotFound = (callback != null); + callback = callback != null ? callback : defaultCallback; + ComponentContext ctx = (ComponentContext) component; + Object[] instances = callbackInstance != null ? new Object[] { callbackInstance } : ctx.getInstances(); - @SuppressWarnings("unchecked") - private <U> ComponentBuilderImpl setComponentCallbackRef(ComponentCallback cbType, Class<U> type, MethodRef<U> callback) { - ensureHasNoLifecycleMethods(); - if (type.equals(Object.class)) { - throw new IllegalStateException("callback does not seam to be one from the possible component implementation classes"); - } - List<MethodRef<Object>> list = m_refs.computeIfAbsent(cbType, l -> new ArrayList<>()); - list.add((instance, component) -> { - Object componentImpl = Stream.of(component.getInstances()) - .filter(impl -> Helpers.getClass(impl).equals(type)) - .findFirst() - .orElseThrow(() -> new IllegalStateException("The method reference " + callback + " does not match any available component impl classes.")); - callback.accept((U) componentImpl, component); - }); + ctx.invokeCallbackMethod(instances, callback, + new Class[][] {{ Component.class }, {}}, + new Object[][] {{ component }, {}}, + logIfNotFound); + } + + private ComponentBuilderImpl setCallbackMethodRef(ComponentCallback cbType, MethodRef ref) { + m_refs.put(cbType, ref); return this; } - + @SuppressWarnings("unused") - private void setLifecycleMethodRefs() { + private void setInternalCallbacks() { Object cb = new Object() { void init(Component comp) { - invokeLfcleCallbacks(ComponentCallback.INIT, comp); + invokeLifecycleCallback(ComponentCallback.INIT, comp); } void start(Component comp) { - invokeLfcleCallbacks(ComponentCallback.START, comp); + invokeLifecycleCallback(ComponentCallback.START, comp); } void stop(Component comp) { - invokeLfcleCallbacks(ComponentCallback.STOP, comp); + invokeLifecycleCallback(ComponentCallback.STOP, comp); } void destroy(Component comp) { - invokeLfcleCallbacks(ComponentCallback.DESTROY, comp); + invokeLifecycleCallback(ComponentCallback.DESTROY, comp); } }; m_component.setCallbacks(cb, "init", "start", "stop", "destroy"); } - private void invokeLfcleCallbacks(ComponentCallback cbType, Component component) { - m_refs.computeIfPresent(cbType, (k, mrefs) -> { - mrefs.forEach(mref -> mref.accept(null, component)); - return mrefs; + private void invokeLifecycleCallback(ComponentCallback cbType, Component component) { + m_refs.computeIfPresent(cbType, (k, mref) -> { + mref.accept(component); + return mref; }); } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/Helpers.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/Helpers.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/Helpers.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/Helpers.java Sun Feb 28 19:11:09 2016 @@ -30,14 +30,17 @@ import java.util.regex.Pattern; import java.util.stream.Stream; import org.apache.felix.dm.Component; +import org.apache.felix.dm.context.ComponentContext; import org.apache.felix.dm.lambda.callbacks.SerializableLambda; +import org.osgi.framework.BundleContext; /** * Various helper methods related to generics and lambda expressions. */ public class Helpers { private final static Pattern LAMBDA_INSTANCE_METHOD_TYPE = Pattern.compile("(L[^;]+)+"); - + private final static String DEFAULT_REQUIRED_DEPENDENCY = "org.apache.felix.dependencymanager.lambda.defaultRequiredDependency"; + /** * Gets the class name of a given object. * @param obj the object whose class has to be returned. @@ -129,6 +132,29 @@ public class Helpers { } /** + * Is a dependency required by default ? + * + * @param c the component on which the dependency is added + * @param ctx the bundle context + * @return true if the dependency is required by default, false if not + */ + public static boolean isDependencyRequiredByDefault(Component c) { + BundleContext ctx = ((ComponentContext) c).getBundleContext(); + String defaultRequiredDependency = ctx.getProperty(DEFAULT_REQUIRED_DEPENDENCY); + if (defaultRequiredDependency != null) { + defaultRequiredDependency = defaultRequiredDependency.trim(); + String componentName = c.getComponentDeclaration().getName(); + for (String pkg : defaultRequiredDependency.split(",")) { + if (componentName.startsWith(pkg)) { + return true; + } + } + } + + return false; + } + + /** * Extracts the actual types of all lambda generic parameters. * Example: for "BiConsumer<String, Integer>", this method returns ["java.lang.String", "java.lang.Integer"]. */ @@ -161,5 +187,5 @@ public class Helpers { .findFirst() .orElseThrow(() -> new RuntimeException("Lambda Method not found")); } - + } Modified: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java (original) +++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/lambda/impl/ServiceDependencyBuilderImpl.java Sun Feb 28 19:11:09 2016 @@ -33,13 +33,14 @@ public class ServiceDependencyBuilderImp private final Component m_component; private String m_filter; private ServiceReference<S> m_ref; - private boolean m_required = true; + private boolean m_required; 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; + private boolean m_requiredSet; public ServiceDependencyBuilderImpl(Component component, Class<S> service) { super(service); @@ -67,6 +68,7 @@ public class ServiceDependencyBuilderImp public ServiceDependencyBuilder<S> required(boolean required) { m_required = required; + m_requiredSet = true; return this; } @@ -119,6 +121,7 @@ public class ServiceDependencyBuilderImp public ServiceDependencyBuilder<S> timeout(long timeout) { m_timeout = timeout; + required(); return this; } @@ -129,12 +132,18 @@ public class ServiceDependencyBuilderImp if (m_ref != null && m_filter != null) { throw new IllegalArgumentException("Can not set ref and filter at the same time"); } + if (m_serviceIface == null && (m_ref == null || m_filter == null)) { + throw new IllegalArgumentException("service interface not specified, and no service reference or service filter specified."); + } 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); } + if (! m_requiredSet) { + m_required = Helpers.isDependencyRequiredByDefault(m_component); + } sd.setRequired(m_required); sd.setDefaultImplementation(m_defaultImpl); if (m_debug != null) { Modified: felix/trunk/dependencymanager/release/resources/changelog.txt URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/release/resources/changelog.txt?rev=1732779&r1=1732778&r2=1732779&view=diff ============================================================================== --- felix/trunk/dependencymanager/release/resources/changelog.txt (original) +++ felix/trunk/dependencymanager/release/resources/changelog.txt Sun Feb 28 19:11:09 2016 @@ -12,16 +12,18 @@ Release Notes - Felix - Version org.apac * [FELIX-5188] - No error log when a factory pid adapter update callback is not found * [FELIX-5192] - ConfigurationDependency race condition when component is stopped * [FELIX-5193] - Factory Pid Adapter race condition when component is stopped - + * [FELIX-5200] - Factory configuration adapter not restarted + ** Improvement - * [FELIX-4689] - Create a more fluent syntax for the dependency manager builder + * [FELIX-5126] - Build DM using Java 8 * [FELIX-5164] - Add support for callback instance in Aspects * [FELIX-5177] - Support injecting configuration proxies * [FELIX-5180] - Support for Java8 Repeatable Properties in DM annotations. * [FELIX-5182] - Cleanup DM samples + * [FELIX-5201] - Improve how components are displayed with gogo shell ** New Feature - * [FELIX-5126] - Build DM using Java 8 + * [FELIX-4689] - Create a more fluent syntax for the dependency manager builder Release Notes - Felix - Version org.apache.felix.dependencymanager-r6 ======================================================================
