Search in sources :

Example 1 with OperationResourceInfoComparator

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);
}
Also used : OperationResourceInfoComparator(org.apache.cxf.jaxrs.model.OperationResourceInfoComparator) Message(org.apache.cxf.message.Message) MetadataMap(org.apache.cxf.jaxrs.impl.MetadataMap) MediaType(javax.ws.rs.core.MediaType) ClassResourceInfo(org.apache.cxf.jaxrs.model.ClassResourceInfo) URITemplate(org.apache.cxf.jaxrs.model.URITemplate) TreeMap(java.util.TreeMap) AsyncResponse(javax.ws.rs.container.AsyncResponse) Response(javax.ws.rs.core.Response) OperationResourceInfo(org.apache.cxf.jaxrs.model.OperationResourceInfo) Level(java.util.logging.Level) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) MetadataMap(org.apache.cxf.jaxrs.impl.MetadataMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Aggregations

LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1 Level (java.util.logging.Level)1 AsyncResponse (javax.ws.rs.container.AsyncResponse)1 MediaType (javax.ws.rs.core.MediaType)1 MultivaluedMap (javax.ws.rs.core.MultivaluedMap)1 Response (javax.ws.rs.core.Response)1 MetadataMap (org.apache.cxf.jaxrs.impl.MetadataMap)1 ClassResourceInfo (org.apache.cxf.jaxrs.model.ClassResourceInfo)1 OperationResourceInfo (org.apache.cxf.jaxrs.model.OperationResourceInfo)1 OperationResourceInfoComparator (org.apache.cxf.jaxrs.model.OperationResourceInfoComparator)1 URITemplate (org.apache.cxf.jaxrs.model.URITemplate)1 Message (org.apache.cxf.message.Message)1