/* * 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>< 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>> 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>< 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>> 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; } }