blob: 2f546ff707ee5f3029eda267a2b09996990fe87d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.cm.impl;
import java.util.Comparator;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationPlugin;
/**
* The <code>RankingComparator</code> may be used to maintain sorted
* sets or to sort arrays such that the first element in the set or
* array is the one to use first and the last elements the one to
* use last.
*/
public abstract class RankingComparator implements Comparator<ServiceReference<?>>
{
/**
* Implements a comparator to sort arrays and sets according to the
* specification of the <code>service.ranking</code> property. This
* results in collections whose first element has the highest ranking
* and the last element has the lowest ranking. Thus the results of
* this comparator are as follows:
* <ul>
* <li><code>&lt; 0</code> if obj1 has higher ranking than obj2</li>
* <li><code>== 0</code> if obj1 and obj2 reference the same service</li>
* <li><code>&gt; 0</code> if obj1 has lower ranking than obj2</li>
* </ul>
*/
public static Comparator<ServiceReference<?>> SRV_RANKING = new RankingComparator()
{
public int compare( ServiceReference<?> obj1, ServiceReference<?> obj2 )
{
final long id1 = this.getLong( obj1, Constants.SERVICE_ID );
final long id2 = this.getLong( obj2, Constants.SERVICE_ID );
if ( id1 == id2 )
{
return 0;
}
final int rank1 = this.getInteger( obj1, Constants.SERVICE_RANKING );
final int rank2 = this.getInteger( obj2, Constants.SERVICE_RANKING );
if ( rank1 == rank2 )
{
return ( id1 < id2 ) ? -1 : 1;
}
return ( rank1 > rank2 ) ? -1 : 1;
}
};
/**
* Implements a comparator to sort arrays and sets according to the
* specification of the <code>service.cmRanking</code> property in
* the Configuration Admin specification. This results in collections
* where the first element has the lowest ranking value and the last
* element has the highest ranking value. Order amongst elements with
* the same ranking value is left undefined, however we order it
* by service id, lowest last. Thus the results of this
* comparator are as follows:
* <ul>
* <li><code>&lt; 0</code> if obj1 has lower ranking than obj2</li>
* <li><code>== 0</code> if obj1 and obj2 have the same ranking</li>
* <li><code>&gt; 0</code> if obj1 has higher ranking than obj2</li>
* </ul>
*/
public static Comparator<ServiceReference<?>> CM_RANKING = new RankingComparator()
{
public int compare( ServiceReference<?> obj1, ServiceReference<?> obj2 )
{
final long id1 = this.getLong( obj1, Constants.SERVICE_ID );
final long id2 = this.getLong( obj2, Constants.SERVICE_ID );
if ( id1 == id2 )
{
return 0;
}
final int rank1 = this.getInteger( obj1, ConfigurationPlugin.CM_RANKING );
final int rank2 = this.getInteger( obj2, ConfigurationPlugin.CM_RANKING );
if ( rank1 == rank2 )
{
return ( id1 > id2 ) ? -1 : 1;
}
return ( rank1 < rank2 ) ? -1 : 1;
}
};
protected int getInteger( ServiceReference<?> sr, String property )
{
Object rankObj = sr.getProperty( property );
if ( rankObj instanceof Integer )
{
return ( ( Integer ) rankObj ).intValue();
}
// null or not an integer
return 0;
}
protected long getLong( ServiceReference<?> sr, String property )
{
Object rankObj = sr.getProperty( property );
if ( rankObj instanceof Long )
{
return ( ( Long ) rankObj ).longValue();
}
// null or not a long
return 0;
}
}