Search in sources :

Example 6 with WriterModel

use of org.glassfish.jersey.message.WriterModel in project jersey by jersey.

the class MethodSelectingRouter method determineResponseMediaType.

/**
     * Determine the {@link MediaType} of the {@link Response} based on writers suitable for the given entity class,
     * pre-selected method and acceptable media types.
     *
     * @param entityClass          entity class to determine the media type for.
     * @param entityType           entity type for writers.
     * @param selectedMethod       pre-selected (invoked) method.
     * @param acceptableMediaTypes acceptable media types from request.
     * @return media type of the response.
     */
private MediaType determineResponseMediaType(final Class<?> entityClass, final Type entityType, final RequestSpecificConsumesProducesAcceptor selectedMethod, final List<AcceptableMediaType> acceptableMediaTypes) {
    // Return pre-selected MediaType.
    if (usePreSelectedMediaType(selectedMethod, acceptableMediaTypes)) {
        return selectedMethod.produces.combinedType;
    }
    final ResourceMethod resourceMethod = selectedMethod.methodRouting.method;
    final Invocable invocable = resourceMethod.getInvocable();
    // Entity class can be null when considering HEAD method || empty entity.
    final Class<?> responseEntityClass = entityClass == null ? invocable.getRawRoutingResponseType() : entityClass;
    final Method handlingMethod = invocable.getHandlingMethod();
    // Media types producible by method.
    final List<MediaType> methodProducesTypes = !resourceMethod.getProducedTypes().isEmpty() ? resourceMethod.getProducedTypes() : Collections.singletonList(MediaType.WILDCARD_TYPE);
    // Applicable entity providers
    final List<WriterModel> writersForEntityType = workers.getWritersModelsForType(responseEntityClass);
    CombinedMediaType selected = null;
    for (final MediaType acceptableMediaType : acceptableMediaTypes) {
        for (final MediaType methodProducesType : methodProducesTypes) {
            if (!acceptableMediaType.isCompatible(methodProducesType)) {
                // no need to go deeper if acceptable and method produces type are incompatible
                continue;
            }
            // Use writers suitable for entity class to determine the media type.
            for (final WriterModel model : writersForEntityType) {
                for (final MediaType writerProduces : model.declaredTypes()) {
                    if (!writerProduces.isCompatible(acceptableMediaType) || !methodProducesType.isCompatible(writerProduces)) {
                        continue;
                    }
                    final CombinedMediaType.EffectiveMediaType effectiveProduces = new CombinedMediaType.EffectiveMediaType(MediaTypes.mostSpecific(methodProducesType, writerProduces), false);
                    final CombinedMediaType candidate = CombinedMediaType.create(acceptableMediaType, effectiveProduces);
                    if (candidate != CombinedMediaType.NO_MATCH) {
                        // Look for a better compatible worker.
                        if (selected == null || CombinedMediaType.COMPARATOR.compare(candidate, selected) < 0) {
                            if (model.isWriteable(responseEntityClass, entityType, handlingMethod.getDeclaredAnnotations(), candidate.combinedType)) {
                                selected = candidate;
                            }
                        }
                    }
                }
            }
        }
    }
    // Found media type for current writer.
    if (selected != null) {
        return selected.combinedType;
    }
    // so it can be written.
    return selectedMethod.produces.combinedType;
}
Also used : Invocable(org.glassfish.jersey.server.model.Invocable) WriterModel(org.glassfish.jersey.message.WriterModel) MediaType(javax.ws.rs.core.MediaType) AcceptableMediaType(org.glassfish.jersey.message.internal.AcceptableMediaType) HttpMethod(javax.ws.rs.HttpMethod) ResourceMethod(org.glassfish.jersey.server.model.ResourceMethod) Method(java.lang.reflect.Method) ResourceMethod(org.glassfish.jersey.server.model.ResourceMethod)

Aggregations

WriterModel (org.glassfish.jersey.message.WriterModel)6 MediaType (javax.ws.rs.core.MediaType)5 ArrayList (java.util.ArrayList)2 AcceptableMediaType (org.glassfish.jersey.message.internal.AcceptableMediaType)2 Invocable (org.glassfish.jersey.server.model.Invocable)2 Method (java.lang.reflect.Method)1 Type (java.lang.reflect.Type)1 LinkedHashSet (java.util.LinkedHashSet)1 HttpMethod (javax.ws.rs.HttpMethod)1 Produces (javax.ws.rs.Produces)1 GenericType (javax.ws.rs.core.GenericType)1 Response (javax.ws.rs.core.Response)1 MessageBodyWriter (javax.ws.rs.ext.MessageBodyWriter)1 ContainerResponse (org.glassfish.jersey.server.ContainerResponse)1 ResourceMethod (org.glassfish.jersey.server.model.ResourceMethod)1