You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2010/03/25 09:40:48 UTC

svn commit: r927304 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: Felix.java ServiceRegistrationImpl.java ServiceRegistry.java capabilityset/CapabilitySet.java

Author: rickhall
Date: Thu Mar 25 08:40:48 2010
New Revision: 927304

URL: http://svn.apache.org/viewvc?rev=927304&view=rev
Log:
Modify service registry to use a CapabilitySet for indexed service
lookup. (FELIX-2040)

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=927304&r1=927303&r2=927304&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Thu Mar 25 08:40:48 2010
@@ -34,6 +34,7 @@ import org.apache.felix.framework.capabi
 import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.Wire;
 import org.apache.felix.framework.ext.SecurityProvider;
 import org.apache.felix.framework.resolver.ResolveException;
@@ -2848,10 +2849,17 @@ ex.printStackTrace();
         throws InvalidSyntaxException
     {
         // Define filter if expression is not null.
-        Filter filter = null;
+        SimpleFilter filter = null;
         if (expr != null)
         {
-            filter = FrameworkUtil.createFilter(expr);
+            try
+            {
+                filter = SimpleFilter.parse(expr);
+            }
+            catch (Exception ex)
+            {
+                throw new InvalidSyntaxException(ex.getMessage(), expr);
+            }
         }
 
         // Ask the service registry for all matching service references.

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java?rev=927304&r1=927303&r2=927304&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java Thu Mar 25 08:40:48 2010
@@ -22,6 +22,9 @@ import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.*;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.resolver.Wire;
 
@@ -69,9 +72,6 @@ class ServiceRegistrationImpl implements
 
         // This reference is the "standard" reference for this
         // service and will always be returned by getReference().
-        // Since all reference to this service are supposed to
-        // be equal, we use the hashcode of this reference for
-        // a references to this service in ServiceReference.
         m_ref = new ServiceReferenceImpl();
     }
 
@@ -164,7 +164,8 @@ class ServiceRegistrationImpl implements
         // Case 2.
         if ((m_factory != null)
             && (m_factory.getClass().getClassLoader() instanceof BundleReference)
-            && !((BundleReference) m_factory.getClass().getClassLoader()).getBundle().equals(m_bundle))
+            && !((BundleReference) m_factory.getClass()
+                .getClassLoader()).getBundle().equals(m_bundle))
         {
             return true;
         }
@@ -315,7 +316,8 @@ class ServiceRegistrationImpl implements
         {
             for (int i = 0; i < m_classes.length; i++)
             {
-                Class clazz = Util.loadClassUsingClass(svcObj.getClass(), m_classes[i], Felix.m_secureAction);
+                Class clazz = Util.loadClassUsingClass(
+                    svcObj.getClass(), m_classes[i], Felix.m_secureAction);
                 if ((clazz == null) || !clazz.isAssignableFrom(svcObj.getClass()))
                 {
                     if (clazz == null)
@@ -376,7 +378,11 @@ class ServiceRegistrationImpl implements
         }
     }
 
-    class ServiceReferenceImpl implements ServiceReference
+    //
+    // ServiceReference implementation
+    //
+
+    class ServiceReferenceImpl implements ServiceReference, Capability
     {
         private ServiceReferenceImpl() {}
 
@@ -385,6 +391,46 @@ class ServiceRegistrationImpl implements
             return ServiceRegistrationImpl.this;
         }
 
+        //
+        // Capability methods.
+        //
+
+        public Module getModule()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public String getNamespace()
+        {
+            return "service-reference";
+        }
+
+        public Directive getDirective(String name)
+        {
+            return null;
+        }
+
+        public List<Directive> getDirectives()
+        {
+            return Collections.emptyList();
+        }
+
+        public Attribute getAttribute(String name)
+        {
+            Object value = ServiceRegistrationImpl.this.getProperty(name);
+            return (value == null) ? null : new Attribute(name, value, false);
+        }
+
+        public List<Attribute> getAttributes()
+        {
+            return Collections.emptyList();
+        }
+
+        public List<String> getUses()
+        {
+            return Collections.emptyList();
+        }
+
         public Object getProperty(String s)
         {
             return ServiceRegistrationImpl.this.getProperty(s);

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java?rev=927304&r1=927303&r2=927304&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java Thu Mar 25 08:40:48 2010
@@ -19,8 +19,10 @@
 package org.apache.felix.framework;
 
 import java.util.*;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
 
-import org.apache.felix.framework.util.FelixConstants;
 import org.osgi.framework.*;
 import org.osgi.framework.hooks.service.*;
 import org.osgi.framework.launch.Framework;
@@ -30,13 +32,16 @@ public class ServiceRegistry
     private final Logger m_logger;
     private long m_currentServiceId = 1L;
     // Maps bundle to an array of service registrations.
-    private final Map m_serviceRegsMap = Collections.synchronizedMap(new HashMap());
+    private final Map m_regsMap = Collections.synchronizedMap(new HashMap());
+    // Capability set for all service registrations.
+    private final CapabilitySet m_regCapSet;
+
     // Maps registration to thread to keep track when a
     // registration is in use, which will cause other
     // threads to wait.
-    private Map m_lockedRegsMap = new HashMap();
+    private final Map m_lockedRegsMap = new HashMap();
     // Maps bundle to an array of usage counts.
-    private Map m_inUseMap = new HashMap();
+    private final Map m_inUseMap = new HashMap();
 
     private final ServiceRegistryCallbacks m_callbacks;
 
@@ -48,11 +53,15 @@ public class ServiceRegistry
     {
         m_logger = logger;
         m_callbacks = callbacks;
+
+        List indices = new ArrayList();
+        indices.add(Constants.OBJECTCLASS);
+        m_regCapSet = new CapabilitySet(indices);
     }
 
     public ServiceReference[] getRegisteredServices(Bundle bundle)
     {
-        ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+        ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
         if (regs != null)
         {
             List refs = new ArrayList(regs.length);
@@ -75,7 +84,7 @@ public class ServiceRegistry
     public ServiceRegistration registerService(
         Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
     {
-        ServiceRegistration reg = null;
+        ServiceRegistrationImpl reg = null;
 
         synchronized (this)
         {
@@ -87,8 +96,9 @@ public class ServiceRegistry
             addHooks(classNames, svcObj, reg.getReference());
 
             // Get the bundles current registered services.
-            ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
-            m_serviceRegsMap.put(bundle, addServiceRegistration(regs, reg));
+            ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
+            m_regsMap.put(bundle, addServiceRegistration(regs, reg));
+            m_regCapSet.addCapability((Capability) reg.getReference());
         }
 
         // Notify callback objects about registered service.
@@ -114,8 +124,9 @@ public class ServiceRegistry
             // new bundles will be able to look up the service.
 
             // Now remove the registered service.
-            ServiceRegistration[] regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
-            m_serviceRegsMap.put(bundle, removeServiceRegistration(regs, reg));
+            ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
+            m_regsMap.put(bundle, removeServiceRegistration(regs, reg));
+            m_regCapSet.removeCapability((Capability) reg.getReference());
         }
 
         // Notify callback objects about unregistering service.
@@ -151,7 +162,7 @@ public class ServiceRegistry
         ServiceRegistration[] regs = null;
         synchronized (this)
         {
-            regs = (ServiceRegistration[]) m_serviceRegsMap.get(bundle);
+            regs = (ServiceRegistration[]) m_regsMap.get(bundle);
         }
 
         // Note, there is no race condition here with respect to the
@@ -171,73 +182,35 @@ public class ServiceRegistry
         // Now remove the bundle itself.
         synchronized (this)
         {
-            m_serviceRegsMap.remove(bundle);
+            m_regsMap.remove(bundle);
         }
     }
 
-    public List getServiceReferences(String className, Filter filter)
+    public synchronized List getServiceReferences(String className, SimpleFilter filter)
     {
-        // Create a filtered list of service references.
-        List list = new ArrayList();
-
-        Object[] registrations = m_serviceRegsMap.values().toArray();
-        
-        // Iterator over all service registrations.
-        for (int i = 0; i < registrations.length; i++)
+        if ((className == null) && (filter == null))
         {
-            ServiceRegistration[] regs = (ServiceRegistration[]) registrations[i];
-
-            for (int regIdx = 0;
-                (regs != null) && (regIdx < regs.length);
-                regIdx++)
-            {
-                try
-                {
-                    // Determine if the registered services matches
-                    // the search criteria.
-                    boolean matched = false;
-
-                    // If className is null, then look at filter only.
-                    if ((className == null) &&
-                        ((filter == null) || filter.match(regs[regIdx].getReference())))
-                    {
-                        matched = true;
-                    }
-                    // If className is not null, then first match the
-                    // objectClass property before looking at the
-                    // filter.
-                    else if (className != null)
-                    {
-                        String[] objectClass = (String[])
-                            ((ServiceRegistrationImpl) regs[regIdx])
-                                .getProperty(FelixConstants.OBJECTCLASS);
-                        for (int classIdx = 0;
-                            classIdx < objectClass.length;
-                            classIdx++)
-                        {
-                            if (objectClass[classIdx].equals(className) &&
-                                ((filter == null) || filter.match(regs[regIdx].getReference())))
-                            {
-                                matched = true;
-                                break;
-                            }
-                        }
-                    }
-
-                    // Add reference if it was a match.
-                    if (matched)
-                    {
-                        list.add(regs[regIdx].getReference());
-                    }
-                }
-                catch (IllegalStateException ex)
-                {
-                    // Don't include the reference as it is not valid anymore
-                }
-            }
+            // Return all services.
+            filter = new SimpleFilter(Constants.OBJECTCLASS, "*", SimpleFilter.PRESENT);
+        }
+        else if ((className != null) && (filter == null))
+        {
+            // Return services matching the class name.
+            filter = new SimpleFilter(Constants.OBJECTCLASS, className, SimpleFilter.EQ);
         }
+        else if ((className != null) && (filter != null))
+        {
+            // Return services matching the class name and filter.
+            List filters = new ArrayList(2);
+            filters.add(new SimpleFilter(Constants.OBJECTCLASS, className, SimpleFilter.EQ));
+            filters.add(filter);
+            filter = new SimpleFilter(null, filters, SimpleFilter.AND);
+        }
+        // else just use the specified filter.
+
+        Set<Capability> matches = m_regCapSet.match(filter, false);
 
-        return list;
+        return new ArrayList(matches);
     }
 
     public synchronized ServiceReference[] getServicesInUse(Bundle bundle)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java?rev=927304&r1=927303&r2=927304&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java Thu Mar 25 08:40:48 2010
@@ -132,10 +132,13 @@ public class CapabilitySet
         Map<Object, Set<Capability>> index, Capability cap, Object capValue)
     {
         Set<Capability> caps = index.get(capValue);
-        caps.remove(cap);
-        if (caps.size() == 0)
+        if (caps != null)
         {
-            index.remove(capValue);
+            caps.remove(cap);
+            if (caps.size() == 0)
+            {
+                index.remove(capValue);
+            }
         }
     }