1 /**********************************************************************
2 * Copyright (c) 2011, 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 * Bernd Hufmann - Initial API and implementation
11 **********************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.loader
;
15 import java
.util
.ArrayList
;
16 import java
.util
.HashMap
;
17 import java
.util
.List
;
19 import java
.util
.concurrent
.CopyOnWriteArrayList
;
20 import java
.util
.concurrent
.locks
.ReentrantLock
;
22 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
23 import org
.eclipse
.core
.runtime
.IStatus
;
24 import org
.eclipse
.core
.runtime
.Status
;
25 import org
.eclipse
.core
.runtime
.jobs
.Job
;
26 import org
.eclipse
.jface
.viewers
.ISelection
;
27 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
28 import org
.eclipse
.swt
.widgets
.Display
;
29 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.component
.TmfComponent
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.request
.TmfEventRequest
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSelectionRangeUpdatedSignal
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignal
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceClosedSignal
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfWindowRangeUpdatedSignal
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.uml2sd
.ITmfSyncSequenceDiagramEvent
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.uml2sd
.TmfSyncSequenceDiagramEvent
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.editors
.ITmfTraceEditor
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.SDView
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
52 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
53 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
54 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.Criteria
;
55 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterCriteria
;
56 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterListDialog
;
57 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDAdvancedPagingProvider
;
58 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFilterProvider
;
59 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFindProvider
;
60 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDGraphNodeSupporter
;
61 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.load
.IUml2SDLoader
;
62 import org
.eclipse
.ui
.IEditorPart
;
63 import org
.eclipse
.ui
.ISelectionListener
;
64 import org
.eclipse
.ui
.IWorkbenchPart
;
65 import org
.eclipse
.ui
.IWorkbenchWindow
;
66 import org
.eclipse
.ui
.PlatformUI
;
67 import org
.eclipse
.ui
.progress
.IProgressConstants
;
71 * This class is a reference implementation of the
72 * <code>org.eclipse.tracecompass.tmf.ui.Uml2SDLoader</code> extension point. It
73 * provides a Sequence Diagram loader for a user space trace with specific trace
74 * content for sending and receiving signals between components. I also includes
75 * a default implementation for the <code>ITmfEvent</code> parsing.
78 * The class <code>TmfUml2SDSyncLoader</code> analyzes events from type
79 * <code>ITmfEvent</code> and creates events type
80 * <code>ITmfSyncSequenceDiagramEvent</code> if the <code>ITmfEvent</code>
81 * contains all relevant information. The analysis checks that the event type
82 * strings contains either string SEND or RECEIVE. If event type matches these
83 * key words, the analyzer will look for strings sender, receiver and signal in
84 * the event fields of type <code>ITmfEventField</code>. If all the data is
85 * found a sequence diagram event from can be created. Note that Sync Messages
86 * are assumed, which means start and end time are the same. <br>
88 * The parsing of the <code>ITmfEvent</code> is done in the method
89 * <code>getSequnceDiagramEvent()</code> of class
90 * <code>TmfUml2SDSyncLoader</code>. By extending the class
91 * <code>TmfUml2SDSyncLoader</code> and overwriting
92 * <code>getSequnceDiagramEvent()</code> a customized parsing algorithm can be
95 * Note that combined traces of multiple components, that contain the trace
96 * information about the same interactions are not supported in the class
97 * <code>TmfUml2SDSyncLoader</code>.
100 * @author Bernd Hufmann
102 public class TmfUml2SDSyncLoader
extends TmfComponent
implements IUml2SDLoader
, ISDFindProvider
, ISDFilterProvider
, ISDAdvancedPagingProvider
, ISelectionListener
{
104 // ------------------------------------------------------------------------
106 // ------------------------------------------------------------------------
109 * Default title name.
111 protected static final String TITLE
= Messages
.TmfUml2SDSyncLoader_ViewName
;
114 * Maximum number of messages per page.
116 protected static final int MAX_NUM_OF_MSG
= 10000;
118 private static final int INDEXING_THREAD_SLEEP_VALUE
= 100;
120 // ------------------------------------------------------------------------
122 // ------------------------------------------------------------------------
124 // Experiment attributes
126 * The TMF trace reference.
128 protected ITmfTrace fTrace
= null;
130 * The current indexing event request.
132 protected ITmfEventRequest fIndexRequest
= null;
134 * The current request to fill a page.
136 protected ITmfEventRequest fPageRequest
= null;
138 * Flag whether the time range signal was sent by this loader class or not
140 protected volatile boolean fIsSignalSent
= false;
142 // The view and event attributes
144 * The sequence diagram view reference.
146 protected SDView fView
= null;
148 * The current sequence diagram frame reference.
150 protected Frame fFrame
= null;
152 * The list of sequence diagram events of current page.
154 protected List
<ITmfSyncSequenceDiagramEvent
> fEvents
= new ArrayList
<>();
156 // Checkpoint and page attributes
158 * The checkpoints of the whole sequence diagram trace (i.e. start time stamp of each page)
160 protected List
<TmfTimeRange
> fCheckPoints
= new ArrayList
<>(MAX_NUM_OF_MSG
);
162 * The current page displayed.
164 protected volatile int fCurrentPage
= 0;
166 * The current time selected.
168 protected ITmfTimestamp fCurrentTime
= null;
170 * Flag to specify that selection of message is done by selection or by signal.
172 protected volatile boolean fIsSelect
= false;
176 * The job for searching across pages.
178 protected SearchJob fFindJob
= null;
180 * List of found nodes within a page.
182 protected List
<GraphNode
> fFindResults
= new ArrayList
<>();
184 * The current find criteria reference
186 protected Criteria fFindCriteria
= null;
188 * The current find index within the list of found nodes (<code>fFindeResults</code> within a page.
190 protected volatile int fCurrentFindIndex
= 0;
194 * The list of active filters.
196 protected List
<FilterCriteria
> fFilterCriteria
= null;
198 // Thread synchronization
200 * The synchronization lock.
202 protected ReentrantLock fLock
= new ReentrantLock();
204 // ------------------------------------------------------------------------
206 // ------------------------------------------------------------------------
208 * Default constructor
210 public TmfUml2SDSyncLoader() {
217 * @param name Name of loader
219 public TmfUml2SDSyncLoader(String name
) {
223 // ------------------------------------------------------------------------
225 // ------------------------------------------------------------------------
228 * Returns the current time if available else null.
230 * @return the current time if available else null
232 public ITmfTimestamp
getCurrentTime() {
235 if (fCurrentTime
!= null) {
245 * Waits for the page request to be completed
247 public void waitForCompletion() {
249 ITmfEventRequest request
= fPageRequest
;
251 if (request
!= null) {
253 request
.waitForCompletion();
254 } catch (InterruptedException e
) {
261 * Handler for the trace opened signal.
262 * @param signal The trace opened signal
265 public void traceOpened(TmfTraceOpenedSignal signal
) {
266 fTrace
= signal
.getTrace();
272 * Signal handler for the trace selected signal.
274 * Spawns a request to index the trace (checkpoints creation) as well as it fills
277 * @param signal The trace selected signal
280 public void traceSelected(TmfTraceSelectedSignal signal
) {
281 // Update the trace reference
282 ITmfTrace trace
= signal
.getTrace();
283 if (!trace
.equals(fTrace
)) {
290 * Method for loading the current selected trace into the view.
291 * Sub-class need to override this method to add the view specific implementation.
293 protected void loadTrace() {
294 ITmfEventRequest indexRequest
= null;
298 final Job job
= new IndexingJob("Indexing " + getName() + "..."); //$NON-NLS-1$ //$NON-NLS-2$
302 indexRequest
= fIndexRequest
;
304 cancelOngoingRequests();
306 TmfTimeRange window
= TmfTimeRange
.ETERNITY
;
308 fIndexRequest
= new TmfEventRequest(ITmfEvent
.class, window
, 0,
309 ITmfEventRequest
.ALL_DATA
, ITmfEventRequest
.ExecutionType
.BACKGROUND
) {
311 private ITmfTimestamp fFirstTime
= null;
312 private ITmfTimestamp fLastTime
= null;
313 private int fNbSeqEvents
= 0;
314 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvents
= new ArrayList
<>(MAX_NUM_OF_MSG
);
317 public void handleData(ITmfEvent event
) {
318 super.handleData(event
);
320 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
321 ITmfTimestamp firstTime
= fFirstTime
;
322 ITmfTimestamp lastTime
= fLastTime
;
324 if (sdEvent
!= null) {
327 if (firstTime
== null) {
328 firstTime
= event
.getTimestamp();
329 fFirstTime
= firstTime
;
332 lastTime
= event
.getTimestamp();
333 fLastTime
= lastTime
;
335 if ((fNbSeqEvents
% MAX_NUM_OF_MSG
) == 0) {
338 fCheckPoints
.add(new TmfTimeRange(firstTime
, lastTime
));
340 fView
.updateCoolBar();
349 if (fNbSeqEvents
> MAX_NUM_OF_MSG
) {
354 fSdEvents
.add(sdEvent
);
356 if (fNbSeqEvents
== MAX_NUM_OF_MSG
) {
357 fillCurrentPage(fSdEvents
);
363 public void handleSuccess() {
364 final ITmfTimestamp firstTime
= fFirstTime
;
365 final ITmfTimestamp lastTime
= fLastTime
;
366 if ((firstTime
!= null) && (lastTime
!= null)) {
370 fCheckPoints
.add(new TmfTimeRange(firstTime
, lastTime
));
372 fView
.updateCoolBar();
379 if (fNbSeqEvents
<= MAX_NUM_OF_MSG
) {
380 fillCurrentPage(fSdEvents
);
383 super.handleSuccess();
387 public void handleCompleted() {
388 if (fEvents
.isEmpty()) {
389 fFrame
= new Frame();
390 // make sure that view is not null when setting frame
398 if (sdView
!= null) {
399 sdView
.setFrameSync(fFrame
);
402 super.handleCompleted();
410 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
411 indexRequest
.cancel();
414 fTrace
.sendRequest(fIndexRequest
);
418 * Signal handler for the trace closed signal.
420 * @param signal The trace closed signal
423 public void traceClosed(TmfTraceClosedSignal signal
) {
424 if (signal
.getTrace() != fTrace
) {
427 ITmfEventRequest indexRequest
= null;
430 indexRequest
= fIndexRequest
;
431 fIndexRequest
= null;
433 cancelOngoingRequests();
435 if (fFilterCriteria
!= null) {
436 fFilterCriteria
.clear();
439 FilterListDialog
.deactivateSavedGlobalFilters();
444 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
445 indexRequest
.cancel();
452 * Moves to the page that contains the time provided by the signal. The
453 * messages will be selected if the provided time is the time of a message.
456 * The selection range signal
460 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal
) {
463 if ((signal
.getSource() != this) && (fFrame
!= null) && (fCheckPoints
.size() > 0)) {
464 fCurrentTime
= signal
.getBeginTime();
474 * Moves to the page that contains the current time provided by signal. No
475 * message will be selected however the focus will be set to the message if
476 * the provided time is the time of a message.
479 * The window range signal
483 public void windowRangeUpdated(TmfWindowRangeUpdatedSignal signal
) {
486 if ((signal
.getSource() != this) && (fFrame
!= null) && !fIsSignalSent
&& (fCheckPoints
.size() > 0)) {
487 TmfTimeRange newTimeRange
= signal
.getCurrentRange();
490 fCurrentTime
= newTimeRange
.getStartTime();
501 public void setViewer(SDView viewer
) {
506 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
507 fView
.setSDFindProvider(this);
508 fView
.setSDPagingProvider(this);
509 fView
.setSDFilterProvider(this);
512 IEditorPart editor
= fView
.getSite().getPage().getActiveEditor();
513 if (editor
instanceof ITmfTraceEditor
) {
514 ITmfTrace trace
= ((ITmfTraceEditor
) editor
).getTrace();
516 traceSelected(new TmfTraceSelectedSignal(this, trace
));
525 public String
getTitleString() {
530 public void dispose() {
532 ITmfEventRequest indexRequest
= null;
535 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
536 // During Eclipse shutdown the active workbench window is null
537 if (window
!= null) {
538 window
.getSelectionService().removePostSelectionListener(this);
541 indexRequest
= fIndexRequest
;
542 fIndexRequest
= null;
543 cancelOngoingRequests();
545 fView
.setSDFindProvider(null);
546 fView
.setSDPagingProvider(null);
547 fView
.setSDFilterProvider(null);
552 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
553 indexRequest
.cancel();
558 public boolean isNodeSupported(int nodeType
) {
560 case ISDGraphNodeSupporter
.LIFELINE
:
561 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
571 public String
getNodeName(int nodeType
, String loaderClassName
) {
573 case ISDGraphNodeSupporter
.LIFELINE
:
574 return Messages
.TmfUml2SDSyncLoader_CategoryLifeline
;
575 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
576 return Messages
.TmfUml2SDSyncLoader_CategoryMessage
;
580 return ""; //$NON-NLS-1$
584 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
585 ISelection sel
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
586 if ((sel
!= null) && (sel
instanceof StructuredSelection
)) {
587 StructuredSelection stSel
= (StructuredSelection
) sel
;
588 if (stSel
.getFirstElement() instanceof TmfSyncMessage
) {
589 TmfSyncMessage syncMsg
= ((TmfSyncMessage
) stSel
.getFirstElement());
590 ITmfTimestamp startTime
= syncMsg
.getStartTime();
591 if (startTime
== null) {
592 startTime
= TmfTimestamp
.BIG_BANG
;
594 broadcast(new TmfSelectionRangeUpdatedSignal(this, startTime
));
600 public boolean find(Criteria toSearch
) {
603 if (fFrame
== null) {
607 if ((fFindResults
== null) || (fFindCriteria
== null) || !fFindCriteria
.compareTo(toSearch
)) {
608 fFindResults
= new CopyOnWriteArrayList
<>();
609 fFindCriteria
= toSearch
;
610 if (fFindCriteria
.isLifeLineSelected()) {
611 for (int i
= 0; i
< fFrame
.lifeLinesCount(); i
++) {
612 if (fFindCriteria
.matches(fFrame
.getLifeline(i
).getName())) {
613 fFindResults
.add(fFrame
.getLifeline(i
));
618 ArrayList
<GraphNode
> msgs
= new ArrayList
<>();
619 if (fFindCriteria
.isSyncMessageSelected()) {
620 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
621 if (fFindCriteria
.matches(fFrame
.getSyncMessage(i
).getName())) {
622 msgs
.add(fFrame
.getSyncMessage(i
));
627 if (!msgs
.isEmpty()) {
628 fFindResults
.addAll(msgs
);
631 List
<GraphNode
> selection
= fView
.getSDWidget().getSelection();
632 if ((selection
!= null) && (selection
.size() == 1)) {
633 fCurrentFindIndex
= fFindResults
.indexOf(selection
.get(0)) + 1;
635 fCurrentFindIndex
= 0;
641 if (fFindResults
.size() > fCurrentFindIndex
) {
642 GraphNode current
= fFindResults
.get(fCurrentFindIndex
);
643 fView
.getSDWidget().moveTo(current
);
647 fCurrentFindIndex
=0;
648 return findInNextPages(fFindCriteria
); // search in other page
655 public void cancel() {
656 cancelOngoingRequests();
660 public boolean filter(List
<FilterCriteria
> filters
) {
663 cancelOngoingRequests();
665 if (filters
== null) {
666 fFilterCriteria
= new ArrayList
<>();
668 List
<FilterCriteria
> list
= filters
;
669 fFilterCriteria
= new ArrayList
<>(list
);
672 fillCurrentPage(fEvents
);
681 public boolean hasNextPage() {
684 int size
= fCheckPoints
.size();
686 return fCurrentPage
< (size
- 1);
695 public boolean hasPrevPage() {
698 return fCurrentPage
> 0;
705 public void nextPage() {
709 if (fCurrentPage
>= (fCheckPoints
.size() - 1)) {
713 cancelOngoingRequests();
723 public void prevPage() {
727 if (fCurrentPage
<= 0) {
731 cancelOngoingRequests();
741 public void firstPage() {
745 cancelOngoingRequests();
755 public void lastPage() {
758 cancelOngoingRequests();
760 fCurrentPage
= fCheckPoints
.size() - 1;
768 public int currentPage() {
778 public int pagesCount() {
781 return fCheckPoints
.size();
788 public void pageNumberChanged(int pagenNumber
) {
789 int localPageNumber
= pagenNumber
;
793 cancelOngoingRequests();
795 if (localPageNumber
< 0) {
798 int size
= fCheckPoints
.size();
799 if (localPageNumber
> (size
- 1)) {
800 localPageNumber
= size
- 1;
802 fCurrentPage
= localPageNumber
;
810 public void broadcast(TmfSignal signal
) {
811 fIsSignalSent
= true;
812 super.broadcast(signal
);
813 fIsSignalSent
= false;
817 * Cancels any ongoing find operation
819 protected void cancelOngoingRequests() {
821 ITmfEventRequest pageRequest
= null;
823 // Cancel the search thread
824 if (fFindJob
!= null) {
829 fFindCriteria
= null;
830 fCurrentFindIndex
= 0;
832 pageRequest
= fPageRequest
;
837 if (pageRequest
!= null && !pageRequest
.isCompleted()) {
838 pageRequest
.cancel();
843 * Resets loader attributes
845 protected void resetLoader() {
850 fCheckPoints
.clear();
852 fCurrentFindIndex
= 0;
853 fFindCriteria
= null;
855 fView
.setFrameSync(new Frame());
865 * Fills current page with sequence diagram content.
867 * @param events sequence diagram events
869 protected void fillCurrentPage(List
<ITmfSyncSequenceDiagramEvent
> events
) {
873 fEvents
= new ArrayList
<>(events
);
874 if (fView
!= null && !events
.isEmpty()) {
875 fView
.toggleWaitCursorAsync(true);
881 final Frame frame
= new Frame();
883 if (!events
.isEmpty()) {
884 Map
<String
, Lifeline
> nodeToLifelineMap
= new HashMap
<>();
886 frame
.setName(Messages
.TmfUml2SDSyncLoader_FrameName
);
888 for (int i
= 0; i
< events
.size(); i
++) {
890 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
892 if ((nodeToLifelineMap
.get(sdEvent
.getSender()) == null) && (!filterLifeLine(sdEvent
.getSender()))) {
893 Lifeline lifeline
= new Lifeline();
894 lifeline
.setName(sdEvent
.getSender());
895 nodeToLifelineMap
.put(sdEvent
.getSender(), lifeline
);
896 frame
.addLifeLine(lifeline
);
899 if ((nodeToLifelineMap
.get(sdEvent
.getReceiver()) == null) && (!filterLifeLine(sdEvent
.getReceiver()))) {
900 Lifeline lifeline
= new Lifeline();
901 lifeline
.setName(sdEvent
.getReceiver());
902 nodeToLifelineMap
.put(sdEvent
.getReceiver(), lifeline
);
903 frame
.addLifeLine(lifeline
);
907 int eventOccurence
= 1;
909 for (int i
= 0; i
< events
.size(); i
++) {
910 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
912 // Check message filter
913 if (filterMessage(sdEvent
)) {
917 // Set the message sender and receiver
918 Lifeline startLifeline
= nodeToLifelineMap
.get(sdEvent
.getSender());
919 Lifeline endLifeline
= nodeToLifelineMap
.get(sdEvent
.getReceiver());
921 // Check if any of the lifelines were filtered
922 if ((startLifeline
== null) || (endLifeline
== null)) {
926 int tmp
= Math
.max(startLifeline
.getEventOccurrence(), endLifeline
.getEventOccurrence());
927 eventOccurence
= Math
.max(eventOccurence
, tmp
);
929 startLifeline
.setCurrentEventOccurrence(eventOccurence
);
930 endLifeline
.setCurrentEventOccurrence(eventOccurence
);
932 TmfSyncMessage message
= new TmfSyncMessage(sdEvent
, eventOccurence
++);
934 message
.setStartLifeline(startLifeline
);
935 message
.setEndLifeline(endLifeline
);
937 message
.setTime(sdEvent
.getStartTime());
939 // add the message to the frame
940 frame
.addMessage(message
);
945 if (!fView
.getSDWidget().isDisposed()) {
946 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
953 // check if view was disposed in the meanwhile
954 if ((fView
!= null) && (!fView
.getSDWidget().isDisposed())) {
956 fView
.setFrame(fFrame
);
958 if (fCurrentTime
!= null) {
959 moveToMessageInPage();
962 if (fFindCriteria
!= null) {
966 fView
.toggleWaitCursorAsync(false);
983 * Moves to a certain message defined by timestamp (across pages)
985 protected void moveToMessage() {
990 page
= getPage(fCurrentTime
);
992 if (page
== fCurrentPage
) {
993 moveToMessageInPage();
1004 * Moves to a certain message defined by timestamp in current page
1006 protected void moveToMessageInPage() {
1009 if (!fView
.getSDWidget().isDisposed()) {
1010 // Check for GUI thread
1011 if(Display
.getCurrent() != null) {
1012 // Already in GUI thread - execute directly
1013 TmfSyncMessage prevMessage
= null;
1014 TmfSyncMessage syncMessage
= null;
1015 boolean isExactTime
= false;
1016 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
1017 if (fFrame
.getSyncMessage(i
) instanceof TmfSyncMessage
) {
1018 syncMessage
= (TmfSyncMessage
) fFrame
.getSyncMessage(i
);
1019 if (syncMessage
.getStartTime().compareTo(fCurrentTime
) == 0) {
1022 } else if ((syncMessage
.getStartTime().compareTo(fCurrentTime
) > 0) && (prevMessage
!= null)) {
1023 syncMessage
= prevMessage
;
1026 prevMessage
= syncMessage
;
1029 if (fIsSelect
&& isExactTime
) {
1030 fView
.getSDWidget().moveTo(syncMessage
);
1033 fView
.getSDWidget().ensureVisible(syncMessage
);
1034 fView
.getSDWidget().clearSelection();
1035 fView
.getSDWidget().redraw();
1039 // Not in GUI thread - queue action in GUI thread.
1040 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1043 moveToMessageInPage();
1055 * Moves to a certain message defined by timestamp (across pages)
1057 protected void moveToPage() {
1062 * Moves to a certain page.
1064 * @param notifyAll true to broadcast time range signal to other signal handlers else false
1066 protected void moveToPage(boolean notifyAll
) {
1068 TmfTimeRange window
= null;
1073 if (fCurrentPage
> fCheckPoints
.size()) {
1076 window
= fCheckPoints
.get(fCurrentPage
);
1081 if (window
== null) {
1082 window
= TmfTimeRange
.ETERNITY
;
1085 fPageRequest
= new TmfEventRequest(ITmfEvent
.class, window
, 0,
1086 ITmfEventRequest
.ALL_DATA
, ITmfEventRequest
.ExecutionType
.FOREGROUND
) {
1087 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvent
= new ArrayList
<>();
1090 public void handleData(ITmfEvent event
) {
1091 super.handleData(event
);
1093 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1095 if (sdEvent
!= null) {
1096 fSdEvent
.add(sdEvent
);
1101 public void handleSuccess() {
1102 fillCurrentPage(fSdEvent
);
1103 super.handleSuccess();
1108 fTrace
.sendRequest(fPageRequest
);
1111 TmfTimeRange timeRange
= getSignalTimeRange(window
.getStartTime());
1112 broadcast(new TmfWindowRangeUpdatedSignal(this, timeRange
));
1117 * Gets page that contains timestamp
1119 * @param time The timestamp
1120 * @return page that contains the time
1122 protected int getPage(ITmfTimestamp time
) {
1127 size
= fCheckPoints
.size();
1128 for (page
= 0; page
< size
; page
++) {
1129 TmfTimeRange timeRange
= fCheckPoints
.get(page
);
1130 if (timeRange
.getEndTime().compareTo(time
) >= 0) {
1144 * Background search in trace for expression in criteria.
1146 * @param findCriteria The find criteria
1147 * @return true if background request was started else false
1149 protected boolean findInNextPages(Criteria findCriteria
) {
1152 if (fFindJob
!= null) {
1156 int nextPage
= fCurrentPage
+ 1;
1158 if ((nextPage
) >= fCheckPoints
.size()) {
1159 // we are at the end
1163 TmfTimeRange window
= new TmfTimeRange(fCheckPoints
.get(nextPage
).getStartTime(), fCheckPoints
.get(fCheckPoints
.size()-1).getEndTime());
1164 fFindJob
= new SearchJob(findCriteria
, window
);
1165 fFindJob
.schedule();
1166 fView
.toggleWaitCursorAsync(true);
1174 * Gets time range for time range signal.
1176 * @param startTime The start time of time range.
1177 * @return the time range
1179 protected TmfTimeRange
getSignalTimeRange(ITmfTimestamp startTime
) {
1182 TmfTimeRange currentRange
= TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange();
1183 long offset
= fTrace
== null ?
0 : currentRange
.getEndTime().getDelta(currentRange
.getStartTime()).toNanos();
1184 ITmfTimestamp initialEndOfWindow
= TmfTimestamp
.create(startTime
.getValue() + offset
, startTime
.getScale());
1185 return new TmfTimeRange(startTime
, initialEndOfWindow
);
1193 * Checks if filter criteria matches the message name in given SD event.
1195 * @param sdEvent The SD event to check
1196 * @return true if match else false.
1198 protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent
) {
1201 if (fFilterCriteria
!= null) {
1202 for(FilterCriteria criteria
: fFilterCriteria
) {
1203 if (criteria
.isActive() && criteria
.getCriteria().isSyncMessageSelected() && criteria
.getCriteria().matches(sdEvent
.getName())) {
1215 * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event.
1217 * @param lifeline the message receiver
1218 * @return true if match else false.
1220 protected boolean filterLifeLine(String lifeline
) {
1223 if (fFilterCriteria
!= null) {
1224 for(FilterCriteria criteria
: fFilterCriteria
) {
1225 if (criteria
.isActive() && criteria
.getCriteria().isLifeLineSelected() && criteria
.getCriteria().matches(lifeline
)) {
1237 * Job to search in trace for given time range.
1239 protected class SearchJob
extends Job
{
1242 * The search event request.
1244 protected final SearchEventRequest fSearchRequest
;
1249 * @param findCriteria The search criteria
1250 * @param window Time range to search in
1252 public SearchJob(Criteria findCriteria
, TmfTimeRange window
) {
1253 super(Messages
.TmfUml2SDSyncLoader_SearchJobDescrition
);
1254 fSearchRequest
= new SearchEventRequest(window
, ITmfEventRequest
.ALL_DATA
,
1255 ITmfEventRequest
.ExecutionType
.FOREGROUND
, findCriteria
);
1259 protected IStatus
run(IProgressMonitor monitor
) {
1260 fSearchRequest
.setMonitor(monitor
);
1262 fTrace
.sendRequest(fSearchRequest
);
1265 fSearchRequest
.waitForCompletion();
1266 } catch (InterruptedException e
) {
1267 Activator
.getDefault().logError("Search request interrupted!", e
); //$NON-NLS-1$
1270 IStatus status
= Status
.OK_STATUS
;
1271 if (fSearchRequest
.isFound() && (fSearchRequest
.getFoundTime() != null)) {
1272 fCurrentTime
= fSearchRequest
.getFoundTime();
1274 // Avoid double-selection. Selection will be done when calling find(criteria)
1275 // after moving to relevant page
1277 if (!fView
.getSDWidget().isDisposed()) {
1278 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1288 if (monitor
.isCanceled()) {
1289 status
= Status
.CANCEL_STATUS
;
1292 // String was not found
1293 status
= new Status(IStatus
.WARNING
, Activator
.PLUGIN_ID
, Messages
.TmfUml2SDSyncLoader_SearchNotFound
);
1295 setProperty(IProgressConstants
.KEEP_PROPERTY
, Boolean
.TRUE
);
1301 fView
.toggleWaitCursorAsync(false);
1311 protected void canceling() {
1312 fSearchRequest
.cancel();
1323 * TMF event request for searching within trace.
1325 protected class SearchEventRequest
extends TmfEventRequest
{
1328 * The find criteria.
1330 private final Criteria fCriteria
;
1332 * A progress monitor
1334 private IProgressMonitor fMonitor
;
1336 * Flag to indicate that node was found according the criteria .
1338 private boolean fIsFound
= false;
1340 * Time stamp of found item.
1342 private ITmfTimestamp fFoundTime
= null;
1349 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1351 * @param nbRequested
1353 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1356 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#FOREGROUND}
1358 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#BACKGROUND}
1360 * The search criteria
1362 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, ExecutionType priority
, Criteria criteria
) {
1363 this(range
, nbRequested
, priority
, criteria
, null);
1371 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1373 * @param nbRequested
1375 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1378 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#FOREGROUND} or
1379 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#BACKGROUND}
1381 * The search criteria
1385 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, ExecutionType priority
, Criteria criteria
, IProgressMonitor monitor
) {
1386 super(ITmfEvent
.class, range
, 0, nbRequested
, priority
);
1387 fCriteria
= new Criteria(criteria
);
1392 public void handleData(ITmfEvent event
) {
1393 super.handleData(event
);
1395 if ((fMonitor
!= null) && fMonitor
.isCanceled()) {
1400 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1402 if (sdEvent
!= null) {
1404 if (fCriteria
.isLifeLineSelected()) {
1405 if (fCriteria
.matches(sdEvent
.getSender())) {
1406 fFoundTime
= event
.getTimestamp();
1411 if (fCriteria
.matches(sdEvent
.getReceiver())) {
1412 fFoundTime
= event
.getTimestamp();
1418 if (fCriteria
.isSyncMessageSelected() && fCriteria
.matches(sdEvent
.getName())) {
1419 fFoundTime
= event
.getTimestamp();
1427 * Set progress monitor.
1429 * @param monitor The monitor to assign
1431 public void setMonitor(IProgressMonitor monitor
) {
1436 * Check if find criteria was met.
1438 * @return true if find criteria was met.
1440 public boolean isFound() {
1445 * Returns timestamp of found time.
1447 * @return timestamp of found time.
1449 public ITmfTimestamp
getFoundTime() {
1455 * Job class to provide progress monitor feedback.
1457 * @author Bernd Hufmann
1459 protected static class IndexingJob
extends Job
{
1462 * @param name The job name
1464 public IndexingJob(String name
) {
1469 protected IStatus
run(IProgressMonitor monitor
) {
1470 while (!monitor
.isCanceled()) {
1472 Thread
.sleep(INDEXING_THREAD_SLEEP_VALUE
);
1473 } catch (InterruptedException e
) {
1474 return Status
.OK_STATUS
;
1478 return Status
.OK_STATUS
;
1484 * Returns sequence diagram event if details in given event are available else null.
1486 * @param tmfEvent Event to parse for sequence diagram event details
1487 * @return sequence diagram event if details are available else null
1489 protected ITmfSyncSequenceDiagramEvent
getSequenceDiagramEvent(ITmfEvent tmfEvent
){
1490 //type = .*RECEIVE.* or .*SEND.*
1491 //content = sender:<sender name>:receiver:<receiver name>,signal:<signal name>
1492 String eventName
= tmfEvent
.getName();
1493 if (eventName
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeSend
) || eventName
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeReceive
)) {
1494 Object sender
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldSender
);
1495 Object receiver
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldReceiver
);
1496 Object name
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldSignal
);
1497 if ((sender
instanceof ITmfEventField
) && (receiver
instanceof ITmfEventField
) && (name
instanceof ITmfEventField
)) {
1498 ITmfSyncSequenceDiagramEvent sdEvent
= new TmfSyncSequenceDiagramEvent(tmfEvent
,
1499 ((ITmfEventField
) sender
).getValue().toString(),
1500 ((ITmfEventField
) receiver
).getValue().toString(),
1501 ((ITmfEventField
) name
).getValue().toString());