001    /*
002     * Copyright (c) 2011, Cloudera, Inc. All Rights Reserved.
003     *
004     * Cloudera, Inc. licenses this file to you under the Apache License,
005     * Version 2.0 (the "License"). You may not use this file except in
006     * compliance with the License. You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
011     * CONDITIONS OF ANY KIND, either express or implied. See the License for
012     * the specific language governing permissions and limitations under the
013     * License.
014     */
015    package com.cloudera.lib.wsrs;
016    
017    import org.slf4j.Logger;
018    import org.slf4j.LoggerFactory;
019    
020    import javax.ws.rs.core.MediaType;
021    import javax.ws.rs.core.Response;
022    import javax.ws.rs.ext.ExceptionMapper;
023    import java.io.PrintWriter;
024    import java.io.StringWriter;
025    import java.util.LinkedHashMap;
026    import java.util.Map;
027    
028    public class ExceptionProvider implements ExceptionMapper<Throwable> {
029      private static Logger LOG = LoggerFactory.getLogger(ExceptionProvider.class);
030    
031      private static final String ENTER = System.getProperty("line.separator");
032    
033      protected Response createResponse(Response.Status status, Throwable throwable, boolean includeTrace) {
034        Map<String, Object> json = new LinkedHashMap<String, Object>();
035        json.put("statusCode", status.getStatusCode());
036        json.put("reason", status.getReasonPhrase());
037        json.put("message", getOneLineMessage(throwable));
038        json.put("exception", throwable.getClass().getName());
039        if (includeTrace) {
040          StringWriter writer = new StringWriter();
041          PrintWriter printWriter = new PrintWriter(writer);
042          throwable.printStackTrace(printWriter);
043          printWriter.close();
044          json.put("trace", writer.toString());
045        }
046        log(status, throwable);
047        return Response.status(status).type(MediaType.APPLICATION_JSON).entity(json).build();
048      }
049    
050      protected String getOneLineMessage(Throwable throwable) {
051        String message = throwable.getMessage();
052        if (message != null) {
053          int i = message.indexOf(ENTER);
054          if (i > -1) {
055            message = message.substring(0, i);
056          }
057        }
058        return message;
059      }
060    
061      protected void log(Response.Status status, Throwable throwable) {
062        LOG.debug("{}", throwable.getMessage(), throwable);
063      }
064    
065      @Override
066      public Response toResponse(Throwable throwable) {
067        return createResponse(Response.Status.BAD_REQUEST, throwable, false);
068      }
069    
070    }