}
// get best writer
List<MediaType> methodProducibleMediaTypesList = new ArrayList<MediaType>(
methodProducibleMediaTypes);
AcceptHeader acceptHeader = request.getAcceptHeader();
if (methodProducibleMediaTypesList.size() == 0) {
methodProducibleMediaTypesList.add(MediaType.WILDCARD_TYPE);
}
final List<MediaType> expandedMethodProducibleMediaTypesList = expandListWithConcreterTypesFromAccept(methodProducibleMediaTypesList, acceptHeader);
MessageBodyWriter<Object> writer = null;
List<Set<MediaType>> expandedMethodProducibleMediaTypeClasses
= getSortedClasses(expandedMethodProducibleMediaTypesList,
new InconsistentMediaTypeComparator(acceptHeader));
Collections.sort(methodProducibleMediaTypesList,
new MediaTypeComparator(acceptHeader));
MediaType relevantMethodProducibleType = null;
for (Set<MediaType> preferenceClass : expandedMethodProducibleMediaTypeClasses) {
int lastWriterConcreteness = -1;
for (MediaType mediaType : preferenceClass) {
MessageBodyWriter<Object> currentWriter = (MessageBodyWriter<Object>) JaxRsHandler.providers.getMessageBodyWriter(entity.getClass(), entityType,
annotations, mediaType);
if (currentWriter != null) {
int writerConcreteness = getWriterConcreteness(currentWriter, mediaType);
if (writerConcreteness > lastWriterConcreteness) {
for (MediaType methodMediaType : methodProducibleMediaTypesList) {
if (methodMediaType.isCompatible(mediaType)) {
relevantMethodProducibleType = methodMediaType;
break;
}
}
writer = currentWriter;
}
}
}
if (writer != null) {
break;
}
}
if (writer == null) {
for (MediaType mediaType : expandedMethodProducibleMediaTypesList) {
try {
writer = new JafMessageBodyWriter<Object>(entity, mediaType);
} catch (UnsupportedDataTypeException ex) {
logger.debug("No JafMessageBodyWriter for {}", mediaType);
}
if (writer != null) {
relevantMethodProducibleType = mediaType;
break;
}
}
}
if (writer == null) {
javax.ws.rs.core.Response r = javax.ws.rs.core.Response.status(
Status.INTERNAL_SERVER_ERROR).entity(
"No suitable MessageBodyWriter available").type(
MediaType.TEXT_PLAIN_TYPE).build();
throw new WebApplicationException(r);
}
// gain producible concreteness by looking at writer's @Produces
MediaType relevantProducibleType = null;
if ((relevantMethodProducibleType == null) || (MediaTypeComparator.countWildChars(relevantMethodProducibleType) > 0)) {
List<MediaType> writerProducibleMediaTypes = getWriterProduces(writer);
Collections.sort(writerProducibleMediaTypes,
new MediaTypeComparator(acceptHeader));
if (relevantMethodProducibleType != null) {
Iterator<MediaType> writerProducibleMediaTypesIter = writerProducibleMediaTypes.iterator();
while (writerProducibleMediaTypesIter.hasNext()) {
MediaType currentProducible = writerProducibleMediaTypesIter.next();
if (!relevantMethodProducibleType.isCompatible(currentProducible)) {
continue;
}
if (MediaTypeComparator.compareByWildCardCount(
relevantMethodProducibleType, currentProducible) == 1) {
relevantProducibleType = currentProducible;
} else {
relevantProducibleType = relevantMethodProducibleType;
}
break;
}
} else {
relevantProducibleType = writerProducibleMediaTypes.get(0);
}
} else {
relevantProducibleType = relevantMethodProducibleType;
}
if (relevantProducibleType == null) {
throw new RuntimeException("The relevantMethodProducibleType " + relevantMethodProducibleType + " is not compatible with any of the producible types of " + writer);
}
// if relevantProducibleType is not concrete get the first matching
// concrete from accept
MediaType mediaType;
if (MediaTypeComparator.countWildChars(relevantProducibleType) == 0) {
mediaType = relevantProducibleType;
} else {
mediaType = relevantProducibleType;
for (MediaType acceptType : acceptHeader.getEntries()) {
if (acceptType.isCompatible(relevantProducibleType)) {
if (MediaTypeComparator.compareByWildCardCount(acceptType,
mediaType) == 1) {
mediaType = acceptType;
}
}
}
}
if (acceptHeader.getAcceptingMediaType(mediaType).isEmpty()) {
if (!mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
throw new WebApplicationException(406);
}
}