All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.internal.util.StackTrace Maven / Gradle / Ivy

/*
 * Copyright (c) 2006-2013 Rogério Liesenfeld
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
 */
package mockit.internal.util;

import java.lang.reflect.*;

/**
 * Provides optimized utility methods to extract stack trace information.
 */
public final class StackTrace
{
   private static final Method getStackTraceDepth = getThrowableMethod("getStackTraceDepth");
   private static final Method getStackTraceElement = getThrowableMethod("getStackTraceElement", int.class);

   private static Method getThrowableMethod(String name, Class... parameterTypes)
   {
      Method m;

      try {
         m = Throwable.class.getDeclaredMethod(name, parameterTypes);
      }
      catch (NoSuchMethodException ignore) {
         return null;
      }

      m.setAccessible(true);
      return m;
   }

   private final Throwable t;
   private final StackTraceElement[] elements;

   public StackTrace() { this(new Throwable()); }

   public StackTrace(Throwable t)
   {
      this.t = t;
      elements = getStackTraceDepth == null ? t.getStackTrace() : null;
   }

   public int getDepth()
   {
      if (elements != null) {
         return elements.length;
      }

      int depth = 0;

      try {
         depth = (Integer) getStackTraceDepth.invoke(t);
      }
      catch (IllegalAccessException ignore) {}
      catch (InvocationTargetException ignored) {}

      return depth;
   }

   public StackTraceElement getElement(int index)
   {
      if (elements != null) {
         return elements[index];
      }

      StackTraceElement element = null;

      try {
         element = (StackTraceElement) getStackTraceElement.invoke(t, index);
      }
      catch (IllegalAccessException ignore) {}
      catch (InvocationTargetException ignored) {}

      return element;
   }

   public static void filterStackTrace(Throwable t)
   {
      new StackTrace(t).filter();
   }

   public void filter()
   {
      int n = getDepth();
      StackTraceElement[] filteredST = new StackTraceElement[n];
      int j = 0;

      for (int i = 0; i < n; i++) {
         StackTraceElement ste = getElement(i);

         if (ste.getFileName() != null) {
            String where = ste.getClassName();

            if (!isSunMethod(ste) && !isTestFrameworkMethod(where) && !isJMockitMethod(where)) {
               filteredST[j] = ste;
               j++;
            }
         }
      }

      StackTraceElement[] newStackTrace = new StackTraceElement[j];
      System.arraycopy(filteredST, 0, newStackTrace, 0, j);
      t.setStackTrace(newStackTrace);

      Throwable cause = t.getCause();

      if (cause != null) {
         new StackTrace(cause).filter();
      }
   }

   private static boolean isSunMethod(StackTraceElement ste)
   {
      return ste.getClassName().startsWith("sun.") && !ste.isNativeMethod();
   }

   private static boolean isTestFrameworkMethod(String where)
   {
      return where.startsWith("org.junit.") || where.startsWith("junit.") || where.startsWith("org.testng.");
   }

   private static boolean isJMockitMethod(String where)
   {
      return where.startsWith("mockit.") && (where.contains(".internal.") || !where.contains("Test"));
   }

   public StackTraceElement findPositionInTestMethod()
   {
      int n = getDepth();

      for (int i = 0; i < n; i++) {
         StackTraceElement ste = getElement(i);

         if (ste.getFileName() != null) {
            String where = ste.getClassName();

            if (!isSunMethod(ste) && !isTestFrameworkMethod(where) && !isJMockitMethod(where)) {
               return ste;
            }
         }
      }

      return null;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy