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;
}
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());
}
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);
}
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);
}
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;
}
Aggregations