Applied patch (FELIX-799) to implement ServiceReference.compareTo() method.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@711332 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 8d6e9ba..2d00d87 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -282,70 +282,12 @@
 
         // Loop through all service references and return
         // the "best" one according to its rank and ID.
-        ServiceReference bestRef = null;
-        Integer bestRank = null;
-        Long bestId = null;
-        for (int i = 0; i < refs.length; i++)
+        ServiceReference bestRef = refs[0];
+        for (int i = 1; i < refs.length; i++)
         {
-            ServiceReference ref = refs[i];
-
-            // The first time through the loop just
-            // assume that the first reference is best.
-            if (bestRef == null)
+            if (bestRef.compareTo(refs[i]) < 0)
             {
-                bestRef = ref;
-                bestRank = (Integer) bestRef.getProperty("service.ranking");
-                // The spec says no ranking defaults to zero.
-                if (bestRank == null)
-                {
-                    bestRank = new Integer(0);
-                }
-                bestId = (Long) bestRef.getProperty("service.id");
-            }
-
-            // Compare current and best references to see if
-            // the current reference is a better choice.
-            Integer rank = (Integer) ref.getProperty("service.ranking");
-
-            // The spec says no ranking defaults to zero.
-            if (rank == null)
-            {
-                rank = new Integer(0);
-            }
-
-            // If the current reference ranking is greater than the
-            // best ranking, then keep the current reference.
-            if (bestRank.compareTo(rank) < 0)
-            {
-                bestRef = ref;
-                bestRank = rank;
-                bestId = (Long) bestRef.getProperty("service.id");
-            }
-            // If rankings are equal, then compare IDs and
-            // keep the smallest.
-            else if (bestRank.compareTo(rank) == 0)
-            {
-                Long id = (Long) ref.getProperty("service.id");
-                // If either reference has a null ID, then keep
-                // the one with a non-null ID.
-                if ((bestId == null) || (id == null))
-                {
-                    bestRef = (bestId == null) ? ref : bestRef;
-                    // bestRank = bestRank; // No need to update since they are equal.
-                    bestId = (Long) bestRef.getProperty("service.id");
-                }
-                // Otherwise compare IDs.
-                else
-                {
-                    // If the current reference ID is less than the
-                    // best ID, then keep the current reference.
-                    if (bestId.compareTo(id) > 0)
-                    {
-                        bestRef = ref;
-                        // bestRank = bestRank; // No need to update since they are equal.
-                        bestId = (Long) bestRef.getProperty("service.id");
-                    }
-                }
+                bestRef = refs[i];
             }
         }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
index 0aceb2b..ea02cc9 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
@@ -22,6 +22,7 @@
 import org.apache.felix.moduleloader.IModule;
 import org.apache.felix.moduleloader.IWire;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
 class ServiceReferenceImpl implements ServiceReference
@@ -195,6 +196,34 @@
 
     public int compareTo(Object reference)
     {
-        throw new UnsupportedOperationException("This feature has not yet been implemented.");
+        ServiceReference other = (ServiceReference) reference;
+
+        Long id = (Long) getProperty(Constants.SERVICE_ID);
+        Long otherId = (Long) other.getProperty(Constants.SERVICE_ID);
+
+        if (id.equals(otherId))
+        {
+            return 0; // same service
+        }
+
+        Integer rank = (Integer) getProperty(Constants.SERVICE_RANKING);
+        Integer otherRank = (Integer) other.getProperty(Constants.SERVICE_RANKING);
+
+        // If no rank, then spec says it defaults to zero.
+        rank = (rank == null) ? new Integer(0) : rank;
+        otherRank = (otherRank == null) ? new Integer(0) : otherRank;
+
+        // Sort by rank in ascending order.
+        if (rank.compareTo(otherRank) < 0)
+        {
+            return -1; // lower rank
+        }
+        else if (rank.compareTo(otherRank) > 0)
+        {
+            return 1; // higher rank
+        }
+
+        // If ranks are equal, then sort by service id in descending order.
+        return (id.compareTo(otherId) < 0) ? 1 : -1;
     }
 }
\ No newline at end of file