Merge branch 'master' into 317943-replace-spring-dm-with-gemini-blueprint

Conflicts:
	org.eclipse.virgo.nano.services/.classpath
diff --git a/build-nano/build.xml b/build-nano/build.xml
index 8588547..f9fa2b9 100644
--- a/build-nano/build.xml
+++ b/build-nano/build.xml
@@ -99,7 +99,7 @@
 				<filter token="MINA.CORE.VERSION" value="${com.springsource.org.apache.mina.core}"/>
 				<filter token="SSHD.CORE.VERSION" value="${com.springsource.org.apache.sshd.core}"/>
 				<filter token="EQUINOX.CONSOLE.VERSION" value="${org.eclipse.equinox.console.supportability}"/>
-				<filter token="SPRING.DM.VERSION" value="${org.springframework.osgi}"/>
+				<filter token="SPRING.DM.VERSION" value="${org.eclipse.gemini.blueprint}"/>
 				<filter token="UTIL.VERSION" value="${org.eclipse.virgo.util}"/>
                 <filter token="CONTENTTYPE.VERSION" value="${org.eclipse.core.contenttype}"/>
                 <filter token="JOBS.VERSION" value="${org.eclipse.core.jobs}"/>
diff --git a/build-nano/publish_resources/features/org.eclipse.virgo.springdm/feature.xml b/build-nano/publish_resources/features/org.eclipse.virgo.springdm/feature.xml
index 0149515..05c6dc3 100755
--- a/build-nano/publish_resources/features/org.eclipse.virgo.springdm/feature.xml
+++ b/build-nano/publish_resources/features/org.eclipse.virgo.springdm/feature.xml
@@ -19,14 +19,14 @@
    </license>
 
    <plugin
-         id="org.springframework.osgi.core"
+         id="org.eclipse.gemini.blueprint.core"
          download-size="0"
          install-size="0"
          version="@SPRING.DM.VERSION@"
          unpack="false"/>
 
    <plugin
-         id="org.springframework.osgi.extender"
+         id="org.eclipse.gemini.blueprint.extender"
          download-size="0"
          install-size="0"
          version="@SPRING.DM.VERSION@"
@@ -34,7 +34,7 @@
          autostart="true"/>
 
    <plugin
-         id="org.springframework.osgi.io"
+         id="org.eclipse.gemini.blueprint.io"
          download-size="0"
          install-size="0"
          version="@SPRING.DM.VERSION@"
diff --git a/build.versions b/build.versions
index 33a897c..f5c5a74 100644
--- a/build.versions
+++ b/build.versions
@@ -15,7 +15,7 @@
 org.eclipse.virgo.build.tools=1.2.1.RELEASE
 org.slf4j=1.6.1
 org.slf4j.spi=1.6.1
-org.springframework.osgi=1.2.1
+org.eclipse.gemini.blueprint=1.0.0.RELEASE
 org.springframework=3.0.5.RELEASE
 org.apache.felix.gogo.shell=0.8.0.v201107131313
 org.apache.felix.gogo.runtime=0.8.0.v201105062003
diff --git a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/BundleUtils.java b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/BundleUtils.java
index 953fdc4..ddffb57 100644
--- a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/BundleUtils.java
+++ b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/BundleUtils.java
@@ -11,33 +11,20 @@
 
 package org.eclipse.virgo.kernel.core;
 
+import org.eclipse.virgo.util.common.StringUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 
-import org.eclipse.virgo.kernel.core.internal.SpringUtils;
-import org.eclipse.virgo.util.common.StringUtils;
-
-
 /**
  * <code>BundleUtils</code> provides utility methods for interacting with {@link Bundle Bundles}.
  * <p />
- *
+ * 
  * <strong>Concurrent Semantics</strong><br />
  * Thread-safe
- *
+ * 
  */
 public final class BundleUtils {
-    
-    /**
-     * Queries whether the supplied {@link Bundle} is Spring-DM powered.
-     * 
-     * @param bundle the <code>Bundle</code>.
-     * @return <code>true</code> if the <code>Bundle</code> is Spring-DM powered, otherwise <code>false</code>.
-     */
-    public static boolean isSpringOsgiPoweredBundle(Bundle bundle) {
-        return SpringUtils.isSpringDMPoweredBundle(bundle);
-    }        
-    
+
     /**
      * Queries whether the supplied {@link Bundle} is a fragment
      * 
@@ -49,6 +36,5 @@
         String fragmentHostHeader = (String) bundle.getHeaders().get(Constants.FRAGMENT_HOST);
         return StringUtils.hasText(fragmentHostHeader);
     }
-    
-    
+
 }
diff --git a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/SpringUtils.java b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/SpringUtils.java
index fb70f4d..3ece4c7 100644
--- a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/SpringUtils.java
+++ b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/SpringUtils.java
@@ -16,34 +16,44 @@
  */
 public class SpringUtils {
 
-    public static final String CONTEXT_DIR = "/META-INF/spring/";
+    private static final String SPRING_DM_CONTEXT_DIR = "/META-INF/spring/";
+    
+    private static final String BLUEPRINT_CONTEXT_DIR = "/OSGI-INF/blueprint/";
 
-    public static final String CONTEXT_FILES = "*.xml";
+    private static final String CONTEXT_FILES = "*.xml";
 
-    public static final String BUNDLE_URL_PREFIX = "osgibundle:";
+    private static final String BUNDLE_URL_PREFIX = "osgibundle:";
 
-    public static final String SPRING_CONTEXT_HEADER = "Spring-Context";
+    private static final String SPRING_CONTEXT_HEADER = "Spring-Context";
+    
+    private static final String BUNDLE_BLUEPRINT_HEADER = "Bundle-Blueprint";
 
-    public static final String DIRECTIVE_SEPARATOR = ";";
+    private static final String DIRECTIVE_SEPARATOR = ";";
 
-    public static final String CONTEXT_LOCATION_SEPARATOR = ",";
+    private static final String CONTEXT_LOCATION_SEPARATOR = ",";
 
-    public static final String CONFIG_WILDCARD = "*";
+    private static final String CONFIG_WILDCARD = "*";
 
-    /** Default configuration location */
-    public static final String DEFAULT_CONFIG = BUNDLE_URL_PREFIX + CONTEXT_DIR + CONTEXT_FILES;
+    /** Default configuration locations */
+    private static final String SPRING_DM_DEFAULT_CONFIG = BUNDLE_URL_PREFIX + SPRING_DM_CONTEXT_DIR + CONTEXT_FILES;
+    private static final String BLUEPRINT_DEFAULT_CONFIG = BUNDLE_URL_PREFIX + BLUEPRINT_CONTEXT_DIR + CONTEXT_FILES;
 
-    public static String[] getSpringContextConfigurations(Bundle bundle) {
+    private static String[] getSpringContextConfigurations(Bundle bundle) {
         String[] locations = getSpringContextHeaderLocations(bundle.getHeaders());
 
         // if no location is specified in the header, try the defaults
         if (isArrayEmpty(locations)) {
             // check the default locations if the manifest doesn't provide any info
-            Enumeration defaultConfig = bundle.findEntries(CONTEXT_DIR, CONTEXT_FILES, false);
+            Enumeration defaultConfig = bundle.findEntries(SPRING_DM_CONTEXT_DIR, CONTEXT_FILES, false);
             if (defaultConfig != null && defaultConfig.hasMoreElements()) {
-                return new String[] { DEFAULT_CONFIG };
+                return new String[] { SPRING_DM_DEFAULT_CONFIG };
             } else {
-                return new String[0];
+                defaultConfig = bundle.findEntries(BLUEPRINT_CONTEXT_DIR, CONTEXT_FILES, false);
+                if (defaultConfig != null && defaultConfig.hasMoreElements()) {
+                    return new String[] { BLUEPRINT_DEFAULT_CONFIG };
+                } else {
+                    return new String[0];
+                }
             }
         } else {
             return locations;
@@ -57,7 +67,7 @@
      * @param headers bundle headers
      * @return array of locations specified (if any)
      */
-    public static String[] getSpringContextHeaderLocations(Dictionary headers) {
+    static String[] getSpringContextHeaderLocations(Dictionary headers) {
         String header = getSpringContextHeader(headers);
         String[] ctxEntries;
         if (StringUtils.hasText(header) && !(';' == header.charAt(0))) {
@@ -68,10 +78,23 @@
             // replace * with a 'digestable' location
             for (int i = 0; i < ctxEntries.length; i++) {
                 if (CONFIG_WILDCARD.equals(ctxEntries[i]))
-                    ctxEntries[i] = DEFAULT_CONFIG;
+                    ctxEntries[i] = SPRING_DM_DEFAULT_CONFIG;
             }
         } else {
-            ctxEntries = new String[0];
+            header = getBundleBlueprintHeader(headers);
+            if (StringUtils.hasText(header) && !(';' == header.charAt(0))) {
+                // get the config locations
+                String locations = StringUtils.tokenizeToStringArray(header, DIRECTIVE_SEPARATOR)[0];
+                // parse it into individual token
+                ctxEntries = StringUtils.tokenizeToStringArray(locations, CONTEXT_LOCATION_SEPARATOR);
+                // replace * with a 'digestable' location
+                for (int i = 0; i < ctxEntries.length; i++) {
+                    if (CONFIG_WILDCARD.equals(ctxEntries[i]))
+                        ctxEntries[i] = BLUEPRINT_DEFAULT_CONFIG;
+                }
+            } else {
+                ctxEntries = new String[0];
+            }
         }
         return ctxEntries;
     }
@@ -80,13 +103,28 @@
         return (array == null || array.length == 0);
     }
 
-    public static String getSpringContextHeader(Dictionary headers) {
+    static String getSpringContextHeader(Dictionary headers) {
         Object header = null;
-        if (headers != null)
+        if (headers != null) {
             header = headers.get(SPRING_CONTEXT_HEADER);
+        }
         return (header != null ? header.toString().trim() : null);
     }
 
+    static String getBundleBlueprintHeader(Dictionary headers) {
+        Object header = null;
+        if (headers != null) {
+            header = headers.get(BUNDLE_BLUEPRINT_HEADER);
+        }
+        return (header != null ? header.toString().trim() : null);
+    }
+    
+    /**
+     * Queries whether the supplied {@link Bundle} is Spring-DM powered.
+     * 
+     * @param bundle the <code>Bundle</code>.
+     * @return <code>true</code> if the <code>Bundle</code> is Spring-DM powered, otherwise <code>false</code>.
+     */
     public static boolean isSpringDMPoweredBundle(Bundle bundle) {
         String[] configurations = getSpringContextConfigurations(bundle);
         return !isArrayEmpty(configurations);
diff --git a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/blueprint/ApplicationContextDependencyMonitor.java b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/blueprint/ApplicationContextDependencyMonitor.java
index e3cb0c6..96bd918 100644
--- a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/blueprint/ApplicationContextDependencyMonitor.java
+++ b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/blueprint/ApplicationContextDependencyMonitor.java
@@ -91,18 +91,24 @@
 
             if (EVENT_WAITING.equals(event.getTopic())) {
                 List<ServiceDependency> serviceDependencies = createServiceDependencies(event);
-                for (ServiceDependency serviceDependency : serviceDependencies) {
-                    addServiceDependencyTicker(serviceDependency, bundle);
+                if (serviceDependencies != null) {
+                    for (ServiceDependency serviceDependency : serviceDependencies) {
+                        addServiceDependencyTicker(serviceDependency, bundle);
+                    }
                 }
             } else if (EVENT_GRACE_PERIOD.equals(event.getTopic())) {
                 List<ServiceDependency> remainingUnsatisfiedDependencies = createServiceDependencies(event);
-                changeInUnsatisfiedDependencies(remainingUnsatisfiedDependencies, bundle);
+                if (remainingUnsatisfiedDependencies != null) {
+                    changeInUnsatisfiedDependencies(remainingUnsatisfiedDependencies, bundle);
+                }
 
             } else if (EVENT_FAILURE.equals(event.getTopic())) {
                 String[] dependenciesArray = (String[]) event.getProperty("dependencies");
                 if (dependenciesArray != null) {
                     List<ServiceDependency> serviceDependencies = createServiceDependencies(event);
-                    serviceDependenciesTimedOut(serviceDependencies, bundle);
+                    if (serviceDependencies != null) {
+                        serviceDependenciesTimedOut(serviceDependencies, bundle);
+                    }
                 } else {
                     containerCreationFailed(bundle);
                 }
@@ -243,14 +249,20 @@
         String[] beanNames = (String[]) event.getProperty("bean.name");
 
         List<ServiceDependency> serviceDependencies = new ArrayList<ServiceDependency>();
-
         if (filters != null && beanNames != null) {
             for (int i = 0; i < filters.length; i++) {
                 serviceDependencies.add(new ServiceDependency(filters[i], beanNames[i]));
             }
+            return serviceDependencies;
         }
 
-        return serviceDependencies;
+        /*
+         * Return null when filters is non-null and beanNames is null. Blueprint events sometimes lack this information,
+         * but a corresponding event including bean names is posted by
+         * BlueprintEventPostingOsgiBundleApplicationContextListener on receipt of the underlying Spring DM event. A
+         * return value of null indicates that the caller should ignore this event.
+         */
+        return filters == null ? serviceDependencies : null;
     }
 
     private static final class ServiceDependency {
diff --git a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/shim/scope/internal/StandardScopeFactory.java b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/shim/scope/internal/StandardScopeFactory.java
index 2086fd1..dec7e33 100644
--- a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/shim/scope/internal/StandardScopeFactory.java
+++ b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/shim/scope/internal/StandardScopeFactory.java
@@ -33,7 +33,9 @@
  */
 public final class StandardScopeFactory implements ScopeFactory {
 
-    private static final String PROPERTY_BEAN_NAME = "org.springframework.osgi.bean.name";
+    private static final String PROPERTY_BLUEPRINT_CONTEXT_SERVICE_NAME = "org.eclipse.gemini.blueprint.context.service.name";
+
+    private static final String PROPERTY_BEAN_NAME = "org.eclipse.gemini.blueprint.bean.name";
 
     private final EventLogger eventLogger;
 
@@ -102,15 +104,15 @@
              */
             serviceScope = (String) ref.getProperty("com.springsource.service.scope");
             if (serviceScope == null) {
-                String beanName = (String) ref.getProperty(PROPERTY_BEAN_NAME);
-                if (beanName == null) {
+                // Blueprint (application) contexts belong in the global scope.
+                if (ref.getProperty(PROPERTY_BLUEPRINT_CONTEXT_SERVICE_NAME) != null) {
                     serviceScope = Scope.SCOPE_ID_GLOBAL;
+                }
+                else
+                if (isBundleScoped(ref.getBundle())) {
+                    serviceScope = Scope.SCOPE_ID_APP;
                 } else {
-                    if (isBundleScoped(ref.getBundle())) {
-                        serviceScope = Scope.SCOPE_ID_APP;
-                    } else {
-                        serviceScope = Scope.SCOPE_ID_GLOBAL;
-                    }
+                    serviceScope = Scope.SCOPE_ID_GLOBAL;
                 }
             } else {
                 this.eventLogger.log(KernelLogEvents.OLD_SCOPING_PROPERTY_USED, ref.getBundle().getSymbolicName(), ref.getBundle().getVersion(),
diff --git a/org.eclipse.virgo.kernel.core/src/test/java/org/eclipse/virgo/kernel/core/internal/SpringUtilsTests.java b/org.eclipse.virgo.kernel.core/src/test/java/org/eclipse/virgo/kernel/core/internal/SpringUtilsTests.java
index 85016ec..647a13e 100644
--- a/org.eclipse.virgo.kernel.core/src/test/java/org/eclipse/virgo/kernel/core/internal/SpringUtilsTests.java
+++ b/org.eclipse.virgo.kernel.core/src/test/java/org/eclipse/virgo/kernel/core/internal/SpringUtilsTests.java
@@ -12,6 +12,7 @@
 package org.eclipse.virgo.kernel.core.internal;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.util.Dictionary;
@@ -46,6 +47,28 @@
     }
     
     @Test
+    public void successfulGetBundleBlueprintHeader() throws Exception {
+        Dictionary dict = new Properties();
+        dict.put("Bundle-Blueprint", "testValue");
+        dict.put("aHeader", "aValue");
+        
+        String result = SpringUtils.getBundleBlueprintHeader(dict);
+        
+        assertEquals("testValue", result);
+    }
+
+    @Test
+    public void failedGetBundleBlueprintHeader() {
+        
+        Dictionary dict = new Properties();
+        dict.put("aHeader", "aValue");
+    
+        String result = SpringUtils.getBundleBlueprintHeader(dict);
+    
+        assertEquals(null, result);
+    }
+    
+    @Test
     public void testIsEmptyCheck() {
         
         Object[] emptyArray = {};
@@ -80,6 +103,29 @@
     }
     
     @Test
+    public void testGetBundleBlueprintHeaderLocations() {
+        //try single location
+        Dictionary dict = new Properties();
+        dict.put("Bundle-Blueprint", "testValue");
+        dict.put("aHeader", "aValue");
+        
+        String[] locations = SpringUtils.getSpringContextHeaderLocations(dict);
+        assertEquals(1, locations.length);
+        assertEquals("testValue", locations[0]);
+        
+        //try with 1+ locations
+        dict = new Properties();
+        dict.put("Bundle-Blueprint", "testValue1,testValue2");
+        dict.put("aHeader", "aValue");
+        
+        locations = SpringUtils.getSpringContextHeaderLocations(dict);
+        assertEquals(2, locations.length);
+        assertEquals("testValue1", locations[0]);
+        assertEquals("testValue2", locations[1]);
+    }
+
+    
+    @Test
     public void testIsSpringPoweredBundle() {
         StubBundle bundle = new StubBundle("org.eclipse.virgo.kernel.startuptest", new Version(1,0,0));
         bundle.addHeader("Spring-Context", "testLocation");
@@ -88,5 +134,22 @@
         assertTrue(isSpringDMPowered);
     }
 
+    @Test
+    public void testIsBlueprintBundleSpringPoweredBundle() {
+        StubBundle bundle = new StubBundle("org.eclipse.virgo.kernel.startuptest", new Version(1,0,0));
+        bundle.addHeader("Bundle-Blueprint", "testLocation");
+        
+        boolean isSpringDMPowered = SpringUtils.isSpringDMPoweredBundle(bundle);
+        assertTrue(isSpringDMPowered);
+    }
+    
+    @Test
+    public void testIsBlueprintDisabledBundleNotSpringPoweredBundle() {
+        StubBundle bundle = new StubBundle("org.eclipse.virgo.kernel.startuptest", new Version(1,0,0));
+        bundle.addHeader("Bundle-Blueprint", "");
+        
+        boolean isSpringDMPowered = SpringUtils.isSpringDMPoweredBundle(bundle);
+        assertFalse(isSpringDMPowered);
+    }
    
 }
diff --git a/org.eclipse.virgo.nano.services/.classpath b/org.eclipse.virgo.nano.services/.classpath
index b950d53..3a47167 100644
--- a/org.eclipse.virgo.nano.services/.classpath
+++ b/org.eclipse.virgo.nano.services/.classpath
@@ -40,6 +40,7 @@
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic.core/3.5.0.M03/org.eclipse.virgo.medic.core-3.5.0.M03.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic.core/1.0.0.CI-B20/org.eclipse.virgo.medic.core-sources-1.0.0.CI-B20.jar"/>
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.6.1/com.springsource.slf4j.api-1.6.1.jar" sourcepath="/KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.6.1/com.springsource.slf4j.api-sources-1.6.1.jar"/>
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.nop/1.6.1/com.springsource.slf4j.nop-1.6.1.jar" sourcepath="/KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.nop/1.6.1/com.springsource.slf4j.nop-sources-1.6.1.jar"/>
+	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.gemini/org.eclipse.gemini.blueprint.core/1.0.0.RELEASE/org.eclipse.gemini.blueprint.core-1.0.0.RELEASE.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.gemini/org.eclipse.gemini.blueprint.core/1.0.0.RELEASE/org.eclipse.gemini.blueprint.core-sources-1.0.0.RELEASE.jar"/>
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.teststubs/org.eclipse.virgo.teststubs.osgi/3.5.0.M03/org.eclipse.virgo.teststubs.osgi-3.5.0.M03.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.teststubs/org.eclipse.virgo.teststubs.osgi/3.5.0.M03/org.eclipse.virgo.teststubs.osgi-sources-3.5.0.M03.jar"/>
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.math/3.5.0.M03/org.eclipse.virgo.util.math-3.5.0.M03.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.math/3.5.0.M03/org.eclipse.virgo.util.math-sources-3.5.0.M03.jar"/>
 	<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.parser.manifest/3.5.0.M03/org.eclipse.virgo.util.parser.manifest-3.5.0.M03.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.parser.manifest/3.5.0.M03/org.eclipse.virgo.util.parser.manifest-sources-3.5.0.M03.jar"/>