Logback: the reliable, generic, fast and flexible logging framework. Copyright (C) 1999-2015, QOS.ch. All rights reserved. This program and the accompanying materials are dual-licensed under either the terms of the Eclipse Public License v1.0 as published by the Eclipse Foundation or (per the licensee's choosing) under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation.
/** * Logback: the reliable, generic, fast and flexible logging framework. * Copyright (C) 1999-2015, QOS.ch. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. */
package ch.qos.logback.classic.spi; import ch.qos.logback.core.CoreConstants;
Convert a throwable into an array of ThrowableDataPoint objects.
Author:Ceki Gülcü
/** * Convert a throwable into an array of ThrowableDataPoint objects. * * * @author Ceki Gülcü */
public class ThrowableProxyUtil { public static final int REGULAR_EXCEPTION_INDENT = 1; public static final int SUPPRESSED_EXCEPTION_INDENT = 1; private static final int BUILDER_CAPACITY = 2048; public static void build(ThrowableProxy nestedTP, Throwable nestedThrowable, ThrowableProxy parentTP) { StackTraceElement[] nestedSTE = nestedThrowable.getStackTrace(); int commonFramesCount = -1; if (parentTP != null) { commonFramesCount = findNumberOfCommonFrames(nestedSTE, parentTP.getStackTraceElementProxyArray()); } nestedTP.commonFrames = commonFramesCount; nestedTP.stackTraceElementProxyArray = steArrayToStepArray(nestedSTE); } static StackTraceElementProxy[] steArrayToStepArray(StackTraceElement[] stea) { if (stea == null) { return new StackTraceElementProxy[0]; } StackTraceElementProxy[] stepa = new StackTraceElementProxy[stea.length]; for (int i = 0; i < stepa.length; i++) { stepa[i] = new StackTraceElementProxy(stea[i]); } return stepa; } static int findNumberOfCommonFrames(StackTraceElement[] steArray, StackTraceElementProxy[] parentSTEPArray) { if (parentSTEPArray == null || steArray == null) { return 0; } int steIndex = steArray.length - 1; int parentIndex = parentSTEPArray.length - 1; int count = 0; while (steIndex >= 0 && parentIndex >= 0) { StackTraceElement ste = steArray[steIndex]; StackTraceElement otherSte = parentSTEPArray[parentIndex].ste; if (ste.equals(otherSte)) { count++; } else { break; } steIndex--; parentIndex--; } return count; } public static String asString(IThrowableProxy tp) { StringBuilder sb = new StringBuilder(BUILDER_CAPACITY); recursiveAppend(sb, null, REGULAR_EXCEPTION_INDENT, tp); return sb.toString(); } private static void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) { if (tp == null) return; subjoinFirstLine(sb, prefix, indent, tp); sb.append(CoreConstants.LINE_SEPARATOR); subjoinSTEPArray(sb, indent, tp); IThrowableProxy[] suppressed = tp.getSuppressed(); if (suppressed != null) { for (IThrowableProxy current : suppressed) { recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + SUPPRESSED_EXCEPTION_INDENT, current); } } recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause()); } public static void indent(StringBuilder buf, int indent) { for (int j = 0; j < indent; j++) { buf.append(CoreConstants.TAB); } } private static void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) { indent(buf, indent - 1); if (prefix != null) { buf.append(prefix); } subjoinExceptionMessage(buf, tp); } public static void subjoinPackagingData(StringBuilder builder, StackTraceElementProxy step) { if (step != null) { ClassPackagingData cpd = step.getClassPackagingData(); if (cpd != null) { if (!cpd.isExact()) { builder.append(" ~["); } else { builder.append(" ["); } builder.append(cpd.getCodeLocation()).append(':').append(cpd.getVersion()).append(']'); } } } public static void subjoinSTEP(StringBuilder sb, StackTraceElementProxy step) { sb.append(step.toString()); subjoinPackagingData(sb, step); }
Params:
  • sb – The StringBuilder the STEPs are appended to.
  • tp – the IThrowableProxy containing the STEPs.
Deprecated:Use subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) instead.
/** * @param sb The StringBuilder the STEPs are appended to. * @param tp the IThrowableProxy containing the STEPs. * @deprecated Use subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) instead. */
public static void subjoinSTEPArray(StringBuilder sb, IThrowableProxy tp) { // not called anymore - but it is public subjoinSTEPArray(sb, REGULAR_EXCEPTION_INDENT, tp); }
Params:
  • sb – The StringBuilder the STEPs are appended to.
  • indentLevel – indentation level used for the STEPs, usually REGULAR_EXCEPTION_INDENT.
  • tp – the IThrowableProxy containing the STEPs.
/** * @param sb The StringBuilder the STEPs are appended to. * @param indentLevel indentation level used for the STEPs, usually REGULAR_EXCEPTION_INDENT. * @param tp the IThrowableProxy containing the STEPs. */
public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) { StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray(); int commonFrames = tp.getCommonFrames(); for (int i = 0; i < stepArray.length - commonFrames; i++) { StackTraceElementProxy step = stepArray[i]; indent(sb, indentLevel); subjoinSTEP(sb, step); sb.append(CoreConstants.LINE_SEPARATOR); } if (commonFrames > 0) { indent(sb, indentLevel); sb.append("... ").append(commonFrames).append(" common frames omitted").append(CoreConstants.LINE_SEPARATOR); } } public static void subjoinFirstLine(StringBuilder buf, IThrowableProxy tp) { int commonFrames = tp.getCommonFrames(); if (commonFrames > 0) { buf.append(CoreConstants.CAUSED_BY); } subjoinExceptionMessage(buf, tp); } public static void subjoinFirstLineRootCauseFirst(StringBuilder buf, IThrowableProxy tp) { if (tp.getCause() != null) { buf.append(CoreConstants.WRAPPED_BY); } subjoinExceptionMessage(buf, tp); } private static void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) { buf.append(tp.getClassName()).append(": ").append(tp.getMessage()); } }