package com.ttech.cordovabuild.web.exception; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import com.ttech.cordovabuild.web.ApiResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.ext.ExceptionMapper; import java.io.IOException; import java.util.*; import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static javax.ws.rs.core.Response.Status.BAD_REQUEST; import static javax.ws.rs.core.Response.Status.OK; public abstract class AbstractExceptionMapper<E extends java.lang.Throwable> implements ExceptionMapper<E> { public static final Logger logger = LoggerFactory .getLogger(AbstractExceptionMapper.class.getPackage().toString()); static Map<String, Set<String>> javascriptTypes = new HashMap<String, Set<String>>(); static ObjectMapper mapper = new ObjectMapper(); static { // application/javascript, application/x-javascript, text/ecmascript, // application/ecmascript, text/jscript javascriptTypes.put( "application", new HashSet<String>(Arrays.asList("x-javascript", "ecmascript", "javascript"))); javascriptTypes.put("text", new HashSet<String>(Arrays.asList("ecmascript", "jscript"))); } @Context HttpHeaders hh; @Context HttpServletRequest httpServletRequest; public boolean isJSONP() { return isJavascript(hh.getAcceptableMediaTypes()); } public static boolean isJavascript(MediaType m) { if (m == null) { return false; } Set<String> subtypes = javascriptTypes.get(m.getType()); if (subtypes == null) { return false; } return subtypes.contains(m.getSubtype()); } public static boolean isJavascript(List<MediaType> l) { for (MediaType m : l) { if (isJavascript(m)) { return true; } } return false; } @Override public Response toResponse(E e) { return toResponse(BAD_REQUEST, e); } public Response toResponse(Status status, E e) { return toResponse(status.getStatusCode(), e); } public Response toResponse(int status, E e) { logger.error("Error in request (" + status + ")", e); ApiResponse response = new ApiResponse( httpServletRequest.getServletPath()); AuthErrorInfo authError = AuthErrorInfo.getForException(e); if (authError != null) { response.setError(authError.getType(), authError.getMessage(), e); } else { response.setError(e); } String jsonResponse = mapToJsonString(response); return toResponse(status, jsonResponse); } public Response toResponse(Status status, String jsonResponse) { return toResponse(status.getStatusCode(), jsonResponse); } public Response toResponse(int status, String jsonResponse) { logger.error("Error in request (" + status + "):\n" + jsonResponse); String callback=httpServletRequest.getParameter("callback"); if (isJSONP() && !Strings.isNullOrEmpty(callback)) { jsonResponse = wrapJSONPResponse(callback, jsonResponse); return Response.status(OK).type("application/javascript") .entity(jsonResponse).build(); } else { return Response.status(status).type(APPLICATION_JSON_TYPE) .entity(jsonResponse).build(); } } public static String wrapJSONPResponse(String callback, String jsonResponse) { if (!Strings.isNullOrEmpty(callback)) { return callback + "(" + jsonResponse + ")"; } else { return jsonResponse; } } public static String mapToJsonString(Object obj) { try { return mapper.writeValueAsString(obj); } catch (JsonGenerationException e) { } catch (JsonMappingException e) { } catch (IOException e) { } return "{}"; } }