/* * � Copyright IBM Corp. 2012, 2015 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.ibm.domino.das.utils; import static com.ibm.domino.commons.model.IGatekeeperProvider.FEATURE_REST_API_DEBUG_IN_ERROR_RESPONSE; import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_CODE; import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_DATA; import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_MESSAGE; import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_TEXT; import static com.ibm.domino.services.rest.RestServiceConstants.ATTR_TYPE; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import lotus.domino.NotesException; import com.ibm.commons.log.Log; import com.ibm.commons.log.LogMgr; import com.ibm.domino.commons.model.IGatekeeperProvider; import com.ibm.domino.commons.model.ProviderFactory; import com.ibm.domino.services.util.JsonWriter; /** Resource handler class * @ibm-not-published * **/ public class ErrorHelper { public static final LogMgr DAS_LOGGER = Log.load("com.ibm.domino.das"); //$NON-NLS-1$ /** * Creates a JSON response with the specified message in the body and * the specified status code. * * @param message * @param status * @return */ public static Response createErrorResponse(String message, Response.Status status) { return createErrorResponse(message, status, null); } public static Response createErrorResponse(String message, Response.Status status, Map<String, Object> extraProps) { DAS_LOGGER.traceEntry("", "createErrorResponse"); //$NON-NLS-1$ $NON-NLS-2$ ResponseBuilder builder = Response.status(status); builder.type(MediaType.APPLICATION_JSON); String jsonEntity = null; StringWriter writer = new StringWriter(); Boolean compact = false; JsonWriter jWriter = new JsonWriter(writer, compact); try { try { jWriter.startObject(); writeProperty(jWriter, ATTR_CODE, status.getStatusCode()); writeProperty(jWriter, ATTR_TEXT, status.getReasonPhrase()); // Write extra properties writeExtraProperties(jWriter, extraProps); // Write message if (message != null) writeProperty(jWriter, "message", message); // $NON-NLS-1$ } finally { jWriter.endObject(); } StringBuffer buffer = writer.getBuffer(); jsonEntity = buffer.toString(); builder.entity(jsonEntity); } catch (IOException ex) { DAS_LOGGER.warn(ex, "Error creating response."); //$NON-NLS-1$ } Response response = builder.build(); DAS_LOGGER.traceExit("", "createErrorResponse", response); //$NON-NLS-1$ $NON-NLS-2$ return response; } /** * Creates a JSON response with an exception stack trace in the body and * the specified status code. * * @param e * @param status * @return */ public static Response createErrorResponse(Exception e, Response.Status status) { return createErrorResponse(e, status, null); } public static Response createErrorResponse(Exception e, Response.Status status, Map<String, Object> extraProps) { DAS_LOGGER.traceEntry("", "createErrorResponse"); //$NON-NLS-1$ $NON-NLS-2$ ResponseBuilder builder = Response.status(status); builder.type(MediaType.APPLICATION_JSON); String jsonEntity = null; StringWriter writer = new StringWriter(); Boolean compact = false; JsonWriter jWriter = new JsonWriter(writer, compact); try { try { jWriter.startObject(); writeProperty(jWriter, ATTR_CODE, status.getStatusCode()); writeProperty(jWriter, ATTR_TEXT, status.getReasonPhrase()); // Write extra properties writeExtraProperties(jWriter, extraProps); // Write the exception writeException(jWriter, e); } finally { jWriter.endObject(); } StringBuffer buffer = writer.getBuffer(); jsonEntity = buffer.toString(); builder.entity(jsonEntity); } catch (IOException ex) { DAS_LOGGER.warn(ex, "Error creating response."); // $NLW-ErrorHelper.ErrorCreatingResponse-1$ } Response response = builder.build(); DAS_LOGGER.traceExit("", "createErrorResponse", response); //$NON-NLS-1$ $NON-NLS-2$ return response; } public static Response createErrorResponse(Throwable e) { String message = null; try { ByteArrayOutputStream os = new ByteArrayOutputStream(); e.printStackTrace(new PrintWriter(os, true)); os.flush(); message = os.toString(); } catch (IOException ioe) { message = e.getMessage(); } return createErrorResponse(message, Response.Status.INTERNAL_SERVER_ERROR); } /** * Writes a JSON int property. * * @param jwriter * @param propName * @param propValue * @throws IOException */ public static void writeProperty(JsonWriter jwriter, String propName, int propValue) throws IOException { jwriter.startProperty(propName); jwriter.outIntLiteral(propValue); jwriter.endProperty(); } /** * Writes a JSON string property. * * @param jwriter * @param propName * @param propValue * @throws IOException */ public static void writeProperty(JsonWriter jwriter, String propName, String propValue) throws IOException { jwriter.startProperty(propName); jwriter.outStringLiteral(propValue); jwriter.endProperty(); } /** * Writes a JSON exception property. * * @param jwriter * @param throwable * @throws IOException */ public static void writeException(JsonWriter jwriter, Throwable throwable) throws IOException { if (throwable == null) { return; } // message jwriter.startProperty(ATTR_MESSAGE); String message = ""; Throwable t = throwable; while ((message == null || message.length() == 0) && t != null) { if (t instanceof NotesException) message = ((NotesException)t).text; else message = t.getMessage(); t = t.getCause(); } if (message == null) jwriter.outStringLiteral(""); //$NON-NLS-1$ else jwriter.outStringLiteral(message); jwriter.endProperty(); // Should we write a stack trace? boolean writeStack = false; ScnContext ctx = ScnContext.getCurrentInstance(); if ( ctx.isScn() ) { IGatekeeperProvider provider = ProviderFactory.getGatekeeperProvider(); if ( provider != null ) { writeStack = provider.isFeatureEnabled(FEATURE_REST_API_DEBUG_IN_ERROR_RESPONSE, ctx.getCustomerId(), ctx.getUserId()); } } else { writeStack = true; } // Write data and type properties if ( writeStack ) { // type writeProperty(jwriter, ATTR_TYPE, ATTR_TEXT); // data jwriter.startProperty(ATTR_DATA); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); jwriter.outStringLiteral(sw.toString()); jwriter.endProperty(); } } private static void writeExtraProperties(JsonWriter jWriter, Map<String, Object> extraProps) throws IOException { if ( extraProps != null ) { Set<String> keys = extraProps.keySet(); if ( keys != null ) { Iterator<String> iterator = keys.iterator(); while (iterator.hasNext()) { String key = iterator.next(); Object obj = extraProps.get(key); if ( obj instanceof String ) { writeProperty(jWriter, key, (String)obj); } else if ( obj instanceof Integer ) { writeProperty(jWriter, key, (Integer)obj); } } } } } private static String getExceptionSummary(Throwable t) { String message = null; if (t instanceof NotesException) message = ((NotesException)t).text; else message = t.getMessage(); return MessageFormat.format("{0} [{1}]", t.getClass().getName(), message == null ? "" : message); } }