1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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
10 * France Lapointe Nguyen - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.ui
.views
.latency
;
15 import org
.eclipse
.jdt
.annotation
.Nullable
;
16 import org
.eclipse
.jface
.action
.Action
;
17 import org
.eclipse
.jface
.action
.IAction
;
18 import org
.eclipse
.jface
.action
.IMenuManager
;
19 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
20 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
21 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
22 import org
.eclipse
.jface
.viewers
.TableViewer
;
23 import org
.eclipse
.swt
.events
.SelectionAdapter
;
24 import org
.eclipse
.swt
.events
.SelectionEvent
;
25 import org
.eclipse
.swt
.widgets
.Display
;
26 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.latency
.LatencyAnalysis
;
27 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.latency
.LatencyAnalysisListener
;
28 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
29 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
30 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
31 import org
.eclipse
.tracecompass
.segmentstore
.core
.SegmentComparators
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSelectionRangeUpdatedSignal
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalManager
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceClosedSignal
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfNanoTimestamp
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestampFormat
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceUtils
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.viewers
.table
.TmfSimpleTableViewer
;
47 * Displays the latency analysis data in a column table
49 * @author France Lapointe Nguyen
51 public class LatencyTableViewer
extends TmfSimpleTableViewer
{
53 // ------------------------------------------------------------------------
55 // ------------------------------------------------------------------------
59 * Abstract class for the column label provider for the latency analysis
62 private abstract class LatencyTableColumnLabelProvider
extends ColumnLabelProvider
{
65 public String
getText(@Nullable Object input
) {
66 if (!(input
instanceof ISegment
)) {
67 /* Doubles as a null check */
68 return ""; //$NON-NLS-1$
70 return getTextFoITimeRange((ISegment
) input
);
73 public abstract String
getTextFoITimeRange(ISegment input
);
77 * Listener to update the model with the latency analysis results once the
78 * latency analysis is fully completed
80 private final class LatencyListener
implements LatencyAnalysisListener
{
82 public void onComplete(LatencyAnalysis activeAnalysis
, ISegmentStore
<ISegment
> data
) {
83 // Check if the active trace was changed while the analysis was
85 if (activeAnalysis
.equals(fAnalysisModule
)) {
92 * Listener to select a range in other viewers when a cell of the latency
93 * table view is selected
95 private class LatencyTableSelectionListener
extends SelectionAdapter
{
97 public void widgetSelected(@Nullable SelectionEvent e
) {
98 ISegment selectedSegment
= ((ISegment
) NonNullUtils
.checkNotNull(e
).item
.getData());
99 ITmfTimestamp start
= new TmfNanoTimestamp(selectedSegment
.getStart());
100 ITmfTimestamp end
= new TmfNanoTimestamp(selectedSegment
.getEnd());
101 TmfSignalManager
.dispatchSignal(new TmfSelectionRangeUpdatedSignal(LatencyTableViewer
.this, start
, end
));
106 * Current latency analysis module
108 private @Nullable LatencyAnalysis fAnalysisModule
= null;
111 * Latency analysis completion listener
113 private LatencyListener fListener
;
115 // ------------------------------------------------------------------------
117 // ------------------------------------------------------------------------
123 * Table viewer of the view
125 public LatencyTableViewer(TableViewer tableViewer
) {
127 // Sort order of the content provider is by start time by default
128 getTableViewer().setContentProvider(new LatencyContentProvider());
129 ITmfTrace trace
= TmfTraceManager
.getInstance().getActiveTrace();
131 fAnalysisModule
= TmfTraceUtils
.getAnalysisModuleOfClass(trace
, LatencyAnalysis
.class, LatencyAnalysis
.ID
);
134 getTableViewer().getTable().addSelectionListener(new LatencyTableSelectionListener());
135 fListener
= new LatencyListener();
138 // ------------------------------------------------------------------------
140 // ------------------------------------------------------------------------
143 * Create columns for start time, end time and duration
145 private void createColumns() {
146 createColumn(Messages
.LatencyTableViewer_startTime
, new LatencyTableColumnLabelProvider() {
148 public String
getTextFoITimeRange(ISegment input
) {
149 return NonNullUtils
.nullToEmptyString(TmfTimestampFormat
.getDefaulTimeFormat().format(input
.getStart()));
151 }, SegmentComparators
.INTERVAL_START_COMPARATOR
);
153 createColumn(Messages
.LatencyTableViewer_endTime
, new LatencyTableColumnLabelProvider() {
155 public String
getTextFoITimeRange(ISegment input
) {
156 return NonNullUtils
.nullToEmptyString(TmfTimestampFormat
.getDefaulTimeFormat().format(input
.getEnd()));
158 }, SegmentComparators
.INTERVAL_END_COMPARATOR
);
160 createColumn(Messages
.LatencyTableViewer_duration
, new LatencyTableColumnLabelProvider() {
162 public String
getTextFoITimeRange(ISegment input
) {
163 return NonNullUtils
.nullToEmptyString(Long
.toString(input
.getLength()));
165 }, SegmentComparators
.INTERVAL_LENGTH_COMPARATOR
);
169 * Update the data in the table viewer
174 public void updateModel(final @Nullable ISegmentStore
<ISegment
> dataInput
) {
175 final TableViewer tableViewer
= getTableViewer();
176 Display
.getDefault().asyncExec(new Runnable() {
179 if (!tableViewer
.getTable().isDisposed()) {
180 // Go to the top of the table
181 tableViewer
.getTable().setTopIndex(0);
182 // Reset selected row
183 tableViewer
.setSelection(StructuredSelection
.EMPTY
);
184 if (dataInput
== null) {
185 tableViewer
.setInput(null);
186 tableViewer
.setItemCount(0);
189 tableViewer
.setInput(dataInput
);
190 LatencyContentProvider latencyContentProvider
= (LatencyContentProvider
) getTableViewer().getContentProvider();
191 tableViewer
.setItemCount(latencyContentProvider
.getSegmentCount());
198 * Set the data into the viewer. Will update model is analysis is completed
199 * or run analysis if not completed
202 * Latency analysis module
204 public void setData(@Nullable LatencyAnalysis analysis
) {
205 // Set the current latency analysis module
206 fAnalysisModule
= analysis
;
207 if (analysis
== null) {
211 ISegmentStore
<ISegment
> results
= analysis
.getResults();
212 // If results are not null, then analysis is completed and model can be
214 if (results
!= null) {
215 updateModel(results
);
218 // If results are null, then add completion listener and run analysis
220 analysis
.addListener(fListener
);
225 protected void appendToTablePopupMenu(IMenuManager manager
, IStructuredSelection sel
) {
226 final ISegment segment
= (ISegment
) sel
.getFirstElement();
228 IAction gotoStartTime
= new Action(Messages
.LatencyView_goToStartEvent
) {
231 broadcast(new TmfSelectionRangeUpdatedSignal(LatencyTableViewer
.this, new TmfNanoTimestamp(segment
.getStart())));
235 IAction gotoEndTime
= new Action(Messages
.LatencyView_goToEndEvent
) {
238 broadcast(new TmfSelectionRangeUpdatedSignal(LatencyTableViewer
.this, new TmfNanoTimestamp(segment
.getEnd())));
242 manager
.add(gotoStartTime
);
243 manager
.add(gotoEndTime
);
246 // ------------------------------------------------------------------------
248 // ------------------------------------------------------------------------
251 * Get current latency analysis module
253 * @return current latency analysis module
255 public @Nullable LatencyAnalysis
getAnalysisModule() {
256 return fAnalysisModule
;
259 // ------------------------------------------------------------------------
261 // ------------------------------------------------------------------------
264 * Trace selected handler
267 * Different opened trace (on which latency analysis as already
268 * been performed) has been selected
271 public void traceSelected(TmfTraceSelectedSignal signal
) {
272 ITmfTrace trace
= signal
.getTrace();
274 setData(TmfTraceUtils
.getAnalysisModuleOfClass(trace
, LatencyAnalysis
.class, LatencyAnalysis
.ID
));
279 * Trace opened handler
282 * New trace (on which latency analysis has not been performed)
286 public void traceOpened(TmfTraceOpenedSignal signal
) {
287 ITmfTrace trace
= signal
.getTrace();
289 setData(TmfTraceUtils
.getAnalysisModuleOfClass(trace
, LatencyAnalysis
.class, LatencyAnalysis
.ID
));
294 * Trace closed handler
297 * Last opened trace was closed
300 public void traceClosed(TmfTraceClosedSignal signal
) {
301 // Check if there is no more opened trace
302 if (TmfTraceManager
.getInstance().getActiveTrace() == null) {
303 if (!getTableViewer().getTable().isDisposed()) {
304 getTableViewer().setInput(null);