FELIX-322 Registering a PersistenceManager service causes a ClassCastException

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@553930 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index fa8e131..8224290 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -515,22 +515,38 @@
 
     private PersistenceManager[] getPersistenceManagers()
     {
-        if ( persistenceManagers == null || persistenceManagerTracker.getTrackingCount() > pmtCount )
+        int currentPmtCount = persistenceManagerTracker.getTrackingCount();
+        if ( persistenceManagers == null || currentPmtCount > pmtCount )
         {
 
+            PersistenceManager[] pm;
+
             ServiceReference[] refs = persistenceManagerTracker.getServiceReferences();
             if ( refs == null || refs.length == 0 )
             {
-                return new PersistenceManager[0];
+                pm = new PersistenceManager[0];
             }
-
-            SortedSet pms = new TreeSet( cmRankComp );
-            for ( int i = 0; i < refs.length; i++ )
+            else
             {
-                pms.add( persistenceManagerTracker.getService( refs[i] ) );
+                // sort the references according to the cmRanking property
+                SortedSet pms = new TreeSet( new RankingComparator( false ) );
+                for ( int i = 0; i < refs.length; i++ )
+                {
+                    pms.add( refs[i] );
+                }
+
+                // create the service array from the sorted set of referenecs
+                pm = new PersistenceManager[pms.size()];
+                int pmIndex = 0;
+                for ( Iterator pi = pms.iterator(); pi.hasNext(); pmIndex++)
+                {
+                    ServiceReference ref = ( ServiceReference ) pi.next();
+                    pm[pmIndex] = ( PersistenceManager ) persistenceManagerTracker.getService( ref );
+                }
             }
 
-            persistenceManagers = ( PersistenceManager[] ) pms.toArray( new PersistenceManager[pms.size()] );
+            pmtCount = currentPmtCount;
+            persistenceManagers = pm;
         }
 
         return persistenceManagers;
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/RankingComparator.java b/configadmin/src/main/java/org/apache/felix/cm/impl/RankingComparator.java
index 657154a..c0da58c 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/RankingComparator.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/RankingComparator.java
@@ -58,37 +58,39 @@
             return 0;
         }
 
-        int rank1 = getInt( ( ServiceReference ) obj1, rankProperty );
-        int rank2 = getInt( ( ServiceReference ) obj2, rankProperty );
+        long rank1 = getLong( ( ServiceReference ) obj1, rankProperty );
+        long rank2 = getLong( ( ServiceReference ) obj2, rankProperty );
+        boolean order = naturalOrder;
 
         // use service id, if rankings are equal
         if ( rank1 == rank2 )
         {
-            rank1 = getInt( ( ServiceReference ) obj1, Constants.SERVICE_ID );
-            rank2 = getInt( ( ServiceReference ) obj2, Constants.SERVICE_ID );
+            rank1 = getLong( ( ServiceReference ) obj1, Constants.SERVICE_ID );
+            rank2 = getLong( ( ServiceReference ) obj2, Constants.SERVICE_ID );
+            order = false; // always order lower service.id before higher
         }
 
         if ( rank1 == rank2 )
         {
             return 0;
         }
-        else if ( naturalOrder && rank1 > rank2)
+        else if ( order )
         {
-            return 1;
+            return ( rank1 > rank2 ) ? 1 : -1;
         }
         else
         {
-            return -1;
+            return ( rank1 < rank2 ) ? 1 : -1;
         }
     }
 
 
-    private int getInt( ServiceReference sr, String property )
+    private long getLong( ServiceReference sr, String property )
     {
         Object rankObj = sr.getProperty( property );
-        if ( rankObj instanceof Integer )
+        if ( rankObj instanceof Number )
         {
-            return ( ( Integer ) rankObj ).intValue();
+            return ( ( Number ) rankObj ).longValue();
         }
 
         // null or not an integer