2929
3030package org .scijava .log ;
3131
32+ import org .scijava .Context ;
33+
3234/**
3335 * Utility class for getting the calling class of a method.
3436 *
@@ -43,12 +45,44 @@ private CallingClassUtils() {
4345 }
4446
4547 /**
48+ * Inspects the stack trace to return the name of the class that calls
49+ * this method, but ignores every class annotated with @IgnoreAsCallingClass.
50+ * <p>
51+ * If every class on the stack trace is annotated, then the class at the
52+ * root of the stack trace is returned.
53+ */
54+ public static String getCallingClassName () {
55+ StackTraceElement [] stackTrace = Thread .currentThread ().getStackTrace ();
56+ for (int i = 1 ; i < stackTrace .length - 2 ; i ++) {
57+ String className = stackTrace [i ].getClassName ();
58+ if (!hasIgnoreAsCallingClassAnnotation (className )) return className ;
59+ }
60+ return stackTrace [stackTrace .length - 1 ].getClassName ();
61+ }
62+
63+ private static boolean hasIgnoreAsCallingClassAnnotation (String className ) {
64+ try {
65+ Class < ? > clazz = Context .getClassLoader ().loadClass (className );
66+ return clazz .isAnnotationPresent (IgnoreAsCallingClass .class );
67+ }
68+ catch (ClassNotFoundException ignore ) {
69+ return false ;
70+ }
71+ }
72+
73+ /**
74+ * @deprecated Use {@link #getCallingClassName()} instead.
75+ *
76+ * Warning: This method throws a IllegalStateException as soon as it comes
77+ * across a class that can't be loaded with the default class loader.
78+ *
4679 * Inspects the stack trace to return the class that calls this method, but
4780 * ignores every class annotated with @IgnoreAsCallingClass.
4881 *
4982 * @throws IllegalStateException if every method on the stack, is in a class
5083 * annotated with @IgnoreAsCallingClass.
5184 */
85+ @ Deprecated
5286 public static Class <?> getCallingClass () {
5387 try {
5488 StackTraceElement [] stackTrace = Thread .currentThread ().getStackTrace ();
0 commit comments