VariantQChecked bestVariant = null;
boolean isIdentityEncodingChecked = false;
for (Iterator<Variant> iter = variants.iterator(); iter.hasNext();) {
double acceptQFactor = -1.0d;
Variant v = iter.next();
logger.debug("Variant being evaluated is: {}", v); //$NON-NLS-1$
MediaType vMediaType = v.getMediaType();
if (vMediaType != null && acceptableMediaTypes != null) {
boolean isCompatible = false;
boolean isAcceptable = true; // explicitly denied by the client
for (MediaType mt : acceptableMediaTypes) {
logger.debug("Checking variant media type {} against Accept media type {}", //$NON-NLS-1$
vMediaType,
mt);
if (mt.isCompatible(vMediaType)) {
Map<String, String> params = mt.getParameters();
String q = params.get("q"); //$NON-NLS-1$
if (q != null) {
try {
Double qAsDouble = Double.valueOf(q);
if (qAsDouble.equals(0.0)) {
isAcceptable = false;
logger
.debug("Accept Media Type: {} is NOT compatible with q-factor {}", //$NON-NLS-1$
mt,
qAsDouble);
break;
}
acceptQFactor = qAsDouble;
} catch (NumberFormatException e) {
logger
.debug("NumberFormatException during MediaType q-factor evaluation: {}", //$NON-NLS-1$
e);
}
} else {
acceptQFactor = 1.0d;
}
isCompatible = true;
logger.debug("Accept Media Type: {} is compatible with q-factor {}", //$NON-NLS-1$
mt,
acceptQFactor);
}
}
if (!isCompatible || !isAcceptable) {
logger.debug("Variant {} is not compatible or not acceptable", vMediaType); //$NON-NLS-1$
continue;
}
}
if (bestVariant != null) {
if (acceptQFactor < bestVariant.acceptMediaTypeQFactor) {
logger
.debug("Best variant's media type {} q-factor {} is greater than current variant {} q-factor {}", //$NON-NLS-1$
new Object[] {bestVariant.variant,
bestVariant.acceptMediaTypeQFactor, vMediaType, acceptQFactor});
continue;
}
}
double acceptLanguageQFactor = -1.0d;
Locale vLocale = v.getLanguage();
if (vLocale != null && languages != null) {
boolean isCompatible = false;
logger.debug("Checking variant locale {}", vLocale); //$NON-NLS-1$
if (languages.getBannedLanguages().contains(vLocale)) {
logger.debug("Variant locale {} was in unacceptable languages", vLocale); //$NON-NLS-1$
continue;
}
for (AcceptLanguage.ValuedLocale locale : languages.getValuedLocales()) {
logger
.debug("Checking against Accept-Language locale {} with quality factor {}", //$NON-NLS-1$
locale.locale,
locale.qValue);
if (locale.isWildcard() || vLocale.equals(locale.locale)) {
logger.debug("Locale is compatible {}", locale.locale); //$NON-NLS-1$
isCompatible = true;
acceptLanguageQFactor = locale.qValue;
break;
}
}
if (!isCompatible) {
logger.debug("Variant locale is not compatible {}", vLocale); //$NON-NLS-1$
continue;
}
}
if (bestVariant != null) {
if (acceptLanguageQFactor < bestVariant.acceptLanguageQFactor) {
logger
.debug("Best variant's language {} q-factor {} is greater than current variant {} q-factor {}", //$NON-NLS-1$
new Object[] {bestVariant.variant,
bestVariant.acceptLanguageQFactor, v, acceptLanguageQFactor});
continue;
}
}
double acceptCharsetQFactor = -1.0d;
String vCharset = ProviderUtils.getCharsetOrNull(v.getMediaType());
boolean hasCharSet = true;
if (vCharset == null) {
hasCharSet = false;
} else if (vCharset != null && charsets != null) {
boolean isCompatible = false;
logger.debug("Checking variant charset: {}", vCharset); //$NON-NLS-1$
if (charsets.getBannedCharsets().contains(vCharset)) {
logger.debug("Variant charset {} was in unacceptable charsets", vCharset); //$NON-NLS-1$
continue;
}
for (AcceptCharset.ValuedCharset charset : charsets.getValuedCharsets()) {
logger
.debug("Checking against Accept-Charset charset {} with quality factor {}", //$NON-NLS-1$
charset.charset,
charset.qValue);
if (charset.isWildcard() || vCharset.equalsIgnoreCase(charset.charset)) {
logger.debug("Charset is compatible with {}", charset.charset); //$NON-NLS-1$
isCompatible = true;
acceptCharsetQFactor = charset.qValue;
break;
}
}
if (!isCompatible) {
logger.debug("Variant charset is not compatible {}", vCharset); //$NON-NLS-1$
/*
* do not remove this from the acceptable list even if not
* compatible but set to -1.0d for now. according to HTTP
* spec, it is "ok" to send
*/
}
}
if (bestVariant != null) {
if (acceptCharsetQFactor < bestVariant.acceptCharsetQFactor && hasCharSet) {
logger
.debug("Best variant's charset {} q-factor {} is greater than current variant {} q-factor {}", //$NON-NLS-1$
new Object[] {bestVariant.variant, bestVariant.acceptCharsetQFactor,
v, acceptCharsetQFactor});
continue;
}
}
double acceptEncodingQFactor = -1.0d;
String vEncoding = v.getEncoding();
if (vEncoding != null) {
logger.debug("Checking variant encoding {}", vEncoding); //$NON-NLS-1$
if (encodings == null || encodings.isAnyEncodingAllowed()) {
logger.debug("Accept-Encoding is null or wildcard"); //$NON-NLS-1$
if (!v.getEncoding().equalsIgnoreCase("identity")) { //$NON-NLS-1$
logger
.debug("Variant encoding {} does not equal identity so not acceptable", //$NON-NLS-1$
vEncoding);
// if there is no Accept Encoding, only identity is
// acceptable