1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.spi;
15
16 import ch.qos.logback.core.CoreConstants;
17
18 import java.util.List;
19
20 import static ch.qos.logback.core.CoreConstants.NA;
21
22
23
24
25
26
27
28 public class CallerData {
29
30
31
32 private static final String LOG4J_CATEGORY = "org.apache.log4j.Category";
33 private static final String SLF4J_BOUNDARY = "org.slf4j.Logger";
34
35
36
37
38
39 public static final int LINE_NA = -1;
40
41 public static final String CALLER_DATA_NA = "?#?:?" + CoreConstants.LINE_SEPARATOR;
42
43
44
45
46 public static final StackTraceElement[] EMPTY_CALLER_DATA_ARRAY = new StackTraceElement[0];
47
48
49
50
51
52 public static StackTraceElement[] extract(Throwable t, String fqnOfInvokingClass, final int maxDepth,
53 List<String> frameworkPackageList) {
54 if (t == null) {
55 return null;
56 }
57
58 StackTraceElement[] steArray = t.getStackTrace();
59 StackTraceElement[] callerDataArray;
60
61 int found = LINE_NA;
62 for (int i = 0; i < steArray.length; i++) {
63 if (isInFrameworkSpace(steArray[i].getClassName(), fqnOfInvokingClass, frameworkPackageList)) {
64
65 found = i + 1;
66 } else {
67 if (found != LINE_NA) {
68 break;
69 }
70 }
71 }
72
73
74 if (found == LINE_NA) {
75 return EMPTY_CALLER_DATA_ARRAY;
76 }
77
78 int availableDepth = steArray.length - found;
79 int desiredDepth = maxDepth < (availableDepth) ? maxDepth : availableDepth;
80
81 callerDataArray = new StackTraceElement[desiredDepth];
82 for (int i = 0; i < desiredDepth; i++) {
83 callerDataArray[i] = steArray[found + i];
84 }
85 return callerDataArray;
86 }
87
88 static boolean isInFrameworkSpace(String currentClass, String fqnOfInvokingClass,
89 List<String> frameworkPackageList) {
90
91
92 if (currentClass.equals(fqnOfInvokingClass) || currentClass.equals(LOG4J_CATEGORY)
93 || currentClass.startsWith(SLF4J_BOUNDARY)
94 || isInFrameworkSpaceList(currentClass, frameworkPackageList)) {
95 return true;
96 } else {
97 return false;
98 }
99 }
100
101
102
103
104
105 private static boolean isInFrameworkSpaceList(String currentClass, List<String> frameworkPackageList) {
106 if (frameworkPackageList == null)
107 return false;
108
109 for (String s : frameworkPackageList) {
110 if (currentClass.startsWith(s))
111 return true;
112 }
113 return false;
114 }
115
116
117
118
119
120
121
122
123 public static StackTraceElement naInstance() {
124 return new StackTraceElement(NA, NA, NA, LINE_NA);
125 }
126
127 }