You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by am...@apache.org on 2017/11/14 17:49:14 UTC
[cxf] branch master updated: [CXF-7553] Consider the req headers'
quality factors in selectVariant
This is an automated email from the ASF dual-hosted git repository.
amccright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new aa7cbcd [CXF-7553] Consider the req headers' quality factors in selectVariant
aa7cbcd is described below
commit aa7cbcdbe33f36ea398835350088994071172ade
Author: Andy McCright <j....@gmail.com>
AuthorDate: Wed Nov 8 11:05:03 2017 -0600
[CXF-7553] Consider the req headers' quality factors in selectVariant
The Request.selectVariant method should return one of the passed-in
Variants that is closest to the variant (combination of Accept,
Accept-Language and Accept-Encoding headers with quality factors
included).
# Conflicts:
# rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
# rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java
---
.../org/apache/cxf/jaxrs/impl/RequestImpl.java | 99 +++++++++++-----------
.../org/apache/cxf/jaxrs/impl/RequestImplTest.java | 28 ++++++
2 files changed, 79 insertions(+), 48 deletions(-)
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
index bb99409..9190eb0 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestImpl.java
@@ -68,45 +68,59 @@ public class RequestImpl implements Request {
List<Locale> acceptLangs = headers.getAcceptableLanguages();
List<String> acceptEncs = parseAcceptEnc(
headers.getRequestHeaders().getFirst(HttpHeaders.ACCEPT_ENCODING));
-
+ List<Variant> requestVariants = sortAllCombinations(acceptMediaTypes, acceptLangs, acceptEncs);
List<Object> varyValues = new LinkedList<Object>();
+ for (Variant requestVar : requestVariants) {
+ for (Variant var : vars) {
+ MediaType mt = var.getMediaType();
+ Locale lang = var.getLanguage();
+ String enc = var.getEncoding();
+
+ boolean mtMatched = mt == null || requestVar.getMediaType().isCompatible(mt);
+ if (mtMatched) {
+ handleVaryValues(varyValues, HttpHeaders.ACCEPT);
+ }
- List<Variant> matchingVars = new LinkedList<Variant>();
- for (Variant var : vars) {
- MediaType mt = var.getMediaType();
- Locale lang = var.getLanguage();
- String enc = var.getEncoding();
-
- boolean mtMatched = mt == null || acceptMediaTypes.isEmpty()
- || JAXRSUtils.intersectMimeTypes(acceptMediaTypes, mt).size() != 0;
- if (mtMatched) {
- handleVaryValues(varyValues, HttpHeaders.ACCEPT);
- }
+ boolean langMatched = lang == null || isLanguageMatched(requestVar.getLanguage(), lang);
+ if (langMatched) {
+ handleVaryValues(varyValues, HttpHeaders.ACCEPT_LANGUAGE);
+ }
- boolean langMatched = lang == null || acceptLangs.isEmpty()
- || isLanguageMatched(acceptLangs, lang);
- if (langMatched) {
- handleVaryValues(varyValues, HttpHeaders.ACCEPT_LANGUAGE);
- }
+ boolean encMatched = acceptEncs.isEmpty() || enc == null
+ || isEncMatached(requestVar.getEncoding(), enc);
+ if (encMatched) {
+ handleVaryValues(varyValues, HttpHeaders.ACCEPT_ENCODING);
+ }
- boolean encMatched = acceptEncs.isEmpty() || enc == null
- || isEncMatached(acceptEncs, enc);
- if (encMatched) {
- handleVaryValues(varyValues, HttpHeaders.ACCEPT_ENCODING);
+ if (mtMatched && encMatched && langMatched) {
+ addVaryHeader(varyValues);
+ return var;
+ }
}
+ }
+ return null;
+ }
- if (mtMatched && encMatched && langMatched) {
- matchingVars.add(var);
+ private static List<Variant> sortAllCombinations(List<MediaType> mediaTypes,
+ List<Locale> langs,
+ List<String> encs) {
+ List<Variant> requestVars = new LinkedList<>();
+ for (MediaType mt : mediaTypes) {
+ for (Locale lang : langs) {
+ if (encs.size() < 1) {
+ requestVars.add(new Variant(mt, lang, null));
+ } else {
+ for (String enc : encs) {
+ requestVars.add(new Variant(mt, lang, enc));
+ }
+ }
}
}
- if (!matchingVars.isEmpty()) {
- addVaryHeader(varyValues);
- Collections.sort(matchingVars, new VariantComparator());
- return matchingVars.get(0);
- }
- return null;
+ Collections.sort(requestVars, VariantComparator.INSTANCE);
+ return requestVars;
}
+
private static void handleVaryValues(List<Object> varyValues, String ...values) {
for (String v : values) {
if (v != null && !varyValues.contains(v)) {
@@ -136,28 +150,15 @@ public class RequestImpl implements Request {
}
}
- private static boolean isLanguageMatched(List<Locale> locales, Locale l) {
+ private static boolean isLanguageMatched(Locale locale, Locale l) {
- for (Locale locale : locales) {
- String language = locale.getLanguage();
- if ("*".equals(language)
- || language.equalsIgnoreCase(l.getLanguage())) {
- return true;
- }
- }
- return false;
+ String language = locale.getLanguage();
+ return "*".equals(language)
+ || language.equalsIgnoreCase(l.getLanguage());
}
- private static boolean isEncMatached(List<String> accepts, String enc) {
- if (accepts.contains(enc)) {
- return true;
- }
- for (String accept : accepts) {
- if ("*".equals(accept)) {
- return true;
- }
- }
- return false;
+ private static boolean isEncMatached(String accepts, String enc) {
+ return accepts == null || "*".equals(accepts) || accepts.contains(enc);
}
private static List<String> parseAcceptEnc(String acceptEnc) {
@@ -339,6 +340,8 @@ public class RequestImpl implements Request {
private static class VariantComparator implements Comparator<Variant> {
+ static final VariantComparator INSTANCE = new VariantComparator();
+
public int compare(Variant v1, Variant v2) {
int result = compareMediaTypes(v1.getMediaType(), v2.getMediaType());
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java
index 2a435a0..ae21c97 100644
--- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/RequestImplTest.java
@@ -145,6 +145,34 @@ public class RequestImplTest extends Assert {
assertSame(var3, new RequestImpl(m).selectVariant(list));
}
+ @Test
+ public void testMultipleVariantsBestMatchMediaTypeQualityFactors() {
+ metadata.putSingle(HttpHeaders.ACCEPT, "a/b;q=0.6, c/d;q=0.5, e/f+json");
+ metadata.putSingle(HttpHeaders.ACCEPT_LANGUAGE, "en-us");
+ metadata.putSingle(HttpHeaders.ACCEPT_ENCODING, "gzip;q=1.0, compress");
+
+ List<Variant> list = new ArrayList<Variant>();
+ Variant var1 = new Variant(MediaType.valueOf("a/b"), new Locale("en"), "gzip");
+ Variant var2 = new Variant(MediaType.valueOf("x/z"), new Locale("en"), "gzip");
+ Variant var3 = new Variant(MediaType.valueOf("e/f+json"), new Locale("en"), "gzip");
+ Variant var4 = new Variant(MediaType.valueOf("c/d"), new Locale("en"), "gzip");
+ list.add(var1);
+ list.add(var2);
+ list.add(var3);
+ list.add(var4);
+ assertSame(var3, new RequestImpl(m).selectVariant(list));
+
+ list.clear();
+ list.add(var1);
+ list.add(var4);
+ assertSame(var1, new RequestImpl(m).selectVariant(list));
+
+ list.clear();
+ list.add(var2);
+ list.add(var4);
+ assertSame(var4, new RequestImpl(m).selectVariant(list));
+ }
+
private void assertSameVariant(MediaType mt, Locale lang, String enc) {
Variant var = new Variant(mt, lang, enc);
List<Variant> list = new ArrayList<>();
--
To stop receiving notification emails like this one, please contact
['"commits@cxf.apache.org" <co...@cxf.apache.org>'].