Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ServiceCallbacksBuilderImpl.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/ServiceCallbacksBuilderImpl.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/ServiceCallbacksBuilderImpl.java (added) +++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ServiceCallbacksBuilderImpl.java Thu Nov 12 22:26:29 2015 @@ -0,0 +1,383 @@ +package org.apache.felix.dm.builder.java.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; + +import org.apache.felix.dm.Component; +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; +import org.osgi.framework.ServiceReference; + +import net.jodah.typetools.TypeResolver; + +/** + * Dependency Callbacks management. + * + * @param <T> the type of the service dependency + * @param <B> the type of the sub-classes which may extend this class + */ +@SuppressWarnings({"unchecked", "unused"}) +public abstract class ServiceCallbacksBuilderImpl<T, B extends ServiceCallbacksBuilderImpl<T, B>> { + /** + * 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, T> { + public void call(I instance, Component c, ServiceReference<T> ref, T 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, T> { + public void inject(I instance, Component c, ServiceReference<T> oldRef, T oldService, ServiceReference<T> newRef, T newService); + } + + /** + * Mapping between a DM service dependency callback ("add"/"change"/"removed/") and a list of component instances that have some method references on + * the given service. + * + * Key: lifecycle service dependency callback ("add", "change", "remove") + * Value: Map<component instance class, MethodRef> + */ + private final ConcurrentHashMap<String, ConcurrentHashMap<Class<?>, MethodRef<?, T>>> m_CbInstanceRefs = new ConcurrentHashMap<>(); + + /** + * Mapping between a DM service dependency callback ("add"/"change"/"removed") and a list of instance callbacks (method references). + * + * Key: lifecycle service dependency callback ("add", "change", "remove") + * Value: List of method references + */ + private final ConcurrentHashMap<String, List<MethodRef<?, T>>> m_CbRefs = new ConcurrentHashMap<>(); + + /** + * Mapping between DM swap callback ("swap"), and list of instance callbacks (method refs). + */ + private final ConcurrentHashMap<Class<?>, SwapMethodRef<?, T>> m_swapCbInstanceRefs = new ConcurrentHashMap<>(); + + /** + * Mapping between DM swap callback ("swap") and list of callbacks (method refs). + */ + private final List<SwapMethodRef<?, T>> m_swapCbRefs = new ArrayList<>(); + + public <I> B onAdd(InstanceService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceService.class, callback.getClass())[0]; + return setCallbackInstanceRef("add", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service)); + } + + public B onAdd(Service<T> callback) { + return setCallbackRef("add", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service)); + } + + public <I> B onAdd(InstanceServiceMap<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceMap.class, callback.getClass())[0]; + return setCallbackInstanceRef("add", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsMap(ref))); + } + + public B onAdd(ServiceMap<T> callback) { + return setCallbackRef("add", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onAdd(InstanceServiceDict<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceDict.class, callback.getClass())[0]; + return setCallbackInstanceRef("add", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsDictionary(ref))); + } + + public B onAdd(ServiceDict<T> callback) { + return setCallbackRef("add", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onAdd(InstanceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("add", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, ref)); + } + + public B onAdd(Ref<T> callback) { + return setCallbackRef("add", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(ref)); + } + + public <I> B onAdd(InstanceServiceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("add", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, ref)); + } + + public B onAdd(ServiceRef<T> callback) { + return setCallbackRef("add", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, ref)); + } + + public <I> B onChange(InstanceService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceService.class, callback.getClass())[0]; + return setCallbackInstanceRef("change", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service)); + } + + public B onChange(Service<T> callback) { + return setCallbackRef("change", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service)); + } + + public <I> B onChange(InstanceServiceMap<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceMap.class, callback.getClass())[0]; + return setCallbackInstanceRef("change", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsMap(ref))); + } + + public B onChange(ServiceMap<T> callback) { + return setCallbackRef("change", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onChange(InstanceServiceDict<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceDict.class, callback.getClass())[0]; + return setCallbackInstanceRef("change", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsDictionary(ref))); + } + + public B onChange(ServiceDict<T> callback) { + return setCallbackRef("change", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onChange(InstanceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("change", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, ref)); + } + + public B onChange(Ref<T> callback) { + return setCallbackRef("change", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(ref)); + } + + public <I> B onChange(InstanceServiceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("change", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, ref)); + } + + public B onChange(ServiceRef<T> callback) { + return setCallbackRef("change", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, ref)); + } + + public <I> B onRemove(InstanceService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceService.class, callback.getClass())[0]; + return setCallbackInstanceRef("remove", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service)); + } + + public B onRemove(Service<T> callback) { + return setCallbackRef("remove", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service)); + } + + public <I> B onRemove(InstanceServiceMap<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceMap.class, callback.getClass())[0]; + return setCallbackInstanceRef("remove", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsMap(ref))); + } + + public B onRemove(ServiceMap<T> callback) { + return setCallbackRef("remove", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onRemove(InstanceServiceDict<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceDict.class, callback.getClass())[0]; + return setCallbackInstanceRef("remove", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, new SRefAsDictionary(ref))); + } + + public B onRemove(ServiceDict<T> callback) { + return setCallbackRef("remove", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onRemove(InstanceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("remove", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, ref)); + } + + public B onRemove(Ref<T> callback) { + return setCallbackRef("remove", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(ref)); + } + + public <I> B onRemove(InstanceServiceRef<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceServiceRef.class, callback.getClass())[0]; + return setCallbackInstanceRef("remove", instanceType, + (I inst, Component c, ServiceReference<T> ref, T service) -> callback.call(inst, service, ref)); + } + + public B onRemove(ServiceRef<T> callback) { + return setCallbackRef("remove", + (Object inst, Component c, ServiceReference<T> ref, T service) -> callback.call(service, ref)); + } + + public <I> B onSwap(InstanceRefServiceRefService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceRefServiceRefService.class, callback.getClass())[0]; + return setSwapInstanceRef(instanceType, + (I inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(inst, oldR, old, replR, repl)); + } + + public B onSwap(RefServiceRefService<T> callback) { + return setSwapRef((Object inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(oldR, old, replR, repl)); + } + + public <I> B onSwap(InstanceMapServiceMapService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceMapServiceMapService.class, callback.getClass())[0]; + return setSwapInstanceRef(instanceType, + (I inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(inst, new SRefAsMap(oldR), old, new SRefAsMap(replR), repl)); + } + + public B onSwap(MapServiceMapService<T> callback) { + return setSwapRef((Object inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(new SRefAsMap(oldR), old, new SRefAsMap(replR), repl)); + } + + public <I> B onSwap(InstanceDictServiceDictService<I, T> callback) { + Class<?> instanceType = TypeResolver.resolveRawArguments(InstanceDictServiceDictService.class, callback.getClass())[0]; + return setSwapInstanceRef(instanceType, + (I inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(inst, new SRefAsDictionary(oldR), old, new SRefAsDictionary(replR), repl)); + } + + public B onSwap(DictServiceDictService<T> callback) { + return setSwapRef((Object inst, Component c, ServiceReference<T> oldR, T old, ServiceReference<T> replR, T repl) -> + callback.call(new SRefAsDictionary(oldR), old, new SRefAsDictionary(replR), repl)); + } + + public <I> B setCallbackInstanceRef(String cb, Class<?> instanceType, MethodRef<I, T> inject) { + ConcurrentHashMap<Class<?>, MethodRef<?, T>> refs = m_CbInstanceRefs.computeIfAbsent(cb, map -> new ConcurrentHashMap<>()); + MethodRef<?, T> ref = refs.get(instanceType); + if (ref != null) { + throw new IllegalStateException("component instance type " + instanceType + " already has a \"" + cb + "\" method reference."); + } + refs.put(instanceType, inject); + return (B) this; + } + + public <I> B setCallbackRef(String cb, MethodRef<I, T> ref) { + m_CbRefs.computeIfAbsent(cb, list -> new ArrayList<>()).add(ref); + return (B) this; + } + + public <I> B setSwapInstanceRef(Class<?> instanceType, SwapMethodRef<I, T> inject) { + m_swapCbInstanceRefs.put(instanceType, inject); + return (B) this; + } + + public <I> B setSwapRef(SwapMethodRef<I, T> ref) { + m_swapCbRefs.add(ref); + return (B) this; + } + + protected Object createCallbackInstance() { + Object cb = null; + + cb = new Object() { + void add(Component c, ServiceReference<T> ref, Object service) { + invokeInstanceMethodRefs("add", c, ref, (T) service); + invokeMethodRefs("add", c, ref, (T) service); + } + + void change(Component c, ServiceReference<T> ref, Object service) { + invokeInstanceMethodRefs("change", c, ref, (T) service); + invokeMethodRefs("change", c, ref, (T) service); + } + + void remove(Component c, ServiceReference<T> ref, Object service) { + invokeInstanceMethodRefs("remove", c, ref, (T) service); + invokeMethodRefs("remove", c, ref, (T) service); + } + + void swap(Component c, ServiceReference<T> oldRef, Object oldSrv, ServiceReference<T> newRef, Object newSrv) { + invokeSwapInstanceMethodRefs(c, oldRef, (T) oldSrv, newRef, (T) newSrv); + invokeSwapMethodRefs(c, oldRef, (T) oldSrv, newRef, (T) newSrv); + } + }; + + return cb; + } + + protected boolean hasCallbacks() { + return m_CbInstanceRefs.size() > 0 || m_CbRefs.size() > 0 || m_swapCbInstanceRefs.size() > 0 || m_swapCbRefs.size() > 0; + } + + protected boolean hasInstanceCallbacks() { + return m_CbInstanceRefs.size() > 0 || m_swapCbInstanceRefs.size() > 0; + } + + private void invokeInstanceMethodRefs(String method, Component comp, ServiceReference<T> ref, T service) { + m_CbInstanceRefs.computeIfPresent(method, (k, mrefs) -> { + Stream.of(comp.getInstances()).forEach(instance -> { + MethodRef<Object, T> mref = (MethodRef<Object, T>) mrefs.get(instance.getClass()); + if (mref != null) { + mref.call(instance, comp, ref, service); + } + }); + return mrefs; + }); + } + + private void invokeMethodRefs(String method, Component comp, ServiceReference<T> ref, T service) { + m_CbRefs.computeIfPresent(method, (k, mrefs) -> { + mrefs.stream().forEach(mref -> mref.call(null, comp, ref, service)); + return mrefs; + }); + } + + private void invokeSwapMethodRefs(Component comp, ServiceReference<T> oRef, T oSrv, ServiceReference<T> nRef, T nSrv) { + m_swapCbRefs.stream().forEach(mref -> mref.inject(null, comp, oRef, oSrv, nRef, nSrv)); + } + + private void invokeSwapInstanceMethodRefs(Component comp, ServiceReference<T> oRef, T oSrv, ServiceReference<T> nRef, T nSrv) { + Stream.of(comp.getInstances()).forEach(instance -> { + SwapMethodRef<Object, T> swapRef = (SwapMethodRef<Object, T>) m_swapCbInstanceRefs.get(instance.getClass()); + if (swapRef != null) { + swapRef.inject(instance, comp, oRef, oSrv, nRef, nSrv); + } + }); + } +}
Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ServiceDependencyBuilderImpl.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/ServiceDependencyBuilderImpl.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/ServiceDependencyBuilderImpl.java (added) +++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/impl/ServiceDependencyBuilderImpl.java Thu Nov 12 22:26:29 2015 @@ -0,0 +1,167 @@ +package org.apache.felix.dm.builder.java.impl; + +import org.apache.felix.dm.Component; +import org.apache.felix.dm.DependencyManager; +import org.apache.felix.dm.ServiceDependency; +import org.apache.felix.dm.builder.java.ServiceDependencyBuilder; +import org.osgi.framework.ServiceReference; + +public class ServiceDependencyBuilderImpl<T> extends ServiceCallbacksBuilderImpl<T, ServiceDependencyBuilderImpl<T>> implements ServiceDependencyBuilder<T> { + private Class<T> m_serviceIface; + private String m_filter; + private ServiceReference<T> m_ref; + private Object m_callbackInstance; + private String m_added; + private String m_changed; + private String m_removed; + private String m_swapped; + private boolean m_callbacksSet; + private Boolean m_autoConfig; // null means setAutoConfig has not been called. + private String m_autoConfigField; + 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 final Component m_component; + + public ServiceDependencyBuilderImpl(Component component, Class<T> service) { + m_serviceIface = service; + m_component = component; + } + + public ServiceDependencyBuilder<T> autoConfig() { + m_autoConfig = true; + return this; + } + + public ServiceDependencyBuilder<T> autoConfig(boolean autoConfig) { + m_autoConfig = autoConfig; + return this; + } + + public ServiceDependencyBuilder<T> autoConfig(String field) { + m_autoConfigField = field; + return this; + } + + public ServiceDependencyBuilder<T> filter(String filter) { + this.m_filter = filter; + return this; + } + + public ServiceDependencyBuilder<T> ref(ServiceReference<T> ref) { + this.m_ref = ref; + return this; + } + + public ServiceDependencyBuilder<T> required() { + return required(true); + } + + public ServiceDependencyBuilder<T> required(boolean required) { + m_required = required; + return this; + } + + public ServiceDependencyBuilder<T> callbackInstance(Object instance) { + m_callbackInstance = instance; + m_callbacksSet = true; + return this; + } + + public ServiceDependencyBuilder<T> onAdd(String added) { + this.m_added = added; + m_callbacksSet = true; + return this; + } + + public ServiceDependencyBuilder<T> onChange(String changed) { + this.m_changed = changed; + m_callbacksSet = true; + return this; + } + + public ServiceDependencyBuilder<T> onRemove(String removed) { + this.m_removed = removed; + m_callbacksSet = true; + return this; + } + + public ServiceDependencyBuilder<T> onSwap(String swapped) { + this.m_swapped = swapped; + m_callbacksSet = true; + return this; + } + + public ServiceDependencyBuilder<T> debug(String label) { + m_debug = label; + return this; + } + + public ServiceDependencyBuilder<T> propagate() { + return propagate(true); + } + + public ServiceDependencyBuilder<T> propagate(boolean propagate) { + m_propagate = propagate; + return this; + } + + public ServiceDependencyBuilder<T> propagateTo(Object instance, String method) { + m_propagateInstance = instance; + m_propagateMethod = method; + return this; + } + + public ServiceDependencyBuilder<T> defImpl(Object defaultImpl) { + m_defaultImpl = defaultImpl; + 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 = 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 (m_callbacksSet) { + sd.setCallbacks(m_callbackInstance, m_added, m_changed, m_removed, m_swapped); + } else if (hasInstanceCallbacks() || hasCallbacks()) { + Object cb = createCallbackInstance(); + sd.setCallbacks(cb, "add", "change", "remove", "swap"); + + if (! hasInstanceCallbacks()) { + sd.setAutoConfig(true); + } + } + + if (m_autoConfigField != null) { + sd.setAutoConfig(m_autoConfigField); + } else if (m_autoConfig != null) { + sd.setAutoConfig(m_autoConfig); + } + return sd; + } +} Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/packageinfo 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/packageinfo?rev=1714132&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/packageinfo (added) +++ felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/src/org/apache/felix/dm/builder/java/packageinfo Thu Nov 12 22:26:29 2015 @@ -0,0 +1 @@ +version 1.0.0 \ No newline at end of file Added: felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/test/.gitignore URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/org.apache.felix.dependencymanager.builder.java/test/.gitignore?rev=1714132&view=auto ============================================================================== (empty) Added: felix/sandbox/pderop/dependencymanager.builder.java/settings.gradle URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.builder.java/settings.gradle?rev=1714132&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager.builder.java/settings.gradle (added) +++ felix/sandbox/pderop/dependencymanager.builder.java/settings.gradle Thu Nov 12 22:26:29 2015 @@ -0,0 +1,127 @@ +/* + * Master Gradle initialization script + * + * Depends on bnd_* values from gradle.properties. + */ + +import aQute.bnd.build.Workspace + +/* Add bnd as a script dependency */ +buildscript { + dependencies { + def bndURI = rootDir.toURI().resolve(bnd_jar) + if (bndURI.scheme != 'file') { + /* If not a local file, copy to a local file in cnf/cache */ + def cnfCache = mkdir("${rootDir}/${bnd_cnf}/cache") + def bndJarFile = new File(cnfCache, 'biz.aQute.bnd.gradle.jar') + if (!bndJarFile.exists()) { + println "Downloading ${bndURI} to ${bndJarFile} ..." + bndURI.toURL().withInputStream { is -> + bndJarFile.withOutputStream { os -> + def bos = new BufferedOutputStream( os ) + bos << is + } + } + } + bndURI = bndJarFile.toURI() + } + classpath files(bndURI) + + /* After the rootProject is created, pass URI to projects */ + gradle.rootProject { rootProject -> + rootProject.ext.bndURI = bndURI + } + } +} + +/* Initialize the bnd workspace */ +def workspace = Workspace.getWorkspace(rootDir, bnd_cnf) +if (workspace == null) { + throw new GradleException("Unable to load workspace ${rootDir}/${bnd_cnf}") +} + +/* Add cnf project to the graph */ +include bnd_cnf + +/* Start with the declared build project name */ +def defaultProjectName = bnd_build + +/* If in a subproject, use the subproject name */ +for (def currentDir = startParameter.currentDir; currentDir != rootDir; currentDir = currentDir.parentFile) { + defaultProjectName = currentDir.name +} + +/* Build a set of project names we need to include from the specified tasks */ +def projectNames = startParameter.taskNames.collect { taskName -> + def elements = taskName.split(':') + switch (elements.length) { + case 1: + return defaultProjectName + case 2: + return elements[0].empty ? bnd_build : elements[0] + default: + return elements[0].empty ? elements[1] : elements[0] + } +}.toSet() + +/* Include the default project name if in a subproject or no tasks specified */ +if ((startParameter.currentDir != rootDir) || projectNames.empty) { + projectNames += defaultProjectName +} + +/* If bnd_build used but declared empty, add all non-private folders of rootDir */ +if (projectNames.remove('')) { + rootDir.eachDir { + def projectName = it.name + if (!projectName.startsWith('.')) { + projectNames += projectName + } + } +} + +/* Add each project and its dependencies to the graph */ +projectNames.each { projectName -> + include projectName + def project = getBndProject(workspace, projectName) + project?.dependson.each { + include it.name + } +} + +/* Get the bnd project for the specified project name */ +def getBndProject(Workspace workspace, String projectName) { + def project = workspace.getProject(projectName) + if (project == null) { + return null + } + project.prepare() + if (project.isValid()) { + return project + } + + project.getInfo(workspace, "${rootDir} :") + def errorCount = 0 + project.warnings.each { + println "Warning: ${it}" + } + project.errors.each { + println "Error : ${it}" + errorCount++ + } + if (!project.isOk()) { + def str = 'even though no errors were reported' + if (errorCount == 1) { + str = 'one error was reported' + } else if (errorCount > 1) { + str = "${errorCount} errors were reported" + } + throw new GradleException("Project ${rootDir}/${projectName} is invalid, ${str}") + } + throw new GradleException("Project ${rootDir}/${projectName} is not a valid bnd project") +} + +/* After the rootProject is created, set up some properties. */ +gradle.rootProject { rootProject -> + rootProject.ext.bndWorkspace = workspace + rootProject.ext.cnf = rootProject.project(bnd_cnf) +}
