
org.apache.cxf.jaxrs.JAXRSUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-rt-frontend-jaxrs Show documentation
Show all versions of cxf-rt-frontend-jaxrs Show documentation
Apache CXF Runtime JAX-RS Frontend
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.jaxrs;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.ConsumeMime;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.MessageBodyReader;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.PrimitiveUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.model.URITemplate;
import org.apache.cxf.jaxrs.provider.HttpHeadersImpl;
import org.apache.cxf.jaxrs.provider.PathSegmentImpl;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.provider.RequestImpl;
import org.apache.cxf.jaxrs.provider.SecurityContextImpl;
import org.apache.cxf.jaxrs.provider.UriInfoImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
public final class JAXRSUtils {
public static final MediaType ALL_TYPES = new MediaType();
private static final Logger LOG = LogUtils.getL7dLogger(JAXRSUtils.class);
private JAXRSUtils() {
}
public static String getHttpMethodValue(Method m) {
for (Annotation a : m.getAnnotations()) {
HttpMethod httpM = a.annotationType().getAnnotation(HttpMethod.class);
if (httpM != null) {
return httpM.value();
}
}
// TODO : make it shorter
for (Class> i : m.getDeclaringClass().getInterfaces()) {
try {
Method interfaceMethod = i.getMethod(m.getName(), m.getParameterTypes());
if (interfaceMethod != null) {
return getHttpMethodValue(interfaceMethod);
}
} catch (NoSuchMethodException ex) {
//ignore
}
}
Class> superC = m.getDeclaringClass().getSuperclass();
if (superC != null) {
try {
Method cMethod = superC.getMethod(m.getName(), m.getParameterTypes());
if (cMethod != null) {
return getHttpMethodValue(cMethod);
}
} catch (NoSuchMethodException ex) {
//ignore
}
}
return null;
}
public static Annotation getMethodAnnotation(Method m,
Class extends Annotation> aClass) {
Annotation a = m.getAnnotation(aClass);
if (a != null) {
return a;
}
for (Class> i : m.getDeclaringClass().getInterfaces()) {
a = getClassMethodAnnotation(m, i, aClass);
if (a != null) {
return a;
}
}
Class> superC = m.getDeclaringClass().getSuperclass();
if (superC != null) {
return getClassMethodAnnotation(m, superC, aClass);
}
return null;
}
private static Annotation getClassMethodAnnotation(Method m,
Class> c,
Class extends Annotation> aClass) {
try {
Method interfaceMethod = c.getMethod(m.getName(), m.getParameterTypes());
if (interfaceMethod != null) {
return getMethodAnnotation(interfaceMethod, aClass);
}
} catch (NoSuchMethodException ex) {
//ignore
}
return null;
}
public static Annotation getClassAnnotation(Class> c,
Class extends Annotation> aClass) {
if (c == null) {
return null;
}
Annotation p = c.getAnnotation(aClass);
if (p != null) {
return p;
}
return getClassAnnotation(c.getSuperclass(), aClass);
}
public static List getPathSegments(String thePath, boolean decode) {
String[] segments = thePath.split("/");
List theList = new ArrayList();
for (String path : segments) {
if (!StringUtils.isEmpty(path)) {
theList.add(new PathSegmentImpl(path, decode));
}
}
return theList;
}
public static List getMediaTypes(String[] values) {
List supportedMimeTypes = new ArrayList(values.length);
for (int i = 0; i < values.length; i++) {
supportedMimeTypes.add(MediaType.parse(values[i]));
}
return supportedMimeTypes;
}
public static ClassResourceInfo findSubResourceClass(ClassResourceInfo resource,
Class subResourceClassType) {
for (ClassResourceInfo subCri : resource.getSubClassResourceInfo()) {
if (subCri.getResourceClass() == subResourceClassType) {
return subCri;
}
}
return null;
}
public static OperationResourceInfo findTargetResourceClass(List resources,
String path,
String httpMethod,
MultivaluedMap values,
String requestContentType,
String acceptContentTypes) {
for (ClassResourceInfo resource : resources) {
URITemplate uriTemplate = resource.getURITemplate();
MultivaluedMap map = new MetadataMap();
if (uriTemplate.match(path, map)) {
String subResourcePath = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
OperationResourceInfo ori = findTargetMethod(resource, subResourcePath, httpMethod, map,
requestContentType, acceptContentTypes);
if (ori != null) {
values.putAll(map);
return ori;
}
}
}
return null;
}
public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource,
String path,
String httpMethod,
MultivaluedMap values,
String requestContentType,
String acceptContentTypes) {
SortedMap> candidateList =
new TreeMap>(
new OperationResourceInfoComparator());
MediaType requestType = requestContentType == null
? ALL_TYPES : MediaType.parse(requestContentType);
List acceptTypes = JAXRSUtils.sortMediaTypes(acceptContentTypes);
for (MediaType acceptType : acceptTypes) {
for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
URITemplate uriTemplate = ori.getURITemplate();
MultivaluedMap map = cloneMap(values);
if (uriTemplate != null && uriTemplate.match(path, map)) {
if (ori.isSubResourceLocator() && matchMimeTypes(requestType, acceptType, ori)) {
candidateList.put(ori, map);
} else if (ori.getHttpMethod().equalsIgnoreCase(httpMethod)
&& matchMimeTypes(requestType, acceptType, ori)) {
String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
if (finalGroup == null || StringUtils.isEmpty(finalGroup)
|| finalGroup.equals("/")) {
candidateList.put(ori, map);
}
}
}
}
if (!candidateList.isEmpty()) {
Map.Entry> firstEntry =
candidateList.entrySet().iterator().next();
values.clear();
values.putAll(firstEntry.getValue());
return firstEntry.getKey();
}
}
return null;
}
public static List getConsumeTypes(ConsumeMime cm) {
return cm == null ? Collections.singletonList(ALL_TYPES)
: getMediaTypes(cm.value());
}
public static List getProduceTypes(ProduceMime pm) {
return pm == null ? Collections.singletonList(ALL_TYPES)
: getMediaTypes(pm.value());
}
private static class OperationResourceInfoComparator implements Comparator {
public int compare(OperationResourceInfo e1, OperationResourceInfo e2) {
List mimeType1 =
getConsumeTypes(e1.getMethod().getAnnotation(ConsumeMime.class));
List mimeType2 =
getConsumeTypes(e2.getMethod().getAnnotation(ConsumeMime.class));
// TODO: we actually need to check all consume and produce types here ?
int result = JAXRSUtils.compareMediaTypes(mimeType1.get(0),
mimeType2.get(0));
if (result == 0) {
//use the media type of output data as the secondary key.
List mimeTypeP1 =
getProduceTypes(e1.getMethod().getAnnotation(ProduceMime.class));
List mimeTypeP2 =
getProduceTypes(e2.getMethod().getAnnotation(ProduceMime.class));
return JAXRSUtils.compareMediaTypes(mimeTypeP1.get(0),
mimeTypeP2.get(0));
} else {
return result;
}
}
}
public static int compareMediaTypes(MediaType mt1, MediaType mt2) {
if (mt1.equals(mt2)) {
float q1 = getMediaTypeQualityFactor(mt1);
float q2 = getMediaTypeQualityFactor(mt2);
int result = Float.compare(q1, q2);
return result == 0 ? result : ~result;
}
if (mt1.isWildcardType() && !mt2.isWildcardType()) {
return 1;
}
if (!mt1.isWildcardType() && mt2.isWildcardType()) {
return -1;
}
if (mt1.getType().equals(mt2.getType())) {
if (mt1.isWildcardSubtype() && !mt2.isWildcardSubtype()) {
return 1;
}
if (!mt1.isWildcardSubtype() && mt2.isWildcardSubtype()) {
return -1;
}
}
return mt1.toString().compareTo(mt2.toString());
}
private static float getMediaTypeQualityFactor(MediaType mt) {
String q = mt.getParameters().get("q");
if (q == null) {
return 1;
}
if (q.charAt(0) == '.') {
q = '0' + q;
}
try {
return Float.parseFloat(q);
} catch (NumberFormatException ex) {
// default value will do
}
return 1;
}
//Message contains following information: PATH, HTTP_REQUEST_METHOD, CONTENT_TYPE, InputStream.
public static List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy