org.apache.cxf.jaxrs.utils.JAXRSUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-jaxrs Show documentation
Show all versions of cxf-bundle-jaxrs Show documentation
Apache CXF JAX-RS Bundle Jar
/**
* 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.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Cookie;
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.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import javax.xml.namespace.QName;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.i18n.BundleUtils;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxrs.ext.ContextProvider;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.MessageContextImpl;
import org.apache.cxf.jaxrs.ext.ProtocolHeaders;
import org.apache.cxf.jaxrs.ext.ProtocolHeadersImpl;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.impl.AsyncResponseImpl;
import org.apache.cxf.jaxrs.impl.ContainerRequestContextImpl;
import org.apache.cxf.jaxrs.impl.ContainerResponseContextImpl;
import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
import org.apache.cxf.jaxrs.impl.HttpServletResponseFilter;
import org.apache.cxf.jaxrs.impl.MediaTypeHeaderProvider;
import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.PathSegmentImpl;
import org.apache.cxf.jaxrs.impl.ProvidersImpl;
import org.apache.cxf.jaxrs.impl.ReaderInterceptorContextImpl;
import org.apache.cxf.jaxrs.impl.ReaderInterceptorMBR;
import org.apache.cxf.jaxrs.impl.RequestImpl;
import org.apache.cxf.jaxrs.impl.ResourceContextImpl;
import org.apache.cxf.jaxrs.impl.ResourceInfoImpl;
import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl;
import org.apache.cxf.jaxrs.impl.ResponseImpl;
import org.apache.cxf.jaxrs.impl.SecurityContextImpl;
import org.apache.cxf.jaxrs.impl.UriInfoImpl;
import org.apache.cxf.jaxrs.impl.WriterInterceptorContextImpl;
import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
import org.apache.cxf.jaxrs.model.BeanParamInfo;
import org.apache.cxf.jaxrs.model.BeanResourceInfo;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.ClassResourceInfoComparator;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfoComparator;
import org.apache.cxf.jaxrs.model.Parameter;
import org.apache.cxf.jaxrs.model.ParameterType;
import org.apache.cxf.jaxrs.model.ProviderInfo;
import org.apache.cxf.jaxrs.model.URITemplate;
import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
public final class JAXRSUtils {
public static final MediaType ALL_TYPES = new MediaType();
public static final String ROOT_RESOURCE_CLASS = "root.resource.class";
public static final String IGNORE_MESSAGE_WRITERS = "ignore.message.writers";
public static final String ROOT_INSTANCE = "service.root.instance";
public static final String ROOT_PROVIDER = "service.root.provider";
public static final String EXCEPTION_FROM_MAPPER = "exception.from.mapper";
public static final String PARTIAL_HIERARCHICAL_MEDIA_SUBTYPE_CHECK =
"media.subtype.partial.check";
public static final String DOC_LOCATION = "wadl.location";
public static final String DEFAULT_PROVIDERS_FOR_SIMPLE_TYPES = "defaultProviders.for.simpleTypes";
public static final String MEDIA_TYPE_Q_PARAM = "q";
public static final String MEDIA_TYPE_QS_PARAM = "qs";
private static final String MEDIA_TYPE_DISTANCE_PARAM = "d";
private static final String DEFAULT_CONTENT_TYPE = "default.content.type";
private static final Logger LOG = LogUtils.getL7dLogger(JAXRSUtils.class);
private static final ResourceBundle BUNDLE = BundleUtils.getBundle(JAXRSUtils.class);
private static final String PATH_SEGMENT_SEP = "/";
private static final String REPORT_FAULT_MESSAGE_PROPERTY = "org.apache.cxf.jaxrs.report-fault-message";
private static final String NO_CONTENT_EXCEPTION = "javax.ws.rs.core.NoContentException";
private static final String HTTP_CHARSET_PARAM = "charset";
private JAXRSUtils() {
}
public static List getPathSegments(String thePath, boolean decode) {
return getPathSegments(thePath, decode, true);
}
public static List getPathSegments(String thePath, boolean decode,
boolean ignoreLastSlash) {
String[] segments = StringUtils.split(thePath, "/");
List theList = new ArrayList();
for (String path : segments) {
if (!StringUtils.isEmpty(path)) {
theList.add(new PathSegmentImpl(path, decode));
}
}
int len = thePath.length();
if (len > 0 && thePath.charAt(len - 1) == '/') {
String value = ignoreLastSlash ? "" : "/";
theList.add(new PathSegmentImpl(value, false));
}
return theList;
}
private static String[] getUserMediaTypes(Object provider, boolean consumes) {
String[] values = null;
if (AbstractConfigurableProvider.class.isAssignableFrom(provider.getClass())) {
List types = null;
if (consumes) {
types = ((AbstractConfigurableProvider)provider).getConsumeMediaTypes();
} else {
types = ((AbstractConfigurableProvider)provider).getProduceMediaTypes();
}
if (types != null) {
values = types.size() > 0 ? types.toArray(new String[types.size()])
: new String[]{"*/*"};
}
}
return values;
}
public static List getProviderConsumeTypes(MessageBodyReader> provider) {
String[] values = getUserMediaTypes(provider, true);
if (values == null) {
return getConsumeTypes(provider.getClass().getAnnotation(Consumes.class));
} else {
return JAXRSUtils.getMediaTypes(values);
}
}
public static List getProviderProduceTypes(MessageBodyWriter> provider) {
String[] values = getUserMediaTypes(provider, false);
if (values == null) {
return getProduceTypes(provider.getClass().getAnnotation(Produces.class));
} else {
return JAXRSUtils.getMediaTypes(values);
}
}
public static List getMediaTypes(String[] values) {
List supportedMimeTypes = new ArrayList(values.length);
for (int i = 0; i < values.length; i++) {
supportedMimeTypes.add(toMediaType(values[i]));
}
return supportedMimeTypes;
}
public static void injectParameters(OperationResourceInfo ori,
Object requestObject,
Message message) {
injectParameters(ori, ori.getClassResourceInfo(), requestObject, message);
}
@SuppressWarnings("unchecked")
public static void injectParameters(OperationResourceInfo ori,
BeanResourceInfo bri,
Object requestObject,
Message message) {
if (bri.isSingleton()
&& (!bri.getParameterMethods().isEmpty() || !bri.getParameterFields().isEmpty())) {
LOG.fine("Injecting request parameters into singleton resource is not thread-safe");
}
// Param methods
MultivaluedMap values =
(MultivaluedMap)message.get(URITemplate.TEMPLATE_PARAMETERS);
for (Method m : bri.getParameterMethods()) {
Parameter p = ResourceUtils.getParameter(0, m.getAnnotations(),
m.getParameterTypes()[0]);
Object o;
if (p.getType() == ParameterType.BEAN && bri instanceof ClassResourceInfo) {
o = createBeanParamValue(message, m.getParameterTypes()[0], ori);
} else {
o = createHttpParameterValue(p,
m.getParameterTypes()[0],
m.getGenericParameterTypes()[0],
m.getParameterAnnotations()[0],
message,
values,
ori);
}
InjectionUtils.injectThroughMethod(requestObject, m, o, message);
}
// Param fields
for (Field f : bri.getParameterFields()) {
Parameter p = ResourceUtils.getParameter(0, f.getAnnotations(),
f.getType());
Object o = null;
if (p.getType() == ParameterType.BEAN && bri instanceof ClassResourceInfo) {
o = createBeanParamValue(message, f.getType(), ori);
} else {
o = createHttpParameterValue(p,
f.getType(),
f.getGenericType(),
f.getAnnotations(),
message,
values,
ori);
}
InjectionUtils.injectFieldValue(f, requestObject, o);
}
}
public static ClassResourceInfo selectResourceClass(List resources,
String path,
MultivaluedMap values,
Message message) {
boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE);
if (isFineLevelLoggable) {
LOG.fine(new org.apache.cxf.common.i18n.Message("START_CRI_MATCH",
BUNDLE,
path).toString());
}
if (resources.size() == 1) {
return resources.get(0).getURITemplate().match(path, values)
? resources.get(0) : null;
}
SortedMap> candidateList =
new TreeMap>(
new ClassResourceInfoComparator(message));
for (ClassResourceInfo cri : resources) {
MultivaluedMap map = new MetadataMap();
if (cri.getURITemplate().match(path, map)) {
candidateList.put(cri, map);
if (isFineLevelLoggable) {
LOG.fine(new org.apache.cxf.common.i18n.Message("CRI_SELECTED_POSSIBLY",
BUNDLE,
cri.getServiceClass().getName(),
path,
cri.getURITemplate().getValue()).toString());
}
} else if (isFineLevelLoggable) {
LOG.fine(new org.apache.cxf.common.i18n.Message("CRI_NO_MATCH",
BUNDLE,
path,
cri.getServiceClass().getName()).toString());
}
}
if (!candidateList.isEmpty()) {
Map.Entry> firstEntry =
candidateList.entrySet().iterator().next();
values.putAll(firstEntry.getValue());
ClassResourceInfo cri = firstEntry.getKey();
if (isFineLevelLoggable) {
LOG.fine(new org.apache.cxf.common.i18n.Message("CRI_SELECTED",
BUNDLE,
cri.getServiceClass().getName(),
path, cri.getURITemplate().getValue()).toString());
}
return cri;
}
return null;
}
public static OperationResourceInfo findTargetMethod(ClassResourceInfo resource,
Message message,
String httpMethod,
MultivaluedMap values,
String requestContentType,
List acceptContentTypes,
boolean logNow) {
boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE);
if (isFineLevelLoggable) {
org.apache.cxf.common.i18n.Message msg =
new org.apache.cxf.common.i18n.Message("START_OPER_MATCH",
BUNDLE,
resource.getServiceClass().getName());
LOG.fine(msg.toString());
}
String path = values.getFirst(URITemplate.FINAL_MATCH_GROUP);
if (path == null) {
path = "/";
}
final boolean getMethod = HttpMethod.GET.equals(httpMethod);
MediaType requestType;
try {
requestType = getMethod ? MediaType.WILDCARD_TYPE : toMediaType(requestContentType);
} catch (IllegalArgumentException ex) {
throw ExceptionUtils.toNotSupportedException(ex, null);
}
SortedMap> candidateList =
new TreeMap>(
new OperationResourceInfoComparator(message, httpMethod,
getMethod, requestType, acceptContentTypes));
int pathMatched = 0;
int methodMatched = 0;
int consumeMatched = 0;
for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) {
boolean added = false;
URITemplate uriTemplate = ori.getURITemplate();
MultivaluedMap map = new MetadataMap(values);
if (uriTemplate != null && uriTemplate.match(path, map)) {
if (ori.isSubResourceLocator()) {
candidateList.put(ori, map);
added = true;
} else {
String finalGroup = map.getFirst(URITemplate.FINAL_MATCH_GROUP);
if (StringUtils.isEmpty(finalGroup) || PATH_SEGMENT_SEP.equals(finalGroup)) {
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
}
}
}
}
if (isFineLevelLoggable) {
if (added) {
LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED_POSSIBLY",
BUNDLE,
ori.getMethodToInvoke().getName()).toString());
} else {
logNoMatchMessage(ori, path, httpMethod, requestType, acceptContentTypes);
}
}
}
if (!candidateList.isEmpty()) {
Map.Entry> firstEntry =
candidateList.entrySet().iterator().next();
values.clear();
values.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, resource.getServiceClass().getName(),
ori.getMethodToInvoke().getName()).toString());
}
if (isFineLevelLoggable) {
LOG.fine(new org.apache.cxf.common.i18n.Message("OPER_SELECTED",
BUNDLE, ori.getMethodToInvoke().getName(),
resource.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));
}
return ori;
}
int status;
// criteria matched the least number of times will determine the error code;
// 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;
}
String name = resource.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),
path,
httpMethod,
mediaTypeToString(requestType),
convertTypesToString(acceptContentTypes));
if (!"OPTIONS".equalsIgnoreCase(httpMethod) && logNow) {
LOG.warning(errorMsg.toString());
}
Response response =
createResponse(resource, message, errorMsg.toString(), status, methodMatched == 0);
throw ExceptionUtils.toHttpException(null, response);
}
private static List intersectSortMediaTypes(List acceptTypes,
List producesTypes,
final boolean checkDistance) {
List all = intersectMimeTypes(acceptTypes, producesTypes, true, checkDistance);
if (all.size() > 1) {
Collections.sort(all, new Comparator() {
public int compare(MediaType mt1, MediaType mt2) {
int result = compareMediaTypes(mt1, mt2, null);
if (result == 0) {
result = compareQualityAndDistance(mt1, mt2, checkDistance);
}
return result;
}
});
}
return all;
}
private static int compareQualityAndDistance(MediaType mt1, MediaType mt2, boolean checkDistance) {
int result = compareMediaTypesQualityFactors(mt1, mt2, MEDIA_TYPE_Q_PARAM);
if (result == 0) {
result = compareMediaTypesQualityFactors(mt1, mt2, MEDIA_TYPE_QS_PARAM);
}
if (result == 0 && checkDistance) {
Integer dist1 = Integer.valueOf(mt1.getParameters().get(MEDIA_TYPE_DISTANCE_PARAM));
Integer dist2 = Integer.valueOf(mt2.getParameters().get(MEDIA_TYPE_DISTANCE_PARAM));
result = dist1.compareTo(dist2);
}
return result;
}
public static boolean noResourceMethodForOptions(Response exResponse, String httpMethod) {
return exResponse != null && exResponse.getStatus() == 405
&& "OPTIONS".equalsIgnoreCase(httpMethod);
}
private static void logNoMatchMessage(OperationResourceInfo ori,
String path, String httpMethod, MediaType requestType, List acceptContentTypes) {
org.apache.cxf.common.i18n.Message errorMsg =
new org.apache.cxf.common.i18n.Message("OPER_NO_MATCH",
BUNDLE,
ori.getMethodToInvoke().getName(),
path,
ori.getURITemplate().getValue(),
httpMethod,
ori.getHttpMethod(),
requestType.toString(),
convertTypesToString(ori.getConsumeTypes()),
convertTypesToString(acceptContentTypes),
convertTypesToString(ori.getProduceTypes()));
LOG.fine(errorMsg.toString());
}
public static Response createResponse(ClassResourceInfo cri, Message msg,
String responseMessage, int status, boolean addAllow) {
ResponseBuilder rb = toResponseBuilder(status);
if (addAllow) {
Set allowedMethods = cri.getAllowedMethods();
for (String m : allowedMethods) {
rb.header("Allow", m);
}
// "OPTIONS" are supported all the time really
if (!allowedMethods.contains("OPTIONS")) {
rb.header("Allow", "OPTIONS");
}
if (!allowedMethods.contains("HEAD") && allowedMethods.contains("GET")) {
rb.header("Allow", "HEAD");
}
}
if (msg != null && MessageUtils.isTrue(msg.getContextualProperty(REPORT_FAULT_MESSAGE_PROPERTY))) {
rb.type(MediaType.TEXT_PLAIN_TYPE).entity(responseMessage);
}
return rb.build();
}
private static boolean matchHttpMethod(String expectedMethod, String httpMethod) {
if (expectedMethod.equalsIgnoreCase(httpMethod)
|| headMethodPossible(expectedMethod, httpMethod)) {
return true;
}
return false;
}
public static boolean headMethodPossible(String expectedMethod, String httpMethod) {
return HttpMethod.HEAD.equalsIgnoreCase(httpMethod) && HttpMethod.GET.equals(expectedMethod);
}
private static String convertTypesToString(List types) {
StringBuilder sb = new StringBuilder();
for (MediaType type : types) {
sb.append(mediaTypeToString(type)).append(',');
}
return sb.toString();
}
public static List getConsumeTypes(Consumes cm) {
return cm == null ? Collections.singletonList(ALL_TYPES)
: getMediaTypes(cm.value());
}
public static List getProduceTypes(Produces pm) {
return pm == null ? Collections.singletonList(ALL_TYPES)
: getMediaTypes(pm.value());
}
public static int compareSortedConsumesMediaTypes(List mts1, List mts2, MediaType ct) {
List actualMts1 = getCompatibleMediaTypes(mts1, ct);
List actualMts2 = getCompatibleMediaTypes(mts2, ct);
return compareSortedMediaTypes(actualMts1, actualMts2, null);
}
public static int compareSortedAcceptMediaTypes(List mts1, List mts2,
List acceptTypes) {
List actualMts1 = intersectSortMediaTypes(mts1, acceptTypes, true);
List actualMts2 = intersectSortMediaTypes(mts2, acceptTypes, true);
int size1 = actualMts1.size();
int size2 = actualMts2.size();
for (int i = 0; i < size1 && i < size2; i++) {
int result = compareMediaTypes(actualMts1.get(i), actualMts2.get(i), null);
if (result == 0) {
result = compareQualityAndDistance(actualMts1.get(i), actualMts2.get(i), true);
}
if (result != 0) {
return result;
}
}
return size1 == size2 ? 0 : size1 < size2 ? -1 : 1;
}
private static List getCompatibleMediaTypes(List mts, MediaType ct) {
List actualMts;
if (mts.size() == 1) {
actualMts = mts;
} else {
actualMts = new LinkedList();
for (MediaType mt : mts) {
if (isMediaTypeCompatible(mt, ct)) {
actualMts.add(mt);
}
}
}
return actualMts;
}
public static int compareSortedMediaTypes(List mts1, List mts2, String qs) {
int size1 = mts1.size();
int size2 = mts2.size();
for (int i = 0; i < size1 && i < size2; i++) {
int result = compareMediaTypes(mts1.get(i), mts2.get(i), qs);
if (result != 0) {
return result;
}
}
return size1 == size2 ? 0 : size1 < size2 ? -1 : 1;
}
public static int compareMediaTypes(MediaType mt1, MediaType mt2) {
return compareMediaTypes(mt1, mt2, MEDIA_TYPE_Q_PARAM);
}
public static int compareMediaTypes(MediaType mt1, MediaType mt2, String qs) {
boolean mt1TypeWildcard = mt1.isWildcardType();
boolean mt2TypeWildcard = mt2.isWildcardType();
if (mt1TypeWildcard && !mt2TypeWildcard) {
return 1;
}
if (!mt1TypeWildcard && mt2TypeWildcard) {
return -1;
}
boolean mt1SubTypeWildcard = mt1.getSubtype().contains(MediaType.MEDIA_TYPE_WILDCARD);
boolean mt2SubTypeWildcard = mt2.getSubtype().contains(MediaType.MEDIA_TYPE_WILDCARD);
if (mt1SubTypeWildcard && !mt2SubTypeWildcard) {
return 1;
}
if (!mt1SubTypeWildcard && mt2SubTypeWildcard) {
return -1;
}
return qs != null ? compareMediaTypesQualityFactors(mt1, mt2, qs) : 0;
}
public static int compareMediaTypesQualityFactors(MediaType mt1, MediaType mt2) {
float q1 = getMediaTypeQualityFactor(mt1.getParameters().get(MEDIA_TYPE_Q_PARAM));
float q2 = getMediaTypeQualityFactor(mt2.getParameters().get(MEDIA_TYPE_Q_PARAM));
return Float.compare(q1, q2) * -1;
}
public static int compareMediaTypesQualityFactors(MediaType mt1, MediaType mt2, String qs) {
float q1 = getMediaTypeQualityFactor(mt1.getParameters().get(qs));
float q2 = getMediaTypeQualityFactor(mt2.getParameters().get(qs));
return Float.compare(q1, q2) * -1;
}
public static float getMediaTypeQualityFactor(String 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