1 /**********************************************************************
2 * Copyright (c) 2011, 2013 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
.linuxtools
.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
.linuxtools
.internal
.tmf
.ui
.Activator
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.component
.TmfComponent
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfDataRequest
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfDataRequest
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.request
.TmfEventRequest
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfRangeSynchSignal
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignal
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTimeSynchSignal
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceClosedSignal
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
47 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTraceManager
;
48 import org
.eclipse
.linuxtools
.tmf
.core
.uml2sd
.ITmfSyncSequenceDiagramEvent
;
49 import org
.eclipse
.linuxtools
.tmf
.core
.uml2sd
.TmfSyncSequenceDiagramEvent
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.editors
.ITmfTraceEditor
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.SDView
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.dialogs
.Criteria
;
56 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterCriteria
;
57 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.dialogs
.FilterListDialog
;
58 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDAdvancedPagingProvider
;
59 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFilterProvider
;
60 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDFindProvider
;
61 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.handlers
.provider
.ISDGraphNodeSupporter
;
62 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.load
.IUml2SDLoader
;
63 import org
.eclipse
.swt
.widgets
.Display
;
64 import org
.eclipse
.ui
.IEditorPart
;
65 import org
.eclipse
.ui
.ISelectionListener
;
66 import org
.eclipse
.ui
.IWorkbenchPart
;
67 import org
.eclipse
.ui
.IWorkbenchWindow
;
68 import org
.eclipse
.ui
.PlatformUI
;
69 import org
.eclipse
.ui
.progress
.IProgressConstants
;
73 * This class is a reference implementation of the
74 * <code>org.eclipse.linuxtools.tmf.ui.Uml2SDLoader</code> extension point. It
75 * provides a Sequence Diagram loader for a user space trace with specific trace
76 * content for sending and receiving signals between components. I also includes
77 * a default implementation for the <code>ITmfEvent</code> parsing.
80 * The class <code>TmfUml2SDSyncLoader</code> analyzes events from type
81 * <code>ITmfEvent</code> and creates events type
82 * <code>ITmfSyncSequenceDiagramEvent</code> if the <code>ITmfEvent</code>
83 * contains all relevant information. The analysis checks that the event type
84 * strings contains either string SEND or RECEIVE. If event type matches these
85 * key words, the analyzer will look for strings sender, receiver and signal in
86 * the event fields of type <code>ITmfEventField</code>. If all the data is
87 * found a sequence diagram event from can be created. Note that Sync Messages
88 * are assumed, which means start and end time are the same. <br>
90 * The parsing of the <code>ITmfEvent</code> is done in the method
91 * <code>getSequnceDiagramEvent()</code> of class
92 * <code>TmfUml2SDSyncLoader</code>. By extending the class
93 * <code>TmfUml2SDSyncLoader</code> and overwriting
94 * <code>getSequnceDiagramEvent()</code> a customized parsing algorithm can be
97 * Note that combined traces of multiple components, that contain the trace
98 * information about the same interactions are not supported in the class
99 * <code>TmfUml2SDSyncLoader</code>.
102 * @author Bernd Hufmann
104 public class TmfUml2SDSyncLoader
extends TmfComponent
implements IUml2SDLoader
, ISDFindProvider
, ISDFilterProvider
, ISDAdvancedPagingProvider
, ISelectionListener
{
106 // ------------------------------------------------------------------------
108 // ------------------------------------------------------------------------
110 * Default title name.
112 protected static final String TITLE
= Messages
.TmfUml2SDSyncLoader_ViewName
;
114 * Default block size for background request.
116 protected static final int DEFAULT_BLOCK_SIZE
= 50000;
118 * Maximum number of messages per page.
120 protected static final int MAX_NUM_OF_MSG
= 10000;
122 private static final int INDEXING_THREAD_SLEEP_VALUE
= 100;
124 // ------------------------------------------------------------------------
126 // ------------------------------------------------------------------------
128 // Experiment attributes
130 * The TMF trace reference.
133 protected ITmfTrace fTrace
= null;
135 * The current indexing event request.
137 protected ITmfEventRequest fIndexRequest
= null;
139 * The current request to fill a page.
141 protected ITmfEventRequest fPageRequest
= null;
143 * Flag whether the time range signal was sent by this loader class or not
145 protected volatile boolean fIsSignalSent
= false;
147 // The view and event attributes
149 * The sequence diagram view reference.
151 protected SDView fView
= null;
153 * The current sequence diagram frame reference.
155 protected Frame fFrame
= null;
157 * The list of sequence diagram events of current page.
159 protected List
<ITmfSyncSequenceDiagramEvent
> fEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>();
161 // Checkpoint and page attributes
163 * The checkpoints of the whole sequence diagram trace (i.e. start time stamp of each page)
165 protected List
<TmfTimeRange
> fCheckPoints
= new ArrayList
<TmfTimeRange
>(MAX_NUM_OF_MSG
);
167 * The current page displayed.
169 protected volatile int fCurrentPage
= 0;
171 * The current time selected.
173 protected ITmfTimestamp fCurrentTime
= null;
175 * Flag to specify that selection of message is done by selection or by signal.
177 protected volatile boolean fIsSelect
= false;
181 * The job for searching across pages.
183 protected SearchJob fFindJob
= null;
185 * List of found nodes within a page.
187 protected List
<GraphNode
> fFindResults
= new ArrayList
<GraphNode
>();
189 * The current find criteria reference
191 protected Criteria fFindCriteria
= null;
193 * The current find index within the list of found nodes (<code>fFindeResults</code> within a page.
195 protected volatile int fCurrentFindIndex
= 0;
199 * The list of active filters.
201 protected List
<FilterCriteria
> fFilterCriteria
= null;
203 // Thread synchronization
205 * The synchronization lock.
207 protected ReentrantLock fLock
= new ReentrantLock();
209 // ------------------------------------------------------------------------
211 // ------------------------------------------------------------------------
213 * Default constructor
215 public TmfUml2SDSyncLoader() {
222 * @param name Name of loader
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
238 public ITmfTimestamp
getCurrentTime() {
241 if (fCurrentTime
!= null) {
251 * Waits for the page request to be completed
253 public void waitForCompletion() {
255 ITmfEventRequest request
= fPageRequest
;
257 if (request
!= null) {
259 request
.waitForCompletion();
260 } catch (InterruptedException e
) {
267 * Handler for the trace opened signal.
268 * @param signal The trace opened signal
272 public void traceOpened(TmfTraceOpenedSignal signal
) {
273 fTrace
= signal
.getTrace();
279 * Signal handler for the trace selected signal.
281 * Spawns a request to index the trace (checkpoints creation) as well as it fills
284 * @param signal The trace selected signal
288 public void traceSelected(TmfTraceSelectedSignal signal
) {
289 // Update the trace reference
290 ITmfTrace trace
= signal
.getTrace();
291 if (!trace
.equals(fTrace
)) {
298 * Method for loading the current selected trace into the view.
299 * Sub-class need to override this method to add the view specific implementation.
302 protected void loadTrace() {
303 ITmfEventRequest indexRequest
= null;
307 final Job job
= new IndexingJob("Indexing " + getName() + "..."); //$NON-NLS-1$ //$NON-NLS-2$
311 indexRequest
= fIndexRequest
;
313 cancelOngoingRequests();
315 TmfTimeRange window
= TmfTimeRange
.ETERNITY
;
317 fIndexRequest
= new TmfEventRequest(ITmfEvent
.class, window
, TmfDataRequest
.ALL_DATA
, DEFAULT_BLOCK_SIZE
, ITmfDataRequest
.ExecutionType
.BACKGROUND
) {
319 private ITmfTimestamp fFirstTime
= null;
320 private ITmfTimestamp fLastTime
= null;
321 private int fNbSeqEvents
= 0;
322 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>(MAX_NUM_OF_MSG
);
325 public void handleData(ITmfEvent event
) {
326 super.handleData(event
);
328 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
330 if (sdEvent
!= null) {
333 if (fFirstTime
== null) {
334 fFirstTime
= event
.getTimestamp();
337 fLastTime
= event
.getTimestamp();
339 if ((fNbSeqEvents
% MAX_NUM_OF_MSG
) == 0) {
342 fCheckPoints
.add(new TmfTimeRange(fFirstTime
, fLastTime
));
344 fView
.updateCoolBar();
353 if (fNbSeqEvents
> MAX_NUM_OF_MSG
) {
358 fSdEvents
.add(sdEvent
);
360 if (fNbSeqEvents
== MAX_NUM_OF_MSG
) {
361 fillCurrentPage(fSdEvents
);
367 public void handleSuccess() {
368 if ((fFirstTime
!= null) && (fLastTime
!= null)) {
372 fCheckPoints
.add(new TmfTimeRange(fFirstTime
, fLastTime
));
374 fView
.updateCoolBar();
381 if (fNbSeqEvents
<= MAX_NUM_OF_MSG
) {
382 fillCurrentPage(fSdEvents
);
385 super.handleSuccess();
389 public void handleCompleted() {
390 if (fEvents
.isEmpty()) {
391 fFrame
= new Frame();
392 // make sure that view is not null when setting frame
400 if (sdView
!= null) {
401 sdView
.setFrameSync(fFrame
);
404 super.handleCompleted();
412 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
413 indexRequest
.cancel();
416 fTrace
.sendRequest(fIndexRequest
);
420 * Signal handler for the trace closed signal.
422 * @param signal The trace closed signal
426 public void traceClosed(TmfTraceClosedSignal signal
) {
427 if (signal
.getTrace() != fTrace
) {
430 ITmfEventRequest indexRequest
= null;
433 indexRequest
= fIndexRequest
;
434 fIndexRequest
= null;
436 cancelOngoingRequests();
438 if (fFilterCriteria
!= null) {
439 fFilterCriteria
.clear();
442 FilterListDialog
.deactivateSavedGlobalFilters();
447 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
448 indexRequest
.cancel();
455 * Moves to the page that contains the time provided by the signal. The messages will be selected
456 * if the provided time is the time of a message.
458 * @param signal The Time synch signal.
461 public void synchToTime(TmfTimeSynchSignal signal
) {
464 if ((signal
.getSource() != this) && (fFrame
!= null) && (fCheckPoints
.size() > 0)) {
465 fCurrentTime
= signal
.getCurrentTime();
475 * Moves to the page that contains the current time provided by signal.
476 * No message will be selected however the focus will be set to the message
477 * if the provided time is the time of a message.
479 * @param signal The time range sync signal
482 public void synchToTimeRange(TmfRangeSynchSignal signal
) {
485 if ((signal
.getSource() != this) && (fFrame
!= null) && !fIsSignalSent
&& (fCheckPoints
.size() > 0)) {
486 TmfTimeRange newTimeRange
= signal
.getCurrentRange();
489 fCurrentTime
= newTimeRange
.getStartTime();
500 public void setViewer(SDView viewer
) {
505 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
506 fView
.setSDFindProvider(this);
507 fView
.setSDPagingProvider(this);
508 fView
.setSDFilterProvider(this);
511 IEditorPart editor
= fView
.getSite().getPage().getActiveEditor();
512 if (editor
instanceof ITmfTraceEditor
) {
513 ITmfTrace trace
= ((ITmfTraceEditor
) editor
).getTrace();
515 traceSelected(new TmfTraceSelectedSignal(this, trace
));
524 public String
getTitleString() {
529 public void dispose() {
531 ITmfEventRequest indexRequest
= null;
534 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
535 // During Eclipse shutdown the active workbench window is null
536 if (window
!= null) {
537 window
.getSelectionService().removePostSelectionListener(this);
540 indexRequest
= fIndexRequest
;
541 fIndexRequest
= null;
542 cancelOngoingRequests();
544 fView
.setSDFindProvider(null);
545 fView
.setSDPagingProvider(null);
546 fView
.setSDFilterProvider(null);
551 if (indexRequest
!= null && !indexRequest
.isCompleted()) {
552 indexRequest
.cancel();
557 public boolean isNodeSupported(int nodeType
) {
559 case ISDGraphNodeSupporter
.LIFELINE
:
560 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
570 public String
getNodeName(int nodeType
, String loaderClassName
) {
572 case ISDGraphNodeSupporter
.LIFELINE
:
573 return Messages
.TmfUml2SDSyncLoader_CategoryLifeline
;
574 case ISDGraphNodeSupporter
.SYNCMESSAGE
:
575 return Messages
.TmfUml2SDSyncLoader_CategoryMessage
;
579 return ""; //$NON-NLS-1$
583 public void selectionChanged(IWorkbenchPart part
, ISelection selection
) {
584 ISelection sel
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
585 if ((sel
!= null) && (sel
instanceof StructuredSelection
)) {
586 StructuredSelection stSel
= (StructuredSelection
) sel
;
587 if (stSel
.getFirstElement() instanceof TmfSyncMessage
) {
588 TmfSyncMessage syncMsg
= ((TmfSyncMessage
) stSel
.getFirstElement());
589 broadcast(new TmfTimeSynchSignal(this, syncMsg
.getStartTime()));
595 public boolean find(Criteria toSearch
) {
598 if (fFrame
== null) {
602 if ((fFindResults
== null) || (fFindCriteria
== null) || !fFindCriteria
.compareTo(toSearch
)) {
603 fFindResults
= new CopyOnWriteArrayList
<GraphNode
>();
604 fFindCriteria
= toSearch
;
605 if (fFindCriteria
.isLifeLineSelected()) {
606 for (int i
= 0; i
< fFrame
.lifeLinesCount(); i
++) {
607 if (fFindCriteria
.matches(fFrame
.getLifeline(i
).getName())) {
608 fFindResults
.add(fFrame
.getLifeline(i
));
613 ArrayList
<GraphNode
> msgs
= new ArrayList
<GraphNode
>();
614 if (fFindCriteria
.isSyncMessageSelected()) {
615 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
616 if (fFindCriteria
.matches(fFrame
.getSyncMessage(i
).getName())) {
617 msgs
.add(fFrame
.getSyncMessage(i
));
622 if (!msgs
.isEmpty()) {
623 fFindResults
.addAll(msgs
);
626 @SuppressWarnings("rawtypes")
627 List selection
= fView
.getSDWidget().getSelection();
628 if ((selection
!= null) && (selection
.size() == 1)) {
629 fCurrentFindIndex
= fFindResults
.indexOf(selection
.get(0)) + 1;
631 fCurrentFindIndex
= 0;
637 if (fFindResults
.size() > fCurrentFindIndex
) {
638 GraphNode current
= fFindResults
.get(fCurrentFindIndex
);
639 fView
.getSDWidget().moveTo(current
);
643 fCurrentFindIndex
=0;
644 return findInNextPages(fFindCriteria
); // search in other page
651 public void cancel() {
652 cancelOngoingRequests();
655 @SuppressWarnings("unchecked")
657 public boolean filter(List
<?
> filters
) {
660 cancelOngoingRequests();
662 if (filters
== null) {
663 fFilterCriteria
= new ArrayList
<FilterCriteria
>();
665 List
<FilterCriteria
> list
= (List
<FilterCriteria
>)filters
;
666 fFilterCriteria
= new ArrayList
<FilterCriteria
>(list
);
669 fillCurrentPage(fEvents
);
678 public boolean hasNextPage() {
681 int size
= fCheckPoints
.size();
683 return fCurrentPage
< (size
- 1);
692 public boolean hasPrevPage() {
695 return fCurrentPage
> 0;
702 public void nextPage() {
706 if (fCurrentPage
>= (fCheckPoints
.size() - 1)) {
710 cancelOngoingRequests();
720 public void prevPage() {
724 if (fCurrentPage
<= 0) {
728 cancelOngoingRequests();
738 public void firstPage() {
742 cancelOngoingRequests();
752 public void lastPage() {
755 cancelOngoingRequests();
757 fCurrentPage
= fCheckPoints
.size() - 1;
765 public int currentPage() {
775 public int pagesCount() {
778 return fCheckPoints
.size();
785 public void pageNumberChanged(int pagenNumber
) {
786 int localPageNumber
= pagenNumber
;
790 cancelOngoingRequests();
792 if (localPageNumber
< 0) {
795 int size
= fCheckPoints
.size();
796 if (localPageNumber
> (size
- 1)) {
797 localPageNumber
= size
- 1;
799 fCurrentPage
= localPageNumber
;
807 public void broadcast(TmfSignal signal
) {
808 fIsSignalSent
= true;
809 super.broadcast(signal
);
810 fIsSignalSent
= false;
814 * Cancels any ongoing find operation
816 protected void cancelOngoingRequests() {
818 ITmfEventRequest pageRequest
= null;
820 // Cancel the search thread
821 if (fFindJob
!= null) {
826 fFindCriteria
= null;
827 fCurrentFindIndex
= 0;
829 pageRequest
= fPageRequest
;
834 if (pageRequest
!= null && !pageRequest
.isCompleted()) {
835 pageRequest
.cancel();
840 * Resets loader attributes
842 protected void resetLoader() {
847 fCheckPoints
.clear();
849 fCurrentFindIndex
= 0;
850 fFindCriteria
= null;
852 fView
.setFrameSync(new Frame());
862 * Fills current page with sequence diagram content.
864 * @param events sequence diagram events
866 protected void fillCurrentPage(List
<ITmfSyncSequenceDiagramEvent
> events
) {
870 fEvents
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>(events
);
871 if (fView
!= null && !events
.isEmpty()) {
872 fView
.toggleWaitCursorAsync(true);
878 final Frame frame
= new Frame();
880 if (!events
.isEmpty()) {
881 Map
<String
, Lifeline
> nodeToLifelineMap
= new HashMap
<String
, Lifeline
>();
883 frame
.setName(Messages
.TmfUml2SDSyncLoader_FrameName
);
885 for (int i
= 0; i
< events
.size(); i
++) {
887 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
889 if ((nodeToLifelineMap
.get(sdEvent
.getSender()) == null) && (!filterLifeLine(sdEvent
.getSender()))) {
890 Lifeline lifeline
= new Lifeline();
891 lifeline
.setName(sdEvent
.getSender());
892 nodeToLifelineMap
.put(sdEvent
.getSender(), lifeline
);
893 frame
.addLifeLine(lifeline
);
896 if ((nodeToLifelineMap
.get(sdEvent
.getReceiver()) == null) && (!filterLifeLine(sdEvent
.getReceiver()))) {
897 Lifeline lifeline
= new Lifeline();
898 lifeline
.setName(sdEvent
.getReceiver());
899 nodeToLifelineMap
.put(sdEvent
.getReceiver(), lifeline
);
900 frame
.addLifeLine(lifeline
);
904 int eventOccurence
= 1;
906 for (int i
= 0; i
< events
.size(); i
++) {
907 ITmfSyncSequenceDiagramEvent sdEvent
= events
.get(i
);
909 // Check message filter
910 if (filterMessage(sdEvent
)) {
914 // Set the message sender and receiver
915 Lifeline startLifeline
= nodeToLifelineMap
.get(sdEvent
.getSender());
916 Lifeline endLifeline
= nodeToLifelineMap
.get(sdEvent
.getReceiver());
918 // Check if any of the lifelines were filtered
919 if ((startLifeline
== null) || (endLifeline
== null)) {
923 int tmp
= Math
.max(startLifeline
.getEventOccurrence(), endLifeline
.getEventOccurrence());
924 eventOccurence
= Math
.max(eventOccurence
, tmp
);
926 startLifeline
.setCurrentEventOccurrence(eventOccurence
);
927 endLifeline
.setCurrentEventOccurrence(eventOccurence
);
929 TmfSyncMessage message
= new TmfSyncMessage(sdEvent
, eventOccurence
++);
931 message
.setStartLifeline(startLifeline
);
932 message
.setEndLifeline(endLifeline
);
934 message
.setTime(sdEvent
.getStartTime());
936 // add the message to the frame
937 frame
.addMessage(message
);
942 if (!fView
.getSDWidget().isDisposed()) {
943 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
950 // check if view was disposed in the meanwhile
951 if ((fView
!= null) && (!fView
.getSDWidget().isDisposed())) {
953 fView
.setFrame(fFrame
);
955 if (fCurrentTime
!= null) {
956 moveToMessageInPage();
959 if (fFindCriteria
!= null) {
963 fView
.toggleWaitCursorAsync(false);
980 * Moves to a certain message defined by timestamp (across pages)
982 protected void moveToMessage() {
987 page
= getPage(fCurrentTime
);
989 if (page
== fCurrentPage
) {
990 moveToMessageInPage();
1001 * Moves to a certain message defined by timestamp in current page
1003 protected void moveToMessageInPage() {
1006 if (!fView
.getSDWidget().isDisposed()) {
1007 // Check for GUI thread
1008 if(Display
.getCurrent() != null) {
1009 // Already in GUI thread - execute directly
1010 TmfSyncMessage prevMessage
= null;
1011 TmfSyncMessage syncMessage
= null;
1012 boolean isExactTime
= false;
1013 for (int i
= 0; i
< fFrame
.syncMessageCount(); i
++) {
1014 if (fFrame
.getSyncMessage(i
) instanceof TmfSyncMessage
) {
1015 syncMessage
= (TmfSyncMessage
) fFrame
.getSyncMessage(i
);
1016 if (syncMessage
.getStartTime().compareTo(fCurrentTime
, false) == 0) {
1019 } else if ((syncMessage
.getStartTime().compareTo(fCurrentTime
, false) > 0) && (prevMessage
!= null)) {
1020 syncMessage
= prevMessage
;
1023 prevMessage
= syncMessage
;
1026 if (fIsSelect
&& isExactTime
) {
1027 fView
.getSDWidget().moveTo(syncMessage
);
1030 fView
.getSDWidget().ensureVisible(syncMessage
);
1031 fView
.getSDWidget().clearSelection();
1032 fView
.getSDWidget().redraw();
1036 // Not in GUI thread - queue action in GUI thread.
1037 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1040 moveToMessageInPage();
1052 * Moves to a certain message defined by timestamp (across pages)
1054 protected void moveToPage() {
1059 * Moves to a certain page.
1061 * @param notifyAll true to broadcast time range signal to other signal handlers else false
1063 protected void moveToPage(boolean notifyAll
) {
1065 TmfTimeRange window
= null;
1070 if (fCurrentPage
> fCheckPoints
.size()) {
1073 window
= fCheckPoints
.get(fCurrentPage
);
1078 if (window
== null) {
1079 window
= TmfTimeRange
.ETERNITY
;
1082 fPageRequest
= new TmfEventRequest(ITmfEvent
.class, window
, TmfDataRequest
.ALL_DATA
, 1, ITmfDataRequest
.ExecutionType
.FOREGROUND
) {
1083 private final List
<ITmfSyncSequenceDiagramEvent
> fSdEvent
= new ArrayList
<ITmfSyncSequenceDiagramEvent
>();
1086 public void handleData(ITmfEvent event
) {
1087 super.handleData(event
);
1089 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1091 if (sdEvent
!= null) {
1092 fSdEvent
.add(sdEvent
);
1097 public void handleSuccess() {
1098 fillCurrentPage(fSdEvent
);
1099 super.handleSuccess();
1104 fTrace
.sendRequest(fPageRequest
);
1107 TmfTimeRange timeRange
= getSignalTimeRange(window
.getStartTime());
1108 broadcast(new TmfRangeSynchSignal(this, timeRange
, timeRange
.getStartTime()));
1113 * Gets page that contains timestamp
1115 * @param time The timestamp
1116 * @return page that contains the time
1119 protected int getPage(ITmfTimestamp time
) {
1124 size
= fCheckPoints
.size();
1125 for (page
= 0; page
< size
; page
++) {
1126 TmfTimeRange timeRange
= fCheckPoints
.get(page
);
1127 if (timeRange
.getEndTime().compareTo(time
, false) >= 0) {
1141 * Background search in trace for expression in criteria.
1143 * @param findCriteria The find criteria
1144 * @return true if background request was started else false
1146 protected boolean findInNextPages(Criteria findCriteria
) {
1149 if (fFindJob
!= null) {
1153 int nextPage
= fCurrentPage
+ 1;
1155 if ((nextPage
) >= fCheckPoints
.size()) {
1156 // we are at the end
1160 TmfTimeRange window
= new TmfTimeRange(fCheckPoints
.get(nextPage
).getStartTime(), fCheckPoints
.get(fCheckPoints
.size()-1).getEndTime());
1161 fFindJob
= new SearchJob(findCriteria
, window
);
1162 fFindJob
.schedule();
1163 fView
.toggleWaitCursorAsync(true);
1171 * Gets time range for time range signal.
1173 * @param startTime The start time of time range.
1174 * @return the time range
1177 protected TmfTimeRange
getSignalTimeRange(ITmfTimestamp startTime
) {
1180 TmfTimeRange currentRange
= TmfTraceManager
.getInstance().getCurrentRange();
1181 long offset
= fTrace
== null ?
0 : currentRange
.getEndTime().getDelta(currentRange
.getStartTime()).normalize(0, startTime
.getScale()).getValue();
1182 TmfTimestamp initialEndOfWindow
= new TmfTimestamp(startTime
.getValue() + offset
, startTime
.getScale(), startTime
.getPrecision());
1183 return new TmfTimeRange(startTime
, initialEndOfWindow
);
1191 * Checks if filter criteria matches the message name in given SD event.
1193 * @param sdEvent The SD event to check
1194 * @return true if match else false.
1196 protected boolean filterMessage(ITmfSyncSequenceDiagramEvent sdEvent
) {
1199 if (fFilterCriteria
!= null) {
1200 for(FilterCriteria criteria
: fFilterCriteria
) {
1201 if (criteria
.isActive() && criteria
.getCriteria().isSyncMessageSelected() && criteria
.getCriteria().matches(sdEvent
.getName())) {
1213 * Checks if filter criteria matches a lifeline name (sender or receiver) in given SD event.
1215 * @param lifeline the message receiver
1216 * @return true if match else false.
1218 protected boolean filterLifeLine(String lifeline
) {
1221 if (fFilterCriteria
!= null) {
1222 for(FilterCriteria criteria
: fFilterCriteria
) {
1223 if (criteria
.isActive() && criteria
.getCriteria().isLifeLineSelected() && criteria
.getCriteria().matches(lifeline
)) {
1235 * Job to search in trace for given time range.
1237 protected class SearchJob
extends Job
{
1240 * The search event request.
1242 protected final SearchEventRequest fSearchRequest
;
1247 * @param findCriteria The search criteria
1248 * @param window Time range to search in
1251 public SearchJob(Criteria findCriteria
, TmfTimeRange window
) {
1252 super(Messages
.TmfUml2SDSyncLoader_SearchJobDescrition
);
1253 fSearchRequest
= new SearchEventRequest(window
, TmfDataRequest
.ALL_DATA
, 1, ITmfDataRequest
.ExecutionType
.FOREGROUND
, findCriteria
);
1257 protected IStatus
run(IProgressMonitor monitor
) {
1258 fSearchRequest
.setMonitor(monitor
);
1260 fTrace
.sendRequest(fSearchRequest
);
1263 fSearchRequest
.waitForCompletion();
1264 } catch (InterruptedException e
) {
1265 Activator
.getDefault().logError("Search request interrupted!", e
); //$NON-NLS-1$
1268 IStatus status
= Status
.OK_STATUS
;
1269 if (fSearchRequest
.isFound() && (fSearchRequest
.getFoundTime() != null)) {
1270 fCurrentTime
= fSearchRequest
.getFoundTime();
1272 // Avoid double-selection. Selection will be done when calling find(criteria)
1273 // after moving to relevant page
1275 if (!fView
.getSDWidget().isDisposed()) {
1276 fView
.getSDWidget().getDisplay().asyncExec(new Runnable() {
1286 if (monitor
.isCanceled()) {
1287 status
= Status
.CANCEL_STATUS
;
1290 // String was not found
1291 status
= new Status(IStatus
.WARNING
, Activator
.PLUGIN_ID
, Messages
.TmfUml2SDSyncLoader_SearchNotFound
);
1293 setProperty(IProgressConstants
.KEEP_PROPERTY
, Boolean
.TRUE
);
1299 fView
.toggleWaitCursorAsync(false);
1309 protected void canceling() {
1310 fSearchRequest
.cancel();
1321 * TMF event request for searching within trace.
1323 protected class SearchEventRequest
extends TmfEventRequest
{
1326 * The find criteria.
1328 private final Criteria fCriteria
;
1330 * A progress monitor
1332 private IProgressMonitor fMonitor
;
1334 * Flag to indicate that node was found according the criteria .
1336 private boolean fIsFound
= false;
1338 * Time stamp of found item.
1340 private ITmfTimestamp fFoundTime
= null;
1344 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1345 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1346 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1347 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#handleData(...)
1348 * @param criteria The search criteria
1350 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, int blockSize
, ExecutionType execType
, Criteria criteria
) {
1351 this(range
, nbRequested
, blockSize
, execType
, criteria
, null);
1356 * @param range @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1357 * @param nbRequested @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1358 * @param blockSize @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1359 * @param execType @see org.eclipse.linuxtools.tmf.request.TmfEventRequest#TmfEventRequest(...)
1360 * @param criteria The search criteria
1361 * @param monitor progress monitor
1363 public SearchEventRequest(TmfTimeRange range
, int nbRequested
, int blockSize
, ExecutionType execType
, Criteria criteria
, IProgressMonitor monitor
) {
1364 super(ITmfEvent
.class, range
, nbRequested
, blockSize
, execType
);
1365 fCriteria
= new Criteria(criteria
);
1370 public void handleData(ITmfEvent event
) {
1371 super.handleData(event
);
1373 if ((fMonitor
!= null) && fMonitor
.isCanceled()) {
1378 ITmfSyncSequenceDiagramEvent sdEvent
= getSequenceDiagramEvent(event
);
1380 if (sdEvent
!= null) {
1382 if (fCriteria
.isLifeLineSelected()) {
1383 if (fCriteria
.matches(sdEvent
.getSender())) {
1384 fFoundTime
= event
.getTimestamp();
1389 if (fCriteria
.matches(sdEvent
.getReceiver())) {
1390 fFoundTime
= event
.getTimestamp();
1396 if (fCriteria
.isSyncMessageSelected() && fCriteria
.matches(sdEvent
.getName())) {
1397 fFoundTime
= event
.getTimestamp();
1405 * Set progress monitor.
1407 * @param monitor The monitor to assign
1409 public void setMonitor(IProgressMonitor monitor
) {
1414 * Check if find criteria was met.
1416 * @return true if find criteria was met.
1418 public boolean isFound() {
1423 * Returns timestamp of found time.
1425 * @return timestamp of found time.
1428 public ITmfTimestamp
getFoundTime() {
1434 * Job class to provide progress monitor feedback.
1437 * @author Bernd Hufmann
1440 protected static class IndexingJob
extends Job
{
1443 * @param name The job name
1445 public IndexingJob(String name
) {
1450 protected IStatus
run(IProgressMonitor monitor
) {
1451 while (!monitor
.isCanceled()) {
1453 Thread
.sleep(INDEXING_THREAD_SLEEP_VALUE
);
1454 } catch (InterruptedException e
) {
1455 return Status
.OK_STATUS
;
1459 return Status
.OK_STATUS
;
1465 * Returns sequence diagram event if details in given event are available else null.
1467 * @param tmfEvent Event to parse for sequence diagram event details
1468 * @return sequence diagram event if details are available else null
1471 protected ITmfSyncSequenceDiagramEvent
getSequenceDiagramEvent(ITmfEvent tmfEvent
){
1472 //type = .*RECEIVE.* or .*SEND.*
1473 //content = sender:<sender name>:receiver:<receiver name>,signal:<signal name>
1474 String eventType
= tmfEvent
.getType().toString();
1475 if (eventType
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeSend
) || eventType
.contains(Messages
.TmfUml2SDSyncLoader_EventTypeReceive
)) {
1476 Object sender
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldSender
);
1477 Object receiver
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldReceiver
);
1478 Object name
= tmfEvent
.getContent().getField(Messages
.TmfUml2SDSyncLoader_FieldSignal
);
1479 if ((sender
instanceof ITmfEventField
) && (receiver
instanceof ITmfEventField
) && (name
instanceof ITmfEventField
)) {
1480 ITmfSyncSequenceDiagramEvent sdEvent
= new TmfSyncSequenceDiagramEvent(tmfEvent
,
1481 ((ITmfEventField
) sender
).getValue().toString(),
1482 ((ITmfEventField
) receiver
).getValue().toString(),
1483 ((ITmfEventField
) name
).getValue().toString());