tmf: display name of custom parser in properties view
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.pcap.ui / src / org / eclipse / linuxtools / internal / tmf / pcap / ui / stream / StreamListView.java
CommitLineData
b6eb4dce
VP
1/*******************************************************************************
2 * Copyright (c) 2014 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 * Vincent Perot - Initial API and implementation
11 *******************************************************************************/
12
93d1d135 13package org.eclipse.linuxtools.internal.tmf.pcap.ui.stream;
b6eb4dce
VP
14
15import java.util.ArrayList;
16import java.util.HashMap;
17import java.util.List;
18import java.util.Map;
19
20import org.eclipse.jdt.annotation.NonNull;
21import org.eclipse.jdt.annotation.Nullable;
93d1d135
AM
22import org.eclipse.linuxtools.internal.tmf.pcap.core.analysis.StreamListAnalysis;
23import org.eclipse.linuxtools.internal.tmf.pcap.core.event.PcapEvent;
24import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStream;
25import org.eclipse.linuxtools.internal.tmf.pcap.core.event.TmfPacketStreamBuilder;
26import org.eclipse.linuxtools.internal.tmf.pcap.core.protocol.TmfProtocol;
27import org.eclipse.linuxtools.internal.tmf.pcap.core.signal.TmfPacketStreamSelectedSignal;
28import org.eclipse.linuxtools.internal.tmf.pcap.core.trace.PcapTrace;
b6eb4dce
VP
29import org.eclipse.linuxtools.internal.tmf.pcap.ui.Activator;
30import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode;
31import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode;
32import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterContainsNode;
33import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode;
34import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterOrNode;
35import org.eclipse.linuxtools.tmf.core.signal.TmfSignal;
36import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
37import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
38import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
39import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
40import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
41import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
b6eb4dce
VP
42import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
43import org.eclipse.linuxtools.tmf.ui.views.TmfView;
44import org.eclipse.linuxtools.tmf.ui.views.filter.FilterManager;
45import org.eclipse.linuxtools.tmf.ui.views.filter.FilterView;
46import org.eclipse.swt.SWT;
47import org.eclipse.swt.custom.CTabFolder;
48import org.eclipse.swt.custom.CTabItem;
49import org.eclipse.swt.events.SelectionAdapter;
50import org.eclipse.swt.events.SelectionEvent;
51import org.eclipse.swt.widgets.Composite;
52import org.eclipse.swt.widgets.Display;
53import org.eclipse.swt.widgets.Event;
54import org.eclipse.swt.widgets.Listener;
55import org.eclipse.swt.widgets.Menu;
56import org.eclipse.swt.widgets.MenuItem;
57import org.eclipse.swt.widgets.Table;
58import org.eclipse.swt.widgets.TableColumn;
59import org.eclipse.swt.widgets.TableItem;
60import org.eclipse.ui.IViewPart;
61import org.eclipse.ui.IWorkbench;
62import org.eclipse.ui.IWorkbenchPage;
63import org.eclipse.ui.PartInitException;
64import org.eclipse.ui.PlatformUI;
65
66/**
67 * Class that represents the Stream List View. Such a view lists all the
68 * available streams from the current experiment. <br>
69 * <br>
70 * TODO Switch to TmfUiRefreshHandler once the behavior is fixed
71 *
72 * FIXME analysis is leaking ressource. Someone I will not name told me not to worry about it since
73 * AnalysisModule will not be autocloseable later.
74 *
75 * @author Vincent Perot
76 */
77public class StreamListView extends TmfView {
78
79 /**
80 * The Stream List View ID.
81 */
82 public static final String ID = "org.eclipse.linuxtools.tmf.pcap.ui.view.stream.list"; //$NON-NLS-1$
83
84 private static final String[] COLUMN_NAMES =
85 { Messages.StreamListView_ID,
86 Messages.StreamListView_EndpointA,
87 Messages.StreamListView_EndpointB,
88 Messages.StreamListView_TotalPackets,
89 Messages.StreamListView_TotalBytes,
90 Messages.StreamListView_PacketsAtoB,
91 Messages.StreamListView_BytesAtoB,
92 Messages.StreamListView_PacketsBtoA,
93 Messages.StreamListView_BytesBtoA,
94 Messages.StreamListView_StartTime,
95 Messages.StreamListView_StopTime,
96 Messages.StreamListView_Duration,
97 Messages.StreamListView_BPSAtoB,
98 Messages.StreamListView_BPSBtoA
99 };
100
101 private static final int[] COLUMN_SIZES =
102 { 75,
103 350,
104 350,
105 110,
106 110,
107 110,
108 110,
109 110,
110 110,
111 180,
112 180,
113 110,
114 110,
115 110 };
116
117 private static final String KEY_PROTOCOL = "$protocol$"; //$NON-NLS-1$
118 private static final String KEY_STREAM = "$stream$"; //$NON-NLS-1$
119
120 private static final String EMPTY_STRING = ""; //$NON-NLS-1$
121
122 private static final long WAIT_TIME = 1000;
123
124 private @Nullable CTabFolder fTabFolder;
125 private @Nullable Map<TmfProtocol, Table> fTableMap;
126
127 private @Nullable TmfPacketStream fCurrentStream;
128 private @Nullable ITmfTrace fCurrentTrace;
129
130 private volatile boolean fStopThread;
131
132 /**
133 * Constructor of the StreamListView class.
134 */
135 public StreamListView() {
136 super(ID);
137 }
138
139 /**
140 * Handler called when an trace is opened.
141 *
142 * @param signal
143 * Contains the information about the selection.
144 */
145 @TmfSignalHandler
146 public void traceOpened(TmfTraceOpenedSignal signal) {
147 fCurrentTrace = signal.getTrace();
148 resetView();
149 queryAnalysis();
150 }
151
152 /**
153 * Handler called when an trace is closed. Checks if the trace is the
154 * current trace and update the view accordingly.
155 *
156 * @param signal
157 * Contains the information about the selection.
158 */
159 @TmfSignalHandler
160 public void traceClosed(TmfTraceClosedSignal signal) {
161 if (fCurrentTrace == signal.getTrace()) {
162 fCurrentTrace = null;
163 resetView();
164 }
165 }
166
167 /**
168 * Handler called when an trace is selected. Checks if the trace has changed
169 * and requests the selected trace if it has not yet been cached.
170 *
171 * @param signal
172 * Contains the information about the selection.
173 */
174 @TmfSignalHandler
175 public void traceSelected(TmfTraceSelectedSignal signal) {
176 if (fCurrentTrace != signal.getTrace()) {
177 fCurrentTrace = signal.getTrace();
178 resetView();
179 queryAnalysis();
180 }
181 }
182
183 private void queryAnalysis() {
184 Thread thread = new Thread(new Runnable() {
185
186 @Override
187 public void run() {
188 ITmfTrace trace = fCurrentTrace;
189 if (trace == null || (!(trace instanceof PcapTrace))) {
190 return;
191 }
192 StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID);
193 if (analysis == null) {
194 return;
195 }
196 while (!analysis.isFinished() && !fStopThread) {
197 updateUI();
198 try {
199 Thread.sleep(WAIT_TIME);
200 } catch (InterruptedException e) {
201 String message = e.getMessage();
202 if (message == null) {
203 message = EMPTY_STRING;
204 }
205 Activator.logError(message, e);
206 return;
207 }
208 }
209 // Update UI one more time (daft punk)
210 if (!fStopThread) {
211 updateUI();
212 }
213
214 }
215 });
216
217 fStopThread = false;
218 thread.start();
219 }
220
221 private void resetView() {
222
223 // Stop thread if needed
224 fStopThread = true;
225
226 // Remove all content in tables
227 final Display display = Display.getDefault();
228 if (display == null || display.isDisposed()) {
229 return;
230 }
231 display.asyncExec(new Runnable() {
232
233 @Override
234 public void run() {
235 if (display.isDisposed()) {
236 return;
237 }
238 Map<TmfProtocol, Table> tableMap = fTableMap;
239 if (tableMap == null) {
240 return;
241 }
242 for (TmfProtocol protocol : tableMap.keySet()) {
243 if (!(tableMap.get(protocol).isDisposed())) {
244 tableMap.get(protocol).removeAll();
245 }
246 }
247 }
248 });
249 }
250
251 private void updateUI() {
252 final Display display = Display.getDefault();
253 if (display == null || display.isDisposed()) {
254 return;
255 }
256 display.asyncExec(new Runnable() {
257
258 @Override
259 public void run() {
260 if (display.isDisposed()) {
261 return;
262 }
263 ITmfTrace trace = fCurrentTrace;
264 if (trace == null) {
265 return;
266 }
267
268 StreamListAnalysis analysis = trace.getAnalysisModuleOfClass(StreamListAnalysis.class, StreamListAnalysis.ID);
269 if (analysis == null) {
270 return;
271 }
272
273 Map<TmfProtocol, Table> tables = fTableMap;
274 if (tables == null) {
275 return;
276 }
277 for (TmfProtocol p : tables.keySet()) {
278 @SuppressWarnings("null")
279 @NonNull TmfProtocol protocol = p;
280 TmfPacketStreamBuilder builder = analysis.getBuilder(protocol);
281 if (builder != null && !(tables.get(protocol).isDisposed())) {
282 for (TmfPacketStream stream : builder.getStreams()) {
283
284 TableItem item;
285 if (stream.getID() < tables.get(protocol).getItemCount()) {
286 item = tables.get(protocol).getItem(stream.getID());
287 } else {
288 item = new TableItem(tables.get(protocol), SWT.NONE);
289 }
290 item.setText(0, String.valueOf(stream.getID()));
291 item.setText(1, stream.getFirstEndpoint().toString());
292 item.setText(2, stream.getSecondEndpoint().toString());
293 item.setText(3, String.valueOf(stream.getNbPackets()));
294 item.setText(4, String.valueOf(stream.getNbBytes()));
295 item.setText(5, String.valueOf(stream.getNbPacketsAtoB()));
296 item.setText(6, String.valueOf(stream.getNbBytesAtoB()));
297 item.setText(7, String.valueOf(stream.getNbPacketsBtoA()));
298 item.setText(8, String.valueOf(stream.getNbBytesBtoA()));
299 item.setText(9, stream.getStartTime().toString());
300 item.setText(10, stream.getStopTime().toString());
301 item.setText(11, String.format("%.3f", stream.getDuration())); //$NON-NLS-1$
302 item.setText(12, String.format("%.3f", stream.getBPSAtoB())); //$NON-NLS-1$
303 item.setText(13, String.format("%.3f", stream.getBPSBtoA())); //$NON-NLS-1$
304 item.setData(KEY_STREAM, stream);
305 }
306 }
307 }
308 }
309
310 });
311 }
312
313 @Override
314 public void createPartControl(@Nullable Composite parent) {
315 // Initialize
316 fTableMap = new HashMap<>();
317 fCurrentTrace = getActiveTrace();
318 fCurrentStream = null;
319
320 // Add a tab folder
321 fTabFolder = new CTabFolder(parent, SWT.NONE);
322 fTabFolder.addSelectionListener(new SelectionAdapter() {
323
324 @Override
325 public void widgetSelected(@Nullable SelectionEvent e) {
326 Map<TmfProtocol, Table> tables = fTableMap;
327 if (tables == null || e == null) {
328 return;
329 }
330 TmfProtocol protocol = (TmfProtocol) e.item.getData(KEY_PROTOCOL);
331 tables.get(protocol).deselectAll();
332 fCurrentStream = null;
333 }
334
335 });
336
337 // Add items and tables for each protocol
338 for (TmfProtocol protocol : TmfProtocol.getAllProtocols()) {
339 if (protocol.supportsStream()) {
340 CTabItem item = new CTabItem(fTabFolder, SWT.NONE);
341 item.setText(protocol.getName());
342 item.setData(KEY_PROTOCOL, protocol);
343 Table table = new Table(fTabFolder, SWT.NONE);
344 table.setHeaderVisible(true);
345 table.setLinesVisible(true);
346
347 // Add columns to table
348 for (int i = 0; i < COLUMN_NAMES.length || i < COLUMN_SIZES.length; i++) {
349 TableColumn column = new TableColumn(table, SWT.NONE);
350 column.setText(COLUMN_NAMES[i]);
351 column.setWidth(COLUMN_SIZES[i]);
352 }
353 item.setControl(table);
354 table.addSelectionListener(new SelectionAdapter() {
355
356 @Override
357 public void widgetSelected(@Nullable SelectionEvent e) {
358 if (e == null) {
359 return;
360 }
361 fCurrentStream = (TmfPacketStream) e.item.getData(KEY_STREAM);
362 }
363
364 });
365
366 Map<TmfProtocol, Table> tables = fTableMap;
367 if (tables == null) {
368 return;
369 }
370
371 tables.put(protocol, table);
372
373 // Add right click menu
374 Menu menu = new Menu(table);
375 MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
376 menuItem.setText(Messages.StreamListView_FollowStream);
377 menuItem.addListener(SWT.Selection, new Listener() {
378
379 @Override
380 public void handleEvent(@Nullable Event event) {
381 TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, fCurrentStream);
382 TmfSignalManager.dispatchSignal(signal);
383 }
384 });
385 menuItem = new MenuItem(menu, SWT.PUSH);
386 menuItem.setText(Messages.StreamListView_Clear);
387 menuItem.addListener(SWT.Selection, new Listener() {
388
389 @Override
390 public void handleEvent(@Nullable Event event) {
391 TmfSignal signal = new TmfPacketStreamSelectedSignal(this, 0, null);
392 TmfSignalManager.dispatchSignal(signal);
393
394 }
395 });
396 menuItem = new MenuItem(menu, SWT.PUSH);
397 menuItem.setText(Messages.StreamListView_ExtractAsFilter);
398 menuItem.addListener(SWT.Selection, new Listener() {
399
400 @Override
401 public void handleEvent(@Nullable Event event) {
402 // Generate filter.
403 ITmfFilterTreeNode filter = generateFilter();
404
405 // Update view and XML
406 updateFilters(filter);
407
408 }
409
410 private void updateFilters(@Nullable ITmfFilterTreeNode filter) {
411 if (filter == null) {
412 return;
413 }
414
415 // Update XML
416 List<ITmfFilterTreeNode> newFilters = new ArrayList<>();
417 ITmfFilterTreeNode[] oldFilters = FilterManager.getSavedFilters();
418 for (int i = 0; i < oldFilters.length; i++) {
419 newFilters.add(oldFilters[i]);
420 }
421 if (!(newFilters.contains(filter))) {
422 newFilters.add(filter);
423 FilterManager.setSavedFilters(newFilters.toArray(new ITmfFilterTreeNode[newFilters.size()]));
424 }
425
426 // Update Filter View
427 try {
428 final IWorkbench wb = PlatformUI.getWorkbench();
429 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
430 IViewPart view = activePage.showView(FilterView.ID);
431 FilterView filterView = (FilterView) view;
432 filterView.addFilter(filter);
433 } catch (final PartInitException e) {
434 TraceUtils.displayErrorMsg(Messages.StreamListView_ExtractAsFilter, "Error opening view " + FilterView.ID + e.getMessage()); //$NON-NLS-1$
435 Activator.logError("Error opening view " + FilterView.ID, e); //$NON-NLS-1$
436 return;
437 }
438
439 }
440
441 private @Nullable ITmfFilterTreeNode generateFilter() {
442 TmfPacketStream stream = fCurrentStream;
443 if (stream == null) {
444 return null;
445 }
446
447 // First stage - root
448 String name = Messages.StreamListView_FilterName_Stream + ' ' + stream.getProtocol().getShortName() + ' ' + stream.getFirstEndpoint()
449 + " <--> " + stream.getSecondEndpoint(); //$NON-NLS-1$
450 TmfFilterNode root = new TmfFilterNode(name);
451
452 // Second stage - and
453 TmfFilterAndNode and = new TmfFilterAndNode(root);
454
455 // Third stage - protocol + or
456 TmfFilterContainsNode protocolFilter = new TmfFilterContainsNode(and);
457 protocolFilter.setField(stream.getProtocol().getName());
458 protocolFilter.setValue(EMPTY_STRING);
459 TmfFilterOrNode or = new TmfFilterOrNode(and);
460
461 // Fourth stage - and
462 TmfFilterAndNode andA = new TmfFilterAndNode(or);
463 TmfFilterAndNode andB = new TmfFilterAndNode(or);
464
465 // Fourth stage - endpoints
466 TmfFilterContainsNode endpointAAndA = new TmfFilterContainsNode(andA);
467 endpointAAndA.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE);
468 endpointAAndA.setValue(stream.getFirstEndpoint());
469 TmfFilterContainsNode endpointBAndA = new TmfFilterContainsNode(andA);
470 endpointBAndA.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION);
471 endpointBAndA.setValue(stream.getSecondEndpoint());
472 TmfFilterContainsNode endpointAAndB = new TmfFilterContainsNode(andB);
473 endpointAAndB.setField(PcapEvent.EVENT_FIELD_PACKET_SOURCE);
474 endpointAAndB.setValue(stream.getSecondEndpoint());
475 TmfFilterContainsNode endpointBAndB = new TmfFilterContainsNode(andB);
476 endpointBAndB.setField(PcapEvent.EVENT_FIELD_PACKET_DESTINATION);
477 endpointBAndB.setValue(stream.getFirstEndpoint());
478
479 return root;
480 }
481 });
482 table.setMenu(menu);
483 }
484 }
485
486 // Ask the analysis for data.
487 queryAnalysis();
488 }
489
490 @Override
491 public void setFocus() {
492 CTabFolder tabFolder = fTabFolder;
493 if (tabFolder != null && !(tabFolder.isDisposed())) {
494 tabFolder.setFocus();
495 }
496 }
497
498}
This page took 0.043038 seconds and 5 git commands to generate.