Coverage Report - net.sourceforge.acelogger.location.resolver.InternalCodeFrameResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
InternalCodeFrameResolver
87%
14/16
50%
6/12
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  
 }