|
|
@@ -6,23 +6,29 @@
|
|
|
*/
|
|
|
package net.ranides.assira.trace;
|
|
|
|
|
|
+import java.lang.StackWalker.StackFrame;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
+import java.util.Optional;
|
|
|
import java.util.function.Function;
|
|
|
+import java.util.function.Predicate;
|
|
|
+import java.util.function.Supplier;
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
import net.ranides.assira.collection.lists.ListUtils;
|
|
|
import net.ranides.assira.generic.ValueUtils;
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
+ *
|
|
|
* @author Ranides Atterwim <ranides@gmail.com>
|
|
|
*/
|
|
|
public final class TraceUtils {
|
|
|
|
|
|
// @todo (assira #1) JDK11: migrate to StackWalker
|
|
|
+ static final Supplier<RuntimeException> THROW = () -> new RuntimeException("Internal: TraceUtils");
|
|
|
|
|
|
static final SecurityResolver RESOLVER_SECURITY = getSecurityResolver();
|
|
|
-
|
|
|
+
|
|
|
static final ThreadResolver RESOLVER_THREAD = new ThreadResolver();
|
|
|
|
|
|
static final ExceptionResolver RESOLVER_EXCEPT = new ExceptionResolver();
|
|
|
@@ -62,83 +68,110 @@ public final class TraceUtils {
|
|
|
RESOLVER_EXCEPT
|
|
|
);
|
|
|
|
|
|
- private TraceUtils() {
|
|
|
- /* utility class */
|
|
|
+ private TraceUtils() {
|
|
|
+ /* utility class */
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static List<StackTraceElement> getFrames() {
|
|
|
return AUTO_LIST_FRAMES.frames();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static List<Class<?>> getTypes() {
|
|
|
return AUTO_LIST_TYPES.types();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static List<String> getNames() {
|
|
|
return AUTO_LIST_NAMES.names();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ public static Optional<StackTraceElement> getFrame(Predicate<StackTraceElement> filter) {
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(s -> s.map(StackFrame::toStackTraceElement).filter(filter).findFirst());
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Optional<Class<?>> getType(Predicate<Class<?>> filter) {
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(s -> s.filter(f -> filter.test(f.getDeclaringClass())).findFirst().map(StackFrame::getDeclaringClass));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Optional<String> getName(Predicate<String> filter) {
|
|
|
+ return StackWalker.getInstance()
|
|
|
+ .walk(s -> s.filter(f -> filter.test(f.getClassName())).findFirst().map(StackFrame::getClassName));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static StackTraceElement getFrame(int index) {
|
|
|
return AUTO_FRAME.frame(index);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static Class<?> getType(int index) {
|
|
|
return AUTO_TYPE.type(index);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Deprecated
|
|
|
public static String getName(int index) {
|
|
|
return AUTO_NAME.name(index);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static StackTraceElement getCalleeFrame() {
|
|
|
- return getFrame(1);
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(f -> f.skip(1).map(StackFrame::toStackTraceElement).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static Class<?> getCalleeType() {
|
|
|
- return getType(1);
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(f -> f.skip(1).map(StackFrame::getDeclaringClass).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static String getCalleeName() {
|
|
|
- return getName(1);
|
|
|
+ return StackWalker.getInstance()
|
|
|
+ .walk(f -> f.skip(1).map(StackFrame::getClassName).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static StackTraceElement getCallerFrame() {
|
|
|
- return getFrame(2);
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(f -> f.skip(2).map(StackFrame::toStackTraceElement).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static Class<?> getCallerType() {
|
|
|
- return getType(2);
|
|
|
+ return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
|
|
+ .walk(f -> f.skip(2).map(StackFrame::getDeclaringClass).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static String getCallerName() {
|
|
|
- return getName(2);
|
|
|
+ return StackWalker.getInstance()
|
|
|
+ .walk(f -> f.skip(2).map(StackFrame::getClassName).findFirst().orElseThrow(THROW));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static List<Class<?>> test_getTypes(Resolver resolver) {
|
|
|
return resolver.types();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static List<String> test_getNames(Resolver resolver) {
|
|
|
return resolver.names();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static Class<?> test_getCalleeType(Resolver resolver) {
|
|
|
return resolver.type(0);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static String test_getCalleeName(Resolver resolver) {
|
|
|
return resolver.name(0);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static Class<?> test_getCallerType(Resolver resolver) {
|
|
|
return resolver.type(1);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
static String test_getCallerName(Resolver resolver) {
|
|
|
return resolver.name(1);
|
|
|
@@ -174,9 +207,9 @@ public final class TraceUtils {
|
|
|
private static <T,R> List<R> tail(int index, Function<T,R> map, List<T> list) {
|
|
|
return ListUtils.map(list, map).subList(index, list.size());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static final class SecurityResolver extends SecurityManager implements Resolver {
|
|
|
-
|
|
|
+
|
|
|
private static final int FIRST = 2;
|
|
|
|
|
|
@Override
|
|
|
@@ -212,7 +245,7 @@ public final class TraceUtils {
|
|
|
}
|
|
|
|
|
|
private static final class ThreadResolver implements Resolver {
|
|
|
-
|
|
|
+
|
|
|
private static final int FIRST = 3;
|
|
|
|
|
|
@Override
|
|
|
@@ -245,7 +278,7 @@ public final class TraceUtils {
|
|
|
throw new UnsupportedOperationException("ThreadResolver does not support Class<?>");
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private static final class ExceptionResolver implements Resolver {
|