You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2011/04/19 11:50:24 UTC

svn commit: r1094978 - in /felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index: BundleContextInterceptor.java FilterIndex.java MultiPropertyExactFilter.java ServiceRegistryCache.java

Author: marrs
Date: Tue Apr 19 09:50:24 2011
New Revision: 1094978

URL: http://svn.apache.org/viewvc?rev=1094978&view=rev
Log:
Fixed some of the TODO items in the code.

Modified:
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/BundleContextInterceptor.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/FilterIndex.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/MultiPropertyExactFilter.java
    felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/ServiceRegistryCache.java

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/BundleContextInterceptor.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/BundleContextInterceptor.java?rev=1094978&r1=1094977&r2=1094978&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/BundleContextInterceptor.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/BundleContextInterceptor.java Tue Apr 19 09:50:24 2011
@@ -18,7 +18,12 @@
  */
 package org.apache.felix.dm.index;
 
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
@@ -39,7 +44,6 @@ public class BundleContextInterceptor ex
         }
         else {
             m_context.addServiceListener(listener, filter);
-//            super.addServiceListener(listener, filter);
         }
     }
 
@@ -50,7 +54,6 @@ public class BundleContextInterceptor ex
         }
         else {
             m_context.addServiceListener(listener);
-//            super.addServiceListener(listener);
         }
     }
 
@@ -61,7 +64,6 @@ public class BundleContextInterceptor ex
         }
         else {
             m_context.removeServiceListener(listener);
-//            super.removeServiceListener(listener);
         }
     }
 
@@ -69,47 +71,52 @@ public class BundleContextInterceptor ex
         // first we ask the cache if there is an index for our request (class and filter combination)
         FilterIndex filterIndex = m_cache.hasFilterIndexFor(clazz, filter);
         if (filterIndex != null) {
-            ServiceReference[] result = filterIndex.getAllServiceReferences(clazz, filter);
-            // TODO filter for assignability
-            return result;
+            List /* <ServiceReference> */ result = filterIndex.getAllServiceReferences(clazz, filter);
+            Iterator iterator = result.iterator();
+            while (iterator.hasNext()) {
+                ServiceReference reference = (ServiceReference) iterator.next();
+                String[] list = (String[]) reference.getProperty(Constants.OBJECTCLASS);
+                for (int i = 0; i < list.length; i++) {
+                    if (!reference.isAssignableTo(m_context.getBundle(), list[i])) {
+                        iterator.remove();
+                        break;
+                    }
+                }
+            }
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
         }
         else {
             // if they don't know, we ask the real bundle context instead
             return m_context.getServiceReferences(clazz, filter);
         }
-        
     }
 
     public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        // TODO implement
-        return m_context.getAllServiceReferences(clazz, filter);
+        // first we ask the cache if there is an index for our request (class and filter combination)
+        FilterIndex filterIndex = m_cache.hasFilterIndexFor(clazz, filter);
+        if (filterIndex != null) {
+            List /* <ServiceReference> */ result = filterIndex.getAllServiceReferences(clazz, filter);
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+        }
+        else {
+            // if they don't know, we ask the real bundle context instead
+            return m_context.getAllServiceReferences(clazz, filter);
+        }
     }
 
     public ServiceReference getServiceReference(String clazz) {
-        // TODO implement
-        return m_context.getServiceReference(clazz);
+        ServiceReference[] references;
+        try {
+            references = getServiceReferences(clazz, null);
+            Arrays.sort(references);
+            return references[references.length - 1];
+        }
+        catch (InvalidSyntaxException e) {
+            throw new Error("Invalid filter syntax thrown for null filter.", e);
+        }
     }
 
     public void serviceChanged(ServiceEvent event) {
         m_cache.serviceChangedForFilterIndices(event);
-//        Entry[] entries = synchronizeCollection();
-//        for (int i = 0; i < entries.length; i++) {
-//            Entry serviceListenerFilterEntry = entries[i];
-//            ServiceListener serviceListener = (ServiceListener) serviceListenerFilterEntry.getKey();
-//            String filter = (String) serviceListenerFilterEntry.getValue();
-//            if (filter == null) {
-//                serviceListener.serviceChanged(event);
-//            }
-//            else {
-//                try {
-//                    if (m_context.createFilter(filter).match(event.getServiceReference())) {
-//                        serviceListener.serviceChanged(event);
-//                    }
-//                }
-//                catch (InvalidSyntaxException e) {
-//                    e.printStackTrace();
-//                }
-//            }
-//        }
     }
 }

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/FilterIndex.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/FilterIndex.java?rev=1094978&r1=1094977&r2=1094978&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/FilterIndex.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/FilterIndex.java Tue Apr 19 09:50:24 2011
@@ -18,10 +18,11 @@
  */
 package org.apache.felix.dm.index;
 
+import java.util.List;
+
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
 
 /**
  * A filter index is an interface you can implement to create your own, optimized index for specific filter expressions.
@@ -34,7 +35,7 @@ public interface FilterIndex {
     /** Determines if the combination of class and filter is applicable for this filter index. */
     public boolean isApplicable(String clazz, String filter);
     /** Returns all service references that match the specified class and filter. */
-    public ServiceReference[] getAllServiceReferences(String clazz, String filter);
+    public List /* <ServiceReference> */ getAllServiceReferences(String clazz, String filter);
     /** Invoked whenever a service event occurs. */
     public void serviceChanged(ServiceEvent event);
     /** Adds a service listener to this filter index. */

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/MultiPropertyExactFilter.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/MultiPropertyExactFilter.java?rev=1094978&r1=1094977&r2=1094978&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/MultiPropertyExactFilter.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/MultiPropertyExactFilter.java Tue Apr 19 09:50:24 2011
@@ -81,7 +81,7 @@ public class MultiPropertyExactFilter im
         tracker.close();
     }
 
-    public ServiceReference[] getAllServiceReferences(String clazz, String filter) {
+    public List /* <ServiceReference> */ getAllServiceReferences(String clazz, String filter) {
         List /* <ServiceReference> */ result = new ArrayList();
         List keys = createKeysFromFilter(clazz, filter);
         Iterator iterator = keys.iterator();
@@ -95,12 +95,7 @@ public class MultiPropertyExactFilter im
                 }
             }
         }
-        if (result.size() == 0) {
-            return null;
-        }
-        else {
-            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
-        }
+        return result;
     }
 
     public Object addingService(ServiceReference reference) {
@@ -118,13 +113,13 @@ public class MultiPropertyExactFilter im
 
     public void addedService(ServiceReference reference, Object service) {
         if (isApplicable(reference.getPropertyKeys())) {
-            update(reference);
+            add(reference);
         }
     }
 
     public void modifiedService(ServiceReference reference, Object service) {
         if (isApplicable(reference.getPropertyKeys())) {
-            update(reference);
+            modify(reference);
         }
     }
 
@@ -133,11 +128,41 @@ public class MultiPropertyExactFilter im
             remove(reference);
         }
     }
-    
-    public void update(ServiceReference reference) {
+
+    public void add(ServiceReference reference) {
+        List /* <String> */ keys = createKeys(reference);
+        synchronized (m_keyToServiceReferencesMap) {
+            for (int i = 0; i < keys.size(); i++) {
+                List /* <ServiceReference> */ references = (List) m_keyToServiceReferencesMap.get(keys.get(i));
+                if (references == null) {
+                    references = new ArrayList();
+                    m_keyToServiceReferencesMap.put(keys.get(i), references);
+                }
+                references.add(reference);
+            }
+        }
+    }
+
+    public void modify(ServiceReference reference) {
         List /* <String> */ keys = createKeys(reference);
         synchronized (m_keyToServiceReferencesMap) {
-            // TODO any 'old' references that are still in the index need to be removed in case of an update
+            // TODO this is a quite expensive linear scan over the existing collection
+            // because we first need to remove any existing references and they can be
+            // all over the place :)
+            Iterator iterator = m_keyToServiceReferencesMap.values().iterator();
+            while (iterator.hasNext()) {
+                List /* <ServiceReference> */ list = (List) iterator.next();
+                if (list != null) {
+                    Iterator i2 = list.iterator();
+                    while (i2.hasNext()) {
+                        ServiceReference ref = (ServiceReference) i2.next();
+                        if (ref.equals(reference)) {
+                            i2.remove();
+                        }
+                    }
+                }
+            }
+            
             for (int i = 0; i < keys.size(); i++) {
                 List /* <ServiceReference> */ references = (List) m_keyToServiceReferencesMap.get(keys.get(i));
                 if (references == null) {
@@ -282,7 +307,6 @@ public class MultiPropertyExactFilter im
     }
     
     private List /* <String> */ createKeysFromFilter(String clazz, String filter) {
-        // TODO array support
         List result = new ArrayList();
         StringBuffer index = new StringBuffer();
         Iterator iterator = m_propertyKeys.iterator();

Modified: felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/ServiceRegistryCache.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/ServiceRegistryCache.java?rev=1094978&r1=1094977&r2=1094978&view=diff
==============================================================================
--- felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/ServiceRegistryCache.java (original)
+++ felix/trunk/dependencymanager/core/src/main/java/org/apache/felix/dm/index/ServiceRegistryCache.java Tue Apr 19 09:50:24 2011
@@ -29,7 +29,6 @@ import org.eclipse.osgi.framework.consol
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 
 public class ServiceRegistryCache implements ServiceListener, CommandProvider {
@@ -136,15 +135,10 @@ public class ServiceRegistryCache implem
                 a2 = ci.nextArgument();
             }
             if (filterIndex.isApplicable(a1, a2)) {
-                ServiceReference[] references = filterIndex.getAllServiceReferences(a1, a2);
-                if (references == null) {
-                    ci.println("No results.");
-                }
-                else {
-                    ci.println("Found " + references.length + " references:");
-                    for (int i = 0; i < references.length; i++) {
-                        ci.println("" + i + " - " + references[i]);
-                    }
+                List /* <ServiceReference> */ references = filterIndex.getAllServiceReferences(a1, a2);
+                ci.println("Found " + references.size() + " references:");
+                for (int i = 0; i < references.size(); i++) {
+                    ci.println("" + i + " - " + references.get(i));
                 }
             }
             else {