}
else if (pathConflicts.containsKey(uri)) {
List<String> strings = new ArrayList<String>();
for (UrlBinding conflict : pathConflicts.get(uri))
strings.add(conflict.toString());
throw new UrlBindingConflictException(uri, strings);
}
// Get all the bindings whose prefix matches the URI
Set<UrlBinding> candidates = null;
for (Entry<String, Set<UrlBinding>> entry : prefixCache.entrySet()) {
if (uri.startsWith(entry.getKey())) {
candidates = entry.getValue();
break;
}
}
// If none matched or exactly one matched then return now
if (candidates == null) {
log.debug("No URL binding matches ", uri);
return null;
}
else if (candidates.size() == 1) {
log.debug("Matched ", uri, " to ", candidates);
return candidates.iterator().next();
}
// Now find the one that matches deepest into the URI with the fewest components
int maxIndex = 0, minComponentCount = Integer.MAX_VALUE, maxComponentMatch = 0;
List<String> conflicts = null;
for (UrlBinding binding : candidates) {
int idx = binding.getPath().length();
List<Object> components = binding.getComponents();
int componentCount = components.size(), componentMatch = 0;
for (Object component : components) {
if (!(component instanceof String))
continue;
String string = (String) component;
int at = uri.indexOf(string, idx);
if (at >= 0) {
idx = at + string.length();
++componentMatch;
}
else if (binding.getSuffix() != null) {
// Prefer suffix matches
string = binding.getSuffix();
at = uri.indexOf(string, idx);
if (at >= 0) {
idx = at + string.length();
++componentMatch;
}
break;
}
else {
break;
}
}
boolean betterMatch = idx > maxIndex
|| (idx == maxIndex && (componentCount < minComponentCount || componentMatch > maxComponentMatch));
if (betterMatch) {
if (conflicts != null)
conflicts.clear();
prototype = binding;
maxIndex = idx;
minComponentCount = componentCount;
maxComponentMatch = componentMatch;
}
else if (idx == maxIndex && componentCount == minComponentCount) {
if (conflicts == null) {
conflicts = new ArrayList<String>(candidates.size());
conflicts.add(prototype.toString());
}
conflicts.add(binding.toString());
prototype = null;
}
}
log.debug("Matched @", maxIndex, " ", uri, " to ", prototype == null ? conflicts : prototype);
if (prototype == null) {
throw new UrlBindingConflictException(uri, conflicts);
}
return prototype;
}