blob: cbd469a0f6cd2798aba24999f6a97514e23e7c6b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.device;
import org.osgi.framework.ServiceReference;
import org.osgi.service.device.Device;
import org.osgi.service.device.DriverSelector;
import org.osgi.service.log.LogService;
import org.osgi.util.tracker.ServiceTracker;
/**
* DriverSelectorTracker class. This class tracks all DriverSelector services.
*
*/
public class DriverSelectorTracker extends ServiceTracker {
/** Driver service name */
protected final static String clazz = "org.osgi.service.device.DriverSelector"; //$NON-NLS-1$
/** LogService object */
protected LogService log;
/** DeviceManager object. */
protected Activator manager;
/**
* Create the DriverTracker.
*
* @param manager DeviceManager object.
* @param device DeviceTracker we are working for.
*/
public DriverSelectorTracker(Activator manager) {
super(manager.context, clazz, null);
this.manager = manager;
log = manager.log;
if (Activator.DEBUG) {
log.log(log.LOG_DEBUG, "DriverSelectorTracker constructor"); //$NON-NLS-1$
}
open();
}
/**
* Select the matching driver.
*
* @param device Device service being matched.
* @param matches Array of the successful matches from Driver services.
* @return ServiceReference to best matched Driver or null of their is no match.
*/
public ServiceReference select(ServiceReference device, Match[] matches) {
if (Activator.DEBUG) {
log.log(device, log.LOG_DEBUG, "DriverSelector select called"); //$NON-NLS-1$
}
//This should give us the highest ranking DriverSelector (if available)
ServiceReference selector = getServiceReference();
if (selector != null) {
DriverSelector service = (DriverSelector) getService(selector);
try {
int index = service.select(device, matches);
if (index == DriverSelector.SELECT_NONE) {
return null;
}
return matches[index].getDriver();
} catch (Throwable t) {
log.log(selector, log.LOG_ERROR, DeviceMsg.DriverSelector_error_during_match, t);
}
}
return defaultSelection(matches);
}
/**
* Default match selection algorithm from OSGi SPR2 spec.
*
* @param matchArray An array of the successful matches.
* @return ServiceReference to the selected Driver service
*/
public ServiceReference defaultSelection(Match[] matches) {
int size = matches.length;
int max = Device.MATCH_NONE;
ServiceReference reference = null;
for (int i = 0; i < size; i++) {
Match driver = matches[i];
int match = driver.getMatchValue();
if (match >= max) {
if (match == max) /* we must break the tie */
{
reference = breakTie(reference, driver.getDriver());
} else {
max = match;
reference = driver.getDriver();
}
}
}
return reference;
}
/**
* Select the service with the highest service.ranking. Break ties
* buy selecting the lowest service.id.
*
*/
public ServiceReference breakTie(ServiceReference ref1, ServiceReference ref2) {
//first we check service rankings
Object property = ref1.getProperty(org.osgi.framework.Constants.SERVICE_RANKING);
int ref1Ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
property = ref2.getProperty(org.osgi.framework.Constants.SERVICE_RANKING);
int ref2Ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
if (ref1Ranking > ref2Ranking) {
return ref1;
} else if (ref2Ranking > ref1Ranking) {
return ref2;
} else // The rankings must match here
{
//we now check service ids
long ref1ID = ((Long) (ref1.getProperty(org.osgi.framework.Constants.SERVICE_ID))).longValue();
long ref2ID = ((Long) (ref2.getProperty(org.osgi.framework.Constants.SERVICE_ID))).longValue();
if (ref1ID < ref2ID) {
return ref1;
}
return ref2;
}
}
}