lttng: Fix AttributeNotFoundException when dealing with event before state dump
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.ui / src / org / eclipse / tracecompass / analysis / timing / ui / views / segmentstore / AbstractSegmentStoreTableViewer.java
CommitLineData
b9fff7ad
BH
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 * Bernd Hufmann - Move abstract class to TMF
12 *******************************************************************************/
13
14package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore;
15
16import org.eclipse.jdt.annotation.Nullable;
17import org.eclipse.jface.action.Action;
18import org.eclipse.jface.action.IAction;
19import org.eclipse.jface.action.IMenuManager;
20import org.eclipse.jface.viewers.ColumnLabelProvider;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.jface.viewers.StructuredSelection;
23import org.eclipse.jface.viewers.TableViewer;
24import org.eclipse.swt.events.SelectionAdapter;
25import org.eclipse.swt.events.SelectionEvent;
26import org.eclipse.swt.widgets.Display;
27import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
28import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
29import org.eclipse.tracecompass.common.core.NonNullUtils;
30import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.Messages;
31import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.SegmentStoreContentProvider;
32import org.eclipse.tracecompass.segmentstore.core.ISegment;
33import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
34import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
35import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
36import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
37import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
38import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
39import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
40import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
41import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
42import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
43import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
44import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
45import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
46import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
47import org.eclipse.tracecompass.tmf.ui.viewers.table.TmfSimpleTableViewer;
48
49/**
50 * Displays the segment store analysis data in a column table
51 *
52 * @author France Lapointe Nguyen
53 * @since 2.0
54 */
55public abstract class AbstractSegmentStoreTableViewer extends TmfSimpleTableViewer {
56
57 // ------------------------------------------------------------------------
58 // Attributes
59 // ------------------------------------------------------------------------
60
61 /**
62 * Abstract class for the column label provider for the segment store
63 * analysis table viewer
64 */
65 private abstract class SegmentStoreTableColumnLabelProvider extends ColumnLabelProvider {
66
67 @Override
68 public String getText(@Nullable Object input) {
69 if (!(input instanceof ISegment)) {
70 /* Doubles as a null check */
71 return ""; //$NON-NLS-1$
72 }
73 return getTextForSegment((ISegment) input);
74 }
75
76 public abstract String getTextForSegment(ISegment input);
77 }
78
79 /**
80 * Listener to update the model with the segment store analysis results
81 * once the analysis is fully completed
82 */
83 private final class AnalysisProgressListener implements IAnalysisProgressListener {
84 @Override
85 public void onComplete(AbstractSegmentStoreAnalysisModule activeAnalysis, ISegmentStore<ISegment> data) {
86 // Check if the active trace was changed while the analysis was
87 // running
88 if (activeAnalysis.equals(fAnalysisModule)) {
89 updateModel(data);
90 }
91 }
92 }
93
94 /**
95 * Listener to select a range in other viewers when a cell of the segment
96 * store table view is selected
97 */
98 private class TableSelectionListener extends SelectionAdapter {
99 @Override
100 public void widgetSelected(@Nullable SelectionEvent e) {
101 ISegment selectedSegment = ((ISegment) NonNullUtils.checkNotNull(e).item.getData());
102 ITmfTimestamp start = new TmfNanoTimestamp(selectedSegment.getStart());
103 ITmfTimestamp end = new TmfNanoTimestamp(selectedSegment.getEnd());
104 TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(AbstractSegmentStoreTableViewer.this, start, end));
105 }
106 }
107
108 /**
109 * Current segment store analysis module
110 */
111 private @Nullable AbstractSegmentStoreAnalysisModule fAnalysisModule = null;
112
113 /**
114 * Analysis progress listener
115 */
116 private AnalysisProgressListener fListener;
117
118 /**
119 * Flag to create columns once
120 */
121 boolean fColumnsCreated = false;
122
123 // ------------------------------------------------------------------------
124 // Constructor
125 // ------------------------------------------------------------------------
126
127 /**
128 * Constructor
129 *
130 * @param tableViewer
131 * Table viewer of the view
132 */
133 public AbstractSegmentStoreTableViewer(TableViewer tableViewer) {
134 super(tableViewer);
135 // Sort order of the content provider is by start time by default
136 getTableViewer().setContentProvider(new SegmentStoreContentProvider());
137 ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
138 if (trace != null) {
139 fAnalysisModule = getSegmentStoreAnalysisModule(trace);
140 }
141 createColumns();
142 getTableViewer().getTable().addSelectionListener(new TableSelectionListener());
143 fListener = new AnalysisProgressListener();
144 }
145
146 // ------------------------------------------------------------------------
147 // Operations
148 // ------------------------------------------------------------------------
149
150 /**
151 * Create default columns for start time, end time and duration
152 */
153 private void createColumns() {
154 createColumn(Messages.SegmentStoreTableViewer_startTime, new SegmentStoreTableColumnLabelProvider() {
155 @Override
156 public String getTextForSegment(ISegment input) {
157 return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getStart()));
158 }
159 }, SegmentComparators.INTERVAL_START_COMPARATOR);
160
161 createColumn(Messages.SegmentStoreTableViewer_endTime, new SegmentStoreTableColumnLabelProvider() {
162 @Override
163 public String getTextForSegment(ISegment input) {
164 return NonNullUtils.nullToEmptyString(TmfTimestampFormat.getDefaulTimeFormat().format(input.getEnd()));
165 }
166 }, SegmentComparators.INTERVAL_END_COMPARATOR);
167
168 createColumn(Messages.SegmentStoreTableViewer_duration, new SegmentStoreTableColumnLabelProvider() {
169 @Override
170 public String getTextForSegment(ISegment input) {
171 return NonNullUtils.nullToEmptyString(Long.toString(input.getLength()));
172 }
173 }, SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
174 }
175
176 /**
177 * Create columns specific to the analysis
178 */
179 protected void createAnalysisColumns() {
180 if (!fColumnsCreated) {
181 AbstractSegmentStoreAnalysisModule analysis = getAnalysisModule();
182 if (analysis != null) {
183 for (final ISegmentAspect aspect : analysis.getSegmentAspects()) {
184 createColumn(aspect.getName(), new SegmentStoreTableColumnLabelProvider() {
185 @Override
186 public String getTextForSegment(ISegment input) {
187 return NonNullUtils.nullToEmptyString(aspect.resolve(input));
188 }
189 },
6ad9d1cb 190 aspect.getComparator());
b9fff7ad
BH
191 }
192 }
193 fColumnsCreated = true;
194 }
195 }
196
197 /**
198 * Update the data in the table viewer
199 *
200 * @param dataInput
201 * New data input
202 */
203 public void updateModel(final @Nullable ISegmentStore<ISegment> dataInput) {
204 final TableViewer tableViewer = getTableViewer();
205 Display.getDefault().asyncExec(new Runnable() {
206 @Override
207 public void run() {
208 if (!tableViewer.getTable().isDisposed()) {
209 // Go to the top of the table
210 tableViewer.getTable().setTopIndex(0);
211 // Reset selected row
212 tableViewer.setSelection(StructuredSelection.EMPTY);
213 if (dataInput == null) {
214 tableViewer.setInput(null);
215 tableViewer.setItemCount(0);
216 return;
217 }
218 tableViewer.setInput(dataInput);
219 SegmentStoreContentProvider contentProvider = (SegmentStoreContentProvider) getTableViewer().getContentProvider();
220 tableViewer.setItemCount(contentProvider.getSegmentCount());
221 }
222 }
223 });
224 }
225
226 /**
227 * Set the data into the viewer. Will update model is analysis is completed
228 * or run analysis if not completed
229 *
230 * @param analysis
231 * segment store analysis module
232 */
233 public void setData(@Nullable AbstractSegmentStoreAnalysisModule analysis) {
234 // Set the current segment store analysis module
235 fAnalysisModule = analysis;
236 if (analysis == null) {
237 updateModel(null);
238 return;
239 }
240
241 createAnalysisColumns();
242
243 ISegmentStore<ISegment> results = analysis.getResults();
244 // If results are not null, then analysis is completed and model can be
245 // updated
246 if (results != null) {
247 updateModel(results);
248 return;
249 }
250 // If results are null, then add completion listener and run analysis
251 updateModel(null);
252 analysis.addListener(fListener);
253 analysis.schedule();
254 }
255
256 /**
257 * Returns the segment store analysis module
258 * @param trace
259 * The trace to consider
260 * @return the segment store analysis module
261 */
262 protected @Nullable abstract AbstractSegmentStoreAnalysisModule getSegmentStoreAnalysisModule(ITmfTrace trace);
263
264 @Override
265 protected void appendToTablePopupMenu(IMenuManager manager, IStructuredSelection sel) {
266 final ISegment segment = (ISegment) sel.getFirstElement();
8ef16fe6
BH
267 if (segment != null) {
268 IAction gotoStartTime = new Action(Messages.SegmentStoreTableViewer_goToStartEvent) {
269 @Override
270 public void run() {
271 broadcast(new TmfSelectionRangeUpdatedSignal(AbstractSegmentStoreTableViewer.this, new TmfNanoTimestamp(segment.getStart())));
272 }
273 };
b9fff7ad 274
8ef16fe6
BH
275 IAction gotoEndTime = new Action(Messages.SegmentStoreTableViewer_goToEndEvent) {
276 @Override
277 public void run() {
278 broadcast(new TmfSelectionRangeUpdatedSignal(AbstractSegmentStoreTableViewer.this, new TmfNanoTimestamp(segment.getEnd())));
279 }
280 };
b9fff7ad 281
8ef16fe6
BH
282 manager.add(gotoStartTime);
283 manager.add(gotoEndTime);
284 }
b9fff7ad
BH
285 }
286
287 // ------------------------------------------------------------------------
288 // Getters
289 // ------------------------------------------------------------------------
290
291 /**
292 * Get current segment store analysis module
293 *
294 * @return current segment store analysis module
295 */
296 public @Nullable AbstractSegmentStoreAnalysisModule getAnalysisModule() {
297 return fAnalysisModule;
298 }
299
300 // ------------------------------------------------------------------------
301 // Signal handlers
302 // ------------------------------------------------------------------------
303
304 /**
305 * Trace selected handler
306 *
307 * @param signal
308 * Different opened trace (on which segment store analysis as
309 * already been performed) has been selected
310 */
311 @TmfSignalHandler
312 public void traceSelected(TmfTraceSelectedSignal signal) {
313 ITmfTrace trace = signal.getTrace();
314 if (trace != null) {
315 setData(getSegmentStoreAnalysisModule(trace));
316 }
317 }
318
319 /**
320 * Trace opened handler
321 *
322 * @param signal
323 * New trace (on which segment store analysis has not been
324 * performed) is opened
325 */
326 @TmfSignalHandler
327 public void traceOpened(TmfTraceOpenedSignal signal) {
328 ITmfTrace trace = signal.getTrace();
329 if (trace != null) {
330 setData(getSegmentStoreAnalysisModule(trace));
331 }
332 }
333
334 /**
335 * Trace closed handler
336 *
337 * @param signal
338 * Last opened trace was closed
339 */
340 @TmfSignalHandler
341 public void traceClosed(TmfTraceClosedSignal signal) {
342 // Check if there is no more opened trace
343 if (TmfTraceManager.getInstance().getActiveTrace() == null) {
344 if (!getTableViewer().getTable().isDisposed()) {
345 getTableViewer().setInput(null);
346 refresh();
347 }
76be6c00
BH
348
349 AbstractSegmentStoreAnalysisModule analysis = getAnalysisModule();
350 if ((analysis != null)) {
351 analysis.removeListener(fListener);
352 }
b9fff7ad
BH
353 }
354 }
355}
This page took 0.052027 seconds and 5 git commands to generate.