use of org.apache.cxf.jaxrs.model.OperationResourceInfoComparator in project cxf by apache.
the class JAXRSUtils method findTargetMethod.
// CHECKSTYLE:OFF
public static OperationResourceInfo findTargetMethod(Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources, Message message, String httpMethod, MultivaluedMap<String, String> matchedValues, String requestContentType, List<MediaType> acceptContentTypes, boolean throwException, boolean recordMatchedUri) {
// CHECKSTYLE:ON
final boolean getMethod = HttpMethod.GET.equals(httpMethod);
MediaType requestType;
try {
requestType = toMediaType(requestContentType);
} catch (IllegalArgumentException ex) {
throw ExceptionUtils.toNotSupportedException(ex, null);
}
SortedMap<OperationResourceInfo, MultivaluedMap<String, String>> candidateList = new TreeMap<OperationResourceInfo, MultivaluedMap<String, String>>(new OperationResourceInfoComparator(message, httpMethod, getMethod, requestType, acceptContentTypes));
int pathMatched = 0;
int methodMatched = 0;
int consumeMatched = 0;
List<OperationResourceInfo> finalPathSubresources = null;
for (Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> rEntry : matchedResources.entrySet()) {
ClassResourceInfo resource = rEntry.getKey();
MultivaluedMap<String, String> values = rEntry.getValue();
String path = getCurrentPath(values);
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("START_OPER_MATCH", BUNDLE, resource.getServiceClass().getName()).toString());
for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
boolean added = false;
URITemplate uriTemplate = ori.getURITemplate();
MultivaluedMap<String, String> map = new MetadataMap<String, String>(values);
if (uriTemplate != null && uriTemplate.match(path, map)) {
String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
boolean finalPath = StringUtils.isEmpty(finalGroup) || PATH_SEGMENT_SEP.equals(finalGroup);
if (ori.isSubResourceLocator()) {
candidateList.put(ori, map);
if (finalPath) {
if (finalPathSubresources == null) {
finalPathSubresources = new LinkedList<OperationResourceInfo>();
}
finalPathSubresources.add(ori);
}
added = true;
} else if (finalPath) {
pathMatched++;
if (matchHttpMethod(ori.getHttpMethod(), httpMethod)) {
methodMatched++;
// CHECKSTYLE:OFF
if (getMethod || matchConsumeTypes(requestType, ori)) {
consumeMatched++;
for (MediaType acceptType : acceptContentTypes) {
if (matchProduceTypes(acceptType, ori)) {
candidateList.put(ori, map);
added = true;
break;
}
}
}
// CHECKSTYLE:ON
}
}
}
LOG.fine(matchMessageLogSupplier(ori, path, httpMethod, requestType, acceptContentTypes, added));
}
}
if (finalPathSubresources != null && pathMatched > 0 && !MessageUtils.getContextualBoolean(message, KEEP_SUBRESOURCE_CANDIDATES, false)) {
for (OperationResourceInfo key : finalPathSubresources) {
candidateList.remove(key);
}
}
if (!candidateList.isEmpty()) {
Map.Entry<OperationResourceInfo, MultivaluedMap<String, String>> firstEntry = candidateList.entrySet().iterator().next();
matchedValues.clear();
matchedValues.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, ori.getClassResourceInfo().getServiceClass().getName(), ori.getMethodToInvoke().getName()).toString());
}
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("OPER_SELECTED", BUNDLE, ori.getMethodToInvoke().getName(), ori.getClassResourceInfo().getServiceClass().getName()).toString());
if (!ori.isSubResourceLocator()) {
MediaType responseMediaType = intersectSortMediaTypes(acceptContentTypes, ori.getProduceTypes(), false).get(0);
message.getExchange().put(Message.CONTENT_TYPE, mediaTypeToString(responseMediaType, MEDIA_TYPE_Q_PARAM, MEDIA_TYPE_QS_PARAM));
}
if (recordMatchedUri) {
pushOntoStack(ori, matchedValues, message);
}
return ori;
}
if (!throwException) {
return null;
}
int status;
// priority : path, method, consumes, produces;
if (pathMatched == 0) {
status = 404;
} else if (methodMatched == 0) {
status = 405;
} else if (consumeMatched == 0) {
status = 415;
} else {
// Not a single Produces match
status = 406;
}
Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> firstCri = matchedResources.entrySet().iterator().next();
String name = firstCri.getKey().isRoot() ? "NO_OP_EXC" : "NO_SUBRESOURCE_METHOD_FOUND";
org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message(name, BUNDLE, message.get(Message.REQUEST_URI), getCurrentPath(firstCri.getValue()), httpMethod, mediaTypeToString(requestType), convertTypesToString(acceptContentTypes));
if (!"OPTIONS".equalsIgnoreCase(httpMethod)) {
Level logLevel = getExceptionLogLevel(message, ClientErrorException.class);
LOG.log(logLevel == null ? Level.FINE : logLevel, () -> errorMsg.toString());
}
Response response = createResponse(getRootResources(message), message, errorMsg.toString(), status, methodMatched == 0);
throw ExceptionUtils.toHttpException(null, response);
}
Aggregations