blob: 5d76d4c9b4cbd6a0aaa89fa07fc16ed22cc3f15e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2015 Xored Software Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.sherlock.ui.reportdetails;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.rcptt.profiling.core.SherlockJobsCore;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Event;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.EventKind;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.EventSource;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Node;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Report;
import org.eclipse.rcptt.sherlock.core.reporting.SimpleReportGenerator;
import org.eclipse.rcptt.sherlock.jobs.jobs.AsyncEventInfo;
import org.eclipse.rcptt.sherlock.jobs.jobs.AsyncInfo;
import org.eclipse.rcptt.sherlock.jobs.jobs.JobEventInfo;
import org.eclipse.rcptt.sherlock.jobs.jobs.JobInfo;
import org.eclipse.rcptt.sherlock.ui.reportdetails.figures.EventFigure;
import org.eclipse.rcptt.sherlock.ui.reportdetails.figures.NodeFigure;
import org.eclipse.rcptt.sherlock.ui.reportdetails.figures.SourceFigure;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ScrollBar;
public class ReportTimelineComposite {
private List<Node> nodes = new ArrayList<Node>();
private Canvas imageCanvas;
private ScrolledComposite sc;
private Figure figureParent;
private LightweightSystem lws;
private StyledText infoText;
private int timeWidth = 600;
private boolean includeTasks = true;
private ColorManager colors = new ColorManager(true);
private long minTime;
private long maxTime;
private boolean showBegined = true;
public ReportTimelineComposite(Report report2, Composite control) {
SashForm sform = new SashForm(control, SWT.VERTICAL | SWT.SMOOTH);
sform.setLayout(new org.eclipse.swt.layout.GridLayout(1, false));
GridDataFactory.fillDefaults().hint(200, 100).grab(true, true)
.applyTo(sform);
sc = new ScrolledComposite(sform, SWT.H_SCROLL | SWT.V_SCROLL
| SWT.BORDER);
imageCanvas = new Canvas(sc, SWT.DOUBLE_BUFFERED);
sc.setContent(imageCanvas);
final Color color = imageCanvas.getDisplay().getSystemColor(
SWT.COLOR_WHITE);
sc.setBackground(new Color(color.getDevice(), color.getRGB()));
imageCanvas.setBackground(new Color(color.getDevice(), color.getRGB()));
updateBounds(50, 50);
GridDataFactory.fillDefaults().hint(200, 100).grab(true, true)
.applyTo(sc);
lws = new LightweightSystem(imageCanvas);
figureParent = new Layer();
GridLayout gl = new GridLayout(1, true);
gl.horizontalSpacing = 0;
gl.verticalSpacing = -1;
figureParent.setLayoutManager(gl);
lws.setContents(figureParent);
Composite g = new Composite(sform, SWT.BORDER);
// g.setText("Details");
infoText = new StyledText(g, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 150).grab(true, false)
.applyTo(g);
GridLayoutFactory.swtDefaults().applyTo(g);
GridDataFactory.fillDefaults().grab(true, true).applyTo(infoText);
sform.setWeights(new int[] { 80, 20 });
}
public void doZoomOut() {
timeWidth = timeWidth - timeWidth / 4;
if (timeWidth < 200) {
timeWidth = 200;
}
ScrollBar bar = sc.getHorizontalBar();
int selection = bar.getSelection();
int maximum = bar.getMaximum();
internalUpdate(nodes);
bar.setSelection((int) ((1.0f * selection / maximum) * bar.getMaximum()));
bar.notifyListeners(SWT.Selection, new org.eclipse.swt.widgets.Event());
}
public void doZoomIn() {
timeWidth = timeWidth + timeWidth / 4;
if (timeWidth > 30000) {
timeWidth = 30000;
}
ScrollBar bar = sc.getHorizontalBar();
int selection = bar.getSelection();
int maximum = bar.getMaximum();
internalUpdate(nodes);
bar.setSelection((int) ((1.0f * selection / maximum) * bar.getMaximum()));
bar.notifyListeners(SWT.Selection, new org.eclipse.swt.widgets.Event());
}
private void updateBounds(int width, int height) {
imageCanvas.setBounds(0, 0, width, height);
// imageCanvas.getViewport().setSize(width, height);
// imageCanvas.setMinSize(width - 1, height - 1);
}
public void update(List<Node> newNodes) {
this.nodes.clear();
this.nodes.addAll(newNodes);
timeWidth = 600;
internalUpdate(nodes);
}
private void internalUpdate(List<Node> newNodes) {
figureParent.removeAll();
minTime = Long.MAX_VALUE;
maxTime = Long.MIN_VALUE;
for (Node node : newNodes) {
long startTime = node.getStartTime();
if (startTime < minTime) {
minTime = startTime;
}
long endTime = node.getEndTime();
if (endTime > maxTime) {
maxTime = endTime;
}
}
long allTime = maxTime - minTime;
Set<Event> processed = new HashSet<Event>();
// Create draw nodes from jobs and asyncs
final Map<EventSource, List<Event>> sourceEvents = new HashMap<EventSource, List<Event>>();
for (Node node : newNodes) {
int st = calcPos(minTime, allTime, node.getStartTime());
int ed = calcPos(minTime, allTime, node.getEndTime()) - st;
NodeFigure nodeFig = null;
if (includeTasks) {
SourceFigure sources = new SourceFigure(node.getName(),
getTimeWidth(), 1);
figureParent.add(sources);
nodeFig = createNodeFigure();
nodeFig.setFill(true);
nodeFig.setNode(node);
nodeFig.setBackgroundColor(colors.getColor(new RGB(220, 220,
220)));
sources.addToContainer(nodeFig, st, 0, ed, 20, 0);
}
List<Event> events = new ArrayList<Event>(node.getEvents());
// We need to collect also events started in all previous and parent
// nodes and not finished here.
Map<EventSource, List<Event>> nonFinishedGroups = new HashMap<EventSource, List<Event>>();
if (showBegined && newNodes.size() < 10) {
List<Event> priorEvents = collectPriorEvents(node);
final Map<EventSource, List<Event>> priorEventsSources = new HashMap<EventSource, List<Event>>();
groupBySources(priorEvents, priorEventsSources);
mergeSources(priorEventsSources);
List<EventSource> sourcesKeys = new ArrayList<EventSource>(
priorEventsSources.keySet());
Collections.sort(sourcesKeys, new Comparator<EventSource>() {
public int compare(EventSource o1, EventSource o2) {
long m1 = getMinTime(priorEventsSources, o1);
long m2 = getMinTime(priorEventsSources, o2);
return (int) (m1 - m2);
}
});
for (EventSource source : sourcesKeys) {
List<Event> events2 = priorEventsSources.get(source);
Map<String, List<Event>> groups = groupByIDs(events2,
new ArrayList<Event>());
// Make small groups
Collection<List<Event>> gvalues = groups.values();
List<List<Event>> smallGroups = new ArrayList<List<Event>>();
for (List<Event> list : gvalues) {
makeSmallGroups(smallGroups, list);
}
Collections.sort(smallGroups,
new Comparator<List<Event>>() {
public int compare(List<Event> o1,
List<Event> o2) {
long minTime1 = calcMinTime(o1);
long minTime2 = calcMinTime(o2);
return (int) (minTime1 - minTime2);
}
});
// Match non finished groups
for (List<Event> list : smallGroups) {
if (list.size() > 2) {
Event last = list.get(list.size() - 1);
if (!last.getKind().equals(EventKind.END)) {
List<Event> llist = nonFinishedGroups
.get(source);
if (llist == null) {
llist = new ArrayList<Event>();
nonFinishedGroups.put(source, llist);
}
llist.add(last);
}
}
}
}
}
final Map<EventSource, List<Event>> localSourceEvents = new HashMap<EventSource, List<Event>>();
// localSourceEvents.putAll(nonFinishedGroups);
groupBySources(events, sourceEvents);
groupBySources(events, localSourceEvents);
// Build draw blocks
if (includeTasks) {
mergeSources(localSourceEvents);
nodeFig.setSources(localSourceEvents);
List<EventSource> sourcesKeys = new ArrayList<EventSource>(
localSourceEvents.keySet());
Collections.sort(sourcesKeys, new Comparator<EventSource>() {
public int compare(EventSource o1, EventSource o2) {
long m1 = getMinTime(localSourceEvents, o1);
long m2 = getMinTime(localSourceEvents, o2);
return (int) (m1 - m2);
}
});
for (EventSource source : sourcesKeys) {
processSource(allTime, processed, node, st, ed,
localSourceEvents, source);
}
for (EventSource source : nonFinishedGroups.keySet()) {
processNonFinishedSource(allTime, node, st, ed,
nonFinishedGroups, source);
}
}
}
mergeSources(sourceEvents);
// Build draw blocks
List<EventSource> sourcesKeys = new ArrayList<EventSource>(
sourceEvents.keySet());
Collections.sort(sourcesKeys, new Comparator<EventSource>() {
public int compare(EventSource o1, EventSource o2) {
long m1 = getMinTime(sourceEvents, o1);
long m2 = getMinTime(sourceEvents, o2);
return (int) (m1 - m2);
}
});
for (EventSource source : sourcesKeys) {
// ArrayList<DrawNode> list = new ArrayList<DrawNode>();
List<Event> events = sourceEvents.get(source);
events.removeAll(processed);
if (events.size() > 0) {
List<List<Event>> instances = groupEvents(events);
SourceFigure sourceRoot = new SourceFigure(
getSourceTitle(source), getTimeWidth(),
instances.size());
sourceRoot.setSource(source);
for (List<Event> list : instances) {
addEventsTo(minTime, allTime, list, sourceRoot, minTime,
allTime, instances.indexOf(list));
}
if (sourceRoot.hasChildInContainer()) {
figureParent.add(sourceRoot);
}
processed.addAll(events);
}
}
Dimension psize = figureParent.getPreferredSize();
updateBounds(psize.width, psize.height);
}
private void groupBySources(List<Event> events,
final Map<EventSource, List<Event>> localSourceEvents) {
for (Event event : events) {
EventSource source = event.getSource();
if (source != null) {
// Put also in loca
List<Event> list = localSourceEvents.get(source);
if (list == null) {
list = new ArrayList<Event>();
localSourceEvents.put(source, list);
}
list.add(event);
}
}
}
/**
* Collect events started before node and not finished yet.
*/
private List<Event> collectPriorEvents(Node node) {
Node parent = node.getParent();
if (parent == null) {
return new ArrayList<Event>();
}
List<Event> result = new ArrayList<Event>();
result.addAll(collectPriorEvents(parent));
EList<Event> events = parent.getEvents();
for (Event event : events) {
if (!event.getKind().equals(EventKind.INFO)
&& event.getTime() < node.getStartTime()) {
result.add(event);
}
}
EList<Node> children = parent.getChildren();
int pos = children.indexOf(node);
for (int i = 0; i < pos; i++) {
EList<Event> evs = children.get(i).getEvents();
for (Event event : evs) {
if (!event.getKind().equals(EventKind.INFO)) {
result.addAll(evs);
}
}
}
return result;
}
private void processSource(long allTime, Set<Event> processed, Node node,
int st, int ed,
final Map<EventSource, List<Event>> localSourceEvents,
EventSource source) {
List<Event> events2 = localSourceEvents.get(source);
processed.addAll(events2);
List<List<Event>> instances = groupEvents(events2);
SourceFigure sourceRoot = new SourceFigure(getSourceTitle(source),
getTimeWidth(), instances.size());
figureParent.add(sourceRoot);
for (List<Event> list : instances) {
addEventsTo(minTime, allTime, list, sourceRoot, st, ed,
instances.indexOf(list));
}
}
private void processNonFinishedSource(long allTime, Node node, int st,
int ed, final Map<EventSource, List<Event>> localSourceEvents,
EventSource source) {
List<Event> events2 = localSourceEvents.get(source);
List<List<Event>> instances = groupEvents(events2);
SourceFigure sourceRoot = new SourceFigure(getSourceTitle(source),
getTimeWidth(), instances.size());
figureParent.add(sourceRoot);
for (List<Event> list : instances) {
int level = instances.indexOf(list);
Set<Event> processed = new HashSet<Event>();
int len = list.size();
for (int i = 0; i < len; i++) {
Event event = list.get(i);
if (processed.contains(event)) {
continue;
}
if (event.getKind().equals(EventKind.BEGIN)) {
// Check for end node
EventFigure childFig = createEventFigure();
childFig.setEvent(event);
childFig.setFill(true);
if (event.getColor() == null) {
childFig.setBackgroundColor(colors.getColor(new RGB(0,
0, 0)));
} else {
Color color = colors.getColor(parseColor(event
.getColor()));
childFig.setBackgroundColor(color);
}
sourceRoot.addToContainer(childFig, st, 0, (int) ed, 20,
level);
}
}
}
}
private List<List<Event>> groupEvents(List<Event> events) {
List<List<Event>> results = new ArrayList<List<Event>>();
List<Event> topGroup = new ArrayList<Event>();
List<Event> infoEvents = new ArrayList<Event>();
Map<String, List<Event>> groups = groupByIDs(events, infoEvents);
// Make small groups
Collection<List<Event>> gvalues = groups.values();
List<List<Event>> smallGroups = new ArrayList<List<Event>>();
for (List<Event> list : gvalues) {
makeSmallGroups(smallGroups, list);
}
Collections.sort(smallGroups, new Comparator<List<Event>>() {
public int compare(List<Event> o1, List<Event> o2) {
long minTime1 = calcMinTime(o1);
long minTime2 = calcMinTime(o2);
return (int) (minTime1 - minTime2);
}
});
// Lets merge groups
for (List<Event> list : smallGroups) {
if (isFitGroup(topGroup, list)) {
topGroup.addAll(list);
} else {
// try to merge events by BEGIN,END pairs
results.add(list);
}
}
if (!topGroup.isEmpty()) {
results.add(topGroup);
}
if (!infoEvents.isEmpty()) {
topGroup.addAll(infoEvents);
}
Collections.sort(results, new Comparator<List<Event>>() {
public int compare(List<Event> o1, List<Event> o2) {
long minTime1 = calcMinTime(o1);
long minTime2 = calcMinTime(o2);
return (int) (minTime1 - minTime2);
}
});
return results;
}
private Map<String, List<Event>> groupByIDs(List<Event> events,
List<Event> infoEvents) {
Map<String, List<Event>> groups = new HashMap<String, List<Event>>();
int len = events.size();
for (int i = 0; i < len; i++) {
Event event = events.get(i);
if (event.getKind().equals(EventKind.INFO)) {
infoEvents.add(event);
continue;
}
String instance = getEventInstance(event);
List<Event> list = groups.get(instance);
if (list == null) {
list = new ArrayList<Event>();
groups.put(instance, list);
}
list.add(event);
}
return groups;
}
private void makeSmallGroups(List<List<Event>> smallGroups, List<Event> list) {
for (int i = 0; i < list.size(); i++) {
Event event = list.get(i);
List<Event> tempGroup = new ArrayList<Event>();
tempGroup.add(event);
if (event.getKind().equals(EventKind.BEGIN)) {
for (int j = i + 1; j < list.size(); j++) {
Event jEvent = list.get(j);
if (jEvent.getKind().equals(EventKind.BEGIN)) {
tempGroup.add(jEvent);
} else if (jEvent.getKind().equals(EventKind.END)) {
tempGroup.add(jEvent);
break;
}
}
}
i += tempGroup.size() - 1;
smallGroups.add(tempGroup);
}
}
private boolean isFitGroup(List<Event> topGroup, List<Event> list) {
if (topGroup.isEmpty()) {
return true;
}
List<List<Event>> smallGroups = new ArrayList<List<Event>>();
makeSmallGroups(smallGroups, topGroup);
long minTime = calcMinTime(list);
long maxTime = calcMaxTime(list);
for (List<Event> glist : smallGroups) {
long gminTime = calcMinTime(glist);
long gmaxTime = calcMaxTime(glist);
if (!(maxTime < gminTime || minTime > gmaxTime)) {
return false;
}
}
return true;
}
private long calcMaxTime(List<Event> list) {
long maxTime = -1;
for (Event event : list) {
if (event.getTime() > maxTime) {
maxTime = event.getTime();
}
}
return maxTime;
}
private long calcMinTime(List<Event> list) {
long minTime = Long.MAX_VALUE;
for (Event event : list) {
if (event.getTime() < minTime) {
minTime = event.getTime();
}
}
return minTime;
}
private String getEventInstance(Event event) {
EObject data = event.getData();
if (data != null) {
if (data instanceof AsyncEventInfo) {
String id = ((AsyncEventInfo) data).getId();
if (id != null) {
return id;
}
} else if (data instanceof JobEventInfo) {
String id = ((JobEventInfo) data).getId();
if (id != null) {
return id;
}
}
}
return "";
}
private void addEventsTo(long minTime, long allTime, List<Event> events,
SourceFigure sourceRoot, long stTime, long edTime, int level) {
Set<Event> processed = new HashSet<Event>();
int len = events.size();
for (int i = 0; i < len; i++) {
Event event = events.get(i);
if (processed.contains(event)) {
continue;
}
if (event.getKind().equals(EventKind.END)) {
EventFigure childFig = createEventFigure();
childFig.setEvent(event);
// childFig.setEndEvent(event);
int cst = (int) stTime;
int cstEnd = calcPos(minTime, allTime, event.getTime());
childFig.setFill(true);
if (event.getColor() == null) {
childFig.setBackgroundColor(colors
.getColor(new RGB(0, 0, 0)));
} else {
Color color = colors.getColor(parseColor(event.getColor()));
childFig.setBorder(new LineBorder(color));
childFig.setBackgroundColor(color);
}
sourceRoot.addToContainer(childFig, cst, 0, cstEnd - cst, 20,
level);
}
if (event.getKind().equals(EventKind.BEGIN)) {
// Check for end node
boolean found = false;
for (int j = i + 1; j < len; j++) {
Event jEvent = events.get(j);
if (jEvent.getKind().equals(EventKind.END)
|| jEvent.getKind().equals(EventKind.BEGIN)) {
if (jEvent.getKind().equals(EventKind.END)) {
processed.add(jEvent);
}
if (!getEventInstance(jEvent).equals(
getEventInstance(jEvent))) {
continue;
}
EventFigure childFig = createEventFigure();
childFig.setEvent(event);
childFig.setEndEvent(jEvent);
int cst = calcPos(minTime, allTime, event.getTime());
int cstEnd = calcPos(minTime, allTime, jEvent.getTime());
childFig.setFill(true);
if (event.getColor() == null) {
childFig.setBackgroundColor(colors
.getColor(new RGB(0, 0, 0)));
} else {
Color color = colors.getColor(parseColor(event
.getColor()));
childFig.setBorder(new LineBorder(color));
childFig.setBackgroundColor(color);
}
sourceRoot.addToContainer(childFig, cst, 0, cstEnd
- cst, 20, level);
found = true;
break;
}
}
if (!found) {
EventFigure childFig = createEventFigure();
childFig.setEvent(event);
int cst = calcPos(minTime, allTime, event.getTime());
childFig.setFill(true);
if (event.getColor() == null) {
childFig.setBackgroundColor(colors.getColor(new RGB(0,
0, 0)));
} else {
Color color = colors.getColor(parseColor(event
.getColor()));
childFig.setBackgroundColor(color);
}
sourceRoot.addToContainer(childFig, cst, 0, (int) edTime
- cst, 20, level);
}
}
}
for (int i = 0; i < len; i++) {
Event event = events.get(i);
if (event.getKind().equals(EventKind.INFO)) {
EventFigure childFig = createEventFigure();
int cst = calcPos(minTime, allTime, event.getTime());
childFig.setFill(true);
childFig.setEvent(event);
if (event.getColor() == null) {
childFig.setBackgroundColor(colors
.getColor(new RGB(0, 0, 0)));
} else {
Color color = colors.getColor(parseColor(event.getColor()));
childFig.setBorder(new LineBorder(color));
childFig.setBackgroundColor(color);
}
sourceRoot.addToContainer(childFig, cst, 0, 1, 20, level);
}
}
// Locate pairs
}
private NodeFigure createNodeFigure() {
final NodeFigure nodeFig = new NodeFigure();
nodeFig.addMouseMotionListener(new MouseMotionListener() {
Border oldBorder;
public void mouseDragged(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
oldBorder = nodeFig.getBorder();
LineBorder border = new LineBorder(2);
border.setStyle(Graphics.LINE_SOLID);
border.setColor(colors.getColor(new RGB(255, 0, 0)));
nodeFig.setBorder(border);
imageCanvas.redraw();
}
public void mouseExited(MouseEvent me) {
nodeFig.setBorder(oldBorder);
}
public void mouseHover(MouseEvent me) {
}
public void mouseMoved(MouseEvent me) {
}
});
nodeFig.addMouseListener(new MouseListener() {
public void mousePressed(MouseEvent me) {
}
public void mouseReleased(MouseEvent me) {
if (nodeFig.getNode() != null) {
updateInfo(nodeFig.getNode(), nodeFig.getSources());
}
}
public void mouseDoubleClicked(MouseEvent me) {
}
});
return nodeFig;
}
private EventFigure createEventFigure() {
final EventFigure efig = new EventFigure();
efig.addMouseMotionListener(new MouseMotionListener() {
Border oldBorder = null;
public void mouseDragged(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
oldBorder = efig.getBorder();
LineBorder border = new LineBorder(2);
border.setStyle(Graphics.LINE_SOLID);
border.setColor(colors.getColor(new RGB(255, 0, 0)));
efig.setBorder(border);
imageCanvas.redraw();
}
public void mouseExited(MouseEvent me) {
efig.setBorder(oldBorder);
}
public void mouseHover(MouseEvent me) {
}
public void mouseMoved(MouseEvent me) {
}
});
efig.addMouseListener(new MouseListener() {
public void mousePressed(MouseEvent me) {
updateInfo(efig.getEvent(), efig.getEndEvent());
}
public void mouseReleased(MouseEvent me) {
}
public void mouseDoubleClicked(MouseEvent me) {
}
});
return efig;
}
private RGB parseColor(String color) {
if (color.startsWith("#") && color.length() == 7) {
int r = Integer.parseInt(color.substring(1, 3), 16);
int g = Integer.parseInt(color.substring(3, 5), 16);
int b = Integer.parseInt(color.substring(5, 7), 16);
return new RGB(r, g, b);
}
return new RGB(0, 0, 0);
}
// Merge sources with same class name into one
private void mergeSources(Map<EventSource, List<Event>> localSourceEvents) {
Map<EventSource, List<Event>> result = new HashMap<EventSource, List<Event>>();
for (EventSource es : localSourceEvents.keySet()) {
String title = getSourceTitle(es);
EventSource mergeTo = null;
for (EventSource res : result.keySet()) {
if (title.equals(getSourceTitle(res))) {
mergeTo = res;
break;
}
}
if (mergeTo == null) {
result.put(es, localSourceEvents.get(es));
} else {
List<Event> rList = new ArrayList<Event>();
rList.addAll(result.get(mergeTo));
rList.addAll(localSourceEvents.get(es));
result.put(mergeTo, rList);
}
}
localSourceEvents.clear();
localSourceEvents.putAll(result);
}
private long getMinTime(
final Map<EventSource, List<Event>> localSourceEvents,
EventSource o1) {
List<Event> list = localSourceEvents.get(o1);
long minTime1 = calcMinTime(list);
return minTime1;
}
protected void updateInfo(Event event, Event endEvent) {
StringBuilder builder = new StringBuilder();
if (event != null && endEvent != null) {
builder.append(
"Start time:"
+ TimeFormatHelper.format(event.getTime() - minTime))
.append("\n");
builder.append(
"Time spend:"
+ TimeFormatHelper.format(endEvent.getTime()
- event.getTime())).append("\n");
} else {
builder.append(
"Time:"
+ TimeFormatHelper.format(event.getTime() - minTime))
.append("\n");
}
EventSource source = event.getSource();
EObject data = source.getProperties().get(SherlockJobsCore.JOBS);
if (data != null && data instanceof AsyncInfo) {
EObject dta = event.getData();
AsyncInfo info = (AsyncInfo) data;
if (info.isSync()) {
builder.append("sync exec:");
} else {
builder.append("async exec:");
if (dta != null && dta instanceof AsyncEventInfo) {
switch (((AsyncEventInfo) dta).getKind()) {
case STARTING:
builder.append("Starting");
break;
case RUNNING:
builder.append("Running");
break;
case DONE:
builder.append("Done");
break;
case TIMER_EXEC:
builder.append("Timer exec");
break;
}
}
}
builder.append("\n");
String cName = info.getRunnableClass();
if (cName == null || cName.startsWith("$")) {
cName = info.getSourceClass() + cName;
}
builder.append(" class name:" + cName).append("\n");
if (info.getSourceClass() != null) {
builder.append(
" source class name:" + info.getSourceClass() + "."
+ info.getSourceMethod()).append("\n");
}
if (info.getSourceFile() != null) {
builder.append(" source file:" + info.getSourceFile()).append(
"\n");
}
if (info.getThisClassName() != null) {
builder.append(" created from:" + info.getThisClassName())
.append("\n");
}
}
if (data != null && data instanceof JobInfo) {
JobInfo info = (JobInfo) data;
builder.append("job:");
EObject dta = event.getData();
if (dta != null && dta instanceof JobEventInfo) {
switch (((JobEventInfo) dta).getKind()) {
case SHEDULED:
builder.append("Sheduled");
break;
case RUNNING:
builder.append("Running");
break;
case CANCELED:
builder.append("Canceled");
break;
case WAITING:
builder.append("Waiting");
break;
case FINISHED:
builder.append("Finished");
break;
case ASYNC_DONE:
builder.append("Async Done");
break;
case SLEPPING:
builder.append("Sleeping");
break;
case ASYNC_FINISH:
builder.append("Waiting async");
break;
}
}
builder.append("\n");
String cName = info.getJobClassName();
if (cName == null || cName.startsWith("$")) {
cName = info.getSourceClass() + cName;
}
builder.append(" class name:" + cName).append("\n");
if (info.getSourceClass() != null) {
builder.append(
" source class name:" + info.getSourceClass() + "."
+ info.getSourceMethod()).append("\n");
}
if (info.getSourceFile() != null) {
builder.append(" source file:" + info.getSourceFile()).append(
"\n");
}
if (info.getThisClassName() != null) {
builder.append(" created from:" + info.getThisClassName())
.append("\n");
}
}
infoText.setText(builder.toString());
}
protected void updateInfo(Node node, Map<EventSource, List<Event>> sources) {
StringBuilder builder = new StringBuilder();
builder.append(
"Start time:"
+ TimeFormatHelper.format(node.getStartTime() - minTime))
.append("\n");
builder.append(
"Time spend:"
+ TimeFormatHelper.format(node.getDuration()))
.append("\n");
SimpleReportGenerator gen = new SimpleReportGenerator();
for (EventSource source : sources.keySet()) {
builder.append("source:" + getSourceTitle(source)).append("\n");
List<Event> events = sources.get(source);
for (Event event : events) {
builder.append("\t" + "event:"
+ TimeFormatHelper.format(event.getTime() - minTime));
StringBuilder b2 = new StringBuilder();
try {
gen.toString(b2, 0, event.getData(), true);
} catch (IOException e) {
// String Builder does not throw
throw new RuntimeException(e);
}
builder.append(" " + b2.toString().replace('\n', ' ').trim())
.append("\n");
}
}
infoText.setText(builder.toString());
}
private int getTimeWidth() {
return timeWidth;
}
private String getSourceTitle(EventSource source) {
EMap<String, EObject> properties = source.getProperties();
EObject eobject = properties.get(SherlockJobsCore.JOBS);
if (eobject != null && eobject instanceof AsyncInfo) {
AsyncInfo info = (AsyncInfo) eobject;
String cName = info.getRunnableClass();
if (cName == null || cName.startsWith("$")) {
cName = info.getSourceClass() + cName;
}
int pos = cName.lastIndexOf('.');
if (info.isTimer()) {
return "\t" + "timer:" + cName.substring(pos + 1);
}
return "\t" + (info.isSync() ? "sync: " : "async: ")
+ cName.substring(pos + 1);
} else if (eobject != null && eobject instanceof JobInfo) {
JobInfo jobInfo = (JobInfo) eobject;
String cName = jobInfo.getJobClassName();
if (cName == null || cName.startsWith("$")) {
cName = jobInfo.getSourceClass() + cName;
}
int pos = cName.lastIndexOf('.');
return "\t" + "job: " + cName.substring(pos + 1);
} /*
* else if (teslaInfo != null) { String name = teslaInfo.getName(); int
* pos = name.lastIndexOf('.'); return "\t" +"cmd: " +
* name.substring(pos + 1); }
*/
return " " + source.getName();
}
private int calcPos(long minTime, long allTime, long time) {
return (int) (getTimeWidth() * (1.0f * (time - minTime) / allTime));
}
public void setShowTasks(boolean includeTasks2) {
includeTasks = includeTasks2;
internalUpdate(nodes);
}
}