Clover coverage report - brownies library - 1.0-beta-1
Coverage timestamp: 月 8 16 2004 17:14:42 GMT+09:00
file stats: LOC: 247   Methods: 6
NCLOC: 115   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
InvocationInfo.java 55% 78.3% 100% 71.3%
coverage coverage
 1   
 /*
 2   
  * Joey and its relative products are published under the terms
 3   
  * of the Apache Software License.
 4   
  */
 5   
 
 6   
 package org.asyrinx.brownie.core.lang;
 7   
 
 8   
 import java.io.PrintWriter;
 9   
 import java.io.StringWriter;
 10   
 
 11   
 /**
 12   
  * @author akima
 13   
  */
 14   
 public class InvocationInfo implements java.io.Serializable {
 15   
 
 16   
     /**
 17   
      * Caller's line number.
 18   
      */
 19   
     transient String lineNumber;
 20   
 
 21   
     /**
 22   
      * Caller's file name.
 23   
      */
 24   
     transient String fileName;
 25   
 
 26   
     /**
 27   
      * Caller's fully qualified class name.
 28   
      */
 29   
     transient String className;
 30   
 
 31   
     /**
 32   
      * Caller's method name.
 33   
      */
 34   
     transient String methodName;
 35   
 
 36   
     // Note that the line.separator property can be looked up even by
 37   
     // applets.
 38   
     private final static String LINE_SEP = System.getProperty("line.separator");
 39   
 
 40   
     private final static int LINE_SEP_LEN = LINE_SEP.length();
 41   
 
 42   
     /**
 43   
      * All available caller information, in the format
 44   
      * <code>fully.qualified.classname.of.caller.methodName(Filename.java:line)</code>
 45   
      */
 46   
     public String fullInfo;
 47   
 
 48   
     private static StringWriter sw = new StringWriter();
 49   
 
 50   
     private static PrintWriter pw = new PrintWriter(sw);
 51   
 
 52   
     /**
 53   
      * When location information is not available the constant <code>NA</code>
 54   
      * is returned. Current value of this string constant is <b>? </b>.
 55   
      */
 56   
     public final static String NA = "?";
 57   
 
 58   
     static final long serialVersionUID = -1325822038990805636L;
 59   
 
 60   
     // Check if we are running in IBM's visual age.
 61   
     static boolean inVisualAge = false;
 62   
     static {
 63  2
         try {
 64   
             //Class dummy = Class.forName("com.ibm.uvm.tools.DebugSupport");
 65  2
             Class.forName("com.ibm.uvm.tools.DebugSupport");
 66  0
             inVisualAge = true;
 67  0
             System.out.println("Detected IBM VisualAge environment.");
 68   
         } catch (Throwable e) {
 69   
             // nothing to do
 70   
         }
 71   
     }
 72   
 
 73  10
     public InvocationInfo(String fqnOfCallingClass) {
 74  10
         this(new Exception(), fqnOfCallingClass);
 75   
     }
 76   
 
 77   
     /**
 78   
      * Instantiate location information based on a Throwable. We expect the
 79   
      * Throwable <code>t</code>, to be in the format
 80   
      * 
 81   
      * <pre>
 82   
      * 
 83   
      *      java.lang.Throwable
 84   
      *      ...
 85   
      *      at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)
 86   
      *      at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)
 87   
      *      at org.apache.log4j.Category.callAppenders(Category.java:131)
 88   
      *      at org.apache.log4j.Category.log(Category.java:512)
 89   
      *      at callers.fully.qualified.className.methodName(FileName.java:74)
 90   
      *      ...
 91   
      *      
 92   
      * </pre>
 93   
      * 
 94   
      * <p>
 95   
      * However, we can also deal with JIT compilers that "lose" the location
 96   
      * information, especially between the parentheses.
 97   
      *  
 98   
      */
 99  10
     public InvocationInfo(Throwable t, String fqnOfCallingClass) {
 100  10
         if (t == null)
 101  0
             return;
 102   
 
 103  10
         String s;
 104   
         // Protect against multiple access to sw.
 105  10
         synchronized (sw) {
 106  10
             t.printStackTrace(pw);
 107  10
             s = sw.toString();
 108  10
             sw.getBuffer().setLength(0);
 109   
         }
 110   
         //System.out.println("s is ["+s+"].");
 111   
 
 112   
         //int ibegin, iend;
 113   
 
 114   
         // Given the current structure of the package, the line
 115   
         // containing "org.apache.log4j.Category." should be printed just
 116   
         // before the caller.
 117   
 
 118   
         // This method of searching may not be fastest but it's safer
 119   
         // than counting the stack depth which is not guaranteed to be
 120   
         // constant across JVM implementations.
 121  10
         int ibegin = s.lastIndexOf(fqnOfCallingClass);
 122  10
         if (ibegin == -1)
 123  0
             return;
 124   
 
 125  10
         ibegin = s.indexOf(LINE_SEP, ibegin);
 126  10
         if (ibegin == -1)
 127  0
             return;
 128  10
         ibegin += LINE_SEP_LEN;
 129   
 
 130   
         // determine end of line
 131  10
         int iend = s.indexOf(LINE_SEP, ibegin);
 132  10
         if (iend == -1)
 133  0
             return;
 134   
 
 135   
         // VA has a different stack trace format which doesn't
 136   
         // need to skip the inital 'at'
 137  10
         if (!inVisualAge) {
 138   
             // back up to first blank character
 139  10
             ibegin = s.lastIndexOf("at ", iend);
 140  10
             if (ibegin == -1)
 141  0
                 return;
 142   
             // Add 3 to skip "at ";
 143  10
             ibegin += 3;
 144   
         }
 145   
         // everything between is the requested stack item
 146  10
         this.fullInfo = s.substring(ibegin, iend);
 147   
     }
 148   
 
 149   
     /**
 150   
      * Return the fully qualified class name of the caller making the logging
 151   
      * request.
 152   
      */
 153  10
     public String getClassName() {
 154  10
         if (fullInfo == null)
 155  0
             return NA;
 156  10
         if (className == null) {
 157   
             // Starting the search from '(' is safer because there is
 158   
             // potentially a dot between the parentheses.
 159  10
             int iend = fullInfo.lastIndexOf('(');
 160  10
             if (iend == -1)
 161  0
                 className = NA;
 162   
             else {
 163  10
                 iend = fullInfo.lastIndexOf('.', iend);
 164   
 
 165   
                 // This is because a stack trace in VisualAge looks like:
 166   
 
 167   
                 //java.lang.RuntimeException
 168   
                 //  java.lang.Throwable()
 169   
                 //  java.lang.Exception()
 170   
                 //  java.lang.RuntimeException()
 171   
                 //  void test.test.B.print()
 172   
                 //  void test.test.A.printIndirect()
 173   
                 //  void test.test.Run.main(java.lang.String [])
 174  10
                 int ibegin = 0;
 175  10
                 if (inVisualAge) {
 176  0
                     ibegin = fullInfo.lastIndexOf(' ', iend) + 1;
 177   
                 }
 178   
 
 179  10
                 if (iend == -1)
 180  0
                     className = NA;
 181   
                 else
 182  10
                     className = this.fullInfo.substring(ibegin, iend);
 183   
             }
 184   
         }
 185  10
         return className;
 186   
     }
 187   
 
 188   
     /**
 189   
      * Return the file name of the caller.
 190   
      * 
 191   
      * <p>
 192   
      * This information is not always available.
 193   
      */
 194  5
     public String getFileName() {
 195  5
         if (fullInfo == null)
 196  0
             return NA;
 197   
 
 198  5
         if (fileName == null) {
 199  5
             int iend = fullInfo.lastIndexOf(':');
 200  5
             if (iend == -1)
 201  3
                 fileName = NA;
 202   
             else {
 203  2
                 int ibegin = fullInfo.lastIndexOf('(', iend - 1);
 204  2
                 fileName = this.fullInfo.substring(ibegin + 1, iend);
 205   
             }
 206   
         }
 207  5
         return fileName;
 208   
     }
 209   
 
 210   
     /**
 211   
      * Returns the line number of the caller.
 212   
      * 
 213   
      * <p>
 214   
      * This information is not always available.
 215   
      */
 216  5
     public String getLineNumber() {
 217  5
         if (fullInfo == null)
 218  0
             return NA;
 219   
 
 220  5
         if (lineNumber == null) {
 221  5
             int iend = fullInfo.lastIndexOf(')');
 222  5
             int ibegin = fullInfo.lastIndexOf(':', iend - 1);
 223  5
             if (ibegin == -1)
 224  3
                 lineNumber = NA;
 225   
             else
 226  2
                 lineNumber = this.fullInfo.substring(ibegin + 1, iend);
 227   
         }
 228  5
         return lineNumber;
 229   
     }
 230   
 
 231   
     /**
 232   
      * Returns the method name of the caller.
 233   
      */
 234  5
     public String getMethodName() {
 235  5
         if (fullInfo == null)
 236  0
             return NA;
 237  5
         if (methodName == null) {
 238  5
             int iend = fullInfo.lastIndexOf('(');
 239  5
             int ibegin = fullInfo.lastIndexOf('.', iend);
 240  5
             if (ibegin == -1)
 241  0
                 methodName = NA;
 242   
             else
 243  5
                 methodName = this.fullInfo.substring(ibegin + 1, iend);
 244   
         }
 245  5
         return methodName;
 246   
     }
 247   
 }