analysis: introduce latency table view
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.ui / src / org / eclipse / tracecompass / internal / analysis / os / linux / ui / views / latency / LatencyTableViewer.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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 * France Lapointe Nguyen - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency;
14
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.eclipse.jface.viewers.ColumnLabelProvider;
17 import org.eclipse.jface.viewers.StructuredSelection;
18 import org.eclipse.jface.viewers.TableViewer;
19 import org.eclipse.swt.events.SelectionAdapter;
20 import org.eclipse.swt.events.SelectionEvent;
21 import org.eclipse.swt.widgets.Display;
22 import org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysis;
23 import org.eclipse.tracecompass.analysis.os.linux.core.latency.LatencyAnalysisListener;
24 import org.eclipse.tracecompass.common.core.NonNullUtils;
25 import org.eclipse.tracecompass.segmentstore.core.ISegment;
26 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
27 import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
28 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
29 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
30 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
31 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
32 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
33 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
34 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
35 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
36 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
37 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
38 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
39 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
40 import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
41
42 /**
43 * Displays the latency analysis data in a column table
44 *
45 * @author France Lapointe Nguyen
46 */
47 public class LatencyTableViewer extends TmfSimpleTableViewer {
48
49 // ------------------------------------------------------------------------
50 // Attributes
51 // ------------------------------------------------------------------------
52
53 /**
54 * Abstract class for the column label provider for the latency analysis
55 * table viewer
56 */
57 private abstract class LatencyTableColumnLabelProvider extends ColumnLabelProvider {
58
59 @Override
60 public String getText(@Nullable Object input) {
61 if (!(input instanceof ISegment)) {
62 /* Doubles as a null check */
63 return ""; //$NON-NLS-1$
64 }
65 return getTextFoITimeRange((ISegment) input);
66 }
67
68 public abstract String getTextFoITimeRange(ISegment input);
69 }
70
71 /**
72 * Listener to update the model with the latency analysis results once the
73 * latency analysis is fully completed
74 */
75 private final class LatencyListener implements LatencyAnalysisListener {
76 @Override
77 public void onComplete(LatencyAnalysis activeAnalysis, ISegmentStore<ISegment> data) {
78 // Check if the active trace was changed while the analysis was
79 // running
80 if (activeAnalysis.equals(fAnalysisModule)) {
81 updateModel(data);
82 }
83 }
84 }
85
86 /**
87 * Listener to select a range in other viewers when a cell of the latency
88 * table view is selected
89 */
90 private class LatencyTableSelectionListener extends SelectionAdapter {
91 @Override
92 public void widgetSelected(@Nullable SelectionEvent e) {
93 ISegment selectedSegment = ((ISegment) NonNullUtils.checkNotNull(e).item.getData());
94 ITmfTimestamp start = new TmfNanoTimestamp(selectedSegment.getStart());
95 ITmfTimestamp end = new TmfNanoTimestamp(selectedSegment.getEnd());
96 TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(LatencyTableViewer.this, start, end));
97 }
98 }
99
100 /**
101 * Current latency analysis module
102 */
103 private @Nullable LatencyAnalysis fAnalysisModule = null;
104
105 /**
106 * Latency analysis completion listener
107 */
108 private LatencyListener fListener;
109
110 // ------------------------------------------------------------------------
111 // Constructor
112 // ------------------------------------------------------------------------
113
114 /**
115 * Constructor
116 *
117 * @param tableViewer
118 * Table viewer of the view
119 */
120 public LatencyTableViewer(TableViewer tableViewer) {
121 super(tableViewer);
122 // Sort order of the content provider is by start time by default
123 getTableViewer().setContentProvider(new LatencyContentProvider());
124 ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
125 if (trace != null) {
126 fAnalysisModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID);
127 }
128 createColumns();
129 getTableViewer().getTable().addSelectionListener(new LatencyTableSelectionListener());
130 fListener = new LatencyListener();
131 }
132
133 // ------------------------------------------------------------------------
134 // Operations
135 // ------------------------------------------------------------------------
136
137 /**
138 * Create columns for start time, end time and duration
139 */
140 private void createColumns() {
141 createColumn(Messages.LatencyTableViewer_startTime, new LatencyTableColumnLabelProvider() {
142 @Override
143 public String getTextFoITimeRange(ISegment input) {
144 return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getStart()));
145 }
146 }, SegmentComparators.INTERVAL_START_COMPARATOR);
147
148 createColumn(Messages.LatencyTableViewer_endTime, new LatencyTableColumnLabelProvider() {
149 @Override
150 public String getTextFoITimeRange(ISegment input) {
151 return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getEnd()));
152 }
153 }, SegmentComparators.INTERVAL_END_COMPARATOR);
154
155 createColumn(Messages.LatencyTableViewer_duration, new LatencyTableColumnLabelProvider() {
156 @Override
157 public String getTextFoITimeRange(ISegment input) {
158 return NonNullUtils.nullToEmptyString(Long.toString(input.getLength()));
159 }
160 }, SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
161 }
162
163 /**
164 * Update the data in the table viewer
165 *
166 * @param dataInput
167 * New data input
168 */
169 public void updateModel(final @Nullable ISegmentStore<ISegment> dataInput) {
170 final TableViewer tableViewer = getTableViewer();
171 Display.getDefault().asyncExec(new Runnable() {
172 @Override
173 public void run() {
174 if (!tableViewer.getTable().isDisposed()) {
175 // Go to the top of the table
176 tableViewer.getTable().setTopIndex(0);
177 // Reset selected row
178 tableViewer.setSelection(StructuredSelection.EMPTY);
179 if (dataInput == null) {
180 tableViewer.setInput(null);
181 tableViewer.setItemCount(0);
182 return;
183 }
184 tableViewer.setInput(dataInput);
185 LatencyContentProvider latencyContentProvider = (LatencyContentProvider) getTableViewer().getContentProvider();
186 tableViewer.setItemCount(latencyContentProvider.getSegmentCount());
187 }
188 }
189 });
190 }
191
192 /**
193 * Set the data into the viewer. Will update model is analysis is completed
194 * or run analysis if not completed
195 *
196 * @param analysis
197 * Latency analysis module
198 */
199 public void setData(@Nullable LatencyAnalysis analysis) {
200 // Set the current latency analysis module
201 fAnalysisModule = analysis;
202 if (analysis == null) {
203 updateModel(null);
204 return;
205 }
206 ISegmentStore<ISegment> results = analysis.getResults();
207 // If results are not null, then analysis is completed and model can be
208 // updated
209 if (results != null) {
210 updateModel(results);
211 return;
212 }
213 // If results are null, then add completion listener and run analysis
214 updateModel(null);
215 analysis.addListener(fListener);
216 analysis.schedule();
217 }
218
219 // ------------------------------------------------------------------------
220 // Getters
221 // ------------------------------------------------------------------------
222
223 /**
224 * Get current latency analysis module
225 *
226 * @return current latency analysis module
227 */
228 public @Nullable LatencyAnalysis getAnalysisModule() {
229 return fAnalysisModule;
230 }
231
232 // ------------------------------------------------------------------------
233 // Signal handlers
234 // ------------------------------------------------------------------------
235
236 /**
237 * Trace selected handler
238 *
239 * @param signal
240 * Different opened trace (on which latency analysis as already
241 * been performed) has been selected
242 */
243 @TmfSignalHandler
244 public void traceSelected(TmfTraceSelectedSignal signal) {
245 ITmfTrace trace = signal.getTrace();
246 if (trace != null) {
247 setData(TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID));
248 }
249 }
250
251 /**
252 * Trace opened handler
253 *
254 * @param signal
255 * New trace (on which latency analysis has not been performed)
256 * is opened
257 */
258 @TmfSignalHandler
259 public void traceOpened(TmfTraceOpenedSignal signal) {
260 ITmfTrace trace = signal.getTrace();
261 if (trace != null) {
262 setData(TmfTraceUtils.getAnalysisModuleOfClass(trace, LatencyAnalysis.class, LatencyAnalysis.ID));
263 }
264 }
265
266 /**
267 * Trace closed handler
268 *
269 * @param signal
270 * Last opened trace was closed
271 */
272 @TmfSignalHandler
273 public void traceClosed(TmfTraceClosedSignal signal) {
274 // Check if there is no more opened trace
275 if (TmfTraceManager.getInstance().getActiveTrace() == null) {
276 if (!getTableViewer().getTable().isDisposed()) {
277 getTableViewer().setInput(null);
278 refresh();
279 }
280 }
281 }
282 }
This page took 0.038044 seconds and 5 git commands to generate.