Java tutorial
/* * * This file is part of antro, the line-level profiler for ant build scripts. * * antro is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * antro is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with antro. If not, see <http://www.gnu.org/licenses/>. */ package ru.jkff.antro; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.util.*; /** * Created on 13:39:02 17.03.2008 * * @author jkff */ public class ReportReader { private static final int REPORT_FILE_BUFFER_SIZE = 10 * 1024 * 1024; public Report readReport(String filename) throws IOException { // function getProfileData() { // return ( // JSONObject (read until {} [] braces are balanced) // ) // } // function getTrace() { // return ( // JSONObject (read until {} [] braces are balanced) // ) // } try { LineNumberReader r = new LineNumberReader( new BufferedReader(new FileReader(filename), REPORT_FILE_BUFFER_SIZE)); StringBuilder sb = new StringBuilder(); String line; while (null != (line = r.readLine())) { sb.append(line); } JSONArray data = new JSONArray(sb.toString()); JSONArray profileData = data.getJSONArray(0); JSONObject traceData = data.getJSONObject(1); return new Report(toTrace(traceData), toAnnotatedFiles(profileData)); } catch (JSONException e) { throw new RuntimeException(e); } } private Map<String, AnnotatedFile> toAnnotatedFiles(JSONArray profileData) throws JSONException { Map<String, AnnotatedFile> res = new HashMap<String, AnnotatedFile>(); for (int i = 0; i < profileData.length(); ++i) { String name = profileData.getJSONObject(i).getString("name"); res.put(name, toAnnotatedFile(profileData.getJSONObject(i).getJSONArray("stat"), name)); } return res; } private AnnotatedFile toAnnotatedFile(JSONArray fileStat, String fileName) throws JSONException { String[] lines = new String[fileStat.length()]; Stat[] stats = new Stat[fileStat.length()]; for (int i = 0; i < fileStat.length(); ++i) { JSONObject line = fileStat.getJSONObject(i); lines[i] = line.getString("text"); stats[i] = line.has("stat") ? toStat(line.getJSONObject("stat")) : null; } return new AnnotatedFile(lines, stats, fileName); } private Stat toStat(JSONObject stat) throws JSONException { double avg = stat.getDouble("avg"); double min = stat.getDouble("min"); double max = stat.getDouble("max"); double first = stat.getDouble("first"); double total = stat.getDouble("total"); int count = stat.getInt("count"); PersistentStack<Call> smin = toStack(stat.getJSONObject("evMin").getJSONArray("stack")); PersistentStack<Call> smax = toStack(stat.getJSONObject("evMax").getJSONArray("stack")); PersistentStack<Call> sfirst = toStack(stat.getJSONObject("evFirst").getJSONArray("stack")); EventWithCallStack evMin = new EventWithCallStack(smin); EventWithCallStack evMax = new EventWithCallStack(smax); EventWithCallStack evFirst = new EventWithCallStack(sfirst); return new Stat(avg, min, max, first, total, count, evMin, evMax, evFirst); } private PersistentStack<Call> toStack(JSONArray stack) throws JSONException { List<Call> calls = new ArrayList<Call>(); for (int i = 0; i < stack.length(); ++i) { calls.add(toCall(stack.getJSONObject(i))); } PersistentStack<Call> res = PersistentStack.empty(); Collections.reverse(calls); for (Call call : calls) { res = res.push(call); } return res; } private Call toCall(JSONObject call) throws JSONException { Call.Kind kind = Call.Kind.valueOf(call.getString("kind")); return new Call(kind, call.getString("name"), toLocation(call.getJSONObject("location"))); } private OurLocation toLocation(JSONObject location) throws JSONException { return new OurLocation(location.has("file") ? location.getString("file") : "(unknown file)", location.getInt("line")); } private Trace toTrace(JSONObject root) throws JSONException { String name = root.getJSONObject("call").getString("name"); Trace t = Trace.newRoot(name, new OurLocation(name, 0)); double total = root.has("total") ? root.getDouble("total") : 0; double own = root.has("own") ? root.getDouble("own") : 0; t.totalTime = total; t.childrenTime = total - own; if (root.has("children")) { JSONArray children = root.getJSONArray("children"); for (int i = 0; i < children.length(); ++i) { t.addChild(toTrace(children.getJSONObject(i), t)); } } return t; } private Trace toTrace(JSONObject root, Trace parent) throws JSONException { Call call = toCall(root.getJSONObject("call")); Trace t = new Trace(parent, call); double total = root.has("total") ? root.getDouble("total") : 0; double own = root.has("own") ? root.getDouble("own") : 0; t.totalTime = total; t.childrenTime = total - own; if (root.has("children")) { JSONArray children = root.getJSONArray("children"); for (int i = 0; i < children.length(); ++i) { t.addChild(toTrace(children.getJSONObject(i), t)); } } return t; } private Set<String> getUsedBuildFiles(Map<OurLocation, Stat> statsByLocation) { Set<String> res = new HashSet<String>(); for (OurLocation loc : statsByLocation.keySet()) { res.add(loc.fileName); } return res; } }