Added: 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=1719841&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceCallbacksBuilderImpl.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceCallbacksBuilderImpl.java Sun Dec 13 22:23:57 2015 @@ -0,0 +1,348 @@ +package org.apache.felix.dm.builder.lambda.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.apache.felix.dm.Component; +import org.apache.felix.dm.builder.lambda.Functions.DictServiceDictService; +import org.apache.felix.dm.builder.lambda.Functions.InstanceDictServiceDictService; +import org.apache.felix.dm.builder.lambda.Functions.InstanceMapServiceMapService; +import org.apache.felix.dm.builder.lambda.Functions.InstanceRef; +import org.apache.felix.dm.builder.lambda.Functions.InstanceRefServiceRefService; +import org.apache.felix.dm.builder.lambda.Functions.InstanceService; +import org.apache.felix.dm.builder.lambda.Functions.InstanceServiceDict; +import org.apache.felix.dm.builder.lambda.Functions.InstanceServiceMap; +import org.apache.felix.dm.builder.lambda.Functions.InstanceServiceRef; +import org.apache.felix.dm.builder.lambda.Functions.MapServiceMapService; +import org.apache.felix.dm.builder.lambda.Functions.Ref; +import org.apache.felix.dm.builder.lambda.Functions.RefServiceRefService; +import org.apache.felix.dm.builder.lambda.Functions.Service; +import org.apache.felix.dm.builder.lambda.Functions.ServiceDict; +import org.apache.felix.dm.builder.lambda.Functions.ServiceMap; +import org.apache.felix.dm.builder.lambda.Functions.ServiceRef; +import org.osgi.framework.ServiceReference; + +/** + * 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 accept(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 accept(I instance, Component c, ServiceReference<T> oldRef, T oldService, ServiceReference<T> newRef, T newService); + } + + /** + * List of service (add/change/remove) callbacks. + */ + private final Map<String, List<MethodRef<Object, T>>> m_refs = new HashMap<>(); + + /** + * List of swap callbacks + */ + private final List<SwapMethodRef<?, T>> m_swapRefs = new ArrayList<>(); + + /** + * TODO + */ + private boolean m_hasComponentInstanceCallbacks; + + public <I> B onAdd(InstanceService<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("add", type, + (instance, component, ref, service) -> callback.call((I) instance, service)); + } + + public B onAdd(Service<T> callback) { + return setCallbackRef("add", (instance, component, sref, service) -> callback.call(service)); + } + + public <I> B onAdd(InstanceServiceMap<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("add", type, + (instance, component, ref, service) -> callback.call((I) instance, service, new SRefAsMap(ref))); + } + + public B onAdd(ServiceMap<T> callback) { + return setCallbackRef("add", + (instance, component, ref, service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onAdd(InstanceServiceDict<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("add", type, + (inst, component, ref, service) -> callback.call((I) inst, service, new SRefAsDictionary(ref))); + } + + public B onAdd(ServiceDict<T> callback) { + return setCallbackRef("add", + (instance, component, ref, service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onAdd(InstanceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("add", type, + (instance, component, ref, service) -> callback.call((I) instance, ref)); + } + + public B onAdd(Ref<T> callback) { + return setCallbackRef("add", + (instance, component, ref, service) -> callback.call(ref)); + } + + public <I> B onAdd(InstanceServiceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("add", type, + (instance, component, ref, service) -> callback.call((I) instance, service, ref)); + } + + public B onAdd(ServiceRef<T> callback) { + return setCallbackRef("add", + (instance, component, ref, service) -> callback.call(service, ref)); + } + + public <I> B onChange(InstanceService<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("change", type, + (instance, component, ref, service) -> callback.call((I) instance, service)); + } + + public B onChange(Service<T> callback) { + return setCallbackRef("change", + (instance, component, ref, service) -> callback.call(service)); + } + + public <I> B onChange(InstanceServiceMap<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("change", type, + (instance, component, ref, service) -> callback.call((I) instance, service, new SRefAsMap(ref))); + } + + public B onChange(ServiceMap<T> callback) { + return setCallbackRef("change", + (instance, component, ref, service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onChange(InstanceServiceDict<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("change", type, + (instance, component, ref, service) -> callback.call((I) instance, service, new SRefAsDictionary(ref))); + } + + public B onChange(ServiceDict<T> callback) { + return setCallbackRef("change", + (instance, component, ref, service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onChange(InstanceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("change", type, + (instance, component, ref, service) -> callback.call((I) instance, ref)); + } + + public B onChange(Ref<T> callback) { + return setCallbackRef("change", + (instance, component, ref, service) -> callback.call(ref)); + } + + public <I> B onChange(InstanceServiceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("change", type, + (instance, component, ref, service) -> callback.call((I) instance, service, ref)); + } + + public B onChange(ServiceRef<T> callback) { + return setCallbackRef("change", + (instance, component, ref, service) -> callback.call(service, ref)); + } + + public <I> B onRemove(InstanceService<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("remove", type, + (instance, component, ref, service) -> callback.call((I) instance, service)); + } + + public B onRemove(Service<T> callback) { + return setCallbackRef("remove", + (instance, component, ref, service) -> callback.call(service)); + } + + public <I> B onRemove(InstanceServiceMap<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("remove", type, + (instance, component, ref, service) -> callback.call((I) instance, service, new SRefAsMap(ref))); + } + + public B onRemove(ServiceMap<T> callback) { + return setCallbackRef("remove", + (instance, component, ref, service) -> callback.call(service, new SRefAsMap(ref))); + } + + public <I> B onRemove(InstanceServiceDict<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("remove", type, + (instance, component, ref, service) -> callback.call((I) instance, service, new SRefAsDictionary(ref))); + } + + public B onRemove(ServiceDict<T> callback) { + return setCallbackRef("remove", + (instance, component, ref, service) -> callback.call(service, new SRefAsDictionary(ref))); + } + + public <I> B onRemove(InstanceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("remove", type, + (instance, component, ref, service) -> callback.call((I) instance, ref)); + } + + public B onRemove(Ref<T> callback) { + return setCallbackRef("remove", + (instance, component, ref, service) -> callback.call(ref)); + } + + public <I> B onRemove(InstanceServiceRef<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceCallbackRef("remove", type, + (instance, component, ref, service) -> callback.call((I) instance, service, ref)); + } + + public B onRemove(ServiceRef<T> callback) { + return setCallbackRef("remove", + (instance, component, ref, service) -> callback.call(service, ref)); + } + + public <I> B onSwap(InstanceRefServiceRefService<I, T> callback) { + String type = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceSwapCallbackRef(type, + (inst, component, oref, oserv, nref, nserv) -> callback.call((I) inst, oref, oserv, nref, nserv)); + } + + public B onSwap(RefServiceRefService<T> callback) { + m_swapRefs.add((inst, component, oref, oserv, nref, nserv) -> callback.call(oref, oserv, nref, nserv)); + return (B) this; + } + + public <I> B onSwap(InstanceMapServiceMapService<I, T> callback) { + String instanceType = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceSwapCallbackRef(instanceType, (inst, component, oref, oserv, nref, nserv) -> + callback.call((I) inst, new SRefAsMap(oref), oserv, new SRefAsMap(nref), nserv)); + } + + public B onSwap(MapServiceMapService<T> callback) { + m_swapRefs.add((inst, component, oref, oserv, nref, nserv) -> + callback.call(new SRefAsMap(oref), oserv, new SRefAsMap(nref), nserv)); + return (B) this; + } + + public <I> B onSwap(InstanceDictServiceDictService<I, T> callback) { + String instanceType = Helpers.extractLambdaGenericType(callback); + return setComponentInstanceSwapCallbackRef(instanceType, (inst, component, oref, oserv, nref, nserv) -> + callback.call((I) inst, new SRefAsDictionary(oref), oserv, new SRefAsDictionary(nref), nserv)); + } + + public B onSwap(DictServiceDictService<T> callback) { + m_swapRefs.add((inst, component, oref, oserv, nref, nserv) -> + callback.call(new SRefAsDictionary(oref), oserv, new SRefAsDictionary(nref), nserv)); + return (B) this; + } + + public <I> B setCallbackRef(String cb, MethodRef<I, T> ref) { + List<MethodRef<Object, T>> list = m_refs.computeIfAbsent(cb, l -> new ArrayList<>()); + list.add((instance, component, sref, service) -> ref.accept(null, component, sref, service)); + return (B) this; + } + + public <I> B setComponentInstanceCallbackRef(String cb, String type, MethodRef<I, T> ref) { + List<MethodRef<Object, T>> list = m_refs.computeIfAbsent(cb, l -> new ArrayList<>()); + list.add((instance, component, sref, service) -> { + Stream.of(component.getInstances()).forEach(inst -> { + if (Helpers.getClassName(inst).equals(type)) { + ref.accept((I) inst, component, sref, service); + } + }); + }); + m_hasComponentInstanceCallbacks = true; + return (B) this; + } + + public <I> B setComponentInstanceSwapCallbackRef(String type, SwapMethodRef<I, T> ref) { + m_swapRefs.add((instance, component, oref, oservice, nref, nservice) -> { + Stream.of(component.getInstances()).forEach(componentInstance -> { + if (Helpers.getClassName(componentInstance).equals(type)) { // Todo detect dynamic proxy ! + ref.accept((I) componentInstance, component, oref, oservice, nref, nservice); + } + }); + }); + return (B) this; + } + + protected Object createCallbackInstance() { + Object cb = null; + + cb = new Object() { + void add(Component c, ServiceReference<T> ref, Object service) { + invokeMethodRefs("add", c, ref, (T) service); + } + + void change(Component c, ServiceReference<T> ref, Object service) { + invokeMethodRefs("change", c, ref, (T) service); + } + + void remove(Component c, ServiceReference<T> ref, Object service) { + invokeMethodRefs("remove", c, ref, (T) service); + } + + void swap(Component c, ServiceReference<T> oldRef, Object oldSrv, ServiceReference<T> newRef, Object newSrv) { + invokeSwapMethodRefs(c, oldRef, (T) oldSrv, newRef, (T) newSrv); + } + }; + + return cb; + } + + protected boolean hasCallbacks() { + return m_refs.size() > 0 || m_swapRefs.size() > 0; + } + + protected boolean hasComponentInstanceCallbacks() { + return m_hasComponentInstanceCallbacks; + } + + private void invokeMethodRefs(String method, Component comp, ServiceReference<T> ref, T service) { + m_refs.computeIfPresent(method, (k, mrefs) -> { + mrefs.forEach(mref -> mref.accept(null, comp, ref, service)); + return mrefs; + }); + } + + protected void invokeSwapMethodRefs(Component c, ServiceReference<T> oref, T osrv, ServiceReference<T> nref, T nsrv) { + m_swapRefs.forEach(ref -> ref.accept(null, c, oref, osrv, nref, nsrv)); + } +}
Added: 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=1719841&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/impl/ServiceDependencyBuilderImpl.java Sun Dec 13 22:23:57 2015 @@ -0,0 +1,167 @@ +package org.apache.felix.dm.builder.lambda.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.lambda.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 (hasComponentInstanceCallbacks() || hasCallbacks()) { + Object cb = createCallbackInstance(); + sd.setCallbacks(cb, "add", "change", "remove", "swap"); + + if (! hasComponentInstanceCallbacks()) { + 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-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/packageinfo URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/packageinfo?rev=1719841&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/packageinfo (added) +++ felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/src/org/apache/felix/dm/builder/lambda/packageinfo Sun Dec 13 22:23:57 2015 @@ -0,0 +1 @@ +version 1.0.0 \ No newline at end of file Added: felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/test/.gitignore URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/org.apache.felix.dependencymanager.lambda/test/.gitignore?rev=1719841&view=auto ============================================================================== (empty) Added: felix/sandbox/pderop/dependencymanager-lambda/settings.gradle URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-lambda/settings.gradle?rev=1719841&view=auto ============================================================================== --- felix/sandbox/pderop/dependencymanager-lambda/settings.gradle (added) +++ felix/sandbox/pderop/dependencymanager-lambda/settings.gradle Sun Dec 13 22:23:57 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) +}