001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.helpers; 015 016import java.util.LinkedList; 017import java.util.List; 018 019import ch.qos.logback.core.CoreConstants; 020 021public class ThrowableToStringArray { 022 023 public static String[] convert(Throwable t) { 024 List<String> strList = new LinkedList<String>(); 025 extract(strList, t, null); 026 return strList.toArray(new String[0]); 027 028 } 029 030 private static void extract(List<String> strList, Throwable t, StackTraceElement[] parentSTE) { 031 032 StackTraceElement[] ste = t.getStackTrace(); 033 final int numberOfcommonFrames = findNumberOfCommonFrames(ste, parentSTE); 034 035 strList.add(formatFirstLine(t, parentSTE)); 036 for (int i = 0; i < (ste.length - numberOfcommonFrames); i++) { 037 strList.add("\tat " + ste[i].toString()); 038 } 039 040 if (numberOfcommonFrames != 0) { 041 strList.add("\t... " + numberOfcommonFrames + " common frames omitted"); 042 } 043 044 Throwable cause = t.getCause(); 045 if (cause != null) { 046 ThrowableToStringArray.extract(strList, cause, ste); 047 } 048 } 049 050 private static String formatFirstLine(Throwable t, StackTraceElement[] parentSTE) { 051 String prefix = ""; 052 if (parentSTE != null) { 053 prefix = CoreConstants.CAUSED_BY; 054 } 055 056 String result = prefix + t.getClass().getName(); 057 if (t.getMessage() != null) { 058 result += ": " + t.getMessage(); 059 } 060 return result; 061 } 062 063 private static int findNumberOfCommonFrames(StackTraceElement[] ste, StackTraceElement[] parentSTE) { 064 if (parentSTE == null) { 065 return 0; 066 } 067 068 int steIndex = ste.length - 1; 069 int parentIndex = parentSTE.length - 1; 070 int count = 0; 071 while (steIndex >= 0 && parentIndex >= 0) { 072 if (ste[steIndex].equals(parentSTE[parentIndex])) { 073 count++; 074 } else { 075 break; 076 } 077 steIndex--; 078 parentIndex--; 079 } 080 return count; 081 } 082 083}