1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.base.avro;
33
34 import gnu.trove.map.TMap;
35 import java.util.ArrayDeque;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.Deque;
39 import java.util.List;
40 import java.util.Set;
41 import java.util.function.Consumer;
42 import javax.annotation.Nonnull;
43 import javax.annotation.Nullable;
44 import javax.annotation.ParametersAreNonnullByDefault;
45 import org.spf4j.base.Methods;
46 import org.spf4j.ds.IdentityHashSet;
47 import org.spf4j.log.Slf4jLogRecord;
48
49
50
51
52 @ParametersAreNonnullByDefault
53 public final class Converters {
54
55 public static final Method ROOT = new Method("JVM", "ROOT");
56
57 private Converters() { }
58
59 public static StackTraceElement convert(final java.lang.StackTraceElement stackTrace) {
60 String className = stackTrace.getClassName();
61 String fileName = stackTrace.getFileName();
62 return new StackTraceElement(new Method(className, stackTrace.getMethodName()),
63 fileName == null ? null : new FileLocation(fileName, stackTrace.getLineNumber(), -1),
64 org.spf4j.base.PackageInfo.getPackageInfo(className));
65 }
66
67 public static List<StackTraceElement> convert(final java.lang.StackTraceElement[] stackTraces) {
68 int l = stackTraces.length;
69 if (l == 0) {
70 return Collections.EMPTY_LIST;
71 }
72 List<StackTraceElement> result = new ArrayList<>(l);
73 for (java.lang.StackTraceElement st : stackTraces) {
74 result.add(convert(st));
75 }
76 return result;
77 }
78
79 public static List<Throwable> convert(final java.lang.Throwable[] throwables, final Set<java.lang.Throwable> seen) {
80 int l = throwables.length;
81 if (l == 0) {
82 return Collections.EMPTY_LIST;
83 }
84 List<Throwable> result = new ArrayList<>(l);
85 for (java.lang.Throwable t : throwables) {
86 result.add(convert(t, seen));
87 }
88 return result;
89 }
90
91 public static Throwable convert(final java.lang.Throwable throwable) {
92 return convert(throwable, new IdentityHashSet<>(4));
93 }
94
95 public static Throwable convert(final java.lang.Throwable throwable,
96 final Set<java.lang.Throwable> seen) {
97 if (seen.contains(throwable)) {
98 return new Throwable(throwable.getClass().getName(),
99 "CIRCULAR REFERENCE:" + throwable.getMessage(),
100 Collections.EMPTY_LIST, null, Collections.EMPTY_LIST);
101 } else {
102 seen.add(throwable);
103 }
104 String message = throwable.getMessage();
105 if (throwable instanceof RemoteException) {
106 return new Throwable(throwable.getClass().getName(),
107 message == null ? "" : message, convert(throwable.getStackTrace()),
108 ((RemoteException) throwable).getRemoteCause(),
109 convert(throwable.getSuppressed(), seen));
110 }
111 java.lang.Throwable cause = throwable.getCause();
112 return new Throwable(throwable.getClass().getName(),
113 message == null ? "" : message,
114 convert(throwable.getStackTrace()),
115 cause == null ? null : convert(cause, seen),
116 convert(throwable.getSuppressed(), seen));
117 }
118
119 public static RemoteException convert(final String source, final Throwable throwable) {
120 return new RemoteException(source, throwable);
121 }
122
123
124 public static List<LogRecord> convert(final String origin, final String traceId,
125 final List<Slf4jLogRecord> logRecords) {
126 List<LogRecord> result = new ArrayList<>(logRecords.size());
127 for (Slf4jLogRecord log : logRecords) {
128 result.add(log.toLogRecord(origin, traceId));
129 }
130 return result;
131 }
132
133
134 public static int convert(final Method method, final org.spf4j.base.StackSamples node,
135 final int parentId, final int id,
136 final Consumer<StackSampleElement> handler) {
137
138 final Deque<TraversalNode> dq = new ArrayDeque<>();
139 dq.addLast(new TraversalNode(method, node, parentId));
140 int nid = id;
141 while (!dq.isEmpty()) {
142 TraversalNode first = dq.removeFirst();
143 org.spf4j.base.StackSamples n = first.getNode();
144 StackSampleElement sample = new StackSampleElement(nid, first.getParentId(),
145 n.getSampleCount(), first.getMethod());
146 final TMap<Method, ? extends org.spf4j.base.StackSamples> subNodes = n.getSubNodes();
147 final int pid = nid;
148 if (subNodes != null) {
149 subNodes.forEachEntry((a, b) -> {
150 dq.addLast(new TraversalNode(a, b, pid));
151 return true;
152 });
153 }
154 handler.accept(sample);
155 nid++;
156 }
157 return nid;
158 }
159
160
161 @ParametersAreNonnullByDefault
162 private static final class TraversalNode {
163
164 private final Method method;
165 private final org.spf4j.base.StackSamples node;
166 private final int parentId;
167
168 TraversalNode(final Method method, final org.spf4j.base.StackSamples node, final int parentId) {
169 this.method = method;
170 this.node = node;
171 this.parentId = parentId;
172 }
173
174 public Method getMethod() {
175 return method;
176 }
177
178 public org.spf4j.base.StackSamples getNode() {
179 return node;
180 }
181
182 public int getParentId() {
183 return parentId;
184 }
185
186 @Override
187 public String toString() {
188 return "TraversalNode{" + "method=" + method + ", node=" + node + ", parentId=" + parentId + '}';
189 }
190
191 }
192
193 @Nonnull
194 public static List<StackSampleElement> convert(@Nullable final org.spf4j.base.StackSamples stackSamples) {
195 if (stackSamples != null) {
196 final List<StackSampleElement> samples = new ArrayList<>();
197 Converters.convert(Methods.ROOT, stackSamples, -1, 0, samples::add);
198 return samples;
199 } else {
200 return Collections.EMPTY_LIST;
201 }
202 }
203
204 }