1 /**********************************************************************
2 * Copyright (c) 2011, 2012 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 **********************************************************************/
12 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.loader
;
14 import java
.util
.ArrayList
;
15 import java
.util
.HashMap
;
16 import java
.util
.List
;
18 import java
.util
.concurrent
.CopyOnWriteArrayList
;
19 import java
.util
.concurrent
.locks
.ReentrantLock
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.core
.runtime
.IStatus
;
23 import org
.eclipse
.core
.runtime
.Status
;
24 import org
.eclipse
.core
.runtime
.jobs
.Job
;
25 import org
.eclipse
.jface
.viewers
.ISelection
;
26 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
27 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.TmfUiPlugin
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.component
.TmfComponent
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.experiment
.TmfExperiment
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfDataRequest
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfDataRequest
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfEventRequest
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentDisposedSignal
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentSelectedSignal
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignal
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.uml2sd
.ITmfSyncSequenceDiagramEvent
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.uml2sd
.TmfSyncSequenceDiagramEvent
;
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
.dialogs
.Criteria
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterCriteria
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterListDialog
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDAdvancedPagingProvider
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFilterProvider
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFindProvider
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDGraphNodeSupporter
;
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
;
67 * This class is a reference implementation of the <code>org.eclipse.linuxtools.tmf.ui.Uml2SDLoader</code> extension point. It provides
68 * a Sequence Diagram loader for a user space trace with specific trace content for sending and
69 * receiving signals between components. I also includes a default implementation for the <code>ITmfEvent</code> parsing.
72 * The class <code>TmfUml2SDSyncLoader</code> analyzes events from type <code>ITmfEvent</code> and creates events type
73 * <code>ITmfSyncSequenceDiagramEvent</code> if the <code>ITmfEvent</code> contains all relevant information.
74 * The analysis checks that the event type strings contains either string SEND or RECEIVE. If event type matches these key
75 * words, the analyzer will look for strings sender, receiver and signal in the event fields of type <code>ITmfEventField</code>.
76 * If all the data is found a sequence diagram event from can be created. Note that Sync Messages are assumed, which
77 * means start and end time are the same. <br>
79 * The parsing of the <code>ITmfEvent</code> is done in the method <code>getSequnceDiagramEvent()</code> of class
80 * <code>TmfUml2SDSyncLoader</code>. By extending the class <code>TmfUml2SDSyncLoader</code> and overwriting
81 * <code>getSequnceDiagramEvent()</code> a customized parsing algorithm can be implemented.<br>
83 * Note that combined traces of multiple components, that contain the trace information about the same interactions are not
84 * supported in the class <code>TmfUml2SDSyncLoader</code>.
87 * @author Bernd Hufmann
89 public class TmfUml2SDSyncLoader
extends TmfComponent
implements IUml2SDLoader
, ISDFindProvider
, ISDFilterProvider
, ISDAdvancedPagingProvider
, ISelectionListener
{
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
97 protected final static String TITLE
= Messages
.TmfUml2SDSyncLoader_ViewName
;
99 * Default block size for background request.
101 protected final static int DEFAULT_BLOCK_SIZE
= 50000;
103 * Maximum number of messages per page.
105 protected final static int MAX_NUM_OF_MSG
= 10000;
107 * Initial time range window.
109 protected final static long INITIAL_WINDOW_OFFSET
= (1L * 100 * 1000 * 1000); // .1sec
111 // ------------------------------------------------------------------------
113 // ------------------------------------------------------------------------
115 // Experiment attributes
117 * The TMF experiment reference.
119 protected TmfExperiment
<ITmfEvent
> fExperiment
= null;
121 * The current indexing event request.
123 protected ITmfEventRequest
<ITmfEvent
> fIndexRequest
= null;
125 * The current request to fill a page.
127 protected ITmfEventRequest
<ITmfEvent
> fPageRequest
= null;
129 * Flag whether the time range signal was sent by this loader class or not
131 volatile protected boolean fIsSignalSent
= false;
133 * The initial request window size.
135 volatile protected long fInitialWindow
= INITIAL_WINDOW_OFFSET
;
137 // The view and event attributes
139 * The sequence diagram view reference.
141 protected SDView fView
= null;
143 * The current sequence diagram frame reference.
145 protected Frame fFrame
= null;
147 * The list of sequence diagram events of current page.
149 protected List
<ITmfSyncSequenceDiagramEvent
> fEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>();
151 // Checkpoint and page attributes
153 * The checkpoints of the whole sequence diagram trace (i.e. start time stamp of each page)
155 protected List
<TmfTimeRange
> fCheckPoints
= new ArrayList
<TmfTimeRange
>(MAX_NUM_OF_MSG
);
157 * The current page displayed.
159 volatile protected int fCurrentPage
= 0;
161 * The current time selected.
163 protected ITmfTimestamp fCurrentTime
= null;
165 * Flag to specify that selection of message is done by selection or by signal.
167 volatile protected boolean fIsSelect
= false;
171 * The job for searching across pages.
173 protected SearchJob fFindJob
= null;
175 * List of found nodes within a page.
177 protected List
<GraphNode
> fFindResults
= new ArrayList
<GraphNode
>();
179 * The current find criteria reference
181 protected Criteria fFindCriteria
= null;
183 * The current find index within the list of found nodes (<code>fFindeResults</code> within a page.
185 volatile protected int fCurrentFindIndex
= 0;
189 * The list of active filters.
191 protected List
<FilterCriteria
> fFilterCriteria
= null;
193 // Thread synchronization
195 * The synchronization lock.
197 protected ReentrantLock fLock
= new ReentrantLock();
199 // ------------------------------------------------------------------------
201 // ------------------------------------------------------------------------
203 * Default constructor
205 public TmfUml2SDSyncLoader() {
212 * @param name Name of loader
214 public TmfUml2SDSyncLoader(String name
) {
218 // ------------------------------------------------------------------------
220 // ------------------------------------------------------------------------
222 * Returns the current time if available else null.
224 * @return the current time if available else null
226 public ITmfTimestamp
getCurrentTime() {
229 if (fCurrentTime
!= null) {
230 return fCurrentTime
.clone();
239 * Waits for the page request to be completed
241 public void waitForCompletion() {
243 ITmfEventRequest
<ITmfEvent
> request
= fPageRequest
;
247 request
.waitForCompletion();
248 } catch (InterruptedException e
) {
254 * Signal handler for the experiment selected signal.
256 * Spawns a request to index the experiment (checkpoints creation) as well as it fills
259 * @param signal The experiment selected signal
261 @SuppressWarnings("unchecked")
263 public void experimentSelected(TmfExperimentSelectedSignal
<ITmfEvent
> signal
) {
265 final Job job
= new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
267 protected IStatus
run(IProgressMonitor monitor
) {
268 while (!monitor
.isCanceled()) {
271 } catch (InterruptedException e
) {
272 return Status
.OK_STATUS
;
276 return Status
.OK_STATUS
;
284 // Update the trace reference
285 TmfExperiment
<ITmfEvent
> exp
= (TmfExperiment
<ITmfEvent
>) signal
.getExperiment();
286 if (!exp
.equals(fExperiment
)) {
290 TmfTimeRange window
= TmfTimeRange
.ETERNITY
;
292 fIndexRequest
= new TmfEventRequest
<ITmfEvent
>(ITmfEvent
.class, window
, TmfDataRequest
.ALL_DATA
, DEFAULT_BLOCK_SIZE
, ITmfDataRequest
.ExecutionType
.BACKGROUND
) {
294 private ITmfTimestamp fFirstTime
= null;
295 private ITmfTimestamp fLastTime
= null;
296 private int fNbSeqEvents
= 0;
297 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>(MAX_NUM_OF_MSG
);
301 * @see org.eclipse.linuxtools.tmf.core.request.TmfDataRequest#handleData(org.eclipse.linuxtools.tmf.core.event.ITmfEvent)
304 public void handleData(ITmfEvent event
) {
305 super.handleData(event
);
307 ITmfSyncSequenceDiagramEvent sdEvent
= getSequnceDiagramEvent(event
);
309 if (sdEvent
!= null) {
312 if (fFirstTime
== null) {
313 fFirstTime
= event
.getTimestamp().clone();
316 fLastTime
= event
.getTimestamp().clone();
318 if ((fNbSeqEvents
% MAX_NUM_OF_MSG
) == 0) {
321 fCheckPoints
.add(new TmfTimeRange(fFirstTime
, fLastTime
));
323 fView
.updateCoolBar();
332 if (fNbSeqEvents
> MAX_NUM_OF_MSG
) {
337 fSdEvents
.add(sdEvent
);
339 if (fNbSeqEvents
== MAX_NUM_OF_MSG
) {
340 fillCurrentPage(fSdEvents
);
347 * @see org.eclipse.linuxtools.tmf.core.request.TmfDataRequest#handleSuccess()
350 public void handleSuccess() {
351 if ((fFirstTime
!= null) && (fLastTime
!= null)) {
355 fCheckPoints
.add(new TmfTimeRange(fFirstTime
, fLastTime
));
357 fView
.updateCoolBar();
364 if (fNbSeqEvents
<= MAX_NUM_OF_MSG
) {
365 fillCurrentPage(fSdEvents
);
368 super.handleSuccess();
373 * @see org.eclipse.linuxtools.tmf.core.request.TmfDataRequest#handleCompleted()
376 public void handleCompleted() {
377 if (fEvents
.isEmpty()) {
378 fFrame
= new Frame();
379 fView
.setFrameSync(fFrame
);
381 super.handleCompleted();
386 fExperiment
.sendRequest(fIndexRequest
);
394 * Signal handler for the experiment disposed signal.
396 * @param signal The experiment disposed signal
399 public void experimentDisposed(TmfExperimentDisposedSignal
<ITmfEvent
> signal
) {
400 if (signal
.getExperiment() != TmfExperiment
.getCurrentExperiment()) {
405 if ((fIndexRequest
!= null) && !fIndexRequest
.isCompleted()) {
406 fIndexRequest
.cancel();
407 fIndexRequest
= null;
410 cancelOngoingRequests();
412 if (fFilterCriteria
!= null) {
413 fFilterCriteria
.clear();
416 FilterListDialog
.deactivateSavedGlobalFilters();
425 * Moves to the page that contains the time provided by the signal. The messages will be selected
426 * if the provided time is the time of a message.
428 * @param signal The Time synch signal.
431 public void synchToTime(TmfTimeSynchSignal signal
) {
434 if ((signal
.getSource() != this) && (fFrame
!= null)) {
436 fCurrentTime
= signal
.getCurrentTime();
446 * Moves to the page that contains the current time provided by signal.
447 * No message will be selected however the focus will be set to the message
448 * if the provided time is the time of a message.
450 * @param signal The time range sync signal
453 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
456 if ((signal
.getSource() != this) && (fFrame
!= null) && !fIsSignalSent
) {
457 TmfTimeRange newTimeRange
= signal
.getCurrentRange();
458 ITmfTimestamp delta
= newTimeRange
.getEndTime().getDelta(newTimeRange
.getStartTime());
459 fInitialWindow
= delta
.getValue();
462 fCurrentTime
= newTimeRange
.getStartTime();
474 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader#setViewer(org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView)
476 @SuppressWarnings("unchecked")
478 public void setViewer(SDView viewer
) {
483 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
484 fView
.setSDFindProvider(this);
485 fView
.setSDPagingProvider(this);
486 fView
.setSDFilterProvider(this);
490 fExperiment
= (TmfExperiment
<ITmfEvent
>) TmfExperiment
.getCurrentExperiment();
491 if (fExperiment
!= null) {
492 experimentSelected(new TmfExperimentSelectedSignal
<ITmfEvent
>(this, fExperiment
));
501 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.load.IUml2SDLoader#getTitleString()
504 public String
getTitleString() {
510 * @see org.eclipse.linuxtools.tmf.component.TmfComponent#dispose()
513 public void dispose() {
517 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().removePostSelectionListener(this);
518 fView
.setSDFindProvider(null);
519 fView
.setSDPagingProvider(null);
520 fView
.setSDFilterProvider(null);
529 * @see org.eclipse.hyades.uml2sd.ui.actions.provider.ISDGraphNodeSupporter#isNodeSupported(int)
532 public boolean isNodeSupported(int nodeType
) {
534 case ISDGraphNodeSupporter
.LIFELINE
:
535 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
546 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDGraphNodeSupporter#getNodeName(int, java.lang.String)
549 public String
getNodeName(int nodeType
, String loaderClassName
) {
551 case ISDGraphNodeSupporter
.LIFELINE
:
552 return Messages
.TmfUml2SDSyncLoader_CategoryLifeline
;
553 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
554 return Messages
.TmfUml2SDSyncLoader_CategoryMessage
;
556 return ""; //$NON-NLS-1$
561 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
564 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
565 ISelection sel
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
566 if ((sel
!= null) && (sel
instanceof StructuredSelection
)) {
567 StructuredSelection stSel
= (StructuredSelection
) sel
;
568 if (stSel
.getFirstElement() instanceof TmfSyncMessage
) {
569 TmfSyncMessage syncMsg
= ((TmfSyncMessage
) stSel
.getFirstElement());
570 broadcast(new TmfTimeSynchSignal(this, syncMsg
.getStartTime()));
578 * org.eclipse.hyades.uml2sd.ui.actions.provider.ISDFindProvider#find(org.eclipse.hyades.uml2sd.ui.actions.widgets.Criteria)
581 public boolean find(Criteria toSearch
) {
584 if (fFrame
== null) {
588 if ((fFindResults
== null) || (fFindCriteria
== null) || !fFindCriteria
.compareTo(toSearch
)) {
589 fFindResults
= new CopyOnWriteArrayList
<GraphNode
>();
590 fFindCriteria
= toSearch
;
591 if (fFindCriteria
.isLifeLineSelected()) {
592 for (int i
= 0; i
< fFrame
.lifeLinesCount(); i
++) {
593 if (fFindCriteria
.matches(fFrame
.getLifeline(i
).getName())) {
594 fFindResults
.add(fFrame
.getLifeline(i
));
599 ArrayList
<GraphNode
> msgs
= new ArrayList
<GraphNode
>();
600 if (fFindCriteria
.isSyncMessageSelected()) {
601 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
602 if (fFindCriteria
.matches(fFrame
.getSyncMessage(i
).getName())) {
603 msgs
.add(fFrame
.getSyncMessage(i
));
608 if (!msgs
.isEmpty()) {
609 fFindResults
.addAll(msgs
);
612 @SuppressWarnings("rawtypes")
613 List selection
= fView
.getSDWidget().getSelection();
614 if ((selection
!= null) && (selection
.size() == 1)) {
615 fCurrentFindIndex
= fFindResults
.indexOf(selection
.get(0)) + 1;
617 fCurrentFindIndex
= 0;
623 if (fFindResults
.size() > fCurrentFindIndex
) {
624 GraphNode current
= fFindResults
.get(fCurrentFindIndex
);
625 fView
.getSDWidget().moveTo(current
);
629 fCurrentFindIndex
=0;
630 return findInNextPages(fFindCriteria
); // search in other page
639 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFindProvider#cancel()
642 public void cancel() {
643 cancelOngoingRequests();
648 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDFilterProvider#filter(java.util.List)
650 @SuppressWarnings("unchecked")
652 public boolean filter(List
<?
> filters
) {
655 cancelOngoingRequests();
657 List
<FilterCriteria
> list
= (List
<FilterCriteria
>)filters
;
658 fFilterCriteria
= new ArrayList
<FilterCriteria
>(list
);
660 fillCurrentPage(fEvents
);
670 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#hasNextPage()
673 public boolean hasNextPage() {
676 int size
= fCheckPoints
.size();
678 return fCurrentPage
< (size
- 1);
688 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#hasPrevPage()
691 public boolean hasPrevPage() {
694 return fCurrentPage
> 0;
702 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#nextPage()
705 public void nextPage() {
709 if (fCurrentPage
>= (fCheckPoints
.size() - 1)) {
713 cancelOngoingRequests();
724 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#prevPage()
727 public void prevPage() {
731 if (fCurrentPage
<= 0) {
735 cancelOngoingRequests();
746 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#firstPage()
749 public void firstPage() {
753 cancelOngoingRequests();
764 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDPagingProvider#lastPage()
767 public void lastPage() {
770 cancelOngoingRequests();
772 fCurrentPage
= fCheckPoints
.size() - 1;
781 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#currentPage()
784 public int currentPage() {
795 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#pagesCount()
798 public int pagesCount() {
801 return fCheckPoints
.size();
809 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.handlers.provider.ISDAdvancedPagingProvider#pageNumberChanged(int)
812 public void pageNumberChanged(int pagenNumber
) {
813 int localPageNumber
= pagenNumber
;
817 cancelOngoingRequests();
819 if (localPageNumber
< 0) {
822 int size
= fCheckPoints
.size();
823 if (localPageNumber
> (size
- 1)) {
824 localPageNumber
= size
- 1;
826 fCurrentPage
= localPageNumber
;
835 * @see org.eclipse.linuxtools.tmf.component.TmfComponent#broadcast(org.eclipse.linuxtools.tmf.signal.TmfSignal)
838 public void broadcast(TmfSignal signal
) {
839 fIsSignalSent
= true;
840 super.broadcast(signal
);
841 fIsSignalSent
= false;
845 * Cancels any ongoing find operation
847 protected void cancelOngoingRequests() {
850 // Cancel the search thread
851 if (fFindJob
!= null) {
856 fFindCriteria
= null;
857 fCurrentFindIndex
= 0;
859 if ((fPageRequest
!= null) && !fPageRequest
.isCompleted()) {
860 fPageRequest
.cancel();
869 * Resets loader attributes
871 protected void resetLoader() {
876 fCheckPoints
.clear();
878 fCurrentFindIndex
= 0;
879 fFindCriteria
= null;
881 fInitialWindow
= INITIAL_WINDOW_OFFSET
;
882 fView
.setFrameSync(new Frame());
892 * Fills current page with sequence diagram content.
894 * @param events sequence diagram events
896 protected void fillCurrentPage(List
<ITmfSyncSequenceDiagramEvent
> events
) {
900 fEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>(events
);
902 fView
.toggleWaitCursorAsync(true);
908 final Frame frame
= new Frame();
910 if (!events
.isEmpty()) {
911 Map
<String
, Lifeline
> nodeToLifelineMap
= new HashMap
<String
, Lifeline
>();
913 frame
.setName(Messages
.TmfUml2SDSyncLoader_FrameName
);
915 for (int i
= 0; i
< events
.size(); i
++) {
917 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
919 if ((nodeToLifelineMap
.get(sdEvent
.getSender()) == null) && (!filterLifeLine(sdEvent
.getSender()))) {
920 Lifeline lifeline
= new Lifeline();
921 lifeline
.setName(sdEvent
.getSender());
922 nodeToLifelineMap
.put(sdEvent
.getSender(), lifeline
);
923 frame
.addLifeLine(lifeline
);
926 if ((nodeToLifelineMap
.get(sdEvent
.getReceiver()) == null) && (!filterLifeLine(sdEvent
.getReceiver()))) {
927 Lifeline lifeline
= new Lifeline();
928 lifeline
.setName(sdEvent
.getReceiver());
929 nodeToLifelineMap
.put(sdEvent
.getReceiver(), lifeline
);
930 frame
.addLifeLine(lifeline
);
934 int eventOccurence
= 1;
936 for (int i
= 0; i
< events
.size(); i
++) {
937 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
939 // Check message filter
940 if (filterMessage(sdEvent
)) {
944 // Set the message sender and receiver
945 Lifeline startLifeline
= nodeToLifelineMap
.get(sdEvent
.getSender());
946 Lifeline endLifeline
= nodeToLifelineMap
.get(sdEvent
.getReceiver());
948 // Check if any of the lifelines were filtered
949 if ((startLifeline
== null) || (endLifeline
== null)) {
953 int tmp
= Math
.max(startLifeline
.getEventOccurrence(), endLifeline
.getEventOccurrence());
954 eventOccurence
= Math
.max(eventOccurence
, tmp
);
956 startLifeline
.setCurrentEventOccurrence(eventOccurence
);
957 endLifeline
.setCurrentEventOccurrence(eventOccurence
);
959 TmfSyncMessage message
= new TmfSyncMessage(sdEvent
, eventOccurence
++);
961 message
.setStartLifeline(startLifeline
);
962 message
.setEndLifeline(endLifeline
);
964 message
.setTime(sdEvent
.getStartTime());
966 // add the message to the frame
967 frame
.addMessage(message
);
972 if (!fView
.getSDWidget().isDisposed()) {
973 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
980 // check if view was disposed in the meanwhile
981 if ((fView
!= null) && (!fView
.getSDWidget().isDisposed())) {
983 fView
.setFrame(fFrame
);
985 if (fCurrentTime
!= null) {
986 moveToMessageInPage();
989 if (fFindCriteria
!= null) {
993 fView
.toggleWaitCursorAsync(false);
1010 * Moves to a certain message defined by timestamp (across pages)
1012 protected void moveToMessage() {
1017 page
= getPage(fCurrentTime
);
1019 if (page
== fCurrentPage
) {
1020 moveToMessageInPage();
1023 fCurrentPage
= page
;
1031 * Moves to a certain message defined by timestamp in current page
1033 protected void moveToMessageInPage() {
1036 if (!fView
.getSDWidget().isDisposed()) {
1037 // Check for GUI thread
1038 if(Display
.getCurrent() != null) {
1039 // Already in GUI thread - execute directly
1040 TmfSyncMessage prevMessage
= null;
1041 TmfSyncMessage syncMessage
= null;
1042 boolean isExactTime
= false;
1043 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
1044 if (fFrame
.getSyncMessage(i
) instanceof TmfSyncMessage
) {
1045 syncMessage
= (TmfSyncMessage
) fFrame
.getSyncMessage(i
);
1046 if (syncMessage
.getStartTime().compareTo(fCurrentTime
, false) == 0) {
1049 } else if ((syncMessage
.getStartTime().compareTo(fCurrentTime
, false) > 0) && (prevMessage
!= null)) {
1050 syncMessage
= prevMessage
;
1053 prevMessage
= syncMessage
;
1056 if (fIsSelect
&& isExactTime
) {
1057 fView
.getSDWidget().moveTo(syncMessage
);
1060 fView
.getSDWidget().ensureVisible(syncMessage
);
1061 fView
.getSDWidget().clearSelection();
1062 fView
.getSDWidget().redraw();
1066 // Not in GUI thread - queue action in GUI thread.
1067 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1070 moveToMessageInPage();
1082 * Moves to a certain message defined by timestamp (across pages)
1084 protected void moveToPage() {
1089 * Moves to a certain page.
1091 * @param notifyAll true to broadcast time range signal to other signal handlers else false
1093 protected void moveToPage(boolean notifyAll
) {
1095 TmfTimeRange window
= null;
1100 if (fCurrentPage
> fCheckPoints
.size()) {
1103 window
= fCheckPoints
.get(fCurrentPage
);
1108 if (window
== null) {
1109 window
= TmfTimeRange
.ETERNITY
;
1112 fPageRequest
= new TmfEventRequest
<ITmfEvent
>(ITmfEvent
.class, window
, TmfDataRequest
.ALL_DATA
, 1, ITmfDataRequest
.ExecutionType
.FOREGROUND
) {
1113 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvent
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>();
1116 public void handleData(ITmfEvent event
) {
1117 super.handleData(event
);
1119 ITmfSyncSequenceDiagramEvent sdEvent
= getSequnceDiagramEvent(event
);
1121 if (sdEvent
!= null) {
1122 fSdEvent
.add(sdEvent
);
1127 public void handleSuccess() {
1128 fillCurrentPage(fSdEvent
);
1129 super.handleSuccess();
1134 fExperiment
.sendRequest(fPageRequest
);
1137 TmfTimeRange timeRange
= getSignalTimeRange(window
.getStartTime());
1138 broadcast(new TmfRangeSynchSignal(this, timeRange
, timeRange
.getStartTime()));
1143 * Gets page that contains timestamp
1145 * @param time The timestamp
1146 * @return page that contains the time
1148 protected int getPage(ITmfTimestamp time
) {
1153 size
= fCheckPoints
.size();
1154 for (page
= 0; page
< size
; page
++) {
1155 TmfTimeRange timeRange
= fCheckPoints
.get(page
);
1156 if (timeRange
.getEndTime().compareTo(time
, false) >= 0) {
1170 * Background search in trace for expression in criteria.
1172 * @param findCriteria The find criteria
1173 * @return true if background request was started else false
1175 protected boolean findInNextPages(Criteria findCriteria
) {
1178 if (fFindJob
!= null) {
1182 int nextPage
= fCurrentPage
+ 1;
1184 if ((nextPage
) >= fCheckPoints
.size()) {
1185 // we are at the end
1189 TmfTimeRange window
= new TmfTimeRange(fCheckPoints
.get(nextPage
).getStartTime().clone(), fCheckPoints
.get(fCheckPoints
.size()-1).getEndTime().clone());
1190 fFindJob
= new SearchJob(findCriteria
, window
);
1191 fFindJob
.schedule();
1192 fView
.toggleWaitCursorAsync(true);
1200 * Gets time range for time range signal.
1202 * @param startTime The start time of time range.
1203 * @return the time range
1205 protected TmfTimeRange
getSignalTimeRange(ITmfTimestamp startTime
) {
1208 TmfTimestamp initialEndOfWindow
= new TmfTimestamp(startTime
.getValue() + fInitialWindow
, startTime
.getScale(), startTime
.getPrecision());
1209 return new TmfTimeRange(startTime
, initialEndOfWindow
);
1217 * Checks if filter criteria matches the message name in given SD event.
1219 * @param sdEvent The SD event to check
1220 * @return true if match else false.
1222 protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent
) {
1225 if (fFilterCriteria
!= null) {
1226 for(FilterCriteria criteria
: fFilterCriteria
) {
1227 if (criteria
.isActive() && criteria
.getCriteria().isSyncMessageSelected() && criteria
.getCriteria().matches(sdEvent
.getName())) {
1239 * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event.
1241 * @param lifeline the message receiver
1242 * @return true if match else false.
1244 protected boolean filterLifeLine(String lifeline
) {
1247 if (fFilterCriteria
!= null) {
1248 for(FilterCriteria criteria
: fFilterCriteria
) {
1249 if (criteria
.isActive() && criteria
.getCriteria().isLifeLineSelected() && criteria
.getCriteria().matches(lifeline
)) {
1261 * Job to search in trace for given time range.
1263 protected class SearchJob
extends Job
{
1266 * The search event request.
1268 final protected SearchEventRequest fSearchRequest
;
1273 * @param findCriteria The search criteria
1274 * @param window Time range to search in
1276 public SearchJob(Criteria findCriteria
, TmfTimeRange window
) {
1277 super(Messages
.TmfUml2SDSyncLoader_SearchJobDescrition
);
1278 fSearchRequest
= new SearchEventRequest(window
, TmfDataRequest
.ALL_DATA
, 1, ITmfDataRequest
.ExecutionType
.FOREGROUND
, findCriteria
);
1283 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
1286 protected IStatus
run(IProgressMonitor monitor
) {
1287 fSearchRequest
.setMonitor(monitor
);
1289 fExperiment
.sendRequest(fSearchRequest
);
1292 fSearchRequest
.waitForCompletion();
1293 } catch (InterruptedException e
) {
1294 TmfUiPlugin
.getDefault().getLog().log(new Status(IStatus
.ERROR
, TmfUiPlugin
.PLUGIN_ID
, "Search request interrupted!", e
)); //$NON-NLS-1$
1297 IStatus status
= Status
.OK_STATUS
;
1298 if (fSearchRequest
.isFound() && (fSearchRequest
.getFoundTime() != null)) {
1299 fCurrentTime
= fSearchRequest
.getFoundTime();
1301 // Avoid double-selection. Selection will be done when calling find(criteria)
1302 // after moving to relevant page
1304 if (!fView
.getSDWidget().isDisposed()) {
1305 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1315 if (monitor
.isCanceled()) {
1316 status
= Status
.CANCEL_STATUS
;
1319 // String was not found
1320 status
= new Status(Status
.WARNING
, TmfUiPlugin
.PLUGIN_ID
, Messages
.TmfUml2SDSyncLoader_SearchNotFound
);
1322 setProperty(IProgressConstants
.KEEP_PROPERTY
, Boolean
.TRUE
);
1328 fView
.toggleWaitCursorAsync(false);
1339 * @see org.eclipse.core.runtime.jobs.Job#canceling()
1342 protected void canceling() {
1343 fSearchRequest
.cancel();
1354 * TMF event request for searching within trace.
1356 protected class SearchEventRequest
extends TmfEventRequest
<ITmfEvent
> {
1359 * The find criteria.
1361 final private Criteria fCriteria
;
1363 * A progress monitor
1365 private IProgressMonitor fMonitor
;
1367 * Flag to indicate that node was found according the criteria .
1369 private boolean fIsFound
= false;
1371 * Time stamp of found item.
1373 private ITmfTimestamp fFoundTime
= null;
1377 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1378 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1379 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1380 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1381 * @param criteria The search criteria
1383 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, int blockSize
, ExecutionType execType
, Criteria criteria
) {
1384 this(range
, nbRequested
, blockSize
, execType
, criteria
, null);
1389 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1390 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1391 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1392 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1393 * @param criteria The search criteria
1394 * @param monitor progress monitor
1396 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, int blockSize
, ExecutionType execType
, Criteria criteria
, IProgressMonitor monitor
) {
1397 super(ITmfEvent
.class, range
, nbRequested
, blockSize
, execType
);
1398 fCriteria
= new Criteria(criteria
);
1404 * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData(org.eclipse.linuxtools.tmf.event.TmfData)
1407 public void handleData(ITmfEvent event
) {
1408 super.handleData(event
);
1410 if ((fMonitor
!= null) && fMonitor
.isCanceled()) {
1415 ITmfSyncSequenceDiagramEvent sdEvent
= getSequnceDiagramEvent(event
);
1417 if (sdEvent
!= null) {
1419 if (fCriteria
.isLifeLineSelected()) {
1420 if (fCriteria
.matches(sdEvent
.getSender())) {
1421 fFoundTime
= event
.getTimestamp().clone();
1426 if (fCriteria
.matches(sdEvent
.getReceiver())) {
1427 fFoundTime
= event
.getTimestamp().clone();
1433 if (fCriteria
.isSyncMessageSelected() && fCriteria
.matches(sdEvent
.getName())) {
1434 fFoundTime
= event
.getTimestamp().clone();
1442 * Set progress monitor.
1446 public void setMonitor(IProgressMonitor monitor
) {
1451 * Check if find criteria was met.
1453 * @return true if find criteria was met.
1455 public boolean isFound() {
1460 * Returns timestamp of found time.
1462 * @return timestamp of found time.
1464 public ITmfTimestamp
getFoundTime() {
1470 * Returns sequence diagram event if details in given event are available else null.
1472 * @param tmfEvent Event to parse for sequence diagram event details
1473 * @return sequence diagram event if details are available else null
1475 protected ITmfSyncSequenceDiagramEvent
getSequnceDiagramEvent(ITmfEvent tmfEvent
){
1476 //type = .*RECEIVE.* or .*SEND.*
1477 //content = sender:<sender name>:receiver:<receiver name>,signal:<signal name>
1478 String eventType
= tmfEvent
.getType().toString();
1479 if (eventType
.contains(Messages
.TmfUml2SDSyncCloader_EventTypeSend
) || eventType
.contains(Messages
.TmfUml2SDSyncCloader_EventTypeReceive
)) {
1480 Object sender
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncCloader_FieldSender
);
1481 Object receiver
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncCloader_FieldReceiver
);
1482 Object name
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncCloader_FieldSignal
);
1483 if ((sender
instanceof ITmfEventField
) && (receiver
instanceof ITmfEventField
) && (name
instanceof ITmfEventField
)) {
1484 ITmfSyncSequenceDiagramEvent sdEvent
= new TmfSyncSequenceDiagramEvent(tmfEvent
,
1485 ((ITmfEventField
) sender
).getValue().toString(),
1486 ((ITmfEventField
) receiver
).getValue().toString(),
1487 ((ITmfEventField
) name
).getValue().toString());