comparison src/nabble/naml/compiler/StackTrace.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 package nabble.naml.compiler;
2
3 import java.util.Collections;
4 import java.util.Map;
5 import java.util.HashMap;
6 import java.util.WeakHashMap;
7 import java.util.EmptyStackException;
8 import fschmidt.util.java.ArrayUtils;
9 import fschmidt.util.java.ArrayStack;
10 import fschmidt.util.java.Stack;
11 import fschmidt.util.java.Interner;
12
13
14 public class StackTrace extends ArrayStack<StackTraceElement> {
15
16 private static final ThreadLocal<Stack<StackTrace>> stack = new ThreadLocal<Stack<StackTrace>>() {
17 protected Stack<StackTrace> initialValue() {
18 Stack<StackTrace> stack = new ArrayStack<StackTrace>();
19 allStacks.put( Thread.currentThread(), stack );
20 return stack;
21 }
22 };
23
24 private static final Map<Thread,Stack<StackTrace>> allStacks = Collections.synchronizedMap(new WeakHashMap<Thread,Stack<StackTrace>>());
25
26 private static final Interner<StackTrace> interner = new Interner<StackTrace>();
27
28 public StackTrace() {}
29
30 StackTrace(StackTrace st) {
31 super(st);
32 }
33
34 StackTrace intern() {
35 trimToSize();
36 return interner.intern(this);
37 }
38
39 public String toString() {
40 StringBuilder buf = new StringBuilder();
41 for( int i=size()-1; i>=0; i-- ) {
42 StackTraceElement stackTraceElement = get(i);
43 buf.append( "\n\tin " ).append( stackTraceElement );
44 }
45 return buf.toString();
46 }
47 /*
48 public boolean containsSourceStartingWith(String s) {
49 for( StackTraceElement ste : this ) {
50 if( ste.source.id.startsWith(s) )
51 return true;
52 }
53 return false;
54 }
55 */
56 static Stack<StackTrace> stack() {
57 return stack.get();
58 }
59
60 private static StackTrace stackTrace(Stack<StackTrace> stack) {
61 StackTrace stackTrace = new StackTrace();
62 for( StackTrace st : stack ) {
63 stackTrace.addAll(st);
64 }
65 return stackTrace;
66 }
67
68 public static StackTrace current() {
69 return stackTrace(stack());
70 }
71
72 public static Map<Thread,String[]> getAllStackTraces() {
73 Map<Thread,Stack<StackTrace>> mapCopy;
74 synchronized(allStacks) {
75 mapCopy = new HashMap<Thread,Stack<StackTrace>>(allStacks);
76 }
77 Map<Thread,String[]> rtn = new HashMap<Thread,String[]>();
78 for( Map.Entry<Thread,Stack<StackTrace>> entry : mapCopy.entrySet() ) {
79 Thread thread = entry.getKey();
80 try {
81 Stack<StackTrace> stack = new ArrayStack<StackTrace>(entry.getValue()); // not thread-safe but the best I can do
82 StackTrace stackTrace = stackTrace(stack);
83 if( stackTrace.isEmpty() )
84 continue;
85 String[] aStr = new String[stackTrace.size()];
86 for( int i=0; i<aStr.length; i++ ) {
87 aStr[i] = stackTrace.get(i).toString();
88 }
89 ArrayUtils.reverse(aStr);
90 rtn.put(thread,aStr);
91 } catch(EmptyStackException e) {}
92 }
93 return rtn;
94 }
95
96 }