001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006package org.fcrepo.http.commons.exceptionhandlers;
007
008import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
009import org.slf4j.Logger;
010
011import javax.ws.rs.core.Context;
012import javax.ws.rs.core.Response;
013import javax.ws.rs.ext.ExceptionMapper;
014import javax.ws.rs.ext.Provider;
015import javax.ws.rs.ext.Providers;
016
017import static javax.ws.rs.core.Response.serverError;
018import static org.fcrepo.http.commons.domain.RDFMediaType.TEXT_PLAIN_WITH_CHARSET;
019import static org.slf4j.LoggerFactory.getLogger;
020
021/**
022 * @author cabeer
023 * @since 9/13/14
024 */
025
026@Provider
027public class RepositoryRuntimeExceptionMapper implements
028        ExceptionMapper<RepositoryRuntimeException>, ExceptionDebugLogging {
029
030    private final Providers providers;
031
032    /**
033     * Get the context Providers so we can rethrow the cause to an appropriate handler
034     * @param providers the providers
035     */
036    public RepositoryRuntimeExceptionMapper(@Context final Providers providers) {
037        this.providers = providers;
038    }
039
040    private static final Logger LOGGER = getLogger(RepositoryExceptionMapper.class);
041
042    @Override
043    public Response toResponse(final RepositoryRuntimeException e) {
044        final Throwable cause = e.getCause();
045        ExceptionMapper<Throwable> exceptionMapper = null;
046
047        if (cause != null) {
048            exceptionMapper = providers.getExceptionMapper((Class<Throwable>) cause.getClass());
049        }
050
051        if (exceptionMapper != null) {
052            return exceptionMapper.toResponse(cause);
053        }
054        LOGGER.error("Caught a repository exception", e);
055        return serverError().entity(null).type(TEXT_PLAIN_WITH_CHARSET).build();
056    }
057}