Search in sources :

Example 86 with OperationResourceInfo

use of org.apache.cxf.jaxrs.model.OperationResourceInfo in project cxf by apache.

the class JAXRSServiceImpl method getServiceInfos.

public List<ServiceInfo> getServiceInfos() {
    if (!createServiceModel) {
        return Collections.emptyList();
    }
    // try to convert to WSDL-centric model so that CXF DataBindings can get initialized
    // might become useful too if we support wsdl2
    // make databindings to use databinding-specific information
    // like @XmlRootElement for ex to select a namespace
    this.put("org.apache.cxf.databinding.namespace", "true");
    List<ServiceInfo> infos = new ArrayList<>();
    for (ClassResourceInfo cri : classResourceInfos) {
        ServiceInfo si = new ServiceInfo();
        infos.add(si);
        QName qname = JAXRSUtils.getClassQName(cri.getServiceClass());
        si.setName(qname);
        InterfaceInfo inf = new InterfaceInfo(si, qname);
        si.setInterface(inf);
        for (OperationResourceInfo ori : cri.getMethodDispatcher().getOperationResourceInfos()) {
            Method m = ori.getMethodToInvoke();
            QName oname = new QName(qname.getNamespaceURI(), m.getName());
            OperationInfo oi = inf.addOperation(oname);
            createMessagePartInfo(oi, m.getReturnType(), qname, m, false);
            for (Parameter pm : ori.getParameters()) {
                if (pm.getType() == ParameterType.REQUEST_BODY) {
                    createMessagePartInfo(oi, ori.getMethodToInvoke().getParameterTypes()[pm.getIndex()], qname, m, true);
                }
            }
        }
    }
    return infos;
}
Also used : ServiceInfo(org.apache.cxf.service.model.ServiceInfo) OperationInfo(org.apache.cxf.service.model.OperationInfo) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) ClassResourceInfo(org.apache.cxf.jaxrs.model.ClassResourceInfo) Parameter(org.apache.cxf.jaxrs.model.Parameter) OperationResourceInfo(org.apache.cxf.jaxrs.model.OperationResourceInfo) InterfaceInfo(org.apache.cxf.service.model.InterfaceInfo) Method(java.lang.reflect.Method)

Example 87 with OperationResourceInfo

use of org.apache.cxf.jaxrs.model.OperationResourceInfo in project cxf by apache.

the class JAXRSInvoker method getServiceObject.

public Object getServiceObject(Exchange exchange) {
    Object root = exchange.remove(JAXRSUtils.ROOT_INSTANCE);
    if (root != null) {
        return root;
    }
    OperationResourceInfo ori = exchange.get(OperationResourceInfo.class);
    ClassResourceInfo cri = ori.getClassResourceInfo();
    return cri.getResourceProvider().getInstance(exchange.getInMessage());
}
Also used : ClassResourceInfo(org.apache.cxf.jaxrs.model.ClassResourceInfo) OperationResourceInfo(org.apache.cxf.jaxrs.model.OperationResourceInfo)

Example 88 with OperationResourceInfo

use of org.apache.cxf.jaxrs.model.OperationResourceInfo in project cxf by apache.

the class JAXRSInInterceptor method processRequest.

private void processRequest(Message message, Exchange exchange) throws IOException {
    ServerProviderFactory providerFactory = ServerProviderFactory.getInstance(message);
    RequestPreprocessor rp = providerFactory.getRequestPreprocessor();
    if (rp != null) {
        rp.preprocess(message, new UriInfoImpl(message, null));
    }
    // Global pre-match request filters
    if (JAXRSUtils.runContainerRequestFilters(providerFactory, message, true, null)) {
        return;
    }
    // HTTP method
    String httpMethod = HttpUtils.getProtocolHeader(message, Message.HTTP_REQUEST_METHOD, HttpMethod.POST, true);
    // Path to match
    String rawPath = HttpUtils.getPathToMatch(message, true);
    Map<String, List<String>> protocolHeaders = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
    // Content-Type
    String requestContentType = null;
    List<String> ctHeaderValues = protocolHeaders.get(Message.CONTENT_TYPE);
    if (ctHeaderValues != null && !ctHeaderValues.isEmpty()) {
        requestContentType = ctHeaderValues.get(0);
        message.put(Message.CONTENT_TYPE, requestContentType);
    }
    if (requestContentType == null) {
        requestContentType = (String) message.get(Message.CONTENT_TYPE);
        if (requestContentType == null) {
            requestContentType = MediaType.WILDCARD;
        }
    }
    // Accept
    String acceptTypes = null;
    List<String> acceptHeaderValues = protocolHeaders.get(Message.ACCEPT_CONTENT_TYPE);
    if (acceptHeaderValues != null && !acceptHeaderValues.isEmpty()) {
        acceptTypes = acceptHeaderValues.get(0);
        message.put(Message.ACCEPT_CONTENT_TYPE, acceptTypes);
    }
    if (acceptTypes == null) {
        acceptTypes = HttpUtils.getProtocolHeader(message, Message.ACCEPT_CONTENT_TYPE, null);
        if (acceptTypes == null) {
            acceptTypes = "*/*";
            message.put(Message.ACCEPT_CONTENT_TYPE, acceptTypes);
        }
    }
    final List<MediaType> acceptContentTypes;
    try {
        acceptContentTypes = JAXRSUtils.sortMediaTypes(acceptTypes, JAXRSUtils.MEDIA_TYPE_Q_PARAM);
    } catch (IllegalArgumentException ex) {
        throw ExceptionUtils.toNotAcceptableException(null, null);
    }
    exchange.put(Message.ACCEPT_CONTENT_TYPE, acceptContentTypes);
    // 1. Matching target resource class
    List<ClassResourceInfo> resources = JAXRSUtils.getRootResources(message);
    Map<ClassResourceInfo, MultivaluedMap<String, String>> matchedResources = JAXRSUtils.selectResourceClass(resources, rawPath, message);
    if (matchedResources == null) {
        org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message("NO_ROOT_EXC", BUNDLE, message.get(Message.REQUEST_URI), rawPath);
        Level logLevel = JAXRSUtils.getExceptionLogLevel(message, NotFoundException.class);
        LOG.log(logLevel == null ? Level.FINE : logLevel, errorMsg.toString());
        Response resp = JAXRSUtils.createResponse(resources, message, errorMsg.toString(), Response.Status.NOT_FOUND.getStatusCode(), false);
        throw ExceptionUtils.toNotFoundException(null, resp);
    }
    MultivaluedMap<String, String> matchedValues = new MetadataMap<>();
    final OperationResourceInfo ori;
    try {
        ori = JAXRSUtils.findTargetMethod(matchedResources, message, httpMethod, matchedValues, requestContentType, acceptContentTypes, true, true);
        setExchangeProperties(message, exchange, ori, matchedValues, resources.size());
    } catch (WebApplicationException ex) {
        if (JAXRSUtils.noResourceMethodForOptions(ex.getResponse(), httpMethod)) {
            Response response = JAXRSUtils.createResponse(resources, null, null, 200, true);
            exchange.put(Response.class, response);
            return;
        }
        throw ex;
    }
    if (LOG.isLoggable(Level.FINE)) {
        LOG.fine("Request path is: " + rawPath);
        LOG.fine("Request HTTP method is: " + httpMethod);
        LOG.fine("Request contentType is: " + requestContentType);
        LOG.fine("Accept contentType is: " + acceptTypes);
        LOG.fine("Found operation: " + ori.getMethodToInvoke().getName());
    }
    // Global and name-bound post-match request filters
    if (!ori.isSubResourceLocator() && JAXRSUtils.runContainerRequestFilters(providerFactory, message, false, ori.getNameBindings())) {
        return;
    }
    // Process parameters
    List<Object> params = JAXRSUtils.processParameters(ori, matchedValues, message);
    message.setContent(List.class, params);
}
Also used : ServerProviderFactory(org.apache.cxf.jaxrs.provider.ServerProviderFactory) Message(org.apache.cxf.message.Message) WebApplicationException(javax.ws.rs.WebApplicationException) MetadataMap(org.apache.cxf.jaxrs.impl.MetadataMap) MediaType(javax.ws.rs.core.MediaType) MessageContentsList(org.apache.cxf.message.MessageContentsList) List(java.util.List) ClassResourceInfo(org.apache.cxf.jaxrs.model.ClassResourceInfo) Response(javax.ws.rs.core.Response) RequestPreprocessor(org.apache.cxf.jaxrs.impl.RequestPreprocessor) Level(java.util.logging.Level) OperationResourceInfo(org.apache.cxf.jaxrs.model.OperationResourceInfo) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) UriInfoImpl(org.apache.cxf.jaxrs.impl.UriInfoImpl)

Example 89 with OperationResourceInfo

use of org.apache.cxf.jaxrs.model.OperationResourceInfo 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<>(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<>();
                        }
                        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)

Example 90 with OperationResourceInfo

use of org.apache.cxf.jaxrs.model.OperationResourceInfo in project cxf by apache.

the class ResourceUtils method createServiceClassResourceInfo.

public static ClassResourceInfo createServiceClassResourceInfo(Map<String, UserResource> resources, UserResource model, Class<?> sClass, boolean isRoot, boolean enableStatic, Bus bus) {
    if (model == null) {
        throw new RuntimeException("Resource class " + sClass.getName() + " has no model info");
    }
    ClassResourceInfo cri = new ClassResourceInfo(sClass, sClass, isRoot, enableStatic, true, model.getConsumes(), model.getProduces(), bus);
    URITemplate t = URITemplate.createTemplate(model.getPath());
    cri.setURITemplate(t);
    MethodDispatcher md = new MethodDispatcher();
    Map<String, UserOperation> ops = model.getOperationsAsMap();
    Method defaultMethod = null;
    Map<String, Method> methodNames = new HashMap<>();
    for (Method m : cri.getServiceClass().getMethods()) {
        if (m.getAnnotation(DefaultMethod.class) != null) {
            // if needed we can also support multiple default methods
            defaultMethod = m;
        }
        methodNames.put(m.getName(), m);
    }
    for (Map.Entry<String, UserOperation> entry : ops.entrySet()) {
        UserOperation op = entry.getValue();
        Method actualMethod = methodNames.get(op.getName());
        if (actualMethod == null) {
            actualMethod = defaultMethod;
        }
        if (actualMethod == null) {
            continue;
        }
        OperationResourceInfo ori = new OperationResourceInfo(actualMethod, cri, URITemplate.createTemplate(op.getPath()), op.getVerb(), op.getConsumes(), op.getProduces(), op.getParameters(), op.isOneway());
        String rClassName = actualMethod.getReturnType().getName();
        if (op.getVerb() == null) {
            if (resources.containsKey(rClassName)) {
                ClassResourceInfo subCri = rClassName.equals(model.getName()) ? cri : createServiceClassResourceInfo(resources, resources.get(rClassName), actualMethod.getReturnType(), false, enableStatic, bus);
                if (subCri != null) {
                    cri.addSubClassResourceInfo(subCri);
                    md.bind(ori, actualMethod);
                }
            }
        } else {
            md.bind(ori, actualMethod);
        }
    }
    cri.setMethodDispatcher(md);
    return checkMethodDispatcher(cri) ? cri : null;
}
Also used : HashMap(java.util.HashMap) ClassResourceInfo(org.apache.cxf.jaxrs.model.ClassResourceInfo) URITemplate(org.apache.cxf.jaxrs.model.URITemplate) Method(java.lang.reflect.Method) DefaultMethod(org.apache.cxf.jaxrs.ext.DefaultMethod) UserOperation(org.apache.cxf.jaxrs.model.UserOperation) DefaultMethod(org.apache.cxf.jaxrs.ext.DefaultMethod) OperationResourceInfo(org.apache.cxf.jaxrs.model.OperationResourceInfo) MethodDispatcher(org.apache.cxf.jaxrs.model.MethodDispatcher) Map(java.util.Map) HashMap(java.util.HashMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Aggregations

OperationResourceInfo (org.apache.cxf.jaxrs.model.OperationResourceInfo)129 ClassResourceInfo (org.apache.cxf.jaxrs.model.ClassResourceInfo)104 Message (org.apache.cxf.message.Message)72 Test (org.junit.Test)70 Method (java.lang.reflect.Method)52 MetadataMap (org.apache.cxf.jaxrs.impl.MetadataMap)40 Customer (org.apache.cxf.jaxrs.Customer)22 Endpoint (org.apache.cxf.endpoint.Endpoint)13 MessageImpl (org.apache.cxf.message.MessageImpl)13 ByteArrayInputStream (java.io.ByteArrayInputStream)12 ArrayList (java.util.ArrayList)12 List (java.util.List)12 MultivaluedMap (javax.ws.rs.core.MultivaluedMap)11 Response (javax.ws.rs.core.Response)11 URITemplate (org.apache.cxf.jaxrs.model.URITemplate)11 Exchange (org.apache.cxf.message.Exchange)11 MediaType (javax.ws.rs.core.MediaType)10 ExchangeImpl (org.apache.cxf.message.ExchangeImpl)10 HttpServletResponse (javax.servlet.http.HttpServletResponse)7 MethodDispatcher (org.apache.cxf.jaxrs.model.MethodDispatcher)7