001/*
002 * Copyright 2015-2024 Ping Identity Corporation
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.unboundid.scim2.common.annotations.NotNull;
021import com.unboundid.scim2.common.exceptions.BadRequestException;
022import com.unboundid.scim2.common.messages.ErrorResponse;
023import com.unboundid.scim2.server.utils.ServerUtils;
024
025import jakarta.ws.rs.WebApplicationException;
026import jakarta.ws.rs.core.Context;
027import jakarta.ws.rs.core.HttpHeaders;
028import jakarta.ws.rs.core.NoContentException;
029import jakarta.ws.rs.core.Request;
030import jakarta.ws.rs.core.Response;
031import jakarta.ws.rs.ext.ExceptionMapper;
032import jakarta.ws.rs.ext.Provider;
033
034/**
035 * A JAX-RS ExceptionMapper for to convert standard WebApplicationExceptions to
036 * SCIM ErrorResponses.
037 */
038@Provider
039public class RuntimeExceptionMapper implements
040    ExceptionMapper<RuntimeException>
041{
042  @NotNull
043  @Context
044  private Request request;
045
046  @NotNull
047  @Context
048  private HttpHeaders headers;
049
050  /**
051   * {@inheritDoc}
052   */
053  @NotNull
054  public Response toResponse(@NotNull final RuntimeException exception)
055  {
056    ErrorResponse errorResponse;
057
058    if(exception instanceof WebApplicationException)
059    {
060      if(exception.getCause() != null && exception.getCause()
061          instanceof NoContentException)
062      {
063        errorResponse = new ErrorResponse(400);
064        errorResponse.setScimType(BadRequestException.INVALID_SYNTAX);
065        errorResponse.setDetail("No content provided. A valid SCIM object " +
066            "represented as a json document is required");
067      }
068      else
069      {
070        errorResponse = new ErrorResponse(
071            ((WebApplicationException) exception).getResponse().getStatus());
072        errorResponse.setDetail(exception.getMessage());
073      }
074    }
075    else
076    {
077      errorResponse = new ErrorResponse(500);
078      errorResponse.setDetail(exception.toString());
079    }
080
081    return ServerUtils.setAcceptableType(
082        Response.status(errorResponse.getStatus()).entity(errorResponse),
083        headers.getAcceptableMediaTypes()).build();
084  }
085}