- package org.ntlab.trace;
-
- import java.io.BufferedReader;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Stack;
-
- public class TraceJPDA {
- protected HashMap<String, ThreadInstanceJPDA> threads = new HashMap<String, ThreadInstanceJPDA>();
-
- /**
- * 指定したJSONトレースファイルを解読して Trace オブジェクトを生成する
- * @param traceFile トレースファイルのパス
- */
- public TraceJPDA(BufferedReader file) {
- try {
- readJPDA(file);
- file.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 指定したJSONトレースファイルを解読して Trace オブジェクトを生成する
- * @param traceFile トレースファイルのパス
- */
- public TraceJPDA(String traceFile) {
- BufferedReader file;
- try {
- file = new BufferedReader(new FileReader(traceFile));
- readJPDA(file);
- file.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private void readJPDA(BufferedReader file) throws IOException {
- // トレースファイル読み込み
- String line = null;
- String[] columns;
- String[] columns2;
- String[] stack;
- String[] signature;
- String threadId;
- String threadName;
- HashMap<String, Integer> threadCallDepths = new HashMap<>();
- int depth = 0;
- long timeStamp = 0L;
- ThreadInstanceJPDA thread = null;
- while ((line = file.readLine()) != null) {
- // トレースファイルの解析
- columns = line.split(":");
- if (columns.length < 4) continue;
- threadName = columns[0];
- threadId = columns[1];
- stack = columns[2].split(" ");
- columns2 = columns[3].split("\t");
- if (columns2.length < 2) continue;
- timeStamp = Integer.parseInt(stack[stack.length - 1]) * 60
- + Integer.parseInt(columns2[0]);
- depth = stack.length - 1;
- signature = columns2[1].split(" -- ");
- thread = threads.get(threadName);
- if (thread == null) {
- thread = new ThreadInstanceJPDA(threadName);
- threads.put(threadName, thread);
- threadCallDepths.put(threadName, 0);
- }
- if (signature.length < 2) continue;
- for (int i = 0; i < threadCallDepths.get(threadName) - depth + 1; i++) {
- thread.returnMethod();
- }
- thread.callMethod(signature[1] + "." + signature[0] + "()", timeStamp);
- threadCallDepths.put(threadName, depth);
- }
- }
-
- /**
- * メソッド毎に全メソッド実行を全てのスレッドから取り出す
- * @return メソッドシグニチャからメソッド実行のリストへのHashMap
- */
- public HashMap<String, ArrayList<MethodExecutionJPDA>> getAllMethodExecutions() {
- final HashMap<String, ArrayList<MethodExecutionJPDA>> results = new HashMap<>();
- for (ThreadInstanceJPDA thread: threads.values()) {
- thread.traverseMethodExecutionsBackward(new MethodExecutionJPDA.IMethodExecutionVisitorJPDA() {
- @Override
- public boolean preVisitThread(ThreadInstanceJPDA thread) {
- return false;
- }
- @Override
- public boolean postVisitThread(ThreadInstanceJPDA thread) {
- return false;
- }
- @Override
- public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution) {
- ArrayList<MethodExecutionJPDA> executions = results.get(methodExecution.getSignature());
- if (executions == null) {
- executions = new ArrayList<MethodExecutionJPDA>();
- results.put(methodExecution.getSignature(), executions);
- }
- executions.add(methodExecution);
- return false;
- }
- @Override
- public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList<MethodExecutionJPDA> children) {
- return false;
- }
- });
- }
- return results;
- }
-
- /**
- * 全メソッドのシグニチャを取得する
- * @return 全メソッドシグニチャ
- */
- public HashSet<String> getAllMethodSignatures() {
- final HashSet<String> results = new HashSet<String>();
- for (ThreadInstanceJPDA thread: threads.values()) {
- thread.traverseMethodExecutionsBackward(new MethodExecutionJPDA.IMethodExecutionVisitorJPDA() {
- @Override
- public boolean preVisitThread(ThreadInstanceJPDA thread) {
- return false;
- }
- @Override
- public boolean postVisitThread(ThreadInstanceJPDA thread) {
- return false;
- }
- @Override
- public boolean preVisitMethodExecution(MethodExecutionJPDA methodExecution) {
- results.add(methodExecution.getSignature());
- return false;
- }
- @Override
- public boolean postVisitMethodExecution(MethodExecutionJPDA methodExecution, ArrayList<MethodExecutionJPDA> children) {
- return false;
- }
-
- });
- }
- return results;
- }
-
- public void traverseMethodExecutionsBackward(MethodExecutionJPDA.IMethodExecutionVisitorJPDA visitor) {
- for (ThreadInstanceJPDA thread: threads.values()) {
- visitor.preVisitThread(thread);
- thread.traverseMethodExecutionsBackward(visitor);
- visitor.postVisitThread(thread);
- }
- }
- }