package org.odata4j.producer.resources; import java.io.StringWriter; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; import org.odata4j.core.ODataConstants; import org.odata4j.core.OError; import org.odata4j.core.OErrors; import org.odata4j.exceptions.ODataProducerException; import org.odata4j.exceptions.ServerErrorException; import org.odata4j.format.FormatWriter; import org.odata4j.format.FormatWriterFactory; import org.odata4j.producer.ErrorResponse; import org.odata4j.producer.ErrorResponseExtension; import org.odata4j.producer.ODataProducer; import org.odata4j.producer.Responses; /** * Provider for correctly formatted server errors. Every {@link RuntimeException} that * is not already an {@link ODataProducerException} is wrapped into a {@link ServerErrorException} * (resulting in an HTTP {@link Status#INTERNAL_SERVER_ERROR}). * * @see ErrorResponseExtension */ @Provider public class ExceptionMappingProvider implements ExceptionMapper<RuntimeException> { @Context protected ContextResolver<ODataProducer> producerResolver; @Context protected UriInfo uriInfo; @Context protected HttpHeaders httpHeaders; public Response toResponse(RuntimeException e) { ODataProducerException exception; if (e instanceof ODataProducerException) exception = (ODataProducerException) e; else exception = new ServerErrorException(e); ErrorResponseExtension errorResponseExtension = producerResolver.getContext(ODataProducer.class).findExtension(ErrorResponseExtension.class); boolean includeInnerError = errorResponseExtension != null && errorResponseExtension.returnInnerError(httpHeaders, uriInfo, exception); FormatWriter<ErrorResponse> fw = FormatWriterFactory.getFormatWriter(ErrorResponse.class, httpHeaders.getAcceptableMediaTypes(), getFormatParameter(), getCallbackParameter()); StringWriter sw = new StringWriter(); fw.write(uriInfo, sw, getErrorResponse(exception, includeInnerError)); return Response.status(exception.getHttpStatus()) .type(fw.getContentType()) .header(ODataConstants.Headers.DATA_SERVICE_VERSION, ODataConstants.DATA_SERVICE_VERSION_HEADER) .entity(sw.toString()) .build(); } public static ErrorResponse getErrorResponse(ODataProducerException exception, boolean includeInnerError) { OError error = exception.getOError(); if (!includeInnerError) error = OErrors.error(error.getCode(), error.getMessage(), null); return Responses.error(error); } private String getFormatParameter() { return uriInfo.getQueryParameters().getFirst("$format"); } private String getCallbackParameter() { return uriInfo.getQueryParameters().getFirst("$callback"); } }