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
.common
.core
.NonNullUtils
;
30 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.component
.TmfComponent
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.request
.ITmfEventRequest
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.request
.TmfEventRequest
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSelectionRangeUpdatedSignal
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignal
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalHandler
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceClosedSignal
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfWindowRangeUpdatedSignal
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestamp
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.uml2sd
.ITmfSyncSequenceDiagramEvent
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.uml2sd
.TmfSyncSequenceDiagramEvent
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.editors
.ITmfTraceEditor
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.SDView
;
52 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
53 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
54 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
55 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.Criteria
;
56 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterCriteria
;
57 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterListDialog
;
58 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDAdvancedPagingProvider
;
59 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFilterProvider
;
60 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFindProvider
;
61 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDGraphNodeSupporter
;
62 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.uml2sd
.load
.IUml2SDLoader
;
63 import org
.eclipse
.ui
.IEditorPart
;
64 import org
.eclipse
.ui
.ISelectionListener
;
65 import org
.eclipse
.ui
.IWorkbenchPart
;
66 import org
.eclipse
.ui
.IWorkbenchWindow
;
67 import org
.eclipse
.ui
.PlatformUI
;
68 import org
.eclipse
.ui
.progress
.IProgressConstants
;
72 * This class is a reference implementation of the
73 * <code>org.eclipse.tracecompass.tmf.ui.Uml2SDLoader</code> extension point. It
74 * provides a Sequence Diagram loader for a user space trace with specific trace
75 * content for sending and receiving signals between components. I also includes
76 * a default implementation for the <code>ITmfEvent</code> parsing.
79 * The class <code>TmfUml2SDSyncLoader</code> analyzes events from type
80 * <code>ITmfEvent</code> and creates events type
81 * <code>ITmfSyncSequenceDiagramEvent</code> if the <code>ITmfEvent</code>
82 * contains all relevant information. The analysis checks that the event type
83 * strings contains either string SEND or RECEIVE. If event type matches these
84 * key words, the analyzer will look for strings sender, receiver and signal in
85 * the event fields of type <code>ITmfEventField</code>. If all the data is
86 * found a sequence diagram event from can be created. Note that Sync Messages
87 * are assumed, which means start and end time are the same. <br>
89 * The parsing of the <code>ITmfEvent</code> is done in the method
90 * <code>getSequnceDiagramEvent()</code> of class
91 * <code>TmfUml2SDSyncLoader</code>. By extending the class
92 * <code>TmfUml2SDSyncLoader</code> and overwriting
93 * <code>getSequnceDiagramEvent()</code> a customized parsing algorithm can be
96 * Note that combined traces of multiple components, that contain the trace
97 * information about the same interactions are not supported in the class
98 * <code>TmfUml2SDSyncLoader</code>.
101 * @author Bernd Hufmann
103 public class TmfUml2SDSyncLoader
extends TmfComponent
implements IUml2SDLoader
, ISDFindProvider
, ISDFilterProvider
, ISDAdvancedPagingProvider
, ISelectionListener
{
105 // ------------------------------------------------------------------------
107 // ------------------------------------------------------------------------
110 * Default title name.
112 protected static final String TITLE
= Messages
.TmfUml2SDSyncLoader_ViewName
;
115 * Maximum number of messages per page.
117 protected static final int MAX_NUM_OF_MSG
= 10000;
119 private static final int INDEXING_THREAD_SLEEP_VALUE
= 100;
121 // ------------------------------------------------------------------------
123 // ------------------------------------------------------------------------
125 // Experiment attributes
127 * The TMF trace reference.
129 protected ITmfTrace fTrace
= null;
131 * The current indexing event request.
133 protected ITmfEventRequest fIndexRequest
= null;
135 * The current request to fill a page.
137 protected ITmfEventRequest fPageRequest
= null;
139 * Flag whether the time range signal was sent by this loader class or not
141 protected volatile boolean fIsSignalSent
= false;
143 // The view and event attributes
145 * The sequence diagram view reference.
147 protected SDView fView
= null;
149 * The current sequence diagram frame reference.
151 protected Frame fFrame
= null;
153 * The list of sequence diagram events of current page.
155 protected List
<ITmfSyncSequenceDiagramEvent
> fEvents
= new ArrayList
<>();
157 // Checkpoint and page attributes
159 * The checkpoints of the whole sequence diagram trace (i.e. start time
160 * stamp of each page)
162 protected List
<TmfTimeRange
> fCheckPoints
= new ArrayList
<>(MAX_NUM_OF_MSG
);
164 * The current page displayed.
166 protected volatile int fCurrentPage
= 0;
168 * The current time selected.
170 protected ITmfTimestamp fCurrentTime
= null;
172 * Flag to specify that selection of message is done by selection or by
175 protected volatile boolean fIsSelect
= false;
179 * The job for searching across pages.
181 protected SearchJob fFindJob
= null;
183 * List of found nodes within a page.
185 protected List
<GraphNode
> fFindResults
= new ArrayList
<>();
187 * The current find criteria reference
189 protected Criteria fFindCriteria
= null;
191 * The current find index within the list of found nodes
192 * (<code>fFindeResults</code> within a page.
194 protected volatile int fCurrentFindIndex
= 0;
198 * The list of active filters.
200 protected List
<FilterCriteria
> fFilterCriteria
= null;
202 // Thread synchronization
204 * The synchronization lock.
206 protected ReentrantLock fLock
= new ReentrantLock();
208 // ------------------------------------------------------------------------
210 // ------------------------------------------------------------------------
212 * Default constructor
214 public TmfUml2SDSyncLoader() {
224 public TmfUml2SDSyncLoader(String name
) {
228 // ------------------------------------------------------------------------
230 // ------------------------------------------------------------------------
233 * Returns the current time if available else null.
235 * @return the current time if available else null
237 public ITmfTimestamp
getCurrentTime() {
240 if (fCurrentTime
!= null) {
250 * Waits for the page request to be completed
252 public void waitForCompletion() {
254 ITmfEventRequest request
= fPageRequest
;
256 if (request
!= null) {
258 request
.waitForCompletion();
259 } catch (InterruptedException e
) {
266 * Handler for the trace opened signal.
269 * The trace opened signal
272 public void traceOpened(TmfTraceOpenedSignal signal
) {
273 fTrace
= signal
.getTrace();
278 * Signal handler for the trace selected signal.
280 * Spawns a request to index the trace (checkpoints creation) as well as it
281 * fills the first page.
284 * The trace selected signal
287 public void traceSelected(TmfTraceSelectedSignal signal
) {
288 // Update the trace reference
289 ITmfTrace trace
= signal
.getTrace();
290 if (!trace
.equals(fTrace
)) {
297 * Method for loading the current selected trace into the view. Sub-class
298 * need to override this method to add the view specific implementation.
300 protected void loadTrace() {
301 ITmfEventRequest indexRequest
= null;
305 final Job job
= new IndexingJob("Indexing " + getName() + "..."); //$NON-NLS-1$ //$NON-NLS-2$
309 indexRequest
= fIndexRequest
;
311 cancelOngoingRequests();
313 TmfTimeRange window
= TmfTimeRange
.ETERNITY
;
315 fIndexRequest
= new TmfEventRequest(ITmfEvent
.class, window
, 0,
316 ITmfEventRequest
.ALL_DATA
, ITmfEventRequest
.ExecutionType
.BACKGROUND
) {
318 private ITmfTimestamp fFirstTime
= null;
319 private ITmfTimestamp fLastTime
= null;
320 private int fNbSeqEvents
= 0;
321 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvents
= new ArrayList
<>(MAX_NUM_OF_MSG
);
324 public void handleData(ITmfEvent event
) {
325 super.handleData(event
);
327 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
328 ITmfTimestamp firstTime
= fFirstTime
;
329 ITmfTimestamp lastTime
= fLastTime
;
331 if (sdEvent
!= null) {
334 if (firstTime
== null) {
335 firstTime
= event
.getTimestamp();
336 fFirstTime
= firstTime
;
339 lastTime
= event
.getTimestamp();
340 fLastTime
= lastTime
;
342 if ((fNbSeqEvents
% MAX_NUM_OF_MSG
) == 0) {
345 fCheckPoints
.add(new TmfTimeRange(firstTime
, lastTime
));
347 fView
.updateCoolBar();
356 if (fNbSeqEvents
> MAX_NUM_OF_MSG
) {
361 fSdEvents
.add(sdEvent
);
363 if (fNbSeqEvents
== MAX_NUM_OF_MSG
) {
364 fillCurrentPage(fSdEvents
);
370 public void handleSuccess() {
371 final ITmfTimestamp firstTime
= fFirstTime
;
372 final ITmfTimestamp lastTime
= fLastTime
;
373 if ((firstTime
!= null) && (lastTime
!= null)) {
377 fCheckPoints
.add(new TmfTimeRange(firstTime
, lastTime
));
379 fView
.updateCoolBar();
386 if (fNbSeqEvents
<= MAX_NUM_OF_MSG
) {
387 fillCurrentPage(fSdEvents
);
390 super.handleSuccess();
394 public void handleCompleted() {
395 if (fEvents
.isEmpty()) {
396 fFrame
= new Frame();
397 // make sure that view is not null when setting frame
405 if (sdView
!= null) {
406 sdView
.setFrameSync(fFrame
);
409 super.handleCompleted();
417 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
418 indexRequest
.cancel();
421 fTrace
.sendRequest(fIndexRequest
);
425 * Signal handler for the trace closed signal.
428 * The trace closed signal
431 public void traceClosed(TmfTraceClosedSignal signal
) {
432 if (signal
.getTrace() != fTrace
) {
435 ITmfEventRequest indexRequest
= null;
438 indexRequest
= fIndexRequest
;
439 fIndexRequest
= null;
441 cancelOngoingRequests();
443 if (fFilterCriteria
!= null) {
444 fFilterCriteria
.clear();
447 FilterListDialog
.deactivateSavedGlobalFilters();
452 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
453 indexRequest
.cancel();
460 * Moves to the page that contains the time provided by the signal. The
461 * messages will be selected if the provided time is the time of a message.
464 * The selection range signal
468 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal
) {
471 if ((signal
.getSource() != this) && (fFrame
!= null) && (fCheckPoints
.size() > 0)) {
472 fCurrentTime
= signal
.getBeginTime();
482 * Moves to the page that contains the current time provided by signal. No
483 * message will be selected however the focus will be set to the message if
484 * the provided time is the time of a message.
487 * The window range signal
491 public void windowRangeUpdated(TmfWindowRangeUpdatedSignal signal
) {
494 if ((signal
.getSource() != this) && (fFrame
!= null) && !fIsSignalSent
&& (fCheckPoints
.size() > 0)) {
495 TmfTimeRange newTimeRange
= signal
.getCurrentRange();
498 fCurrentTime
= newTimeRange
.getStartTime();
509 public void setViewer(SDView viewer
) {
514 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
515 fView
.setSDFindProvider(this);
516 fView
.setSDPagingProvider(this);
517 fView
.setSDFilterProvider(this);
520 IEditorPart editor
= fView
.getSite().getPage().getActiveEditor();
521 if (editor
instanceof ITmfTraceEditor
) {
522 ITmfTrace trace
= ((ITmfTraceEditor
) editor
).getTrace();
524 traceSelected(new TmfTraceSelectedSignal(this, trace
));
533 public String
getTitleString() {
538 public void dispose() {
540 ITmfEventRequest indexRequest
= null;
543 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
544 // During Eclipse shutdown the active workbench window is null
545 if (window
!= null) {
546 window
.getSelectionService().removePostSelectionListener(this);
549 indexRequest
= fIndexRequest
;
550 fIndexRequest
= null;
551 cancelOngoingRequests();
553 fView
.setSDFindProvider(null);
554 fView
.setSDPagingProvider(null);
555 fView
.setSDFilterProvider(null);
560 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
561 indexRequest
.cancel();
566 public boolean isNodeSupported(int nodeType
) {
568 case ISDGraphNodeSupporter
.LIFELINE
:
569 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
579 public String
getNodeName(int nodeType
, String loaderClassName
) {
581 case ISDGraphNodeSupporter
.LIFELINE
:
582 return Messages
.TmfUml2SDSyncLoader_CategoryLifeline
;
583 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
584 return Messages
.TmfUml2SDSyncLoader_CategoryMessage
;
588 return ""; //$NON-NLS-1$
592 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
593 ISelection sel
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
594 if ((sel
!= null) && (sel
instanceof StructuredSelection
)) {
595 StructuredSelection stSel
= (StructuredSelection
) sel
;
596 if (stSel
.getFirstElement() instanceof TmfSyncMessage
) {
597 TmfSyncMessage syncMsg
= ((TmfSyncMessage
) stSel
.getFirstElement());
598 ITmfTimestamp startTime
= syncMsg
.getStartTime();
599 if (startTime
== null) {
600 startTime
= TmfTimestamp
.BIG_BANG
;
602 broadcast(new TmfSelectionRangeUpdatedSignal(this, startTime
));
608 public boolean find(Criteria toSearch
) {
611 if (fFrame
== null) {
615 if ((fFindResults
== null) || (fFindCriteria
== null) || !fFindCriteria
.compareTo(toSearch
)) {
616 fFindResults
= new CopyOnWriteArrayList
<>();
617 fFindCriteria
= toSearch
;
618 if (fFindCriteria
.isLifeLineSelected()) {
619 for (int i
= 0; i
< fFrame
.lifeLinesCount(); i
++) {
620 if (fFindCriteria
.matches(fFrame
.getLifeline(i
).getName())) {
621 fFindResults
.add(fFrame
.getLifeline(i
));
626 ArrayList
<GraphNode
> msgs
= new ArrayList
<>();
627 if (fFindCriteria
.isSyncMessageSelected()) {
628 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
629 if (fFindCriteria
.matches(fFrame
.getSyncMessage(i
).getName())) {
630 msgs
.add(fFrame
.getSyncMessage(i
));
635 if (!msgs
.isEmpty()) {
636 fFindResults
.addAll(msgs
);
639 List
<GraphNode
> selection
= fView
.getSDWidget().getSelection();
640 if ((selection
!= null) && (selection
.size() == 1)) {
641 fCurrentFindIndex
= fFindResults
.indexOf(selection
.get(0)) + 1;
643 fCurrentFindIndex
= 0;
646 // ++ is not atomic, but we are in a lock
647 fCurrentFindIndex
= fCurrentFindIndex
+ 1;
650 if (fFindResults
.size() > fCurrentFindIndex
) {
651 GraphNode current
= fFindResults
.get(fCurrentFindIndex
);
652 fView
.getSDWidget().moveTo(current
);
656 fCurrentFindIndex
= 0;
657 return findInNextPages(fFindCriteria
); // search in other page
664 public void cancel() {
665 cancelOngoingRequests();
669 public boolean filter(List
<FilterCriteria
> filters
) {
672 cancelOngoingRequests();
674 if (filters
== null) {
675 fFilterCriteria
= new ArrayList
<>();
677 List
<FilterCriteria
> list
= filters
;
678 fFilterCriteria
= new ArrayList
<>(list
);
681 fillCurrentPage(fEvents
);
690 public boolean hasNextPage() {
693 int size
= fCheckPoints
.size();
695 return fCurrentPage
< (size
- 1);
704 public boolean hasPrevPage() {
707 return fCurrentPage
> 0;
714 public void nextPage() {
718 if (fCurrentPage
>= (fCheckPoints
.size() - 1)) {
722 cancelOngoingRequests();
724 // ++ is not atomic but we are in a lock
725 fCurrentPage
= fCurrentPage
+ 1;
733 public void prevPage() {
737 if (fCurrentPage
<= 0) {
741 cancelOngoingRequests();
743 // -- is not atomic but we are in a lock
744 fCurrentPage
= fCurrentPage
- 1;
752 public void firstPage() {
756 cancelOngoingRequests();
766 public void lastPage() {
769 cancelOngoingRequests();
771 fCurrentPage
= fCheckPoints
.size() - 1;
779 public int currentPage() {
789 public int pagesCount() {
792 return fCheckPoints
.size();
799 public void pageNumberChanged(int pagenNumber
) {
800 int localPageNumber
= pagenNumber
;
804 cancelOngoingRequests();
806 if (localPageNumber
< 0) {
809 int size
= fCheckPoints
.size();
810 if (localPageNumber
> (size
- 1)) {
811 localPageNumber
= size
- 1;
813 fCurrentPage
= localPageNumber
;
821 public void broadcast(TmfSignal signal
) {
822 fIsSignalSent
= true;
823 super.broadcast(signal
);
824 fIsSignalSent
= false;
828 * Cancels any ongoing find operation
830 protected void cancelOngoingRequests() {
832 ITmfEventRequest pageRequest
= null;
834 // Cancel the search thread
835 if (fFindJob
!= null) {
840 fFindCriteria
= null;
841 fCurrentFindIndex
= 0;
843 pageRequest
= fPageRequest
;
848 if (pageRequest
!= null && !pageRequest
.isCompleted()) {
849 pageRequest
.cancel();
854 * Resets loader attributes
856 protected void resetLoader() {
861 fCheckPoints
.clear();
863 fCurrentFindIndex
= 0;
864 fFindCriteria
= null;
866 fView
.setFrameSync(new Frame());
875 * Fills current page with sequence diagram content.
878 * sequence diagram events
880 protected void fillCurrentPage(List
<ITmfSyncSequenceDiagramEvent
> events
) {
884 fEvents
= new ArrayList
<>(events
);
885 if (fView
!= null && !events
.isEmpty()) {
886 fView
.toggleWaitCursorAsync(true);
892 final Frame frame
= new Frame();
894 if (!events
.isEmpty()) {
895 Map
<String
, Lifeline
> nodeToLifelineMap
= new HashMap
<>();
897 frame
.setName(Messages
.TmfUml2SDSyncLoader_FrameName
);
899 for (int i
= 0; i
< events
.size(); i
++) {
901 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
903 if ((nodeToLifelineMap
.get(sdEvent
.getSender()) == null) && (!filterLifeLine(sdEvent
.getSender()))) {
904 Lifeline lifeline
= new Lifeline();
905 lifeline
.setName(sdEvent
.getSender());
906 nodeToLifelineMap
.put(sdEvent
.getSender(), lifeline
);
907 frame
.addLifeLine(lifeline
);
910 if ((nodeToLifelineMap
.get(sdEvent
.getReceiver()) == null) && (!filterLifeLine(sdEvent
.getReceiver()))) {
911 Lifeline lifeline
= new Lifeline();
912 lifeline
.setName(sdEvent
.getReceiver());
913 nodeToLifelineMap
.put(sdEvent
.getReceiver(), lifeline
);
914 frame
.addLifeLine(lifeline
);
918 int eventOccurence
= 1;
920 for (int i
= 0; i
< events
.size(); i
++) {
921 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
923 // Check message filter
924 if (filterMessage(sdEvent
)) {
928 // Set the message sender and receiver
929 Lifeline startLifeline
= nodeToLifelineMap
.get(sdEvent
.getSender());
930 Lifeline endLifeline
= nodeToLifelineMap
.get(sdEvent
.getReceiver());
932 // Check if any of the lifelines were filtered
933 if ((startLifeline
== null) || (endLifeline
== null)) {
937 int tmp
= Math
.max(startLifeline
.getEventOccurrence(), endLifeline
.getEventOccurrence());
938 eventOccurence
= Math
.max(eventOccurence
, tmp
);
940 startLifeline
.setCurrentEventOccurrence(eventOccurence
);
941 endLifeline
.setCurrentEventOccurrence(eventOccurence
);
943 TmfSyncMessage message
= new TmfSyncMessage(sdEvent
, eventOccurence
++);
945 message
.setStartLifeline(startLifeline
);
946 message
.setEndLifeline(endLifeline
);
948 message
.setTime(sdEvent
.getStartTime());
950 // add the message to the frame
951 frame
.addMessage(message
);
956 if (!fView
.getSDWidget().isDisposed()) {
957 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
964 // check if view was disposed in the meanwhile
965 if ((fView
!= null) && (!fView
.getSDWidget().isDisposed())) {
967 fView
.setFrame(fFrame
);
969 if (fCurrentTime
!= null) {
970 moveToMessageInPage();
973 if (fFindCriteria
!= null) {
977 fView
.toggleWaitCursorAsync(false);
993 * Moves to a certain message defined by timestamp (across pages)
995 protected void moveToMessage() {
1000 page
= getPage(fCurrentTime
);
1002 if (page
== fCurrentPage
) {
1003 moveToMessageInPage();
1006 fCurrentPage
= page
;
1014 * Moves to a certain message defined by timestamp in current page
1016 protected void moveToMessageInPage() {
1019 if (!fView
.getSDWidget().isDisposed()) {
1020 // Check for GUI thread
1021 if (Display
.getCurrent() != null) {
1022 // Already in GUI thread - execute directly
1023 TmfSyncMessage prevMessage
= null;
1024 TmfSyncMessage syncMessage
= null;
1025 boolean isExactTime
= false;
1026 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
1027 if (fFrame
.getSyncMessage(i
) instanceof TmfSyncMessage
) {
1028 syncMessage
= (TmfSyncMessage
) fFrame
.getSyncMessage(i
);
1029 if (syncMessage
.getStartTime().compareTo(fCurrentTime
) == 0) {
1032 } else if ((syncMessage
.getStartTime().compareTo(fCurrentTime
) > 0) && (prevMessage
!= null)) {
1033 syncMessage
= prevMessage
;
1036 prevMessage
= syncMessage
;
1039 if (fIsSelect
&& isExactTime
) {
1040 fView
.getSDWidget().moveTo(syncMessage
);
1042 fView
.getSDWidget().ensureVisible(syncMessage
);
1043 fView
.getSDWidget().clearSelection();
1044 fView
.getSDWidget().redraw();
1047 // Not in GUI thread - queue action in GUI thread.
1048 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1051 moveToMessageInPage();
1062 * Moves to a certain message defined by timestamp (across pages)
1064 protected void moveToPage() {
1069 * Moves to a certain page.
1072 * true to broadcast time range signal to other signal handlers
1075 protected void moveToPage(boolean notifyAll
) {
1077 TmfTimeRange window
= null;
1082 if (fCurrentPage
> fCheckPoints
.size()) {
1085 window
= fCheckPoints
.get(fCurrentPage
);
1090 if (window
== null) {
1091 window
= TmfTimeRange
.ETERNITY
;
1094 fPageRequest
= new TmfEventRequest(ITmfEvent
.class, window
, 0,
1095 ITmfEventRequest
.ALL_DATA
, ITmfEventRequest
.ExecutionType
.FOREGROUND
) {
1096 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvent
= new ArrayList
<>();
1099 public void handleData(ITmfEvent event
) {
1100 super.handleData(event
);
1102 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1104 if (sdEvent
!= null) {
1105 fSdEvent
.add(sdEvent
);
1110 public void handleSuccess() {
1111 fillCurrentPage(fSdEvent
);
1112 super.handleSuccess();
1117 fTrace
.sendRequest(fPageRequest
);
1120 TmfTimeRange timeRange
= getSignalTimeRange(window
.getStartTime());
1121 broadcast(new TmfWindowRangeUpdatedSignal(this, timeRange
));
1126 * Gets page that contains timestamp
1130 * @return page that contains the time
1132 protected int getPage(ITmfTimestamp time
) {
1137 size
= fCheckPoints
.size();
1138 for (page
= 0; page
< size
; page
++) {
1139 TmfTimeRange timeRange
= fCheckPoints
.get(page
);
1140 if (timeRange
.getEndTime().compareTo(time
) >= 0) {
1154 * Background search in trace for expression in criteria.
1156 * @param findCriteria
1158 * @return true if background request was started else false
1160 protected boolean findInNextPages(Criteria findCriteria
) {
1163 if (fFindJob
!= null) {
1167 int nextPage
= fCurrentPage
+ 1;
1169 if ((nextPage
) >= fCheckPoints
.size()) {
1170 // we are at the end
1174 TmfTimeRange window
= new TmfTimeRange(fCheckPoints
.get(nextPage
).getStartTime(), fCheckPoints
.get(fCheckPoints
.size() - 1).getEndTime());
1175 fFindJob
= new SearchJob(findCriteria
, window
);
1176 fFindJob
.schedule();
1177 fView
.toggleWaitCursorAsync(true);
1185 * Gets time range for time range signal.
1188 * The start time of time range.
1189 * @return the time range
1191 protected TmfTimeRange
getSignalTimeRange(ITmfTimestamp startTime
) {
1194 TmfTimeRange currentRange
= TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange();
1195 long offset
= fTrace
== null ?
0 : currentRange
.getEndTime().getDelta(currentRange
.getStartTime()).toNanos();
1196 ITmfTimestamp initialEndOfWindow
= TmfTimestamp
.create(startTime
.getValue() + offset
, startTime
.getScale());
1197 return new TmfTimeRange(startTime
, initialEndOfWindow
);
1204 * Checks if filter criteria matches the message name in given SD event.
1207 * The SD event to check
1208 * @return true if match else false.
1210 protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent
) {
1213 if (fFilterCriteria
!= null) {
1214 for (FilterCriteria criteria
: fFilterCriteria
) {
1215 if (criteria
.isActive() && criteria
.getCriteria().isSyncMessageSelected() && criteria
.getCriteria().matches(sdEvent
.getName())) {
1227 * Checks if filter criteria matches a lifeline name (sender or receiver) in
1231 * the message receiver
1232 * @return true if match else false.
1234 protected boolean filterLifeLine(String lifeline
) {
1237 if (fFilterCriteria
!= null) {
1238 for (FilterCriteria criteria
: fFilterCriteria
) {
1239 if (criteria
.isActive() && criteria
.getCriteria().isLifeLineSelected() && criteria
.getCriteria().matches(lifeline
)) {
1251 * Job to search in trace for given time range.
1253 protected class SearchJob
extends Job
{
1256 * The search event request.
1258 protected final SearchEventRequest fSearchRequest
;
1263 * @param findCriteria
1264 * The search criteria
1266 * Time range to search in
1268 public SearchJob(Criteria findCriteria
, TmfTimeRange window
) {
1269 super(Messages
.TmfUml2SDSyncLoader_SearchJobDescrition
);
1270 fSearchRequest
= new SearchEventRequest(window
, ITmfEventRequest
.ALL_DATA
,
1271 ITmfEventRequest
.ExecutionType
.FOREGROUND
, findCriteria
);
1275 protected IStatus
run(IProgressMonitor monitor
) {
1276 fSearchRequest
.setMonitor(monitor
);
1278 fTrace
.sendRequest(fSearchRequest
);
1281 fSearchRequest
.waitForCompletion();
1282 } catch (InterruptedException e
) {
1283 Activator
.getDefault().logError("Search request interrupted!", e
); //$NON-NLS-1$
1286 IStatus status
= Status
.OK_STATUS
;
1287 if (fSearchRequest
.isFound() && (fSearchRequest
.getFoundTime() != null)) {
1288 fCurrentTime
= fSearchRequest
.getFoundTime();
1291 * Avoid double-selection. Selection will be done when calling
1292 * find(criteria) after moving to relevant page
1295 if (!fView
.getSDWidget().isDisposed()) {
1296 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1305 if (monitor
.isCanceled()) {
1306 status
= Status
.CANCEL_STATUS
;
1308 // String was not found
1309 status
= new Status(IStatus
.WARNING
, Activator
.PLUGIN_ID
, Messages
.TmfUml2SDSyncLoader_SearchNotFound
);
1311 setProperty(IProgressConstants
.KEEP_PROPERTY
, Boolean
.TRUE
);
1317 fView
.toggleWaitCursorAsync(false);
1327 protected void canceling() {
1328 fSearchRequest
.cancel();
1339 * TMF event request for searching within trace.
1341 protected class SearchEventRequest
extends TmfEventRequest
{
1344 * The find criteria.
1346 private final Criteria fCriteria
;
1348 * A progress monitor
1350 private IProgressMonitor fMonitor
;
1352 * Flag to indicate that node was found according the criteria .
1354 private boolean fIsFound
= false;
1356 * Time stamp of found item.
1358 private ITmfTimestamp fFoundTime
= null;
1365 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1367 * @param nbRequested
1369 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1372 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#FOREGROUND}
1374 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#BACKGROUND}
1376 * The search criteria
1378 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, ExecutionType priority
, Criteria criteria
) {
1379 this(range
, nbRequested
, priority
, criteria
, null);
1387 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1389 * @param nbRequested
1391 * {@link TmfEventRequest#TmfEventRequest(Class, TmfTimeRange, long, int, org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType)
1394 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#FOREGROUND}
1396 * {@link org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType#BACKGROUND}
1398 * The search criteria
1402 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, ExecutionType priority
, Criteria criteria
, IProgressMonitor monitor
) {
1403 super(ITmfEvent
.class, range
, 0, nbRequested
, priority
);
1404 fCriteria
= new Criteria(criteria
);
1409 public void handleData(ITmfEvent event
) {
1410 super.handleData(event
);
1412 if ((fMonitor
!= null) && fMonitor
.isCanceled()) {
1417 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1419 if (sdEvent
!= null) {
1421 if (fCriteria
.isLifeLineSelected()) {
1422 if (fCriteria
.matches(sdEvent
.getSender())) {
1423 fFoundTime
= event
.getTimestamp();
1428 if (fCriteria
.matches(sdEvent
.getReceiver())) {
1429 fFoundTime
= event
.getTimestamp();
1435 if (fCriteria
.isSyncMessageSelected() && fCriteria
.matches(sdEvent
.getName())) {
1436 fFoundTime
= event
.getTimestamp();
1444 * Set progress monitor.
1447 * The monitor to assign
1449 public void setMonitor(IProgressMonitor monitor
) {
1454 * Check if find criteria was met.
1456 * @return true if find criteria was met.
1458 public boolean isFound() {
1463 * Returns timestamp of found time.
1465 * @return timestamp of found time.
1467 public ITmfTimestamp
getFoundTime() {
1473 * Job class to provide progress monitor feedback.
1475 * @author Bernd Hufmann
1477 protected static class IndexingJob
extends Job
{
1483 public IndexingJob(String name
) {
1488 protected IStatus
run(IProgressMonitor monitor
) {
1489 while (!monitor
.isCanceled()) {
1491 Thread
.sleep(INDEXING_THREAD_SLEEP_VALUE
);
1492 } catch (InterruptedException e
) {
1493 return Status
.OK_STATUS
;
1497 return Status
.OK_STATUS
;
1502 * Returns sequence diagram event if details in given event are available
1506 * Event to parse for sequence diagram event details
1507 * @return sequence diagram event if details are available else null
1509 protected ITmfSyncSequenceDiagramEvent
getSequenceDiagramEvent(ITmfEvent tmfEvent
) {
1510 // type = .*RECEIVE.* or .*SEND.*
1511 // content = sender:<sender name>:receiver:<receiver
1512 // name>,signal:<signal name>
1513 String eventName
= tmfEvent
.getName();
1514 if (eventName
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeSend
) || eventName
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeReceive
)) {
1515 Object sender
= tmfEvent
.getContent().getFieldValue(Object
.class, NonNullUtils
.checkNotNull(Messages
.TmfUml2SDSyncLoader_FieldSender
));
1516 Object receiver
= tmfEvent
.getContent().getFieldValue(Object
.class, NonNullUtils
.checkNotNull(Messages
.TmfUml2SDSyncLoader_FieldReceiver
));
1517 ITmfEventField content
= tmfEvent
.getContent();
1518 Object name
= content
.getFieldValue(Object
.class, NonNullUtils
.checkNotNull(Messages
.TmfUml2SDSyncLoader_FieldSignal
));
1519 if ((sender
!= null) && (receiver
!= null) && (name
!= null)) {
1520 ITmfSyncSequenceDiagramEvent sdEvent
= new TmfSyncSequenceDiagramEvent(tmfEvent
,
1522 receiver
.toString(),