001/*
002 * Copyright 2015-2016 UnboundID Corp.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License (GPLv2 only)
006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
007 * as published by the Free Software Foundation.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, see <http://www.gnu.org/licenses>.
016 */
017
018package com.unboundid.scim2.server.providers;
019
020import com.fasterxml.jackson.core.JsonParseException;
021import com.fasterxml.jackson.core.JsonProcessingException;
022import com.unboundid.scim2.common.exceptions.BadRequestException;
023import com.unboundid.scim2.common.exceptions.ScimException;
024import com.unboundid.scim2.common.exceptions.ServerErrorException;
025import com.unboundid.scim2.common.messages.ErrorResponse;
026import com.unboundid.scim2.server.utils.ServerUtils;
027
028import javax.ws.rs.core.Context;
029import javax.ws.rs.core.HttpHeaders;
030import javax.ws.rs.core.Request;
031import javax.ws.rs.core.Response;
032import javax.ws.rs.ext.ExceptionMapper;
033import javax.ws.rs.ext.Provider;
034
035/**
036 * A JAX-RS ExceptionMapper for to convert Jackson JsonProcessingException to
037 * SCIM ErrorResponses.
038 */
039@Provider
040public class JsonProcessingExceptionMapper implements
041    ExceptionMapper<JsonProcessingException>
042{
043  @Context
044  private Request request;
045  @Context
046  private HttpHeaders headers;
047
048  /**
049   * {@inheritDoc}
050   */
051  public Response toResponse(final JsonProcessingException exception)
052  {
053    ErrorResponse errorResponse;
054    if(exception instanceof JsonParseException)
055    {
056      StringBuilder builder = new StringBuilder();
057      builder.append("Unable to parse request: ");
058      builder.append(exception.getOriginalMessage());
059      if(exception.getLocation() != null)
060      {
061        builder.append(" at line: ");
062        builder.append(exception.getLocation().getLineNr());
063        builder.append(", column: ");
064        builder.append(exception.getLocation().getColumnNr());
065      }
066      errorResponse =
067          BadRequestException.invalidSyntax(builder.toString()).getScimError();
068    }
069    else
070    {
071      if(exception.getCause() != null &&
072          exception.getCause() instanceof ScimException)
073      {
074        errorResponse = ((ScimException) exception.getCause()).getScimError();
075      }
076      else
077      {
078        errorResponse =
079            new ServerErrorException(exception.getMessage()).getScimError();
080      }
081    }
082
083    return ServerUtils.setAcceptableType(
084        Response.status(errorResponse.getStatus()).entity(errorResponse),
085        headers.getAcceptableMediaTypes()).build();
086  }
087}