Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
StackTrace |
|
| 2.8;2.8 |
1 | /** | |
2 | * Copyright (C) 2013 Matthias Langer | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | package at.ipsquare.commons.core.util; | |
17 | ||
18 | import java.util.Arrays; | |
19 | ||
20 | /** | |
21 | * Utility methods for dealing with stack traces. | |
22 | * | |
23 | * @since 2.0.0 | |
24 | * @author Matthias Langer | |
25 | */ | |
26 | public final class StackTrace | |
27 | { | |
28 | /** | |
29 | * Returns the current stack trace, starting with the invocation of this method (unlike {@link Thread#getStackTrace()}). | |
30 | * | |
31 | * <h4>Note:</h4> | |
32 | * This method might return an empty array if the VM has no stack trace information | |
33 | * concerning the current thread. With a decent VM however, this should never happen. | |
34 | */ | |
35 | public static StackTraceElement[] get() | |
36 | { | |
37 | 2 | StackTraceElement[] elems = Thread.currentThread().getStackTrace(); |
38 | 2 | int first = firstElemBelowThisClass(elems); |
39 | 2 | return Arrays.copyOfRange(elems, first, elems.length); |
40 | } | |
41 | ||
42 | /** | |
43 | * Returns the first element in the stack that does not originate from the class of the caller. | |
44 | */ | |
45 | public static StackTraceElement firstElementBelowClass() | |
46 | { | |
47 | 60 | StackTraceElement[] elems = Thread.currentThread().getStackTrace(); |
48 | 60 | int first = firstElemBelowThisClass(elems); |
49 | 60 | Class<?> callerClass = associatedClass(elems[first]); |
50 | 130 | for(int i = first + 1; i < elems.length; ++i) |
51 | { | |
52 | 130 | StackTraceElement current = elems[i]; |
53 | 130 | if(!callerClass.equals(associatedClass(current))) |
54 | 60 | return current; |
55 | } | |
56 | 0 | return null; |
57 | } | |
58 | ||
59 | private static int firstElemBelowThisClass(StackTraceElement[] elems) | |
60 | { | |
61 | 62 | boolean seenThisClass = false; |
62 | 62 | int i = 0; |
63 | 310 | for(; i < elems.length; ++i) |
64 | { | |
65 | 186 | StackTraceElement elem = elems[i]; |
66 | 186 | Class<?> clazz = associatedClass(elem); |
67 | 186 | if(StackTrace.class.equals(clazz)) |
68 | 62 | seenThisClass = true; |
69 | 124 | else if(seenThisClass) |
70 | 62 | break; |
71 | } | |
72 | 62 | return i; |
73 | } | |
74 | ||
75 | /** | |
76 | * Returns the class associated with the given {@link StackTraceElement}. | |
77 | */ | |
78 | static Class<?> associatedClass(StackTraceElement elem) | |
79 | { | |
80 | try | |
81 | { | |
82 | 448 | return Class.forName(elem.getClassName()); |
83 | } | |
84 | 0 | catch(ClassNotFoundException e) |
85 | { | |
86 | 0 | throw new RuntimeException("Could not find class from StackTraceElement; trouble awaits.", e); |
87 | } | |
88 | } | |
89 | ||
90 | private StackTrace() | |
91 | 0 | { |
92 | ||
93 | 0 | } |
94 | } |