package bndtools.model.resolution;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bndtools.core.ui.resource.R5LabelFormatter;
import org.osgi.framework.Version;
import org.osgi.resource.Capability;
import org.osgi.resource.Namespace;
import org.osgi.resource.Requirement;
public class CapReqComparator implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Requirement)
return compareReqToObj((Requirement) o1, o2);
if (o1 instanceof RequirementWrapper)
return compareReqToObj(((RequirementWrapper) o1).requirement, o2);
if (o1 instanceof Capability)
return compareCapToObj((Capability) o1, o2);
return 0;
}
private int compareReqToObj(Requirement r1, Object o2) {
if (o2 instanceof Requirement)
return compareReqToReq(r1, (Requirement) o2);
if (o2 instanceof RequirementWrapper)
return compareReqToReq(r1, ((RequirementWrapper) o2).requirement);
// requirements sort before other things
return -1;
}
private int compareCapToObj(Capability c1, Object o2) {
if (o2 instanceof Capability)
return compareCapToCap(c1, (Capability) o2);
// capabilities sort after other things
return 1;
}
private int compareCapToCap(Capability c1, Capability c2) {
// Compare namespaces
String ns1 = c1.getNamespace();
String ns2 = c2.getNamespace();
int nsDiff = ns1.compareTo(ns2);
if (nsDiff != 0)
return nsDiff;
// Compare the main attribute
String attribName = R5LabelFormatter.getMainAttributeName(ns1);
String attrib1 = c1.getAttributes().get(attribName).toString();
String attrib2 = c2.getAttributes().get(attribName).toString();
int attribDiff = attrib1.compareTo(attrib2);
if (attribDiff != 0)
return attribDiff;
// Compare the versions
String versionAttribName = R5LabelFormatter.getVersionAttributeName(ns1);
if (versionAttribName == null)
return 0;
Version v1 = (Version) c1.getAttributes().get(versionAttribName);
if (v1 == null)
v1 = Version.emptyVersion;
Version v2 = (Version) c2.getAttributes().get(versionAttribName);
if (v2 == null)
v2 = Version.emptyVersion;
return v1.compareTo(v2);
}
private int compareReqToReq(Requirement r1, Requirement r2) {
// Compare namespaces
String ns1 = r1.getNamespace();
String ns2 = r2.getNamespace();
int nsDiff = ns1.compareTo(ns2);
if (nsDiff != 0)
return nsDiff;
// Get the main attribute
Pattern filterPattern = R5LabelFormatter.getFilterPattern(ns1);
if (filterPattern == null)
return 0;
String filter1 = r1.getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
Matcher m1 = filterPattern.matcher(filter1);
String filter2 = r2.getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
Matcher m2 = filterPattern.matcher(filter2);
if (!m1.find() || !m2.find())
return 0;
String attrib1 = m1.group(1);
String attrib2 = m2.group(1);
if (attrib1 == null || attrib2 == null)
return 0;
return attrib1.compareTo(attrib2);
}
}