Remove unneeded checkNotNull() calls
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / viewers / statistics / TmfStatisticsViewer.java
CommitLineData
cfd22ad0 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2012, 2015 Ericsson
cfd22ad0
MD
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Mathieu Denis <mathieu.denis@polymtl.ca> - Initial API and implementation
89c06060 11 * Alexandre Montplaisir - Port to ITmfStatistics provider
0fcf3b09 12 * Patrick Tasse - Support selection range
12d85f6c 13 * Bernd Hufmann - Fix range selection updates
cfd22ad0
MD
14 *******************************************************************************/
15
1743f395 16package org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics;
cfd22ad0 17
c14c0757 18import java.util.Collection;
de83d1ab 19import java.util.HashMap;
cfd22ad0 20import java.util.List;
89c06060 21import java.util.Map;
cfd22ad0 22
de83d1ab 23import org.eclipse.core.runtime.jobs.Job;
378e6b92 24import org.eclipse.jface.viewers.StructuredSelection;
cfd22ad0
MD
25import org.eclipse.jface.viewers.TreeViewer;
26import org.eclipse.jface.viewers.TreeViewerColumn;
27import org.eclipse.jface.viewers.Viewer;
28import org.eclipse.jface.viewers.ViewerComparator;
cfd22ad0 29import org.eclipse.swt.SWT;
cdf994ef 30import org.eclipse.swt.custom.SashForm;
cfd22ad0
MD
31import org.eclipse.swt.events.SelectionAdapter;
32import org.eclipse.swt.events.SelectionEvent;
33import org.eclipse.swt.graphics.Color;
34import org.eclipse.swt.graphics.Cursor;
cfd22ad0
MD
35import org.eclipse.swt.widgets.Composite;
36import org.eclipse.swt.widgets.Control;
37import org.eclipse.swt.widgets.Display;
38import org.eclipse.swt.widgets.Event;
39import org.eclipse.swt.widgets.Listener;
2bdf0193
AM
40import org.eclipse.tracecompass.tmf.core.component.TmfComponent;
41import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
97c71024 42import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
cdf994ef 43import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
2bdf0193 44import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
2bdf0193
AM
45import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule;
46import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
47import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
48import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
21852dfa 49import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
2bdf0193 50import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
b8585c7c 51import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
5c5fa260 52import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
2bdf0193 53import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer;
378e6b92
ACL
54import org.eclipse.tracecompass.internal.tmf.ui.viewers.piecharts.TmfPieChartViewer;
55import org.eclipse.tracecompass.internal.tmf.ui.viewers.piecharts.model.TmfPieChartStatisticsModel;
56import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfBaseColumnData;
57import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider;
58import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsFormatter;
59import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsTree;
60import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager;
61import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode;
62import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfTreeContentProvider;
cfd22ad0
MD
63
64/**
65 * A basic viewer to display statistics in the statistics view.
66 *
8b60cb37
MD
67 * It is linked to a single ITmfTrace until its disposal.
68 *
cfd22ad0 69 * @author Mathieu Denis
cfd22ad0 70 */
05627bda 71public class TmfStatisticsViewer extends TmfViewer {
cfd22ad0 72
87f83123
AM
73 /** The actual tree viewer to display */
74 private TreeViewer fTreeViewer;
05627bda 75
87f83123
AM
76 /** Update range synchronization object */
77 private final Object fStatisticsRangeUpdateSyncObj = new Object();
73fbf6be 78
cdf994ef
ACL
79 /** The statistics tree linked to this viewer */
80 private TmfStatisticsTree fStatisticsData;
81
87f83123
AM
82 /** The trace that is displayed by this viewer */
83 private ITmfTrace fTrace;
89c06060 84
87f83123 85 /** Indicates to process all events */
05627bda
MD
86 private boolean fProcessAll;
87
87f83123 88 /** View instance counter (for multiple statistics views) */
cfd22ad0
MD
89 private static int fCountInstance = 0;
90
87f83123 91 /** Number of this instance. Used as an instance ID. */
cfd22ad0
MD
92 private int fInstanceNb;
93
87f83123 94 /** Object to store the cursor while waiting for the trace to load */
cfd22ad0
MD
95 private Cursor fWaitCursor = null;
96
97 /**
05627bda
MD
98 * Counts the number of times waitCursor() has been called. It avoids
99 * removing the waiting cursor, since there may be multiple requests running
100 * at the same time.
101 */
102 private int fWaitCursorCount = 0;
103
87f83123 104 /** Tells to send a time range request when the trace gets updated. */
05627bda
MD
105 private boolean fSendRangeRequest = true;
106
de83d1ab
MAL
107 private final Map<ITmfTrace, Job> fUpdateJobsPartial = new HashMap<>();
108 private final Map<ITmfTrace, Job> fUpdateJobsGlobal = new HashMap<>();
109
cdf994ef
ACL
110 private TmfPieChartViewer fPieChartViewer;
111
112 private SashForm fSash;
de83d1ab 113
cdf994ef 114 private TmfPieChartStatisticsModel fPieChartModel;
de83d1ab 115
05627bda
MD
116 /**
117 * Create a basic statistics viewer. To be used in conjunction with
118 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
119 *
120 * @param parent
121 * The parent composite that will hold the viewer
122 * @param viewerName
123 * The name that will be assigned to this viewer
124 * @param trace
125 * The trace that is displayed by this viewer
126 * @see TmfComponent
127 */
128 public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) {
129 init(parent, viewerName, trace);
130 }
131
132 /**
133 * Initialize the statistics viewer.
cfd22ad0
MD
134 *
135 * @param parent
05627bda
MD
136 * The parent component of the viewer.
137 * @param viewerName
138 * The name to give to the viewer.
139 * @param trace
140 * The trace that will be displayed by the viewer.
cfd22ad0 141 */
05627bda
MD
142 public void init(Composite parent, String viewerName, ITmfTrace trace) {
143 super.init(parent, viewerName);
cfd22ad0
MD
144 // Increment a counter to make sure the tree ID is unique.
145 fCountInstance++;
146 fInstanceNb = fCountInstance;
05627bda
MD
147 fTrace = trace;
148
faa38350 149 // The viewer will process all events if he is assigned to an experiment
05627bda
MD
150 fProcessAll = (trace instanceof TmfExperiment);
151
152 initContent(parent);
8b60cb37 153 initInput();
05627bda
MD
154 }
155
05627bda
MD
156 @Override
157 public void dispose() {
158 super.dispose();
159 if (fWaitCursor != null) {
160 fWaitCursor.dispose();
161 }
8b60cb37 162
de83d1ab
MAL
163 for (Job j : fUpdateJobsGlobal.values()) {
164 j.cancel();
165 }
166
167 for (Job j : fUpdateJobsPartial.values()) {
168 j.cancel();
169 }
170
66792052 171 // Clean the model for this viewer
36033ff0 172 TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID());
cdf994ef 173 fPieChartViewer.reinitializeCharts();
05627bda
MD
174 }
175
1c0de632
AM
176 // ------------------------------------------------------------------------
177 // Signal handlers
178 // ------------------------------------------------------------------------
89c06060 179
05627bda 180 /**
faa38350 181 * Handles the signal about new trace range.
05627bda
MD
182 *
183 * @param signal
faa38350 184 * The trace range updated signal
05627bda
MD
185 */
186 @TmfSignalHandler
faa38350
PT
187 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
188 ITmfTrace trace = signal.getTrace();
05627bda 189 // validate
faa38350 190 if (!isListeningTo(trace)) {
05627bda
MD
191 return;
192 }
193
3c934968
MD
194 synchronized (fStatisticsRangeUpdateSyncObj) {
195 // Sends the time range request only once from this method.
196 if (fSendRangeRequest) {
197 fSendRangeRequest = false;
21852dfa
AM
198
199 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
200 TmfTimeRange timeRange = ctx.getSelectionRange();
0fcf3b09 201 requestTimeRangeData(trace, timeRange);
3c934968 202 }
05627bda 203 }
faa38350 204 requestData(trace, signal.getRange());
05627bda
MD
205 }
206
0fcf3b09
PT
207 /**
208 * Handles the time synch updated signal. It updates the time range
209 * statistics.
210 *
211 * @param signal
212 * Contains the information about the new selected time range.
97c71024 213 * @since 1.0
0fcf3b09
PT
214 */
215 @TmfSignalHandler
97c71024 216 public void timeSynchUpdated(TmfSelectionRangeUpdatedSignal signal) {
faa38350
PT
217 if (fTrace == null) {
218 return;
219 }
0fcf3b09
PT
220 ITmfTimestamp begin = signal.getBeginTime();
221 ITmfTimestamp end = signal.getEndTime();
222 TmfTimeRange timeRange = new TmfTimeRange(begin, end);
223 requestTimeRangeData(fTrace, timeRange);
05627bda
MD
224 }
225
1c0de632
AM
226 // ------------------------------------------------------------------------
227 // Class methods
228 // ------------------------------------------------------------------------
229
05627bda
MD
230 /*
231 * Returns the primary control associated with this viewer.
232 *
233 * @return the SWT control which displays this viewer's content
234 */
235 @Override
236 public Control getControl() {
cdf994ef 237 return fSash;
05627bda
MD
238 }
239
240 /**
241 * Get the input of the viewer.
242 *
243 * @return an object representing the input of the statistics viewer.
244 */
245 public Object getInput() {
246 return fTreeViewer.getInput();
247 }
248
05627bda
MD
249 /**
250 * This method can be overridden to implement another way of representing
251 * the statistics data and to retrieve the information for display.
252 *
253 * @return a TmfStatisticsData object.
254 */
36033ff0 255 public TmfStatisticsTree getStatisticData() {
05627bda 256 if (fStatisticsData == null) {
36033ff0 257 fStatisticsData = new TmfStatisticsTree();
05627bda
MD
258 }
259 return fStatisticsData;
260 }
261
cdf994ef
ACL
262 /**
263 * @return the model of the piecharts in this viewer
264 * @since 2.0
265 */
1904e6a4 266 public TmfPieChartStatisticsModel getPieChartModel() {
cdf994ef
ACL
267 if (fPieChartModel == null) {
268 fPieChartModel = new TmfPieChartStatisticsModel();
1904e6a4
ACL
269 }
270 return fPieChartModel;
cdf994ef
ACL
271 }
272
05627bda
MD
273 /**
274 * Returns a unique ID based on name to be associated with the statistics
275 * tree for this viewer. For a same name, it will always return the same ID.
276 *
277 * @return a unique statistics tree ID.
278 */
279 public String getTreeID() {
280 return getName() + fInstanceNb;
281 }
282
283 @Override
284 public void refresh() {
285 final Control viewerControl = getControl();
286 // Ignore update if disposed
287 if (viewerControl.isDisposed()) {
288 return;
289 }
cdf994ef
ACL
290 refreshTree();
291 refreshPieCharts(true, true);
292 }
293
294 /**
295 * Only refreshes the Tree viewer
296 */
1904e6a4 297 private void refreshTree() {
cdf994ef
ACL
298 final Control viewerControl = getControl();
299 // Ignore update if disposed
300 if (viewerControl.isDisposed()) {
301 return;
302 }
05627bda 303
cdf994ef 304 Display.getDefault().asyncExec(new Runnable() {
05627bda
MD
305 @Override
306 public void run() {
307 if (!viewerControl.isDisposed()) {
308 fTreeViewer.refresh();
309 }
310 }
311 });
312 }
313
cdf994ef
ACL
314 /**
315 * Only refreshes the piecharts depending on the parameters
1904e6a4
ACL
316 *
317 * @param refreshGlobal
318 * if we have to refresh the global piechart
319 * @param refreshSelection
320 * if we have to refresh the selection piechart
cdf994ef
ACL
321 * @since 2.0
322 */
323 protected void refreshPieCharts(final boolean refreshGlobal, final boolean refreshSelection) {
324 final Control viewerControl = getControl();
325 // Ignore update if disposed
326 if (viewerControl.isDisposed()) {
327 return;
328 }
329
330 Display.getDefault().asyncExec(new Runnable() {
331 @Override
332 public void run() {
333 if (!viewerControl.isDisposed()) {
334 fPieChartViewer.refresh(refreshGlobal, refreshSelection);
335 }
336 }
337 });
338 }
339
3c934968
MD
340 /**
341 * Will force a request on the partial event count if one is needed.
342 */
343 public void sendPartialRequestOnNextUpdate() {
344 synchronized (fStatisticsRangeUpdateSyncObj) {
345 fSendRangeRequest = true;
346 }
347 }
348
05627bda
MD
349 /**
350 * Focus on the statistics tree of the viewer
351 */
352 public void setFocus() {
353 fTreeViewer.getTree().setFocus();
354 }
355
05627bda
MD
356 /**
357 * Cancels the request if it is not already completed
358 *
359 * @param request
360 * The request to be canceled
361 */
fd3f1eff 362 protected void cancelOngoingRequest(ITmfEventRequest request) {
05627bda
MD
363 if (request != null && !request.isCompleted()) {
364 request.cancel();
365 }
366 }
367
368 /**
369 * This method can be overridden to change the representation of the data in
370 * the columns.
371 *
b3a26928 372 * @return An object of type {@link TmfBaseColumnDataProvider}.
05627bda 373 */
b3a26928 374 protected TmfBaseColumnDataProvider getColumnDataProvider() {
05627bda
MD
375 return new TmfBaseColumnDataProvider();
376 }
cfd22ad0 377
05627bda
MD
378 /**
379 * Initialize the content that will be drawn in this viewer
380 *
381 * @param parent
382 * The parent of the control to create
383 */
384 protected void initContent(Composite parent) {
cdf994ef 385
cfd22ad0 386 final List<TmfBaseColumnData> columnDataList = getColumnDataProvider().getColumnData();
cfd22ad0 387
1904e6a4 388 fSash = new SashForm(parent, SWT.HORIZONTAL);
cdf994ef
ACL
389
390 fTreeViewer = new TreeViewer(fSash, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
391 fPieChartViewer = new TmfPieChartViewer(fSash);
378e6b92
ACL
392 fPieChartViewer.addEventTypeSelectionListener(new Listener() {
393
394 @Override
395 public void handleEvent(Event event) {
396 String eventTypeName = event.text;
397 if (getStatisticData().getRootNode() == null ||
378e6b92
ACL
398 fTreeViewer.getTree() == null) {
399 return;
400 }
401 /* Get all the nodes corresponding to the event name */
402 List<TmfStatisticsTreeNode> nodes = (List<TmfStatisticsTreeNode>) getStatisticData().getRootNode().findChildren(eventTypeName, true);
403 if (nodes.isEmpty()) {
404 /* Shouldn't happen, except for when selecting "Others" */
405 return;
406 }
407 /* Only select the first in the collection */
408 fTreeViewer.setSelection(new StructuredSelection(nodes.get(0)), true);
409 }
410 });
411
412 /* Make sure the sash is split in 2 equal parts */
413 fSash.setWeights(new int[] { 100, 100 });
cdf994ef 414
cfd22ad0
MD
415 fTreeViewer.setContentProvider(new TmfTreeContentProvider());
416 fTreeViewer.getTree().setHeaderVisible(true);
417 fTreeViewer.setUseHashlookup(true);
418
419 // Creates the columns defined by the column data provider
420 for (final TmfBaseColumnData columnData : columnDataList) {
421 final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment());
422 treeColumn.getColumn().setText(columnData.getHeader());
423 treeColumn.getColumn().setWidth(columnData.getWidth());
424 treeColumn.getColumn().setToolTipText(columnData.getTooltip());
425
df2b3dbb
VP
426 // If is dummy column
427 if (columnData == columnDataList.get(TmfBaseColumnDataProvider.StatsColumn.DUMMY.getIndex())) {
428 treeColumn.getColumn().setResizable(false);
429 }
430
431 // A comparator is defined.
432 if (columnData.getComparator() != null) {
cfd22ad0
MD
433 // Adds a listener on the columns header for sorting purpose.
434 treeColumn.getColumn().addSelectionListener(new SelectionAdapter() {
435
436 private ViewerComparator reverseComparator;
437
438 @Override
439 public void widgetSelected(SelectionEvent e) {
440 // Initializes the reverse comparator once.
441 if (reverseComparator == null) {
442 reverseComparator = new ViewerComparator() {
443 @Override
444 public int compare(Viewer viewer, Object e1, Object e2) {
445 return -1 * columnData.getComparator().compare(viewer, e1, e2);
446 }
447 };
448 }
449
450 if (fTreeViewer.getTree().getSortDirection() == SWT.UP
451 || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) {
452 /*
df2b3dbb
VP
453 * Puts the descendant order if the old order was up
454 * or if the selected column has changed.
cfd22ad0
MD
455 */
456 fTreeViewer.setComparator(columnData.getComparator());
457 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
458 } else {
459 /*
460 * Puts the ascendant ordering if the selected
461 * column hasn't changed.
462 */
463 fTreeViewer.setComparator(reverseComparator);
464 fTreeViewer.getTree().setSortDirection(SWT.UP);
465 }
466 fTreeViewer.getTree().setSortColumn(treeColumn.getColumn());
467 }
468 });
469 }
470 treeColumn.setLabelProvider(columnData.getLabelProvider());
471 }
472
df2b3dbb 473 // Handler that will draw the percentages and the bar charts.
cfd22ad0
MD
474 fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
475 @Override
476 public void handleEvent(Event event) {
477 if (columnDataList.get(event.index).getPercentageProvider() != null) {
df2b3dbb 478
cfd22ad0
MD
479 TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData();
480
df2b3dbb
VP
481 // If node is hidden, exit immediately.
482 if (TmfBaseColumnDataProvider.HIDDEN_FOLDER_LEVELS.contains(node.getName())) {
cfd22ad0
MD
483 return;
484 }
485
1904e6a4
ACL
486 // Otherwise, get percentage and draw bar and text if
487 // applicable.
df2b3dbb
VP
488 double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node);
489
490 // The item is selected.
491 if ((event.detail & SWT.SELECTED) > 0) {
1904e6a4
ACL
492 // Draws our own background to avoid overwriting the
493 // bar.
cfd22ad0
MD
494 event.gc.fillRectangle(event.x, event.y, event.width, event.height);
495 event.detail &= ~SWT.SELECTED;
496 }
497
df2b3dbb
VP
498 // Drawing the percentage text
499 // if events are present in top node
500 // and the current node is not the top node
501 // and if is total or partial events column.
502 // If not, exit the method.
503 if (!((event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() || event.index == TmfBaseColumnDataProvider.StatsColumn.PARTIAL.getIndex())
504 && node != node.getTop())) {
505 return;
506 }
507
508 long eventValue = event.index == TmfBaseColumnDataProvider.StatsColumn.TOTAL.getIndex() ?
509 node.getTop().getValues().getTotal() : node.getTop().getValues().getPartial();
510
511 if (eventValue != 0) {
512
513 int oldAlpha = event.gc.getAlpha();
514 Color oldForeground = event.gc.getForeground();
515 Color oldBackground = event.gc.getBackground();
516
517 // Bar to draw
518 if (percentage != 0) {
519 /*
520 * Draws a transparent gradient rectangle from the
521 * color of foreground and background.
522 */
523 int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage);
524 event.gc.setAlpha(64);
525 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE));
526 event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
527 event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true);
528 event.gc.drawRectangle(event.x, event.y, barWidth, event.height);
529
530 // Restore old values
531 event.gc.setBackground(oldBackground);
532 event.gc.setAlpha(oldAlpha);
533 event.detail &= ~SWT.BACKGROUND;
534
535 }
536
537 String percentageText = TmfStatisticsFormatter.toPercentageText(percentage);
538 String absoluteNumberText = TmfStatisticsFormatter.toColumnData(node, TmfBaseColumnDataProvider.StatsColumn.getColumn(event.index));
539
540 if (event.width > event.gc.stringExtent(percentageText).x + event.gc.stringExtent(absoluteNumberText).x) {
541 int textHeight = event.gc.stringExtent(percentageText).y;
542 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
543 event.gc.drawText(percentageText, event.x, event.y + (event.height - textHeight) / 2, true);
544 }
545
546 // Restores old values
547 event.gc.setForeground(oldForeground);
548
549 }
cfd22ad0
MD
550 }
551 }
df2b3dbb 552
cfd22ad0
MD
553 });
554
555 // Initializes the comparator parameters
556 fTreeViewer.setComparator(columnDataList.get(0).getComparator());
557 fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0));
558 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
559 }
560
8b60cb37
MD
561 /**
562 * Initializes the input for the tree viewer.
8b60cb37
MD
563 */
564 protected void initInput() {
565 String treeID = getTreeID();
faa38350 566 TmfStatisticsTreeNode statisticsTreeNode;
36033ff0 567 if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) {
faa38350
PT
568 // The statistics root is already present
569 statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID);
8b60cb37
MD
570
571 // Checks if the trace is already in the statistics tree.
faa38350 572 int numNodeTraces = statisticsTreeNode.getNbChildren();
8b60cb37 573
c14c0757
GB
574 Collection<ITmfTrace> traces = TmfTraceManager.getTraceSet(fTrace);
575 int numTraces = traces.size();
8b60cb37
MD
576
577 if (numTraces == numNodeTraces) {
578 boolean same = true;
579 /*
580 * Checks if the experiment contains the same traces as when
581 * previously selected.
582 */
c14c0757
GB
583 for (ITmfTrace trace : traces) {
584 String traceName = trace.getName();
faa38350 585 if (!statisticsTreeNode.containsChild(traceName)) {
8b60cb37
MD
586 same = false;
587 break;
588 }
589 }
590
591 if (same) {
592 // No need to reload data, all traces are already loaded
faa38350 593 fTreeViewer.setInput(statisticsTreeNode);
8b60cb37
MD
594 return;
595 }
596 // Clears the old content to start over
faa38350 597 statisticsTreeNode.reset();
8b60cb37
MD
598 }
599 } else {
600 // Creates a new tree
faa38350 601 statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData());
8b60cb37
MD
602 }
603
604 // Sets the input to a clean data model
faa38350 605 fTreeViewer.setInput(statisticsTreeNode);
cdf994ef
ACL
606 /* Set a new model for the piecharts and keep a reference */
607 fPieChartViewer.setInput(getPieChartModel());
8b60cb37
MD
608 }
609
cfd22ad0 610 /**
faa38350 611 * Tells if the viewer is listening to a trace.
cfd22ad0 612 *
1c0de632 613 * @param trace
05627bda
MD
614 * The trace that the viewer may be listening
615 * @return true if the viewer is listening to the trace, false otherwise
cfd22ad0 616 */
1c0de632
AM
617 protected boolean isListeningTo(ITmfTrace trace) {
618 if (fProcessAll || trace == fTrace) {
05627bda 619 return true;
cfd22ad0 620 }
05627bda 621 return false;
cfd22ad0
MD
622 }
623
624 /**
faa38350 625 * Called when an trace request has been completed successfully.
cfd22ad0 626 *
05627bda
MD
627 * @param global
628 * Tells if the request is a global or time range (partial)
629 * request.
cfd22ad0 630 */
05627bda 631 protected void modelComplete(boolean global) {
cdf994ef 632 refreshTree();
05627bda 633 waitCursor(false);
cfd22ad0
MD
634 }
635
636 /**
faa38350 637 * Sends the request to the trace for the whole trace
cfd22ad0 638 *
faa38350
PT
639 * @param trace
640 * The trace used to send the request
8b260d9f 641 * @param timeRange
faa38350 642 * The range to request to the trace
cfd22ad0 643 */
faa38350
PT
644 protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) {
645 buildStatisticsTree(trace, timeRange, true);
cfd22ad0
MD
646 }
647
648 /**
faa38350 649 * Sends the time range request from the trace
cfd22ad0 650 *
faa38350
PT
651 * @param trace
652 * The trace used to send the request
8b260d9f 653 * @param timeRange
faa38350 654 * The range to request to the trace
cfd22ad0 655 */
faa38350 656 protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) {
faa38350 657 buildStatisticsTree(trace, timeRange, false);
89c06060
AM
658 }
659
660 /**
df2b3dbb
VP
661 * Requests all the data of the trace to the state system which contains
662 * information about the statistics.
89c06060 663 *
df2b3dbb
VP
664 * Since the viewer may be listening to multiple traces, it may receive an
665 * experiment rather than a single trace. The filtering is done with the
89c06060
AM
666 * method {@link #isListeningTo(String trace)}.
667 *
faa38350
PT
668 * @param trace
669 * The trace for which a request must be done
89c06060
AM
670 * @param timeRange
671 * The time range that will be requested to the state system
672 * @param isGlobal
673 * Tells if the request is for the global event count or the
674 * partial one.
675 */
d6b46913 676 private void buildStatisticsTree(final ITmfTrace trace, final TmfTimeRange timeRange, final boolean isGlobal) {
36033ff0 677 final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
89c06060
AM
678 if (statsData == null) {
679 return;
680 }
681
de83d1ab
MAL
682 Map<ITmfTrace, Job> updateJobs;
683 if (isGlobal) {
684 updateJobs = fUpdateJobsGlobal;
de83d1ab
MAL
685 } else {
686 updateJobs = fUpdateJobsPartial;
de83d1ab 687 }
89c06060 688
1d83ed07 689 for (ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
de83d1ab
MAL
690 if (!isListeningTo(aTrace)) {
691 continue;
692 }
d6b46913 693
de83d1ab 694 /* Retrieve the statistics object */
b8585c7c 695 final TmfStatisticsModule statsMod = TmfTraceUtils.getAnalysisModuleOfClass(aTrace, TmfStatisticsModule.class, TmfStatisticsModule.ID);
de83d1ab
MAL
696 if (statsMod == null) {
697 /* No statistics module available for this trace */
698 continue;
699 }
55954069 700
de83d1ab
MAL
701 Job job = updateJobs.get(aTrace);
702 if (job == null) {
cdf994ef 703 job = new StatisticsUpdateJob("Statistics update", aTrace, isGlobal, timeRange, statsMod, this); //$NON-NLS-1$
de83d1ab
MAL
704 updateJobs.put(aTrace, job);
705 job.setSystem(true);
706 job.schedule();
89c06060 707 }
89c06060 708 }
cfd22ad0
MD
709 }
710
711 /**
05627bda 712 * Resets the number of events within the time range
cfd22ad0 713 */
05627bda 714 protected void resetTimeRangeValue() {
36033ff0 715 TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
05627bda
MD
716 if (treeModelRoot != null && treeModelRoot.hasChildren()) {
717 treeModelRoot.resetTimeRangeValue();
718 }
cfd22ad0
MD
719 }
720
721 /**
df2b3dbb
VP
722 * When the trace is loading the cursor will be different so the user knows
723 * that the processing is not finished yet.
05627bda
MD
724 *
725 * Calls to this method are stacked.
cfd22ad0 726 *
05627bda 727 * @param waitRequested
cfd22ad0 728 * Indicates if we need to show the waiting cursor, or the
05627bda 729 * default one.
cfd22ad0 730 */
05627bda 731 protected void waitCursor(final boolean waitRequested) {
cfd22ad0
MD
732 if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) {
733 return;
734 }
735
05627bda 736 boolean needsUpdate = false;
cfd22ad0 737 Display display = fTreeViewer.getControl().getDisplay();
05627bda
MD
738 if (waitRequested) {
739 fWaitCursorCount++;
740 if (fWaitCursor == null) { // The cursor hasn't been initialized yet
741 fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT);
742 }
743 if (fWaitCursorCount == 1) { // The cursor is not in waiting mode
744 needsUpdate = true;
745 }
746 } else {
747 if (fWaitCursorCount > 0) { // The cursor is in waiting mode
748 fWaitCursorCount--;
749 if (fWaitCursorCount == 0) { // No more reason to wait
750 // Put back the default cursor
751 needsUpdate = true;
752 }
753 }
cfd22ad0
MD
754 }
755
05627bda
MD
756 if (needsUpdate) {
757 // Performs the updates on the UI thread
758 display.asyncExec(new Runnable() {
759 @Override
760 public void run() {
761 if ((fTreeViewer != null)
762 && (!fTreeViewer.getTree().isDisposed())) {
763 Cursor cursor = null; // indicates default
764 if (waitRequested) {
765 cursor = fWaitCursor;
766 }
767 fTreeViewer.getControl().setCursor(cursor);
cfd22ad0 768 }
cfd22ad0 769 }
05627bda
MD
770 });
771 }
cfd22ad0 772 }
cdf994ef
ACL
773
774 /**
1904e6a4
ACL
775 * @param isGlobal
776 * if the job to remove is global or partial
777 * @param jobTrace
778 * The trace
cdf994ef
ACL
779 */
780 void removeFromJobs(boolean isGlobal, ITmfTrace jobTrace) {
781 Map<ITmfTrace, Job> updateJobs = isGlobal ? fUpdateJobsGlobal : fUpdateJobsPartial;
782 Job job = updateJobs.remove(jobTrace);
783 if (job != null) {
784 job.cancel();
785 }
786 }
cfd22ad0 787}
This page took 0.143699 seconds and 5 git commands to generate.