SortedMap<OperationResourceInfo, MultivaluedMap<String, String>> candidateList =
new TreeMap<OperationResourceInfo, MultivaluedMap<String, String>>(
new OperationResourceInfoComparator(message, httpMethod));
MediaType requestType = requestContentType == null
? ALL_TYPES : MediaType.valueOf(requestContentType);
int pathMatched = 0;
int methodMatched = 0;
int consumeMatched = 0;
int produceMatched = 0;
boolean subresourcesOnly = true;
for (MediaType acceptType : acceptContentTypes) {
for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
URITemplate uriTemplate = ori.getURITemplate();
MultivaluedMap<String, String> map = new MetadataMap<String, String>(values);
if (uriTemplate != null && uriTemplate.match(path, map)) {
boolean added = false;
if (ori.isSubResourceLocator()) {
candidateList.put(ori, map);
added = true;
} else {
String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
if (finalGroup == null || StringUtils.isEmpty(finalGroup)
|| finalGroup.equals("/")) {
pathMatched++;
boolean mMatched = matchHttpMethod(ori.getHttpMethod(), httpMethod);
boolean cMatched = matchConsumeTypes(requestType, ori);
boolean pMatched = matchProduceTypes(acceptType, ori);
if (mMatched && cMatched && pMatched) {
subresourcesOnly = false;
candidateList.put(ori, map);
added = true;
} else {
methodMatched = mMatched ? methodMatched + 1 : methodMatched;
produceMatched = pMatched ? produceMatched + 1 : produceMatched;
consumeMatched = cMatched ? consumeMatched + 1 : consumeMatched;
logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
}
} else {
logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
}
}
if (added && LOG.isLoggable(Level.FINE)) {
LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED_POSSIBLY",
BUNDLE,
ori.getMethodToInvoke().getName()).toString());
}
} else {
logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
}
}
if (!candidateList.isEmpty() && !subresourcesOnly) {
break;
}
}
if (!candidateList.isEmpty()) {
Map.Entry<OperationResourceInfo, MultivaluedMap<String, String>> firstEntry =
candidateList.entrySet().iterator().next();
values.clear();
values.putAll(firstEntry.getValue());
OperationResourceInfo ori = firstEntry.getKey();
if (headMethodPossible(ori.getHttpMethod(), httpMethod)) {
LOG.info(new org.apache.cxf.common.i18n.Message("GET_INSTEAD_OF_HEAD",
BUNDLE, resource.getServiceClass().getName(),
ori.getMethodToInvoke().getName()).toString());
}
LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED",
BUNDLE, ori.getMethodToInvoke().getName(),
resource.getServiceClass().getName()).toString());
return ori;
}
int status;
// criteria matched the least number of times will determine the error code;
// priority : path, method, consumes, produces;
if (pathMatched == 0) {
status = 404;
} else if (methodMatched == 0) {
status = 405;
} else if (consumeMatched <= produceMatched) {
status = 415;
} else {
status = 406;
}
String name = resource.isRoot() ? "NO_OP_EXC" : "NO_SUBRESOURCE_METHOD_FOUND";
org.apache.cxf.common.i18n.Message errorMsg =
new org.apache.cxf.common.i18n.Message(name,
BUNDLE,
path,
httpMethod,
requestType.toString(),
convertTypesToString(acceptContentTypes));
if (!"OPTIONS".equalsIgnoreCase(httpMethod) && logNow) {
LOG.warning(errorMsg.toString());
}
ResponseBuilder rb = createResponseBuilder(resource, status, methodMatched == 0);