use of org.apache.cxf.jaxrs.impl.MetadataMap 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);
}
use of org.apache.cxf.jaxrs.impl.MetadataMap in project cxf by apache.
the class JAXRSUtils method selectResourceClass.
public static Map<ClassResourceInfo, MultivaluedMap<String, String>> selectResourceClass(List<ClassResourceInfo> resources, String path, Message message) {
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("START_CRI_MATCH", BUNDLE, path).toString());
if (resources.size() == 1) {
MultivaluedMap<String, String> values = new MetadataMap<String, String>();
return resources.get(0).getURITemplate().match(path, values) ? Collections.singletonMap(resources.get(0), values) : null;
}
SortedMap<ClassResourceInfo, MultivaluedMap<String, String>> candidateList = new TreeMap<ClassResourceInfo, MultivaluedMap<String, String>>(new ClassResourceInfoComparator(message));
for (ClassResourceInfo cri : resources) {
MultivaluedMap<String, String> map = new MetadataMap<String, String>();
if (cri.getURITemplate().match(path, map)) {
candidateList.put(cri, map);
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("CRI_SELECTED_POSSIBLY", BUNDLE, cri.getServiceClass().getName(), path, cri.getURITemplate().getValue()).toString());
} else {
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("CRI_NO_MATCH", BUNDLE, path, cri.getServiceClass().getName()).toString());
}
}
if (!candidateList.isEmpty()) {
Map<ClassResourceInfo, MultivaluedMap<String, String>> cris = new LinkedHashMap<ClassResourceInfo, MultivaluedMap<String, String>>(candidateList.size());
ClassResourceInfo firstCri = null;
for (Map.Entry<ClassResourceInfo, MultivaluedMap<String, String>> entry : candidateList.entrySet()) {
ClassResourceInfo cri = entry.getKey();
if (cris.isEmpty()) {
firstCri = cri;
cris.put(cri, entry.getValue());
} else if (firstCri != null && URITemplate.compareTemplates(firstCri.getURITemplate(), cri.getURITemplate()) == 0) {
cris.put(cri, entry.getValue());
} else {
break;
}
LOG.fine(() -> new org.apache.cxf.common.i18n.Message("CRI_SELECTED", BUNDLE, cri.getServiceClass().getName(), path, cri.getURITemplate().getValue()).toString());
}
return cris;
}
return null;
}
use of org.apache.cxf.jaxrs.impl.MetadataMap in project cxf by apache.
the class JAXRSUtils method processMatrixParam.
private static Object processMatrixParam(Message m, String key, Class<?> pClass, Type genericType, Annotation[] paramAnns, String defaultValue, boolean decode) {
List<PathSegment> segments = JAXRSUtils.getPathSegments((String) m.get(Message.REQUEST_URI), decode);
if (!segments.isEmpty()) {
MultivaluedMap<String, String> params = new MetadataMap<String, String>();
for (PathSegment ps : segments) {
MultivaluedMap<String, String> matrix = ps.getMatrixParameters();
for (Map.Entry<String, List<String>> entry : matrix.entrySet()) {
for (String value : entry.getValue()) {
params.add(entry.getKey(), value);
}
}
}
if ("".equals(key)) {
return InjectionUtils.handleBean(pClass, paramAnns, params, ParameterType.MATRIX, m, false);
}
List<String> values = params.get(key);
return InjectionUtils.createParameterObject(values, pClass, genericType, paramAnns, defaultValue, false, ParameterType.MATRIX, m);
}
return null;
}
use of org.apache.cxf.jaxrs.impl.MetadataMap in project cxf by apache.
the class JAXRSServiceFactoryBeanTest method testSubResources.
@Test
public void testSubResources() throws Exception {
JAXRSServiceFactoryBean sf = new JAXRSServiceFactoryBean();
sf.setEnableStaticResolution(true);
sf.setResourceClasses(org.apache.cxf.jaxrs.resources.BookStore.class);
sf.create();
List<ClassResourceInfo> resources = ((JAXRSServiceImpl) sf.getService()).getClassResourceInfos();
assertEquals(1, resources.size());
// Verify root ClassResourceInfo: BookStore
ClassResourceInfo rootCri = resources.get(0);
assertNotNull(rootCri.getURITemplate());
URITemplate template = rootCri.getURITemplate();
MultivaluedMap<String, String> values = new MetadataMap<String, String>();
assertTrue(template.match("/bookstore/books/123", values));
assertTrue(rootCri.hasSubResources());
MethodDispatcher md = rootCri.getMethodDispatcher();
assertEquals(7, md.getOperationResourceInfos().size());
for (OperationResourceInfo ori : md.getOperationResourceInfos()) {
if ("getDescription".equals(ori.getMethodToInvoke().getName())) {
assertEquals("GET", ori.getHttpMethod());
assertEquals("/path", ori.getURITemplate().getValue());
assertEquals("text/bar", ori.getProduceTypes().get(0).toString());
assertEquals("text/foo", ori.getConsumeTypes().get(0).toString());
assertFalse(ori.isSubResourceLocator());
} else if ("getAuthor".equals(ori.getMethodToInvoke().getName())) {
assertEquals("GET", ori.getHttpMethod());
assertEquals("/path2", ori.getURITemplate().getValue());
assertEquals("text/bar2", ori.getProduceTypes().get(0).toString());
assertEquals("text/foo2", ori.getConsumeTypes().get(0).toString());
assertFalse(ori.isSubResourceLocator());
} else if ("getBook".equals(ori.getMethodToInvoke().getName())) {
assertNull(ori.getHttpMethod());
assertNotNull(ori.getURITemplate());
assertTrue(ori.isSubResourceLocator());
} else if ("getNewBook".equals(ori.getMethodToInvoke().getName())) {
assertNull(ori.getHttpMethod());
assertNotNull(ori.getURITemplate());
assertTrue(ori.isSubResourceLocator());
} else if ("addBook".equals(ori.getMethodToInvoke().getName())) {
assertEquals("POST", ori.getHttpMethod());
assertNotNull(ori.getURITemplate());
assertFalse(ori.isSubResourceLocator());
} else if ("updateBook".equals(ori.getMethodToInvoke().getName())) {
assertEquals("PUT", ori.getHttpMethod());
assertNotNull(ori.getURITemplate());
assertFalse(ori.isSubResourceLocator());
} else if ("deleteBook".equals(ori.getMethodToInvoke().getName())) {
assertEquals("DELETE", ori.getHttpMethod());
assertNotNull(ori.getURITemplate());
assertFalse(ori.isSubResourceLocator());
} else {
fail("unexpected OperationResourceInfo" + ori.getMethodToInvoke().getName());
}
}
// Verify sub-resource ClassResourceInfo: Book
assertEquals(1, rootCri.getSubResources().size());
ClassResourceInfo subCri = rootCri.getSubResources().iterator().next();
assertNull(subCri.getURITemplate());
assertEquals(org.apache.cxf.jaxrs.resources.Book.class, subCri.getResourceClass());
MethodDispatcher subMd = subCri.getMethodDispatcher();
assertEquals(2, subMd.getOperationResourceInfos().size());
// getChapter method
OperationResourceInfo subOri = subMd.getOperationResourceInfos().iterator().next();
assertEquals("GET", subOri.getHttpMethod());
assertNotNull(subOri.getURITemplate());
// getState method
OperationResourceInfo subOri2 = subMd.getOperationResourceInfos().iterator().next();
assertEquals("GET", subOri2.getHttpMethod());
assertNotNull(subOri2.getURITemplate());
}
use of org.apache.cxf.jaxrs.impl.MetadataMap in project cxf by apache.
the class SelectMethodCandidatesTest method testSelectUsingQualityFactors.
@Test
public void testSelectUsingQualityFactors() throws Exception {
JAXRSServiceFactoryBean sf = new JAXRSServiceFactoryBean();
sf.setResourceClasses(org.apache.cxf.jaxrs.resources.TestResource.class);
sf.create();
List<ClassResourceInfo> resources = ((JAXRSServiceImpl) sf.getService()).getClassResourceInfos();
String contentTypes = "*/*";
String acceptContentTypes = "application/xml;q=0.5,application/json";
MetadataMap<String, String> values = new MetadataMap<String, String>();
OperationResourceInfo ori = findTargetResourceClass(resources, createMessage(), "/1/2/3/d/resource1", "GET", values, contentTypes, sortMediaTypes(acceptContentTypes));
assertNotNull(ori);
assertEquals("jsonResource needs to be selected", "jsonResource", ori.getMethodToInvoke().getName());
}
Aggregations