Integrate the TmfEvent+ITmfTimestamp API
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / impl / TmfUml2SDSyncLoader.java
1 /**********************************************************************
2 * Copyright (c) 2011 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 * Bernd Hufmann - Initial API and implementation
11 **********************************************************************/
12 package org.eclipse.linuxtools.tmf.ui.views.uml2sd.impl;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.concurrent.CopyOnWriteArrayList;
18 import java.util.concurrent.locks.ReentrantLock;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Status;
23 import org.eclipse.core.runtime.jobs.Job;
24 import org.eclipse.jface.viewers.ISelection;
25 import org.eclipse.jface.viewers.StructuredSelection;
26 import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
27 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
28 import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
29 import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
30 import org.eclipse.linuxtools.tmf.core.event.TmfNoSuchFieldException;
31 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
32 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
33 import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
34 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
35 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
36 import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
37 import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
38 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
39 import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
40 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
41 import org.eclipse.linuxtools.tmf.core.signal.TmfSignal;
42 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
43 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
44 import org.eclipse.linuxtools.tmf.core.uml2sd.ITmfSyncSequenceDiagramEvent;
45 import org.eclipse.linuxtools.tmf.core.uml2sd.TmfSyncSequenceDiagramEvent;
46 import org.eclipse.linuxtools.tmf.ui.TmfUiPlugin;
47 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView;
48 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Frame;
49 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode;
50 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline;
51 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider;
52 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider;
53 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider;
54 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter;
55 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.widgets.Criteria;
56 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.widgets.FilterCriteria;
57 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.widgets.FilterListDialog;
58 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader;
59 import org.eclipse.swt.widgets.Display;
60 import org.eclipse.ui.ISelectionListener;
61 import org.eclipse.ui.IWorkbenchPart;
62 import org.eclipse.ui.PlatformUI;
63 import org.eclipse.ui.progress.IProgressConstants;
64
65 /**
66 * <b><u>TmfUml2SDSyncLoader</u></b>
67 * <p>
68 * Implementation of the org.eclipse.linuxtools.tmf.ui.Uml2SDLoader extension point to provide
69 * a Sequence Diagram loader for a UST trace with specific trace content for sending and
70 * receiving signals between components. Includes default implementation for the TmfEvent parsing.
71 * </p>
72 */
73 public class TmfUml2SDSyncLoader extends TmfComponent implements IUml2SDLoader, ISDFindProvider, ISDFilterProvider, ISDAdvancedPagingProvider, ISelectionListener {
74
75 // ------------------------------------------------------------------------
76 // Attributes
77 // ------------------------------------------------------------------------
78 protected final static String TITLE = Messages.TmfUml2SDSyncLoader_ViewName;
79 protected final static int DEFAULT_BLOCK_SIZE = 50000;
80 protected final static int MAX_NUM_OF_MSG = 10000;
81 protected static final long INITIAL_WINDOW_OFFSET = (1L * 100 * 1000 * 1000); // .1sec
82
83 // Experiment attributes
84 protected TmfExperiment<TmfEvent> fExperiment = null;
85 protected ITmfEventRequest<TmfEvent> fIndexRequest = null;
86 protected ITmfEventRequest<TmfEvent> fPageRequest = null;
87 volatile protected boolean fIsSignalSent = false;
88 volatile protected long fInitialWindow = INITIAL_WINDOW_OFFSET;
89
90 // The view and event attributes
91 protected SDView fView = null;
92 protected Frame fFrame = null;
93 protected List<ITmfSyncSequenceDiagramEvent> fEvents = new ArrayList<ITmfSyncSequenceDiagramEvent>();
94
95 // Checkpoint and page attributes
96 protected List<TmfTimeRange> fCheckPoints = new ArrayList<TmfTimeRange>(MAX_NUM_OF_MSG);
97 volatile protected int fCurrentPage = 0;
98 protected ITmfTimestamp fCurrentTime = null;
99 volatile protected boolean fIsSelect = false;
100
101 // Search attributes
102 protected SearchJob fFindJob = null;
103 protected List<GraphNode> fFindResults = new ArrayList<GraphNode>();
104 protected Criteria fFindCriteria = null;
105 volatile protected int fCurrentFindIndex = 0;
106
107 // Filter attributes
108 protected List<FilterCriteria> fFilterCriteria = null;
109
110 // Thread synchronization
111 protected ReentrantLock fLock = new ReentrantLock();
112
113 // ------------------------------------------------------------------------
114 // Constructors
115 // ------------------------------------------------------------------------
116
117 public TmfUml2SDSyncLoader() {
118 super(TITLE);
119 }
120
121 public TmfUml2SDSyncLoader(String name) {
122 super(name);
123 }
124
125 // ------------------------------------------------------------------------
126 // Operations
127 // ------------------------------------------------------------------------
128
129 /**
130 * @return returns the current time if available else null
131 */
132 public ITmfTimestamp getCurrentTime() {
133 fLock.lock();
134 try {
135 if (fCurrentTime != null) {
136 return fCurrentTime.clone();
137 }
138 return null;
139 } finally {
140 fLock.unlock();
141 }
142 }
143
144 /**
145 * Waits for the page request to be completed
146 */
147 public void waitForCompletion() {
148 fLock.lock();
149 ITmfEventRequest<TmfEvent> request = fPageRequest;
150 fLock.unlock();
151 if (request != null)
152 try {
153 request.waitForCompletion();
154 } catch (InterruptedException e) {
155 // ignore
156 }
157 }
158
159 /**
160 * Spawns a request to index the experiment (checkpoints creation) as well as it fills
161 * the first page.
162 *
163 * @param signal The experiment selected signal
164 */
165 @SuppressWarnings("unchecked")
166 @TmfSignalHandler
167 public void experimentSelected(TmfExperimentSelectedSignal<TmfEvent> signal) {
168
169 fLock.lock();
170 try {
171 // Update the trace reference
172 TmfExperiment<TmfEvent> exp = (TmfExperiment<TmfEvent>) signal.getExperiment();
173 if (!exp.equals(fExperiment)) {
174 fExperiment = exp;
175 }
176
177 // TmfTimeRange window = getInitTRange(fExperiment.getTimeRange());
178 TmfTimeRange window = TmfTimeRange.Eternity;
179
180 fIndexRequest = new TmfEventRequest<TmfEvent>(TmfEvent.class, window, TmfDataRequest.ALL_DATA, DEFAULT_BLOCK_SIZE, ITmfDataRequest.ExecutionType.BACKGROUND) {
181
182 private ITmfTimestamp fFirstTime = null;
183 private ITmfTimestamp fLastTime = null;
184 private int fNbSeqEvents = 0;
185 private List<ITmfSyncSequenceDiagramEvent> fSdEvents = new ArrayList<ITmfSyncSequenceDiagramEvent>(MAX_NUM_OF_MSG);
186
187 @Override
188 public void handleData(TmfEvent event) {
189 super.handleData(event);
190
191 ITmfSyncSequenceDiagramEvent sdEvent = getSequnceDiagramEvent(event);
192
193 if (sdEvent != null) {
194 ++fNbSeqEvents;
195
196 if (fFirstTime == null) {
197 fFirstTime = event.getTimestamp().clone();
198 }
199
200 fLastTime = event.getTimestamp().clone();
201
202 if ((fNbSeqEvents % MAX_NUM_OF_MSG) == 0) {
203 fLock.lock();
204 try {
205 fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime));
206 if (fView != null) {
207 fView.updateCoolBar();
208 }
209 } finally {
210 fLock.unlock();
211 }
212 fFirstTime = null;
213
214 }
215
216 if (fNbSeqEvents > MAX_NUM_OF_MSG) {
217 // page is full
218 return;
219 }
220
221 fSdEvents.add(sdEvent);
222
223 if (fNbSeqEvents == MAX_NUM_OF_MSG) {
224 fillCurrentPage(fSdEvents);
225 }
226 }
227 }
228
229 @Override
230 public void handleSuccess() {
231 // long indexingEnd = System.nanoTime();
232 if ((fFirstTime != null) && (fLastTime != null)) {
233
234 fLock.lock();
235 try {
236 fCheckPoints.add(new TmfTimeRange(fFirstTime, fLastTime));
237 if (fView != null) {
238 fView.updateCoolBar();
239 }
240 } finally {
241 fLock.unlock();
242 }
243 }
244
245 if (fNbSeqEvents <= MAX_NUM_OF_MSG) {
246 fillCurrentPage(fSdEvents);
247 }
248
249 super.handleSuccess();
250 }
251
252 @Override
253 public void handleCompleted() {
254 if (fEvents.size() == 0) {
255 fFrame = new Frame();
256 fView.setFrameSync(fFrame);
257 }
258 super.handleCompleted();
259 }
260 };
261
262 ((TmfExperiment<TmfEvent>) fExperiment).sendRequest((ITmfDataRequest<TmfEvent>) fIndexRequest);
263 } finally {
264 fLock.unlock();
265 }
266 }
267
268 /**
269 * @param signal The experiment disposed signal
270 */
271 @TmfSignalHandler
272 public void experimentDisposed(TmfExperimentDisposedSignal<TmfEvent> signal) {
273 fLock.lock();
274 try {
275 if ((fIndexRequest != null) && !fIndexRequest.isCompleted()) {
276 fIndexRequest.cancel();
277 fIndexRequest = null;
278 }
279
280 cancelOngoingRequests();
281
282 if (fFilterCriteria != null) {
283 fFilterCriteria.clear();
284 }
285
286 FilterListDialog.deactivateSavedGlobalFilters();
287
288 resetLoader();
289 } finally {
290 fLock.unlock();
291 }
292 }
293
294 /**
295 * Moves to the page that contains the time provided by the signal. The messages will be selected
296 * if the provided time is the time of a message.
297 *
298 * @param signal The Time synch signal.
299 */
300 @TmfSignalHandler
301 public void synchToTime(TmfTimeSynchSignal signal) {
302 fLock.lock();
303 try {
304 if ((signal.getSource() != this) && (fFrame != null)) {
305
306 fCurrentTime = signal.getCurrentTime();
307 fIsSelect = true;
308 moveToMessage();
309 }
310 } finally {
311 fLock.unlock();
312 }
313 }
314
315 /**
316 * Moves to the page that contains the current time provided by signal.
317 * No message will be selected however the focus will be set to the message
318 * if the provided time is the time of a message.
319 *
320 * @param signal The time range sync signal
321 */
322 @TmfSignalHandler
323 public void synchToTimeRange(TmfRangeSynchSignal signal) {
324 fLock.lock();
325 try {
326 if ((signal.getSource() != this) && (fFrame != null) && !fIsSignalSent) {
327 TmfTimeRange newTimeRange = signal.getCurrentRange();
328 TmfTimestamp delta = (TmfTimestamp) newTimeRange.getEndTime().getDelta(newTimeRange.getStartTime());
329 fInitialWindow = delta.getValue();
330
331 fIsSelect = false;
332 fCurrentTime = newTimeRange.getStartTime();
333
334 moveToMessage();
335 }
336 } finally {
337 fLock.unlock();
338 }
339
340 }
341
342 /*
343 * (non-Javadoc)
344 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader#setViewer(org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView)
345 */
346 @SuppressWarnings("unchecked")
347 @Override
348 public void setViewer(SDView viewer) {
349
350 fLock.lock();
351 try {
352 fView = viewer;
353 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
354 fView.setSDFindProvider(this);
355 fView.setSDPagingProvider(this);
356 fView.setSDFilterProvider(this);
357
358 resetLoader();
359
360 fExperiment = (TmfExperiment<TmfEvent>) TmfExperiment.getCurrentExperiment();
361 if (fExperiment != null) {
362 experimentSelected(new TmfExperimentSelectedSignal<TmfEvent>(this, fExperiment));
363 }
364 } finally {
365 fLock.unlock();
366 }
367 }
368
369 /*
370 * (non-Javadoc)
371 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader#getTitleString()
372 */
373 @Override
374 public String getTitleString() {
375 return getName();
376 }
377
378 /*
379 * (non-Javadoc)
380 * @see org.eclipse.linuxtools.tmf.component.TmfComponent#dispose()
381 */
382 @Override
383 public void dispose() {
384 super.dispose();
385 fLock.lock();
386 try {
387 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().removePostSelectionListener(this);
388 fView.setSDFindProvider(null);
389 fView.setSDPagingProvider(null);
390 fView.setSDFilterProvider(null);
391 fView = null;
392 } finally {
393 fLock.unlock();
394 }
395 }
396
397 /*
398 * (non-Javadoc)
399 * @see org.eclipse.hyades.uml2sd.ui.actions.provider.ISDGraphNodeSupporter#isNodeSupported(int)
400 */
401 @Override
402 public boolean isNodeSupported(int nodeType) {
403 switch (nodeType) {
404 case ISDGraphNodeSupporter.LIFELINE:
405 case ISDGraphNodeSupporter.SYNCMESSAGE:
406 return true;
407
408 default:
409 break;
410 }
411 return false;
412 }
413
414 /*
415 * (non-Javadoc)
416 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter#getNodeName(int, java.lang.String)
417 */
418 @Override
419 public String getNodeName(int nodeType, String loaderClassName) {
420 switch (nodeType) {
421 case ISDGraphNodeSupporter.LIFELINE:
422 return Messages.TmfUml2SDSyncLoader_CategoryLifeline;
423 case ISDGraphNodeSupporter.SYNCMESSAGE:
424 return Messages.TmfUml2SDSyncLoader_CategoryMessage;
425 }
426 return ""; //$NON-NLS-1$
427 }
428
429 /*
430 * (non-Javadoc)
431 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
432 */
433 @Override
434 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
435 ISelection sel = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
436 if (sel != null && (sel instanceof StructuredSelection)) {
437 StructuredSelection stSel = (StructuredSelection) sel;
438 if (stSel.getFirstElement() instanceof TmfSyncMessage) {
439 TmfSyncMessage syncMsg = ((TmfSyncMessage) stSel.getFirstElement());
440 broadcast(new TmfTimeSynchSignal(this, syncMsg.getStartTime()));
441 }
442 }
443 }
444
445 /*
446 * (non-Javadoc)
447 * @see
448 * org.eclipse.hyades.uml2sd.ui.actions.provider.ISDFindProvider#find(org.eclipse.hyades.uml2sd.ui.actions.widgets.Criteria)
449 */
450 @Override
451 public boolean find(Criteria toSearch) {
452 fLock.lock();
453 try {
454 if (fFrame == null) {
455 return false;
456 }
457
458 if (fFindResults == null || fFindCriteria == null || !fFindCriteria.compareTo(toSearch)) {
459 fFindResults = new CopyOnWriteArrayList<GraphNode>();
460 fFindCriteria = toSearch;
461 if (fFindCriteria.isLifeLineSelected()) {
462 for (int i = 0; i < fFrame.lifeLinesCount(); i++) {
463 if (fFindCriteria.matches(fFrame.getLifeline(i).getName())) {
464 fFindResults.add(fFrame.getLifeline(i));
465 }
466 }
467 }
468
469 ArrayList<GraphNode> msgs = new ArrayList<GraphNode>();
470 if (fFindCriteria.isSyncMessageSelected()) {
471 for (int i = 0; i < fFrame.syncMessageCount(); i++) {
472 if (fFindCriteria.matches(fFrame.getSyncMessage(i).getName())) {
473 msgs.add(fFrame.getSyncMessage(i));
474 }
475 }
476 }
477
478 if (msgs.size() > 0) {
479 fFindResults.addAll(msgs);
480 }
481
482 @SuppressWarnings("rawtypes")
483 List selection = fView.getSDWidget().getSelection();
484 if (selection != null && selection.size() == 1)
485 fCurrentFindIndex = fFindResults.indexOf(selection.get(0)) + 1;
486 else
487 fCurrentFindIndex = 0;
488 } else {
489 fCurrentFindIndex++;
490 }
491
492 if (fFindResults.size() > fCurrentFindIndex) {
493 GraphNode current = (GraphNode) fFindResults.get(fCurrentFindIndex);
494 fView.getSDWidget().moveTo(current);
495 return true;
496 } else {
497 fFindResults = null;
498 fCurrentFindIndex =0;
499 return findInNextPages(fFindCriteria); // search in other page
500 }
501 } finally {
502 fLock.unlock();
503 }
504 }
505
506 /*
507 * (non-Javadoc)
508 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider#cancel()
509 */
510 @Override
511 public void cancel() {
512 cancelOngoingRequests();
513 }
514
515 /*
516 * (non-Javadoc)
517 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider#filter(java.util.List)
518 */
519 @SuppressWarnings("unchecked")
520 @Override
521 public boolean filter(List<?> filters) {
522 fLock.lock();
523 try {
524 cancelOngoingRequests();
525
526 List<FilterCriteria> list = (List<FilterCriteria>)filters;
527 fFilterCriteria = new ArrayList<FilterCriteria>(list);
528
529 fillCurrentPage(fEvents);
530
531 } finally {
532 fLock.unlock();
533 }
534 return true;
535 }
536
537 /*
538 * (non-Javadoc)
539 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#hasNextPage()
540 */
541 @Override
542 public boolean hasNextPage() {
543 fLock.lock();
544 try {
545 int size = fCheckPoints.size();
546 if (size > 0) {
547 return fCurrentPage < size - 1;
548 }
549 } finally {
550 fLock.unlock();
551 }
552 return false;
553 }
554
555 /*
556 * (non-Javadoc)
557 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#hasPrevPage()
558 */
559 @Override
560 public boolean hasPrevPage() {
561 fLock.lock();
562 try {
563 return fCurrentPage > 0;
564 } finally {
565 fLock.unlock();
566 }
567 }
568
569 /*
570 * (non-Javadoc)
571 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#nextPage()
572 */
573 @Override
574 public void nextPage() {
575 fLock.lock();
576 try {
577 // Safety check
578 if (fCurrentPage >= fCheckPoints.size() - 1)
579 return;
580
581 cancelOngoingRequests();
582 fCurrentTime = null;
583 fCurrentPage++;
584 moveToPage();
585 } finally {
586 fLock.unlock();
587 }
588 }
589
590 /*
591 * (non-Javadoc)
592 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#prevPage()
593 */
594 @Override
595 public void prevPage() {
596 fLock.lock();
597 try {
598 // Safety check
599 if (fCurrentPage <= 0)
600 return;
601
602 cancelOngoingRequests();
603 fCurrentTime = null;
604 fCurrentPage--;
605 moveToPage();
606 } finally {
607 fLock.unlock();
608 }
609 }
610
611 /*
612 * (non-Javadoc)
613 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#firstPage()
614 */
615 @Override
616 public void firstPage() {
617 fLock.lock();
618 try {
619
620 cancelOngoingRequests();
621 fCurrentTime = null;
622 fCurrentPage = 0;
623 moveToPage();
624 } finally {
625 fLock.unlock();
626 }
627 }
628
629 /*
630 * (non-Javadoc)
631 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#lastPage()
632 */
633 @Override
634 public void lastPage() {
635 fLock.lock();
636 try {
637 cancelOngoingRequests();
638 fCurrentTime = null;
639 fCurrentPage = fCheckPoints.size() - 1;
640 moveToPage();
641 } finally {
642 fLock.unlock();
643 }
644 }
645
646 /*
647 * (non-Javadoc)
648 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#currentPage()
649 */
650 @Override
651 public int currentPage() {
652 fLock.lock();
653 try {
654 return fCurrentPage;
655 } finally {
656 fLock.unlock();
657 }
658 }
659
660 /*
661 * (non-Javadoc)
662 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#pagesCount()
663 */
664 @Override
665 public int pagesCount() {
666 fLock.lock();
667 try {
668 return fCheckPoints.size();
669 } finally {
670 fLock.unlock();
671 }
672 }
673
674 /*
675 * (non-Javadoc)
676 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#pageNumberChanged(int)
677 */
678 @Override
679 public void pageNumberChanged(int pageNumber) {
680 fLock.lock();
681 try {
682 cancelOngoingRequests();
683
684 if (pageNumber < 0) {
685 pageNumber = 0;
686 }
687 int size = fCheckPoints.size();
688 if (pageNumber > size - 1) {
689 pageNumber = size - 1;
690 }
691 fCurrentPage = pageNumber;
692 moveToPage();
693 } finally {
694 fLock.unlock();
695 }
696 }
697
698 /*
699 * (non-Javadoc)
700 * @see org.eclipse.linuxtools.tmf.component.TmfComponent#broadcast(org.eclipse.linuxtools.tmf.signal.TmfSignal)
701 */
702 @Override
703 public void broadcast(TmfSignal signal) {
704 fIsSignalSent = true;
705 super.broadcast(signal);
706 fIsSignalSent = false;
707 }
708
709 /**
710 * Cancels any ongoing find operation
711 */
712 protected void cancelOngoingRequests() {
713 fLock.lock();
714 try {
715 // Cancel the search thread
716 if (fFindJob != null) {
717 fFindJob.cancel();
718 }
719 fFindResults = null;
720 fFindCriteria = null;
721 fCurrentFindIndex = 0;
722
723 if ((fPageRequest != null) && !fPageRequest.isCompleted()) {
724 fPageRequest.cancel();
725 fPageRequest = null;
726 }
727 } finally {
728 fLock.unlock();
729 }
730 }
731
732 /**
733 * Resets loader attributes
734 */
735 protected void resetLoader() {
736 fLock.lock();
737 try {
738 fCurrentTime = null;
739 fEvents.clear();
740 fCheckPoints.clear();
741 fCurrentPage = 0;
742 fCurrentFindIndex = 0;
743 fFindCriteria = null;
744 fFindResults = null;
745 fInitialWindow = INITIAL_WINDOW_OFFSET;
746 fView.setFrameSync(new Frame());
747 fFrame = null;
748 }
749 finally {
750 fLock.unlock();
751 }
752
753 }
754
755 /**
756 * Fills current page with sequence diagram content.
757 * @param events sequence diagram events
758 */
759 protected void fillCurrentPage(List<ITmfSyncSequenceDiagramEvent> events) {
760
761 fLock.lock();
762 try {
763 fEvents = new ArrayList<ITmfSyncSequenceDiagramEvent>(events);
764 if (fView != null) {
765 fView.toggleWaitCursorAsync(true);
766 }
767 } finally {
768 fLock.unlock();
769 }
770
771 final Frame frame = new Frame();
772 if (events.size() > 0) {
773
774 HashMap<String, Lifeline> nodeToLifelineMap = new HashMap<String, Lifeline>();
775
776 frame.setName(Messages.TmfUml2SDSyncLoader_FrameName);
777
778 for (int i = 0; i < events.size(); i++) {
779
780 ITmfSyncSequenceDiagramEvent sdEvent = events.get(i);
781
782 if ((nodeToLifelineMap.get(sdEvent.getSender()) == null) && (!filterLifeLine(sdEvent.getSender()))) {
783 Lifeline lifeline = new Lifeline();
784 lifeline.setName(sdEvent.getSender());
785 nodeToLifelineMap.put(sdEvent.getSender(), lifeline);
786 frame.addLifeLine(lifeline);
787 }
788
789 if ((nodeToLifelineMap.get(sdEvent.getReceiver()) == null) && (!filterLifeLine(sdEvent.getReceiver()))) {
790 Lifeline lifeline = new Lifeline();
791 lifeline.setName(sdEvent.getReceiver());
792 nodeToLifelineMap.put(sdEvent.getReceiver(), lifeline);
793 frame.addLifeLine(lifeline);
794 }
795 }
796
797 int eventOccurence = 1;
798
799 for (int i = 0; i < events.size(); i++) {
800 ITmfSyncSequenceDiagramEvent sdEvent = (TmfSyncSequenceDiagramEvent) events.get(i);
801
802 // Check message filter
803 if (filterMessage(sdEvent)) {
804 continue;
805 }
806
807 // Set the message sender and receiver
808 Lifeline startLifeline = (Lifeline) nodeToLifelineMap.get(sdEvent.getSender());
809 Lifeline endLifeline = (Lifeline) nodeToLifelineMap.get(sdEvent.getReceiver());
810
811 // Check if any of the lifelines were filtered
812 if (startLifeline == null || endLifeline == null) {
813 continue;
814 }
815
816 int tmp = Math.max(startLifeline.getEventOccurrence(), endLifeline.getEventOccurrence());
817 eventOccurence = Math.max(eventOccurence, tmp);
818
819 startLifeline.setCurrentEventOccurrence(eventOccurence);
820 endLifeline.setCurrentEventOccurrence(eventOccurence);
821
822 TmfSyncMessage message = new TmfSyncMessage(sdEvent, eventOccurence++);
823
824 message.setStartLifeline(startLifeline);
825 message.setEndLifeline(endLifeline);
826
827 message.setTime(sdEvent.getStartTime());
828
829 // add the message to the frame
830 frame.addMessage(message);
831
832 }
833 fLock.lock();
834 try {
835 if (!fView.getSDWidget().isDisposed()) {
836 fView.getSDWidget().getDisplay().asyncExec(new Runnable() {
837
838 @Override
839 public void run() {
840
841 fLock.lock();
842 try {
843 // check if view was disposed in the meanwhile
844 if ((fView != null) && (!fView.getSDWidget().isDisposed())) {
845 fFrame = frame;
846 fView.setFrame(fFrame);
847
848 if (fCurrentTime != null) {
849 moveToMessageInPage();
850 }
851
852 if (fFindCriteria != null) {
853 find(fFindCriteria);
854 }
855
856 fView.toggleWaitCursorAsync(false);
857 }
858 } finally {
859 fLock.unlock();
860 }
861
862 }
863 });
864 }
865 }
866 finally {
867 fLock.unlock();
868 }
869 }
870 }
871
872 /**
873 * Moves to a certain message defined by timestamp (across pages)
874 */
875 protected void moveToMessage() {
876 int page = 0;
877
878 fLock.lock();
879 try {
880 page = getPage(fCurrentTime);
881
882 if (page == fCurrentPage) {
883 moveToMessageInPage();
884 return;
885 }
886 fCurrentPage = page;
887 moveToPage(false);
888 } finally {
889 fLock.unlock();
890 }
891 }
892
893 /**
894 * Moves to a certain message defined by timestamp in current page
895 */
896 protected void moveToMessageInPage() {
897 fLock.lock();
898 try {
899 if (!fView.getSDWidget().isDisposed()) {
900 // Check for GUI thread
901 if(Display.getCurrent() != null) {
902 // Already in GUI thread - execute directly
903 TmfSyncMessage prevMessage = null;
904 TmfSyncMessage syncMessage = null;
905 boolean isExactTime = false;
906 for (int i = 0; i < fFrame.syncMessageCount(); i++) {
907 if (fFrame.getSyncMessage(i) instanceof TmfSyncMessage) {
908 syncMessage = (TmfSyncMessage) fFrame.getSyncMessage(i);
909 if (syncMessage.getStartTime().compareTo(fCurrentTime, false) == 0) {
910 isExactTime = true;
911 break;
912 }
913 else if (syncMessage.getStartTime().compareTo(fCurrentTime, false) > 0) {
914 if (prevMessage != null) {
915 syncMessage = prevMessage;
916 break;
917 }
918 }
919 prevMessage = syncMessage;
920 }
921 }
922 if (fIsSelect && isExactTime) {
923 fView.getSDWidget().moveTo(syncMessage);
924 }
925 else {
926 fView.getSDWidget().ensureVisible(syncMessage);
927 fView.getSDWidget().clearSelection();
928 fView.getSDWidget().redraw();
929 }
930 }
931 else {
932 // Not in GUI thread - queue action in GUI thread.
933 fView.getSDWidget().getDisplay().asyncExec(new Runnable() {
934 @Override
935 public void run() {
936 moveToMessageInPage();
937 }
938 });
939 }
940 }
941 }
942 finally {
943 fLock.unlock();
944 }
945 }
946
947 /**
948 * Moves to a certain message defined by timestamp (across pages)
949 */
950 protected void moveToPage() {
951 moveToPage(true);
952 }
953
954 /**
955 * Moves to a certain page.
956 * @param notifyAll true to broadcast time range signal to other signal handlers else false
957 */
958 protected void moveToPage(boolean notifyAll) {
959
960 TmfTimeRange window = TmfTimeRange.Eternity;
961
962 fLock.lock();
963 try {
964 // Safety check
965 if (fCurrentPage > fCheckPoints.size()) {
966 return;
967 }
968 window = fCheckPoints.get(fCurrentPage);
969 } finally {
970 fLock.unlock();
971 }
972
973 fPageRequest = new TmfEventRequest<TmfEvent>(TmfEvent.class, window, TmfDataRequest.ALL_DATA, 1, ITmfDataRequest.ExecutionType.FOREGROUND) {
974 private List<ITmfSyncSequenceDiagramEvent> fSdEvent = new ArrayList<ITmfSyncSequenceDiagramEvent>();
975
976 @Override
977 public void handleData(TmfEvent event) {
978 super.handleData(event);
979
980 ITmfSyncSequenceDiagramEvent sdEvent = getSequnceDiagramEvent(event);
981
982 if (sdEvent != null) {
983 fSdEvent.add(sdEvent);
984 }
985 }
986
987 @Override
988 public void handleSuccess() {
989 fillCurrentPage(fSdEvent);
990 super.handleSuccess();
991 }
992
993 };
994
995 ((TmfExperiment<TmfEvent>) fExperiment).sendRequest((ITmfDataRequest<TmfEvent>) fPageRequest);
996
997 if (notifyAll) {
998 TmfTimeRange timeRange = getSignalTimeRange(window.getStartTime());
999 broadcast(new TmfRangeSynchSignal(this, timeRange, timeRange.getStartTime()));
1000 }
1001 }
1002
1003 /**
1004 * Gets page that contains timestamp
1005 * @param time The timestamp
1006 * @return page that contains the time
1007 */
1008 protected int getPage(ITmfTimestamp time) {
1009 int page;
1010 int size;
1011 fLock.lock();
1012 try {
1013 size = fCheckPoints.size();
1014 for (page = 0; page < size; page++) {
1015 TmfTimeRange timeRange = fCheckPoints.get(page);
1016 if (timeRange.getEndTime().compareTo(time, false) >= 0) {
1017 break;
1018 }
1019 }
1020 if (page >= size) {
1021 page = size - 1;
1022 }
1023 return page;
1024 } finally {
1025 fLock.unlock();
1026 }
1027 }
1028
1029 /**
1030 * Background search in trace for expression in criteria.
1031 * @param findCriteria The find criteria
1032 * @return true if background request was started else false
1033 */
1034 protected boolean findInNextPages(Criteria findCriteria) {
1035 fLock.lock();
1036 try {
1037 if (fFindJob != null) {
1038 return true;
1039 }
1040
1041 int nextPage = fCurrentPage + 1;
1042
1043 if ((nextPage) >= fCheckPoints.size()) {
1044 // we are at the end
1045 return false;
1046 }
1047
1048 TmfTimeRange window = new TmfTimeRange(fCheckPoints.get(nextPage).getStartTime().clone(), fCheckPoints.get(fCheckPoints.size()-1).getEndTime().clone());
1049 fFindJob = new SearchJob(findCriteria, window);
1050 fFindJob.schedule();
1051 fView.toggleWaitCursorAsync(true);
1052 } finally {
1053 fLock.unlock();
1054 }
1055 return true;
1056 }
1057
1058 /**
1059 * Gets time range for time range signal.
1060 * @param startTime The start time of time range.
1061 * @return
1062 */
1063 protected TmfTimeRange getSignalTimeRange(ITmfTimestamp startTime) {
1064 fLock.lock();
1065 try {
1066 TmfTimestamp initialEndOfWindow = new TmfTimestamp(startTime.getValue() + fInitialWindow, startTime.getScale(), startTime.getPrecision());
1067 return new TmfTimeRange(startTime, initialEndOfWindow);
1068 }
1069 finally {
1070 fLock.unlock();
1071 }
1072 }
1073
1074 /**
1075 * Checks if filter criteria matches the message name in given SD event.
1076 * @param sdEvent The SD event to check
1077 * @return true if match else false.
1078 */
1079 protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent) {
1080 fLock.lock();
1081 try {
1082 if (fFilterCriteria != null) {
1083 for(FilterCriteria criteria : fFilterCriteria) {
1084 if (criteria.isActive() && criteria.getCriteria().isSyncMessageSelected() ) {
1085
1086 if(criteria.getCriteria().matches(sdEvent.getName())) {
1087 return true;
1088 }
1089 }
1090 }
1091 }
1092 } finally {
1093 fLock.unlock();
1094 }
1095 return false;
1096 }
1097
1098 /**
1099 * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event.
1100 * @param sdEvent The SD event to check
1101 * @return true if match else false.
1102 */
1103 protected boolean filterLifeLine(String lifeline) {
1104 fLock.lock();
1105 try {
1106 if (fFilterCriteria != null) {
1107 for(FilterCriteria criteria : fFilterCriteria) {
1108 if (criteria.isActive() && criteria.getCriteria().isLifeLineSelected()) {
1109
1110 if(criteria.getCriteria().matches(lifeline)) {
1111 return true;
1112 }
1113 }
1114 }
1115 }
1116 } finally {
1117 fLock.unlock();
1118 }
1119 return false;
1120 }
1121
1122 /**
1123 * Job to search in trace for given time range.
1124 */
1125 protected class SearchJob extends Job {
1126
1127 final protected SearchEventRequest fSearchRequest;
1128
1129 /**
1130 * Constructor
1131 *
1132 * @param findCriteria The search criteria
1133 * @param window Time range to search in
1134 */
1135 public SearchJob(Criteria findCriteria, TmfTimeRange window) {
1136 super(Messages.TmfUml2SDSyncLoader_SearchJobDescrition);
1137 fSearchRequest = new SearchEventRequest(window, TmfDataRequest.ALL_DATA, 1, ITmfDataRequest.ExecutionType.FOREGROUND, findCriteria);
1138 }
1139
1140 /*
1141 * (non-Javadoc)
1142 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
1143 */
1144 @Override
1145 protected IStatus run(IProgressMonitor monitor) {
1146 fSearchRequest.setMonitor(monitor);
1147
1148 ((TmfExperiment<TmfEvent>) fExperiment).sendRequest((ITmfDataRequest<TmfEvent>) fSearchRequest);
1149
1150 try {
1151 fSearchRequest.waitForCompletion();
1152 } catch (InterruptedException e) {
1153 e.printStackTrace();
1154 }
1155
1156 IStatus status = Status.OK_STATUS;
1157 if (fSearchRequest.isFound() && fSearchRequest.getFoundTime() != null) {
1158 fCurrentTime = fSearchRequest.getFoundTime();
1159
1160 // Avoid double-selection. Selection will be done when calling find(criteria)
1161 // after moving to relevant page
1162 fIsSelect = false;
1163 if (!fView.getSDWidget().isDisposed()) {
1164 fView.getSDWidget().getDisplay().asyncExec(new Runnable() {
1165
1166 @Override
1167 public void run() {
1168 moveToMessage();
1169 }
1170 });
1171 }
1172 }
1173 else {
1174 if (monitor.isCanceled()) {
1175 status = Status.CANCEL_STATUS;
1176 }
1177 else {
1178 // String was not found
1179 status = new Status(Status.WARNING, TmfUiPlugin.PLUGIN_ID, Messages.TmfUml2SDSyncLoader_SearchNotFound);
1180 }
1181 setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
1182 }
1183 monitor.done();
1184
1185 fLock.lock();
1186 try {
1187 fView.toggleWaitCursorAsync(false);
1188 fFindJob = null;
1189 } finally {
1190 fLock.unlock();
1191 }
1192
1193 return status;
1194 }
1195
1196 /*
1197 * (non-Javadoc)
1198 * @see org.eclipse.core.runtime.jobs.Job#canceling()
1199 */
1200 @Override
1201 protected void canceling() {
1202 fSearchRequest.cancel();
1203 fLock.lock();
1204 try {
1205 fFindJob = null;
1206 } finally {
1207 fLock.unlock();
1208 }
1209 }
1210 }
1211
1212 /**
1213 * TMF event request for searching within trace.
1214 */
1215 protected class SearchEventRequest extends TmfEventRequest<TmfEvent> {
1216
1217 final private Criteria fCriteria;
1218
1219 private IProgressMonitor fMonitor;
1220 private boolean fIsFound = false;
1221 private ITmfTimestamp fFoundTime = null;
1222
1223 /**
1224 * Constructor
1225 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1226 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1227 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1228 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1229 * @param criteria The search criteria
1230 */
1231 public SearchEventRequest(TmfTimeRange range, int nbRequested, int blockSize, ExecutionType execType, Criteria criteria) {
1232 this(range, nbRequested, blockSize, execType, criteria, null);
1233 }
1234
1235 /**
1236 * Constructor
1237 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1238 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1239 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1240 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1241 * @param criteria The search criteria
1242 * @param monitor progress monitor
1243 */
1244 public SearchEventRequest(TmfTimeRange range, int nbRequested, int blockSize, ExecutionType execType, Criteria criteria, IProgressMonitor monitor) {
1245 super(TmfEvent.class, range, nbRequested, blockSize, execType);
1246 fCriteria = new Criteria(criteria);
1247 fMonitor = monitor;
1248 }
1249
1250 /*
1251 * (non-Javadoc)
1252 * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData(org.eclipse.linuxtools.tmf.event.TmfData)
1253 */
1254 @Override
1255 public void handleData(TmfEvent event) {
1256 super.handleData(event);
1257
1258 if ((fMonitor!= null) && fMonitor.isCanceled()) {
1259 super.cancel();
1260 return;
1261 }
1262
1263 ITmfSyncSequenceDiagramEvent sdEvent = getSequnceDiagramEvent(event);
1264
1265 if (sdEvent != null) {
1266
1267 if (fCriteria.isLifeLineSelected()) {
1268 if (fCriteria.matches(sdEvent.getSender())) {
1269 fFoundTime = event.getTimestamp().clone();
1270 fIsFound = true;
1271 super.cancel();
1272 }
1273
1274 if (fCriteria.matches(sdEvent.getReceiver())) {
1275 fFoundTime = event.getTimestamp().clone();
1276 fIsFound = true;
1277 super.cancel();
1278 }
1279 }
1280
1281 if (fCriteria.isSyncMessageSelected()) {
1282 if (fCriteria.matches(sdEvent.getName())) {
1283 fFoundTime = event.getTimestamp().clone();
1284 fIsFound = true;
1285 super.cancel();
1286 }
1287 }
1288 }
1289 }
1290
1291 /*
1292 * (non-Javadoc)
1293 * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCompleted()
1294 */
1295 @Override
1296 public void handleCompleted() {
1297 super.handleCompleted();
1298 }
1299
1300 /**
1301 * Set progress monitor.
1302 * @param monitor
1303 */
1304 public void setMonitor(IProgressMonitor monitor) {
1305 fMonitor = monitor;
1306 }
1307
1308 /**
1309 * Check if find criteria was met.
1310 * @return true if find criteria was met.
1311 */
1312 public boolean isFound() {
1313 return fIsFound;
1314 }
1315
1316 /**
1317 * @return timestamp of found time.
1318 */
1319 public ITmfTimestamp getFoundTime() {
1320 return fFoundTime;
1321 }
1322 }
1323
1324 /**
1325 * @param tmfEvent Event to parse for sequence diagram event details
1326 * @return sequence diagram event if details are available else null
1327 */
1328 protected ITmfSyncSequenceDiagramEvent getSequnceDiagramEvent(TmfEvent tmfEvent){
1329 //type = .*RECEIVE.* or .*SEND.*
1330 //content = sender:<sender name>:receiver:<receiver name>,signal:<signal name>
1331 String eventType = tmfEvent.getType().toString();
1332 if (eventType.contains(Messages.TmfUml2SDSyncCloader_EventTypeSend) ||
1333 eventType.contains(Messages.TmfUml2SDSyncCloader_EventTypeReceive)) {
1334 try {
1335 Object sender = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncCloader_FieldSender);
1336 Object receiver = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncCloader_FieldReceiver);
1337 Object name = tmfEvent.getContent().getField(Messages.TmfUml2SDSyncCloader_FieldSignal);
1338 if ((sender instanceof TmfEventField) && (receiver instanceof TmfEventField) && (name instanceof TmfEventField)) {
1339 ITmfSyncSequenceDiagramEvent sdEvent = new TmfSyncSequenceDiagramEvent(tmfEvent,
1340 ((TmfEventField)sender).getValue().toString(),
1341 ((TmfEventField)receiver).getValue().toString(),
1342 ((TmfEventField)name).getValue().toString());
1343
1344 return sdEvent;
1345 }
1346 } catch (TmfNoSuchFieldException e) {
1347 }
1348 }
1349 return null;
1350 }
1351 }
This page took 0.063303 seconds and 5 git commands to generate.