You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by da...@apache.org on 2012/03/08 14:17:55 UTC

svn commit: r1298382 - in /aries/trunk/spi-fly: spi-fly-core/src/main/java/org/apache/aries/spifly/ spi-fly-core/src/main/java/org/apache/aries/spifly/api/ spi-fly-core/src/test/java/org/apache/aries/spifly/ spi-fly-dynamic-bundle/src/test/java/org/apa...

Author: davidb
Date: Thu Mar  8 13:17:55 2012
New Revision: 1298382

URL: http://svn.apache.org/viewvc?rev=1298382&view=rev
Log:
Initial refactor to support the latest ServiceLoader Mediator spec.

Modified:
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerBundleTrackerCustomizer.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerHeaderProcessor.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
    aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java
    aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/impl4/AltSPIImpl2.java
    aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java Thu Mar  8 13:17:55 2012
@@ -37,7 +37,6 @@ import org.apache.aries.spifly.api.SpiFl
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.BundleTracker;
@@ -87,7 +86,7 @@ public abstract class BaseActivator impl
         activator = this;
     }
 
-    public void addConsumerWeavingData(Bundle bundle, String consumerHeaderName) {
+    public void addConsumerWeavingData(Bundle bundle, String consumerHeaderName) throws Exception {
         if (bundleWeavingData.containsKey(bundle)) {
             // This bundle was already processed
             return;
@@ -229,14 +228,12 @@ public abstract class BaseActivator impl
                     }
                 } else if (desc.getFilter() != null) {
                     Hashtable<String, Object> d = new Hashtable<String, Object>();
-                    d.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, b.getSymbolicName());
-                    d.put(Constants.BUNDLE_VERSION_ATTRIBUTE, b.getVersion());
 
                     if (ServiceLoader.class.getName().equals(className) &&
                         "load".equals(methodName)) {
                         String type = args.get(new Pair<Integer, String>(0, Class.class.getName()));
                         if (type != null) {
-                            d.put(SpiFlyConstants.CONSUMED_SPI_CONDITION, type);
+                            d.put(SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE, type);
                             d.putAll(getCustomBundleAttributes(type, b));
                         }
                     }

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerBundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerBundleTrackerCustomizer.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerBundleTrackerCustomizer.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerBundleTrackerCustomizer.java Thu Mar  8 13:17:55 2012
@@ -25,7 +25,7 @@ import org.osgi.util.tracker.BundleTrack
 public class ConsumerBundleTrackerCustomizer implements BundleTrackerCustomizer {
     private final BaseActivator activator;
     private final String headerName;
-    
+
     public ConsumerBundleTrackerCustomizer(BaseActivator baseActivator, String consumerHeaderName) {
         activator = baseActivator;
         headerName = consumerHeaderName;
@@ -33,7 +33,11 @@ public class ConsumerBundleTrackerCustom
 
     @Override
     public Object addingBundle(Bundle bundle, BundleEvent event) {
-        activator.addConsumerWeavingData(bundle, headerName);                    
+        try {
+            activator.addConsumerWeavingData(bundle, headerName);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
         return bundle;
     }
 

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerHeaderProcessor.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerHeaderProcessor.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerHeaderProcessor.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ConsumerHeaderProcessor.java Thu Mar  8 13:17:55 2012
@@ -19,7 +19,10 @@
 package org.apache.aries.spifly;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.ServiceLoader;
 import java.util.Set;
@@ -34,6 +37,13 @@ import org.osgi.framework.InvalidSyntaxE
 import org.osgi.framework.Version;
 
 public class ConsumerHeaderProcessor {
+    private static final Dictionary<String, String> PROCESSOR_FILTER_MATCH;
+
+    static {
+        PROCESSOR_FILTER_MATCH = new Hashtable<String, String>();
+        PROCESSOR_FILTER_MATCH.put(SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE, SpiFlyConstants.CLIENT_EXTENDER_NAME);
+    }
+
     /**
      * Parses headers of the following syntax:
      * <ul>
@@ -62,7 +72,7 @@ public class ConsumerHeaderProcessor {
      * @param consumerHeader the <tt>SPI-Consumer</tt> header.
      * @return an instance of the {@link WeavingData} class.
      */
-    public static Set<WeavingData> processHeader(String consumerHeaderName, String consumerHeader) {
+    public static Set<WeavingData> processHeader(String consumerHeaderName, String consumerHeader) throws Exception {
         if (SpiFlyConstants.REQUIRE_CAPABILITY.equals(consumerHeaderName)) {
             return processRequireCapabilityHeader(consumerHeader);
         }
@@ -165,31 +175,28 @@ public class ConsumerHeaderProcessor {
         return weavingData;
     }
 
-    private static Set<WeavingData> processRequireCapabilityHeader(String consumerHeader) {
+    private static Set<WeavingData> processRequireCapabilityHeader(String consumerHeader) throws InvalidSyntaxException {
         Set<WeavingData> weavingData = new HashSet<WeavingData>();
 
         List<GenericMetadata> requirements = ManifestHeaderProcessor.parseRequirementString(consumerHeader);
-        for (GenericMetadata req : requirements) {
-            if (SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE.equals(req.getNamespace())) {
-                if (SpiFlyConstants.CLIENT_EXTENDER_NAME.equals(req.getAttributes().get(SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE))) {
-                    ArgRestrictions ar = new ArgRestrictions();
-                    ar.addRestriction(0, Class.class.getName());
-                    MethodRestriction mr = new MethodRestriction("load", ar);
-
-                    List<BundleDescriptor> allowedBundles = new ArrayList<BundleDescriptor>();
-                    String filterString = req.getDirectives().get(SpiFlyConstants.PROVIDER_FILTER_DIRECTIVE);
-                    if (filterString != null) {
-                        try {
-                            Filter filter = FrameworkUtil.createFilter(filterString);
-                            allowedBundles.add(new BundleDescriptor(filter));
-                        } catch (InvalidSyntaxException e) {
-                            throw new IllegalArgumentException("Syntax error in filter " + filterString + " which appears in " + consumerHeader);
-                        }
-                    }
+        GenericMetadata extenderRequirement = findRequirement(requirements, SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE, SpiFlyConstants.CLIENT_EXTENDER_NAME);
+        Collection<GenericMetadata> serviceLoaderRequirements = findAllMetadata(requirements, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE);
 
-                    weavingData.add(createWeavingData(ServiceLoader.class.getName(), "load", mr, allowedBundles));
+        if (extenderRequirement != null) {
+            ArgRestrictions ar = new ArgRestrictions();
+            ar.addRestriction(0, Class.class.getName());
+            MethodRestriction mr = new MethodRestriction("load", ar);
+
+            List<BundleDescriptor> allowedBundles = new ArrayList<BundleDescriptor>();
+            for (GenericMetadata req : serviceLoaderRequirements) {
+                String slFilterString = req.getDirectives().get(SpiFlyConstants.FILTER_DIRECTIVE);
+                if (slFilterString != null) {
+                    Filter slFilter = FrameworkUtil.createFilter(slFilterString);
+                    allowedBundles.add(new BundleDescriptor(slFilter));
                 }
             }
+
+            weavingData.add(createWeavingData(ServiceLoader.class.getName(), "load", mr, allowedBundles));
         }
 
         return weavingData;
@@ -209,4 +216,44 @@ public class ConsumerHeaderProcessor {
         return new WeavingData(className, methodName, argClasses, restrictions,
                 allowedBundles.size() == 0 ? null : allowedBundles);
     }
+
+    private static GenericMetadata findRequirement(List<GenericMetadata> requirements, String namespace, String type) throws InvalidSyntaxException {
+        Dictionary<String, String> nsAttr = new Hashtable<String, String>();
+        nsAttr.put(namespace, type);
+
+        for (GenericMetadata req : requirements) {
+            if (namespace.equals(req.getNamespace())) {
+                String filterString = req.getDirectives().get(SpiFlyConstants.FILTER_DIRECTIVE);
+                if (filterString != null) {
+                    Filter filter = FrameworkUtil.createFilter(filterString);
+                    if (filter.match(nsAttr)) {
+                        return req;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+
+//    private static GenericMetadata findMetadata(List<GenericMetadata> requirements, String namespace, String type) {
+//        for (GenericMetadata req : requirements) {
+//            if (namespace.equals(req.getNamespace())) {
+//                if (type.equals(req.getAttributes().get(namespace))) {
+//                    return req;
+//                }
+//            }
+//        }
+//        return null;
+//    }
+
+    private static Collection<GenericMetadata> findAllMetadata(List<GenericMetadata> requirements, String namespace) {
+        List<GenericMetadata> reqs = new ArrayList<ManifestHeaderProcessor.GenericMetadata>();
+        for (GenericMetadata req : requirements) {
+            if (namespace.equals(req.getNamespace())) {
+                reqs.add(req);
+            }
+        }
+        return reqs;
+    }
 }

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java Thu Mar  8 13:17:55 2012
@@ -24,6 +24,7 @@ import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
@@ -40,6 +41,9 @@ import org.apache.aries.util.manifest.Ma
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
@@ -68,11 +72,15 @@ public class ProviderBundleTrackerCustom
 
         List<String> providedServices = null;
         Map<String, Object> customAttributes = new HashMap<String, Object>();
-        Map<String, String> directives = new HashMap<String, String>();
         if (bundle.getHeaders().get(SpiFlyConstants.REQUIRE_CAPABILITY) != null) {
-            providedServices = readRequireCapability(bundle.getHeaders(), directives, customAttributes);
+            try {
+                providedServices = readRequireCapability(bundle.getHeaders(), customAttributes);
+            } catch (InvalidSyntaxException e) {
+                log(LogService.LOG_ERROR, "Unable to read capabilities from bundle " + bundle, e);
+            }
         }
 
+        boolean fromSPIProviderHeader = false;
         if (providedServices == null && bundle.getHeaders().get(SpiFlyConstants.SPI_PROVIDER_HEADER) != null) {
             String header = bundle.getHeaders().get(SpiFlyConstants.SPI_PROVIDER_HEADER).toString().trim();
             if ("*".equals(header)) {
@@ -80,6 +88,7 @@ public class ProviderBundleTrackerCustom
             } else {
                 providedServices = Arrays.asList(header.split(","));
             }
+            fromSPIProviderHeader = true;
         }
 
         if (providedServices == null) {
@@ -102,12 +111,12 @@ public class ProviderBundleTrackerCustom
         if (servicesDir == null)
             return null;
 
-        List<URL> serviceFiles = new ArrayList<URL>();
+        List<URL> serviceFileURLs = new ArrayList<URL>();
 
         @SuppressWarnings("unchecked")
         Enumeration<URL> entries = bundle.findEntries(METAINF_SERVICES, "*", false);
         if (entries != null) {
-            serviceFiles.addAll(Collections.list(entries));
+            serviceFileURLs.addAll(Collections.list(entries));
         }
 
         Object bcp = bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
@@ -119,29 +128,29 @@ public class ProviderBundleTrackerCustom
 
                 URL url = bundle.getResource(entry);
                 if (url != null) {
-                    serviceFiles.addAll(getMetaInfServiceURLsFromJar(url));
+                    serviceFileURLs.addAll(getMetaInfServiceURLsFromJar(url));
                 }
             }
         }
 
         List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
-        for (URL serviceFile : serviceFiles) {
-            log(LogService.LOG_INFO, "Found SPI resource: " + serviceFile);
+        for (URL serviceFileURL : serviceFileURLs) {
+            log(LogService.LOG_INFO, "Found SPI resource: " + serviceFileURL);
 
             try {
                 BufferedReader reader = new BufferedReader(
-                        new InputStreamReader(serviceFile.openStream()));
+                        new InputStreamReader(serviceFileURL.openStream()));
                 String className = null;
                 while((className = reader.readLine()) != null) {
                     try {
                         if (className.startsWith("#"))
                             continue; // a comment
 
-                        String s = serviceFile.toExternalForm();
-                        int idx = s.lastIndexOf('/');
+                        String serviceFile = serviceFileURL.toExternalForm();
+                        int idx = serviceFile.lastIndexOf('/');
                         String registrationClassName = className;
-                        if (s.length() > idx) {
-                            registrationClassName = s.substring(idx + 1);
+                        if (serviceFile.length() > idx) {
+                            registrationClassName = serviceFile.substring(idx + 1);
                         }
                         if (providedServices.size() > 0 && !providedServices.contains(registrationClassName))
                             continue;
@@ -150,13 +159,16 @@ public class ProviderBundleTrackerCustom
                         Object o = cls.newInstance();
                         log(LogService.LOG_INFO, "Instantiated SPI provider: " + o);
 
-                        Hashtable<String, Object> props = new Hashtable<String, Object>();
-                        props.put(SpiFlyConstants.SPI_PROVIDER_URL_PROPERTY, serviceFile);
-                        props.putAll(customAttributes);
+                        Hashtable<String, Object> properties;
+                        if (fromSPIProviderHeader)
+                            properties = new Hashtable<String, Object>();
+                        else
+                            properties = findServiceRegistrationProperties(bundle.getHeaders(), registrationClassName, className);
 
-                        if (!"false".equalsIgnoreCase(directives.get(SpiFlyConstants.SERVICE_REGISTRY_DIRECTIVE))) {
+                        if (properties != null) {
+                            properties.put(SpiFlyConstants.SERVICELOADER_URL_PROPERTY, serviceFile);
                             ServiceRegistration reg = bundle.getBundleContext()
-                                    .registerService(registrationClassName, o, props);
+                                    .registerService(registrationClassName, o, properties);
                             registrations.add(reg);
                             log(LogService.LOG_INFO, "Registered service: " + reg);
                         }
@@ -165,11 +177,11 @@ public class ProviderBundleTrackerCustom
                         log(LogService.LOG_INFO, "Registered provider: " + registrationClassName + " in bundle " + bundle.getSymbolicName());
                     } catch (Exception e) {
                         log(LogService.LOG_WARNING,
-                                "Could not load SPI implementation referred from " + serviceFile, e);
+                                "Could not load SPI implementation referred from " + serviceFileURL, e);
                     }
                 }
             } catch (IOException e) {
-                log(LogService.LOG_WARNING, "Could not read SPI metadata from " + serviceFile, e);
+                log(LogService.LOG_WARNING, "Could not read SPI metadata from " + serviceFileURL, e);
             }
         }
 
@@ -179,12 +191,46 @@ public class ProviderBundleTrackerCustom
     // An empty list returned means 'all SPIs'
     // A return value of null means no SPIs
     // A populated list means: only these SPIs
-    private List<String> readRequireCapability(Dictionary<?,?> headers, Map<String, String> directives, Map<String, Object> customAttributes) {
-        Object capabilityHeader = headers.get(SpiFlyConstants.REQUIRE_CAPABILITY);
+    private List<String> readRequireCapability(Dictionary<?,?> headers, Map<String, Object> customAttributes) throws InvalidSyntaxException {
+        Object requirementHeader = headers.get(SpiFlyConstants.REQUIRE_CAPABILITY);
+        if (requirementHeader == null)
+            return null;
+
+        List<GenericMetadata> requirements = ManifestHeaderProcessor.parseRequirementString(requirementHeader.toString());
+        GenericMetadata extenderRequirement = findRequirement(requirements, SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE, SpiFlyConstants.PROVIDER_EXTENDER_NAME);
+        if (extenderRequirement == null)
+            return null;
+
+        List<GenericMetadata> capabilities;
+        Object capabilityHeader = headers.get(SpiFlyConstants.PROVIDE_CAPABILITY);
+        if (capabilityHeader == null) {
+            capabilities = Collections.emptyList();
+        } else {
+            capabilities = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader.toString());
+        }
+
+        List<String> serviceNames = new ArrayList<String>();
+        for (GenericMetadata serviceLoaderCapability : findAllMetadata(capabilities, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE)) {
+            for (Map.Entry<String, Object> entry : serviceLoaderCapability.getAttributes().entrySet()) {
+                if (SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE.equals(entry.getKey())) {
+                    serviceNames.add(entry.getValue().toString());
+                    continue;
+                }
+
+                customAttributes.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return serviceNames;
+
+/*
+        //******************
+        Object capabilityHeaderxx = headers.get(SpiFlyConstants.REQUIRE_CAPABILITY);
         if (capabilityHeader == null)
             return null;
 
-        List<GenericMetadata> capabilities = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader.toString());
+        // Find the extender namespace and check that its filter matches serviceloader.registrar
+        // if so, find all capabilties in osgi.serviceloader namespace,
+        List<GenericMetadata> capabilitiesxx = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader.toString());
         for (GenericMetadata cap : capabilities) {
             if (!SpiFlyConstants.EXTENDER_CAPABILITY_NAMESPACE.equals(cap.getNamespace()))
                 continue;
@@ -217,6 +263,43 @@ public class ProviderBundleTrackerCustom
             return serviceNames;
         }
         return null;
+        */
+    }
+
+    // null means don't register,
+    // otherwise the return value should be taken as the service registration properties
+    private Hashtable<String, Object> findServiceRegistrationProperties(Dictionary<?,?> headers, String spiName, String implName) {
+        Object capabilityHeader = headers.get(SpiFlyConstants.PROVIDE_CAPABILITY);
+        if (capabilityHeader == null)
+            return null;
+
+        List<GenericMetadata> capabilities = ManifestHeaderProcessor.parseCapabilityString(capabilityHeader.toString());
+        GenericMetadata cap = findCapability(capabilities, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE, spiName);
+
+        Hashtable<String, Object> properties = new Hashtable<String, Object>();
+        if (cap != null) {
+            for (Map.Entry<String, Object> entry : cap.getAttributes().entrySet()) {
+                if (SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE.equals(entry.getKey()))
+                    continue;
+
+                properties.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        String registerDirective = cap.getDirectives().get(SpiFlyConstants.REGISTER_DIRECTIVE);
+        if (registerDirective == null) {
+            return properties;
+        } else {
+            if ("".equals(registerDirective.trim()))
+                return null;
+
+            if ("*".equals(registerDirective.trim()))
+                return properties;
+
+            if (implName.equals(registerDirective.trim()))
+                return properties;
+        }
+        return null;
     }
 
     private List<URL> getMetaInfServiceURLsFromJar(URL url) {
@@ -266,4 +349,43 @@ public class ProviderBundleTrackerCustom
     private void log(int level, String message, Throwable th) {
         activator.log(level, message, th);
     }
+
+    private static GenericMetadata findRequirement(List<GenericMetadata> requirements, String namespace, String type) throws InvalidSyntaxException {
+        Dictionary<String, String> nsAttr = new Hashtable<String, String>();
+        nsAttr.put(namespace, type);
+
+        for (GenericMetadata req : requirements) {
+            if (namespace.equals(req.getNamespace())) {
+                String filterString = req.getDirectives().get(SpiFlyConstants.FILTER_DIRECTIVE);
+                if (filterString != null) {
+                    Filter filter = FrameworkUtil.createFilter(filterString);
+                    if (filter.match(nsAttr)) {
+                        return req;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private GenericMetadata findCapability(List<GenericMetadata> capabilities, String namespace, String spiName) {
+        for (GenericMetadata cap : capabilities) {
+            if (namespace.equals(cap.getNamespace())) {
+                if (spiName.equals(cap.getAttributes().get(namespace))) {
+                    return cap;
+                }
+            }
+        }
+        return null;
+    }
+
+    private static Collection<GenericMetadata> findAllMetadata(List<GenericMetadata> requirements, String namespace) {
+        List<GenericMetadata> reqs = new ArrayList<ManifestHeaderProcessor.GenericMetadata>();
+        for (GenericMetadata req : requirements) {
+            if (namespace.equals(req.getNamespace())) {
+                reqs.add(req);
+            }
+        }
+        return reqs;
+    }
 }

Modified: aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/api/SpiFlyConstants.java Thu Mar  8 13:17:55 2012
@@ -20,26 +20,37 @@ package org.apache.aries.spifly.api;
 
 public interface SpiFlyConstants {
     // Not taken from OSGi Constants because this code needs to compile with the 4.2 OSGi classes.
+    String PROVIDE_CAPABILITY = "Provide-Capability";
     String REQUIRE_CAPABILITY = "Require-Capability";
+    String FILTER_DIRECTIVE = "filter";
 
     String SPI_CONSUMER_HEADER = "SPI-Consumer";
     String SPI_PROVIDER_HEADER = "SPI-Provider";
 
     String EXTENDER_CAPABILITY_NAMESPACE = "osgi.extender";
+    String SERVICELOADER_CAPABILITY_NAMESPACE = "osgi.serviceloader";
 
+    // Rename these
     String CLIENT_EXTENDER_NAME = "serviceloader.processor";
     String PROVIDER_EXTENDER_NAME = "serviceloader.registrar";
 
-    String CLIENT_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + EXTENDER_CAPABILITY_NAMESPACE + "=" + CLIENT_EXTENDER_NAME;
-    String PROVIDER_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + EXTENDER_CAPABILITY_NAMESPACE + "=" + PROVIDER_EXTENDER_NAME;
+    // String CLIENT_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + EXTENDER_CAPABILITY_NAMESPACE + "=" + CLIENT_EXTENDER_NAME;
+    String CLIENT_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + FILTER_DIRECTIVE +
+    		":=\"(" + EXTENDER_CAPABILITY_NAMESPACE + "=" + CLIENT_EXTENDER_NAME + ")\"";
+    // String PROVIDER_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + EXTENDER_CAPABILITY_NAMESPACE + "=" + PROVIDER_EXTENDER_NAME;
+    String PROVIDER_REQUIREMENT = EXTENDER_CAPABILITY_NAMESPACE + "; " + FILTER_DIRECTIVE +
+            ":=\"(" + EXTENDER_CAPABILITY_NAMESPACE + "=" + PROVIDER_EXTENDER_NAME + ")\"";
 
     String CONSUMED_SPI_CONDITION = "spi";
 
+    String REGISTER_DIRECTIVE = "register";
+    // TODO the following can go
     String PROVIDED_SPI_DIRECTIVE = "provided-spi";
+    // TODO the following can go
     String PROVIDER_FILTER_DIRECTIVE = "provider-filter";
     String SERVICE_REGISTRY_DIRECTIVE = "service-registry";
 
     String PROCESSED_SPI_CONSUMER_HEADER = "X-SpiFly-Processed-SPI-Consumer";
 
-    String SPI_PROVIDER_URL_PROPERTY = "spi.provider.url";
+    String SERVICELOADER_URL_PROPERTY = "serviceloader.url";
 }

Modified: aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-core/src/test/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizerGenericCapabilityTest.java Thu Mar  8 13:17:55 2012
@@ -71,7 +71,12 @@ public class ProviderBundleTrackerCustom
         EasyMock.replay(sreg);
 
         BundleContext implBC = mockSPIBundleContext(sreg);
-        Bundle implBundle = mockSPIBundle(implBC);
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI");
+        Bundle implBundle = mockSPIBundle(implBC, headers);
+
 
         assertEquals("Precondition", 0, activator.findProviderBundles("org.apache.aries.mytest.MySPI").size());
         // Call addingBundle();
@@ -104,8 +109,12 @@ public class ProviderBundleTrackerCustom
         EasyMock.replay(sreg);
 
         BundleContext implBC = mockSPIBundleContext(sreg);
-        Bundle implBundle = mockSPIBundle(implBC, SpiFlyConstants.PROVIDER_REQUIREMENT +
-                "; " + SpiFlyConstants.SERVICE_REGISTRY_DIRECTIVE + ":=true; approval=global");
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI; approval=yeah; " +
+                SpiFlyConstants.REGISTER_DIRECTIVE + ":=*");
+        Bundle implBundle = mockSPIBundle(implBC, headers);
 
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
         assertEquals(1, registrations.size());
@@ -115,7 +124,45 @@ public class ProviderBundleTrackerCustom
 
         Map<String, Object> attrs = activator.getCustomBundleAttributes("org.apache.aries.mytest.MySPI", implBundle);
         assertEquals(1, attrs.size());
-        assertEquals("global", attrs.get("approval"));
+        assertEquals("yeah", attrs.get("approval"));
+    }
+
+    @Test
+    public void testNonServiceRegistryBundle() throws Exception {
+        Bundle spiBundle = EasyMock.createMock(Bundle.class);
+        EasyMock.replay(spiBundle);
+        BaseActivator activator = new BaseActivator() {
+            @Override
+            public void start(BundleContext context) throws Exception {}
+        };
+
+        ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, spiBundle);
+
+        ServiceRegistration sreg = EasyMock.createMock(ServiceRegistration.class);
+        EasyMock.replay(sreg);
+
+        BundleContext implBC = mockSPIBundleContext(sreg);
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI; approval=yeah;" +
+                SpiFlyConstants.REGISTER_DIRECTIVE + ":=\"\"");
+        Bundle implBundle = mockSPIBundle(implBC, headers);
+
+        List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
+        assertEquals(0, registrations.size());
+        Collection<Bundle> bundles = activator.findProviderBundles("org.apache.aries.mytest.MySPI");
+        assertEquals(1, bundles.size());
+        assertSame(implBundle, bundles.iterator().next());
+
+        Map<String, Object> attrs = activator.getCustomBundleAttributes("org.apache.aries.mytest.MySPI", implBundle);
+        assertEquals(1, attrs.size());
+        assertEquals("yeah", attrs.get("approval"));
+    }
+
+    @Test
+    public void testRegisterAltAttributeDatatype() throws Exception {
+        // TODO
     }
 
     @Test
@@ -131,14 +178,18 @@ public class ProviderBundleTrackerCustom
         ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, spiBundle);
 
         BundleContext implBC = mockSPIBundleContext4();
-        Bundle implBundle =
-            mockSPIBundle4(implBC, SpiFlyConstants.PROVIDER_REQUIREMENT + "; " + SpiFlyConstants.PROVIDED_SPI_DIRECTIVE + ":=org.apache.aries.mytest.MySPI; approval=global");
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY, SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI2; approval=yeah; " +
+        		SpiFlyConstants.REGISTER_DIRECTIVE + ":=\"org.apache.aries.spifly.impl4.MySPIImpl4b\"");
+        Bundle implBundle = mockSPIBundle4(implBC, headers);
 
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
         assertEquals(1, registrations.size());
-        assertEquals("org.apache.aries.mytest.MySPI", registrations.iterator().next().getReference().getProperty(Constants.OBJECTCLASS));
-        assertNotNull(registrations.iterator().next().getReference().getProperty(SpiFlyConstants.SPI_PROVIDER_URL_PROPERTY));
-        assertEquals("global", registrations.iterator().next().getReference().getProperty("approval"));
+        assertEquals("org.apache.aries.mytest.MySPI2", registrations.iterator().next().getReference().getProperty(Constants.OBJECTCLASS));
+        assertNotNull(registrations.iterator().next().getReference().getProperty(SpiFlyConstants.SERVICELOADER_URL_PROPERTY));
+        assertEquals("yeah", registrations.iterator().next().getReference().getProperty("approval"));
     }
 
     @Test
@@ -154,18 +205,36 @@ public class ProviderBundleTrackerCustom
         ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, spiBundle);
 
         BundleContext implBC = mockSPIBundleContext4();
-        Bundle implBundle =
-            mockSPIBundle4(implBC, SpiFlyConstants.PROVIDER_REQUIREMENT + "; " + SpiFlyConstants.PROVIDED_SPI_DIRECTIVE + ":=\"org.apache.aries.mytest.MySPI,org.apache.aries.mytest.MySPI2\"; approval=global");
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY,
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI; approval=yeah, " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI2");
+        Bundle implBundle = mockSPIBundle4(implBC, headers);
 
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
         assertEquals("Expected 3 registrations, one for MySPI and 2 for MySPI2", 3, registrations.size());
         Set<String> expectedObjectClasses = new HashSet<String>(Arrays.asList("org.apache.aries.mytest.MySPI", "org.apache.aries.mytest.MySPI2"));
         Set<String> actualObjectClasses = new HashSet<String>();
+
+        boolean foundMySPI = false;
+        boolean foundMySPI2 = false;
         for (ServiceRegistration sr : registrations) {
             actualObjectClasses.add((String) sr.getReference().getProperty(Constants.OBJECTCLASS));
-            assertNotNull(sr.getReference().getProperty(SpiFlyConstants.SPI_PROVIDER_URL_PROPERTY));
-            assertEquals("global", sr.getReference().getProperty("approval"));
+            assertNotNull(sr.getReference().getProperty(SpiFlyConstants.SERVICELOADER_URL_PROPERTY));
+            if ("org.apache.aries.mytest.MySPI".equals(sr.getReference().getProperty(Constants.OBJECTCLASS))) {
+                assertEquals("yeah", sr.getReference().getProperty("approval"));
+                foundMySPI = true;
+            } else if ("org.apache.aries.mytest.MySPI2".equals(sr.getReference().getProperty(Constants.OBJECTCLASS))) {
+                assertNull(sr.getReference().getProperty("approval"));
+                foundMySPI2 = true;
+            }
         }
+        assertTrue(foundMySPI);
+        assertTrue(foundMySPI2);
+
         assertEquals(expectedObjectClasses, actualObjectClasses);
     }
 
@@ -182,8 +251,14 @@ public class ProviderBundleTrackerCustom
         ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, spiBundle);
 
         BundleContext implBC = mockSPIBundleContext4();
-        Bundle implBundle =
-            mockSPIBundle4(implBC, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY,
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI," +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI2");
+        Bundle implBundle = mockSPIBundle4(implBC, headers);
 
         List<ServiceRegistration> registrations = customizer.addingBundle(implBundle, null);
         assertEquals(3, registrations.size());
@@ -236,46 +311,6 @@ public class ProviderBundleTrackerCustom
     }
 
     @Test
-    public void testNoEffectiveValue() throws Exception {
-        Bundle spiBundle = EasyMock.createMock(Bundle.class);
-        EasyMock.replay(spiBundle);
-        BaseActivator activator = new BaseActivator() {
-            @Override
-            public void start(BundleContext context) throws Exception {}
-        };
-
-        ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(activator, spiBundle);
-
-        ServiceRegistration sreg = EasyMock.createMock(ServiceRegistration.class);
-        EasyMock.replay(sreg);
-
-        BundleContext implBC = mockSPIBundleContext(sreg);
-        Bundle implBundle = mockSPIBundle(implBC, "osgi.spi.provider");
-
-        assertNull(customizer.addingBundle(implBundle, null));
-        Collection<Bundle> bundles = activator.findProviderBundles("org.apache.aries.mytest.MySPI");
-        assertEquals(0, bundles.size());
-    }
-
-    @Test
-    public void testAddingBundleSPIBundle() throws Exception {
-        BundleContext implBC = mockSPIBundleContext(EasyMock.createNiceMock(ServiceRegistration.class));
-        Bundle spiBundle = mockSPIBundle(implBC);
-
-        ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(EasyMock.createNiceMock(BaseActivator.class), spiBundle);
-        assertNull("The SpiFly bundle itself should be ignored", customizer.addingBundle(spiBundle, null));
-    }
-
-    @Test
-    public void testAddingNonOptInBundle() throws Exception {
-        BundleContext implBC = mockSPIBundleContext(EasyMock.createNiceMock(ServiceRegistration.class));
-        Bundle implBundle = mockSPIBundle(implBC, null);
-
-        ProviderBundleTrackerCustomizer customizer = new ProviderBundleTrackerCustomizer(EasyMock.createNiceMock(BaseActivator.class), null);
-        assertNull("Bundle doesn't opt-in so should be ignored", customizer.addingBundle(implBundle, null));
-    }
-
-    @Test
     @SuppressWarnings("unchecked")
     public void testAddingBundleWithBundleClassPath() throws Exception {
         Bundle spiBundle = EasyMock.createMock(Bundle.class);
@@ -308,6 +343,9 @@ public class ProviderBundleTrackerCustom
 
         Dictionary<String, String> headers = new Hashtable<String, String>();
         headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.PROVIDER_REQUIREMENT);
+        headers.put(SpiFlyConstants.PROVIDE_CAPABILITY,
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; " +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "=org.apache.aries.mytest.MySPI");
         headers.put(Constants.BUNDLE_CLASSPATH, ".,non-jar.jar,embedded.jar,embedded2.jar");
         EasyMock.expect(implBundle.getHeaders()).andReturn(headers).anyTimes();
 
@@ -360,12 +398,17 @@ public class ProviderBundleTrackerCustom
     }
 
     private Bundle mockSPIBundle(BundleContext implBC, String spiProviderHeader) throws ClassNotFoundException {
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, spiProviderHeader);
+        return mockSPIBundle(implBC, headers);
+    }
+
+    private Bundle mockSPIBundle(BundleContext implBC, Dictionary<String, String> headers) throws ClassNotFoundException {
+        if (headers == null)
+            headers = new Hashtable<String, String>();
+
         Bundle implBundle = EasyMock.createNiceMock(Bundle.class);
         EasyMock.expect(implBundle.getBundleContext()).andReturn(implBC).anyTimes();
-
-        Dictionary<String, String> headers = new Hashtable<String, String>();
-        if (spiProviderHeader != null)
-            headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, spiProviderHeader);
         EasyMock.expect(implBundle.getHeaders()).andReturn(headers).anyTimes();
 
         // List the resources found at META-INF/services in the test bundle
@@ -424,13 +467,9 @@ public class ProviderBundleTrackerCustom
         return implBC;
     }
 
-    private Bundle mockSPIBundle4(BundleContext implBC, String spiProviderHeader) throws ClassNotFoundException {
+    private Bundle mockSPIBundle4(BundleContext implBC, Dictionary<String, String> headers) throws ClassNotFoundException {
         Bundle implBundle = EasyMock.createNiceMock(Bundle.class);
         EasyMock.expect(implBundle.getBundleContext()).andReturn(implBC).anyTimes();
-
-        Dictionary<String, String> headers = new Hashtable<String, String>();
-        if (spiProviderHeader != null)
-            headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, spiProviderHeader);
         EasyMock.expect(implBundle.getHeaders()).andReturn(headers).anyTimes();
 
         // List the resources found at META-INF/services in the test bundle

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookGenericCapabilityTest.java Thu Mar  8 13:17:55 2012
@@ -259,6 +259,7 @@ public class ClientWeavingHookGenericCap
         Assert.assertEquals("All three services should be invoked in the correct order", "ollehHELLO5", result);
     }
 
+    /* This is currently not supported in the generic model
     @Test
     public void testClientSpecifyingProvider() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
@@ -352,27 +353,26 @@ public class ClientWeavingHookGenericCap
         Object result = method.invoke(cls.newInstance(), "hello");
         Assert.assertEquals("All providers should be selected for this one", "ollehimpl4", result);
     }
+    */
 
     @Test
     public void testServiceFiltering() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT +
-                "; " + SpiFlyConstants.PROVIDER_FILTER_DIRECTIVE + ":=\"(|(" + SpiFlyConstants.CONSUMED_SPI_CONDITION + "=org.apache.aries.mytest.MySPI)" +
-                "(&(" + SpiFlyConstants.CONSUMED_SPI_CONDITION + "=org.apache.aries.mytest.AltSPI)(bundle-symbolic-name=impl4)))\"");
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT + "," +
+            SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE +
+                "; filter:=\"(osgi.serviceloader=org.apache.aries.mytest.AltSPI)\";");
 
-        Bundle providerBundle1 = mockProviderBundle("impl1", 1);
         Bundle providerBundle2 = mockProviderBundle("impl2", 2);
         Bundle providerBundle4 = mockProviderBundle("impl4", 4);
-        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle1, new HashMap<String, Object>());
         activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2, new HashMap<String, Object>());
         activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle2, new HashMap<String, Object>());
         activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle4, new HashMap<String, Object>());
         activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle4, new HashMap<String, Object>());
 
-        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle1, providerBundle2, providerBundle4);
+        Bundle consumerBundle = mockConsumerBundle(headers, providerBundle2, providerBundle4);
         activator.addConsumerWeavingData(consumerBundle, SpiFlyConstants.REQUIRE_CAPABILITY);
 
-        Bundle spiFlyBundle = mockSpiFlyBundle(consumerBundle, providerBundle1, providerBundle2, providerBundle4);
+        Bundle spiFlyBundle = mockSpiFlyBundle(consumerBundle, providerBundle2, providerBundle4);
         WeavingHook wh = new ClientWeavingHook(spiFlyBundle.getBundleContext(), activator);
 
         // Weave the TestClient class.
@@ -380,12 +380,11 @@ public class ClientWeavingHookGenericCap
         WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.dynamic.TestClient", consumerBundle);
         wh.weave(wc);
 
-        // Invoke the woven class and check that it propertly sets the TCCL so that the
-        // META-INF/services/org.apache.aries.mytest.MySPI file from impl2 is visible.
+        // Invoke the woven class. Since MySPI wasn't selected nothing should be returned
         Class<?> cls = wc.getDefinedClass();
         Method method = cls.getMethod("test", new Class [] {String.class});
         Object result = method.invoke(cls.newInstance(), "hello");
-        Assert.assertEquals("All providers should be selected for this one", "ollehHELLO5impl4", result);
+        Assert.assertEquals("No providers should be selected for this one", "", result);
 
         // Weave the AltTestClient class.
         URL cls2Url = getClass().getResource("AltTestClient.class");
@@ -396,24 +395,30 @@ public class ClientWeavingHookGenericCap
         Class<?> cls2 = wc2.getDefinedClass();
         Method method2 = cls2.getMethod("test", new Class [] {long.class});
         Object result2 = method2.invoke(cls2.newInstance(), 4096);
-        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L*4096L, result2);
+        Assert.assertEquals("All Providers should be selected", (4096L*4096L)-4096L, result2);
+
     }
 
     @Test
     public void testServiceFilteringAlternative() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT +
-                "; " + SpiFlyConstants.PROVIDER_FILTER_DIRECTIVE + ":=\"(|(!(" + SpiFlyConstants.CONSUMED_SPI_CONDITION + "=org.apache.aries.mytest.AltSPI))" +
-                "(&(" + SpiFlyConstants.CONSUMED_SPI_CONDITION + "=org.apache.aries.mytest.AltSPI)(bundle-symbolic-name=impl4)))\"");
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT + "," +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE +
+                "; filter:=\"(|(!(osgi.serviceloader=org.apache.aries.mytest.AltSPI))" +
+                            "(&(osgi.serviceloader=org.apache.aries.mytest.AltSPI)(bundle-symbolic-name=impl4)))\"");
 
         Bundle providerBundle1 = mockProviderBundle("impl1", 1);
         Bundle providerBundle2 = mockProviderBundle("impl2", 2);
         Bundle providerBundle4 = mockProviderBundle("impl4", 4);
         activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle1, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle2, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle4, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle4, new HashMap<String, Object>());
+        HashMap<String, Object> attrs2 = new HashMap<String, Object>();
+        attrs2.put("bundle-symbolic-name", "impl2");
+        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2, attrs2);
+        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle2, attrs2);
+        HashMap<String, Object> attrs4 = new HashMap<String, Object>();
+        attrs4.put("bundle-symbolic-name", "impl4");
+        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle4, attrs4);
+        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle4, attrs4);
 
         Bundle consumerBundle = mockConsumerBundle(headers, providerBundle1, providerBundle2, providerBundle4);
         activator.addConsumerWeavingData(consumerBundle, SpiFlyConstants.REQUIRE_CAPABILITY);
@@ -442,23 +447,28 @@ public class ClientWeavingHookGenericCap
         Class<?> cls2 = wc2.getDefinedClass();
         Method method2 = cls2.getMethod("test", new Class [] {long.class});
         Object result2 = method2.invoke(cls2.newInstance(), 4096);
-        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L*4096L, result2);
+        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L, result2);
     }
 
     @Test
     public void testServiceFilteringNarrow() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT +
-                "; " + SpiFlyConstants.PROVIDER_FILTER_DIRECTIVE + ":=\"(&(" + SpiFlyConstants.CONSUMED_SPI_CONDITION + "=org.apache.aries.mytest.AltSPI)(bundle-symbolic-name=impl4))\"");
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT + "," +
+                SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE +
+                "; filter:=\"(&(osgi.serviceloader=org.apache.aries.mytest.AltSPI)(bundle-symbolic-name=impl4))\"");
 
         Bundle providerBundle1 = mockProviderBundle("impl1", 1);
         Bundle providerBundle2 = mockProviderBundle("impl2", 2);
         Bundle providerBundle4 = mockProviderBundle("impl4", 4);
         activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle1, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle2, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle4, new HashMap<String, Object>());
-        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle4, new HashMap<String, Object>());
+        HashMap<String, Object> attrs2 = new HashMap<String, Object>();
+        attrs2.put("bundle-symbolic-name", "impl2");
+        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle2, attrs2);
+        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle2, attrs2);
+        HashMap<String, Object> attrs4 = new HashMap<String, Object>();
+        attrs4.put("bundle-symbolic-name", "impl4");
+        activator.registerProviderBundle("org.apache.aries.mytest.MySPI", providerBundle4, attrs4);
+        activator.registerProviderBundle("org.apache.aries.mytest.AltSPI", providerBundle4, attrs4);
 
         Bundle consumerBundle = mockConsumerBundle(headers, providerBundle1, providerBundle2, providerBundle4);
         activator.addConsumerWeavingData(consumerBundle, SpiFlyConstants.REQUIRE_CAPABILITY);
@@ -487,14 +497,14 @@ public class ClientWeavingHookGenericCap
         Class<?> cls2 = wc2.getDefinedClass();
         Method method2 = cls2.getMethod("test", new Class [] {long.class});
         Object result2 = method2.invoke(cls2.newInstance(), 4096);
-        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L*4096L, result2);
+        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L, result2);
     }
 
     @Test
     public void testFilteringCustomAttribute() throws Exception {
         Dictionary<String, String> headers = new Hashtable<String, String>();
-        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT +
-                "; " + SpiFlyConstants.PROVIDER_FILTER_DIRECTIVE + ":=\"(approval=global)\"");
+        headers.put(SpiFlyConstants.REQUIRE_CAPABILITY, SpiFlyConstants.CLIENT_REQUIREMENT + ", " +
+            SpiFlyConstants.SERVICELOADER_CAPABILITY_NAMESPACE + "; filter:=\"(approval=global)\"");
 
         Bundle providerBundle1 = mockProviderBundle("impl1", 1);
         Bundle providerBundle2 = mockProviderBundle("impl2", 2);

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/ClientWeavingHookTest.java Thu Mar  8 13:17:55 2012
@@ -387,7 +387,7 @@ public class ClientWeavingHookTest {
         Class<?> cls2 = wc2.getDefinedClass();
         Method method2 = cls2.getMethod("test", new Class [] {long.class});
         Object result2 = method2.invoke(cls2.newInstance(), 4096);
-        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L*4096L, result2);
+        Assert.assertEquals("Only the services from bundle impl4 should be selected", -4096L, result2);
     }
 
     @Test

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/impl4/AltSPIImpl2.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/impl4/AltSPIImpl2.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/impl4/AltSPIImpl2.java (original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/test/java/org/apache/aries/spifly/dynamic/impl4/AltSPIImpl2.java Thu Mar  8 13:17:55 2012
@@ -23,6 +23,6 @@ import org.apache.aries.mytest.AltSPI;
 public class AltSPIImpl2 implements AltSPI {
     @Override
     public long square(long l) {
-        return -l * l;
+        return -l;
     }
 }

Modified: aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java?rev=1298382&r1=1298381&r2=1298382&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java (original)
+++ aries/trunk/spi-fly/spi-fly-static-tool/src/main/java/org/apache/aries/spifly/statictool/Main.java Thu Mar  8 13:17:55 2012
@@ -74,7 +74,7 @@ public class Main {
         }
     }
 
-    private static void weaveJar(String jarPath) throws IOException {
+    private static void weaveJar(String jarPath) throws Exception {
         System.out.println("[SPI Fly Static Tool] Processing: " + jarPath);
 
         File jarFile = new File(jarPath);
@@ -139,7 +139,7 @@ public class Main {
         return new File(s);
     }
 
-    private static void weaveDir(File dir, String consumerHeader, String bundleClassPath) throws IOException {
+    private static void weaveDir(File dir, String consumerHeader, String bundleClassPath) throws Exception {
         String dirName = dir.getAbsolutePath();
 
         DirTree dt = new DirTree(dir);
@@ -185,7 +185,7 @@ public class Main {
         }
     }
 
-    private static void weaveBCPJar(File jarFile, String consumerHeader) throws IOException {
+    private static void weaveBCPJar(File jarFile, String consumerHeader) throws Exception {
         File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + jarFile.getName() + "_" + System.currentTimeMillis());
         try {
             Manifest manifest = unJar(jarFile, tempDir);