package eu.europeana.cloud.service.mcs.rest.exceptionmappers;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import eu.europeana.cloud.common.response.ErrorInfo;
import eu.europeana.cloud.service.mcs.exception.*;
import eu.europeana.cloud.service.mcs.status.McsErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
/**
* Maps exceptions thrown by services to {@link Response}.
*/
public class UnitedExceptionMapper {
static final int UNPROCESSABLE_ENTITY = 422;
private final static Logger LOGGER = LoggerFactory.getLogger(UnitedExceptionMapper.class);
/**
* Maps {@link CannotModifyPersistentRepresentationException} to {@link Response}. Returns a response with HTTP
* status code 405 - "Method Not Allowed" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(CannotModifyPersistentRepresentationException exception) {
return buildResponse(Response.Status.METHOD_NOT_ALLOWED, McsErrorCode.CANNOT_MODIFY_PERSISTENT_REPRESENTATION,
exception);
}
/**
* Maps {@link CannotPersistEmptyRepresentationException} to {@link Response}. Returns a response with HTTP status
* code 405 - "Method Not Allowed" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(CannotPersistEmptyRepresentationException exception) {
return buildResponse(Response.Status.METHOD_NOT_ALLOWED, McsErrorCode.CANNOT_PERSIST_EMPTY_REPRESENTATION,
exception);
}
/**
* Maps {@link DataSetAlreadyExistsException} to {@link Response}. Returns a response with HTTP status code 409 -
* "Conflict" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(DataSetAlreadyExistsException exception) {
return buildResponse(Response.Status.CONFLICT, McsErrorCode.DATASET_ALREADY_EXISTS, exception);
}
/**
* Maps {@link DataSetNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(DataSetNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.DATASET_NOT_EXISTS, exception);
}
/**
* Maps {@link FileAlreadyExistsException} to {@link Response}. Returns a response with HTTP status code 409 -
* "Conflict" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(FileAlreadyExistsException exception) {
return buildResponse(Response.Status.CONFLICT, McsErrorCode.FILE_ALREADY_EXISTS, exception);
}
/**
* Maps {@link FileNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(FileNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.FILE_NOT_EXISTS, exception);
}
/**
* Maps {@link RecordNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(RecordNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.RECORD_NOT_EXISTS, exception);
}
/**
* Maps {@link RepresentationNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(RepresentationNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.REPRESENTATION_NOT_EXISTS, exception);
}
/**
* Maps {@link VersionNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(VersionNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.VERSION_NOT_EXISTS, exception);
}
/**
* Maps {@link FileContentHashMismatchException} to {@link Response}. Returns a response with HTTP status code 422 -
* "Unprocessable Entity" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(FileContentHashMismatchException exception) {
return buildResponse(UNPROCESSABLE_ENTITY, McsErrorCode.FILE_CONTENT_HASH_MISMATCH, exception);
}
/**
* Maps {@link WrongContentRangeException} to {@link Response}. Returns a response with HTTP status code 416 -
* "Requested Range Not Satisfiable" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(WrongContentRangeException exception) {
return buildResponse(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE, McsErrorCode.WRONG_CONTENT_RANGE,
exception);
}
/**
* Maps {@link RuntimeException} to {@link Response}. Returns a response with HTTP status code 500 -
* "Internal Server Error" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(RuntimeException exception) {
if (exception instanceof AccessDeniedException) {
return buildResponse(Response.Status.METHOD_NOT_ALLOWED,
McsErrorCode.ACCESS_DENIED_OR_OBJECT_DOES_NOT_EXIST_EXCEPTION,
exception);
}
if (exception instanceof IllegalArgumentException) {
return buildResponse(Response.Status.BAD_REQUEST, McsErrorCode.BAD_PARAMETER_VALUE, exception);
}
LOGGER.error("Unexpected error occured.", exception);
return buildResponse(Response.Status.INTERNAL_SERVER_ERROR, McsErrorCode.OTHER, exception);
}
/**
* Maps {@link WebApplicationException} to {@link Response}. Returns a response with from a given exception and a
* {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(WebApplicationException exception) {
return buildResponse(exception.getResponse().getStatus(), McsErrorCode.OTHER, exception);
}
/**
* Maps {@link ProviderNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not Found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(ProviderNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.PROVIDER_NOT_EXISTS, exception);
}
/**
* Maps {@link AccessDeniedOrObjectDoesNotExistException} to {@link Response}. Returns a response with HTTP status code 403 -
* "Method not Allowed" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(AccessDeniedOrObjectDoesNotExistException exception) {
return buildResponse(Response.Status.METHOD_NOT_ALLOWED, McsErrorCode.ACCESS_DENIED_OR_OBJECT_DOES_NOT_EXIST_EXCEPTION, exception);
}
/**
* Maps {@link RevisionIsNotValidException} to {@link Response}. Returns a response with HTTP status code 405 -
* "Method not Allowed" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(RevisionIsNotValidException exception) {
return buildResponse(Response.Status.METHOD_NOT_ALLOWED, McsErrorCode.REVISION_IS_NOT_VALID, exception);
}
/**
* Maps {@link RevisionNotExistsException} to {@link Response}. Returns a response with HTTP status code 404 -
* "Not found" and a {@link ErrorInfo} with exception details as a message body.
*
* @param exception the exception to map to a response
* @return a response mapped from the supplied exception
*/
public Response toResponse(RevisionNotExistsException exception) {
return buildResponse(Response.Status.NOT_FOUND, McsErrorCode.REVISION_NOT_EXISTS, exception);
}
private static Response buildResponse(Response.Status httpStatus, McsErrorCode errorCode, Exception e) {
return buildResponse(httpStatus.getStatusCode(), errorCode, e);
}
private static Response buildResponse(int httpStatusCode, McsErrorCode errorCode, Exception e) {
return Response.status(httpStatusCode).type(MediaType.APPLICATION_XML).entity(new ErrorInfo(errorCode.name(), e.getMessage())).build();
}
}