/*
From http://www.jdotsoft.com/download/ThrowableFormatter.java
*/
package edu.mbl.jif.utils;
/*
* File: ThrowableFormatter.java
*
* Copyright (C) 2013 JDotSoft. All Rights Reserved.
*
* 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.
*
* $Id: ThrowableFormatter.java,v 1.10 2013/04/05 22:12:30 mg Exp $
*/
/**
* Helper class to format exceptions.
*/
public abstract class ThrowableFormatter {
public static final int FULL_STACK = -1;
/**
* Formats exception with custom message, thread name
* and full stack trace.
*
* @param sMsg custom message
* @param t thread with exception
* @param e exception
* @return formatted exception
*/
public final static String format(String sMsg, Throwable e, Thread t) {
return format(sMsg, e, FULL_STACK, t);
}
/**
* Formats exception with custom message, current thread name
* and full stack trace.
*
* @param sMsg custom message
* @param e exception
* @return formatted exception
*/
public final static String format(String sMsg, Throwable e) {
return format(sMsg, e, FULL_STACK);
}
/**
* Formats exception with custom message, current thread name
* and specified stack trace depth.
*
* @param sMsg custom message
* @param e exception
* @param nStackDepth trace stack depth:
* {@link #FULL_STACK} - to format with full trace stack
* 0 - to format with "exception class + message"
* @return formatted exception
*/
public final static String format(String sMsg, Throwable e, int nStackDepth) {
return format(sMsg, e, nStackDepth, Thread.currentThread());
}
/**
* Formats exception with custom message, thread name (if not null)
* and specified stack depth.
*
* @param sMsg custom message
* @param t thread with exception
* @param e exception
* @param nStackDepth trace stack depth:
* {@link #FULL_STACK} - to format with full trace stack
* 0 - to format with "exception class + message"
* @return formatted exception
*/
public final static String format(String sMsg, Throwable e, int nStackDepth, Thread t) {
StringBuilder sb = new StringBuilder();
if (sMsg != null && sMsg.trim().length() > 0) {
sb.append(sMsg).append('\n');
}
if (t != null) {
sb.append("Thread: ").append(t.getName()).append('\n');
}
if (e != null) {
sb.append(format(e, nStackDepth));
}
return sb.toString();
}
/**
* Formats exception with full stack trace without custom message and without thread name.
*
* @param t exception
* @return formatted exception
*/
public final static String format(Throwable t) {
return format(t, FULL_STACK);
}
/**
* Formats exception without custom message and without thread name.
*
* @param t exception
* @param nStackDepth trace stack depth:
* {@link #FULL_STACK} - to format with full trace stack
* 0 - to format with "exception class + message"
* @return formatted exception
*/
public final static String format(Throwable t, int nStackDepth) {
StringBuilder sb = new StringBuilder();
int n = 1;
for (Throwable e = t; e != null; e = e.getCause()) {
// Each e.getCause() will print something like this:
// [3] com.acme.web.xxx.XxxException: Cannot ...
// at com.acme.web.xxx.Xxxx(Xxxx.java:1322)
//
if (n > 1) {
sb.append('\n');
}
sb.append('[');
sb.append(n);
sb.append("] ");
sb.append(e.getClass().getName());
sb.append(": ");
String sMsg = e.getMessage();
if (sMsg != null) {
if (sMsg.endsWith("\n")) {
sMsg = sMsg.substring(0, sMsg.length() - 1);
}
sb.append(sMsg);
}
StackTraceElement[] a_stack = e.getStackTrace();
for (int i = 0; i < a_stack.length; i++) {
if (nStackDepth >= 0 && i >= nStackDepth) {
break;
}
sb.append("\n at ");
sb.append(a_stack[i].toString());
}
n++;
}
return sb.toString();
}
/**
* Formats exception in friendly format (messages only).
*
* @param t exception
* @return formatted exception
*/
public final static String formatFriendly(Throwable t) {
StringBuilder sb = new StringBuilder();
for (Throwable e = t; e != null; e = e.getCause()) {
if (sb.length() > 0) {
sb.append("\n caused by: ");
}
String sMsg = e.getMessage();
if (sMsg == null || sMsg.length() == 0) {
sMsg = e.getClass().getSimpleName();
}
sb.append(sMsg);
}
return sb.toString();
}
/**
* Converts a string to html format by replacing newline symbols
* to <br> and space symbols to < >.
*
* @param s input string.
* @return output string in html format.
*/
public static String toHtml(String s) {
StringBuilder sb = new StringBuilder(s.length() * 2);
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch (ch) {
case '\n':
sb.append("<br>");
break;
case ' ':
sb.append(" ");
break;
default:
sb.append(ch);
break;
}
}
return sb.toString();
}
} // class ThrowableFormatter