Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
InternalCodeFrameResolver |
|
| 4.0;4 |
1 | /* | |
2 | * This file is part of AceLogger. | |
3 | * | |
4 | * AceLogger is free software: you can redistribute it and/or modify it under the terms of the GNU | |
5 | * Lesser General Public License as published by the Free Software Foundation, either version 3 of | |
6 | * the License, or (at your option) any later version. | |
7 | * | |
8 | * AceLogger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without | |
9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
10 | * Lesser General Public License for more details. | |
11 | * | |
12 | * You should have received a copy of the GNU Lesser General Public License along with AceLogger. | |
13 | * If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>. | |
14 | */ | |
15 | package net.sourceforge.acelogger.location.resolver; | |
16 | ||
17 | import net.sourceforge.acelogger.BaseLogger; | |
18 | ||
19 | /** | |
20 | * An implementation of CodeFrameResolver that regresses a fixed number of calls. | |
21 | * | |
22 | * @author Zardi (https://sourceforge.net/users/daniel_zardi) | |
23 | * @version 1.0.0 | |
24 | * @since 1.0.0 | |
25 | */ | |
26 | public class InternalCodeFrameResolver extends BaseCodeFrameResolver { | |
27 | ||
28 | /** | |
29 | * The depth of this class in the logging structure. | |
30 | */ | |
31 | private static final int METHOD_DEPTH = 2; | |
32 | ||
33 | /** | |
34 | * The number of calls to 'look back'. | |
35 | */ | |
36 | private final int frameShift; | |
37 | ||
38 | /** | |
39 | * Constructs a new InternalCodeFrameResolver for the supplied frame shift. | |
40 | * | |
41 | * @param frameShift | |
42 | * The number of calls that should be retroceded. | |
43 | * @since 1.0.0 | |
44 | */ | |
45 | 36 | public InternalCodeFrameResolver(int frameShift) { |
46 | 36 | this.frameShift = frameShift + METHOD_DEPTH; |
47 | 36 | } |
48 | ||
49 | /** {@inheritDoc} */ | |
50 | public StackTraceElement getCodeFrame(Thread currentThread) { | |
51 | 37 | StackTraceElement[] stackTrace = currentThread.getStackTrace(); |
52 | 37 | int userCodeCallIndex = 0; |
53 | 74 | for (int i = 0; i < stackTrace.length; i++) { |
54 | 74 | String frameClassName = stackTrace[i].getClassName(); |
55 | 74 | if (!frameClassName.startsWith("java.util.concurrent") |
56 | && !frameClassName.startsWith("java.lang.Thread")) { | |
57 | 37 | userCodeCallIndex = i; |
58 | 37 | if (i + frameShift < stackTrace.length) { |
59 | 37 | userCodeCallIndex += frameShift; |
60 | } | |
61 | break; | |
62 | } | |
63 | } | |
64 | 37 | StackTraceElement userCodeFrame = stackTrace[userCodeCallIndex]; |
65 | /* | |
66 | * FIXME: Is this right? If the call was made without the cause parameter, then the method | |
67 | * depth is 1 high | |
68 | */ | |
69 | 37 | if (userCodeFrame.getClassName().equals(BaseLogger.class.getCanonicalName()) |
70 | && userCodeCallIndex + 1 < stackTrace.length) { | |
71 | 0 | userCodeCallIndex++; |
72 | 0 | userCodeFrame = stackTrace[userCodeCallIndex]; |
73 | } | |
74 | 37 | return userCodeFrame; |
75 | } | |
76 | ||
77 | } |