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 static javax.ws.rs.core.Response.status;
009import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
010import static org.fcrepo.http.commons.domain.RDFMediaType.TEXT_PLAIN_WITH_CHARSET;
011import static org.slf4j.LoggerFactory.getLogger;
012
013import java.util.regex.Matcher;
014import java.util.regex.Pattern;
015
016import javax.ws.rs.core.Response;
017import javax.ws.rs.ext.ExceptionMapper;
018import javax.ws.rs.ext.Provider;
019
020import org.slf4j.Logger;
021
022import org.apache.jena.query.QueryParseException;
023
024
025/**
026 * Handles Sparql query parsing exceptions thrown when querying or updating.
027 *
028 * @author whikloj
029 * @since September 9, 2014
030 */
031@Provider
032public class QueryParseExceptionMapper implements
033        ExceptionMapper<QueryParseException>, ExceptionDebugLogging {
034
035    private static final Logger LOGGER = getLogger(QueryParseExceptionMapper.class);
036
037    @Override
038    public Response toResponse(final QueryParseException e) {
039
040        LOGGER.error("Captured a query parse exception {}", e.getMessage());
041        debugException(this, e, LOGGER);
042        if (e.getMessage().matches(".* Unresolved prefixed name: .*")) {
043            final Pattern namespacePattern =
044                Pattern.compile("Unresolved prefixed name: (\\w+:\\w+)");
045            final Matcher namespaceMatch =
046                namespacePattern.matcher(e.getMessage());
047            if (namespaceMatch.find()) {
048                final String msg =
049                    String.format(
050                        "There are one or more undefined namespace(s) in your request [ %s ], " +
051                        "please define them before retrying",
052                        namespaceMatch.group(1));
053                return status(BAD_REQUEST).entity(msg).type(TEXT_PLAIN_WITH_CHARSET).build();
054            }
055        }
056
057        return status(BAD_REQUEST).entity(e.getMessage()).type(TEXT_PLAIN_WITH_CHARSET).build();
058    }
059
060}