tmf: Simple warning fixes in tmf.core and tests
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / core / Frame.java
1 /**********************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * Copyright (c) 2011, 2012 Ericsson.
4 *
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
9 *
10 * Contributors:
11 * IBM - Initial API and implementation
12 * Bernd Hufmann - Updated for TMF
13 **********************************************************************/
14 package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core;
15
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.Iterator;
19 import java.util.List;
20
21 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
22 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor;
23 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
24 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref;
25 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator;
26
27 /**
28 * The Frame class is the base sequence diagram graph nodes container.<br>
29 * For instance, only one frame can be drawn in the View.<br>
30 * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.<br>
31 * Only the graph node added to their representing list will be drawn.
32 *
33 * The lifelines are appended along the X axsis when added in a frame.<br>
34 * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.<br>
35 *
36 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details
37 * @author sveyrier
38 * @version 1.0
39 */
40 public class Frame extends BasicFrame {
41
42 // ------------------------------------------------------------------------
43 // Attributes
44 // ------------------------------------------------------------------------
45 /**
46 * The lifeline that is current highlighted.
47 */
48 protected Lifeline fHighlightLifeline = null;
49 /**
50 * The value of the start event.
51 */
52 protected int fStartEvent = 0;
53 /**
54 * The nubmer of events in the frame.
55 */
56 protected int fNbEvent = 0;
57 /**
58 * The color for highlighting.
59 */
60 protected IColor fHighlightColor = null;
61 /**
62 * The list of time events of the corresponding execution occurrences.
63 */
64 protected List<SDTimeEvent> fExecutionOccurrencesWithTime;
65 /**
66 * The Array of lifeline categories.
67 */
68 protected LifelineCategories[] fLifelineCategories = null;
69
70 // ------------------------------------------------------------------------
71 // Methods
72 // ------------------------------------------------------------------------
73
74 /**
75 * Returns a list of all lifelines known by this frame. Known lifelines are the only one which can be displayed on
76 * screen.
77 *
78 * @return the lifelines list
79 */
80 protected List<GraphNode> getLifelines() {
81 if (!fHasChilden) {
82 return null;
83 }
84 return (List<GraphNode>) fNodes.get(Lifeline.LIFELINE_TAG);
85 }
86
87 /**
88 * Returns the number of lifelines stored in the frame
89 *
90 * @return the number of lifelines
91 */
92 public int lifeLinesCount() {
93 List<GraphNode> lifelines = getLifelines();
94 if (lifelines != null) {
95 return lifelines.size();
96 }
97 return 0;
98 }
99
100 /**
101 * Returns the lifeline at the given index in the lifelines array
102 *
103 * @param index the position in the lifeline array
104 * @return the lifeline or <code>null</code>
105 */
106 public Lifeline getLifeline(int index) {
107 if ((getLifelines() != null) && (index >= 0) && (index < lifeLinesCount())) {
108 return (Lifeline) getLifelines().get(index);
109 }
110 return null;
111 }
112
113 /**
114 * Returns a list of syncMessages known by this frame. Known syncMessages are the only on which can be displayed on
115 * screen
116 *
117 * @return the syncMessages list
118 */
119 protected List<GraphNode> getSyncMessages() {
120 if (!fHasChilden) {
121 return null;
122 }
123 return (List<GraphNode>) fNodes.get(SyncMessage.SYNC_MESS_TAG);
124 }
125
126 /**
127 * Returns the number of syncMessages stored in the frame
128 *
129 * @return the number of syncMessage
130 */
131 public int syncMessageCount() {
132 if (getSyncMessages() != null) {
133 return getSyncMessages().size();
134 }
135 return 0;
136 }
137
138 /**
139 * Returns the syncMessage at the given index in the syncMessages array
140 *
141 * @param index the position in the syncMessages array
142 * @return the syncMessage or <code>null</code>
143 */
144 public SyncMessage getSyncMessage(int index) {
145 if ((getSyncMessages() != null) && (index >= 0) && (index < getSyncMessages().size())) {
146 return (SyncMessage) getSyncMessages().get(index);
147 }
148 return null;
149 }
150
151 /**
152 * Returns a list of asyncMessages known by this frame. Known asyncMessages are the only on which can be displayed
153 * on screen
154 *
155 * @return the asyncMessages list or <code>null</code>
156 */
157 protected List<GraphNode> getAsyncMessages() {
158 if (!fHasChilden) {
159 return null;
160 }
161 return (List<GraphNode>) fNodes.get(AsyncMessage.ASYNC_MESS_TAG);
162 }
163
164 /**
165 * Returns the number of asyncMessage stored in the frame
166 *
167 * @return the number of asyncMessage
168 */
169 public int asyncMessageCount() {
170 if (getAsyncMessages() != null) {
171 return getAsyncMessages().size();
172 }
173 return 0;
174 }
175
176 /**
177 * Returns the asyncMessage at the given index in the asyncMessage array
178 *
179 * @param index the position in the asyncMessage array
180 * @return the asyncMessage or <code>null</code>
181 */
182 public AsyncMessage getAsyncMessage(int index) {
183 if ((getAsyncMessages() != null) && (index >= 0) && (index < getAsyncMessages().size())) {
184 return (AsyncMessage) getAsyncMessages().get(index);
185 }
186 return null;
187 }
188
189 /**
190 * Returns a list of syncMessages return known by this frame. Known syncMessages return are the only on which can be
191 * displayed on screen
192 *
193 * @return the syncMessages return list or <code>null</code>
194 */
195 protected List<GraphNode> getSyncMessagesReturn() {
196 if (!fHasChilden) {
197 return null;
198 }
199 return (List<GraphNode>) fNodes.get(SyncMessageReturn.SYNC_MESS_RET_TAG);
200 }
201
202 /**
203 * Returns the number of syncMessageReturn stored in the frame
204 *
205 * @return the number of syncMessageReturn
206 */
207 public int syncMessageReturnCount() {
208 if (getSyncMessagesReturn() != null) {
209 return getSyncMessagesReturn().size();
210 }
211 return 0;
212 }
213
214 /**
215 * Returns the syncMessageReturn at the given index in the syncMessageReturn array
216 *
217 * @param index the position in the syncMessageReturn array
218 * @return the syncMessageReturn or <code>null</code>
219 */
220 public SyncMessageReturn getSyncMessageReturn(int index) {
221 if ((getSyncMessagesReturn() != null) && (index >= 0) && (index < getSyncMessagesReturn().size())) {
222 return (SyncMessageReturn) getSyncMessagesReturn().get(index);
223 }
224 return null;
225 }
226
227 /**
228 * Returns a list of asyncMessageRetun known by this frame. Known asyncMessageRetun are the only on which can be
229 * displayed on screen
230 *
231 * @return the asyncMessageRetun list or <code>null</code>
232 */
233 protected List<GraphNode> getAsyncMessagesReturn() {
234 if (!fHasChilden) {
235 return null;
236 }
237 return (List<GraphNode>) fNodes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG);
238 }
239
240 /**
241 * Returns the number of asyncMessageReturn stored in the frame
242 *
243 * @return the number of asyncMessageReturn
244 */
245 public int asyncMessageReturnCount() {
246 if (getAsyncMessagesReturn() != null) {
247 return getAsyncMessagesReturn().size();
248 }
249 return 0;
250 }
251
252 /**
253 * Returns the asyncMessageReturn at the given index in the asyncMessageReturn array
254 *
255 * @param index the position in the asyncMessageReturn array
256 * @return the asyncMessageReturn or <code>null</code>
257 */
258 public AsyncMessageReturn getAsyncMessageReturn(int index) {
259 if ((getAsyncMessagesReturn() != null) && (index >= 0) && (index < getAsyncMessagesReturn().size())) {
260 return (AsyncMessageReturn) getAsyncMessagesReturn().get(index);
261 }
262 return null;
263 }
264
265 /**
266 * Adds a lifeline to the frame lifelines list. The lifeline X drawing order depends on the lifeline addition order
267 * into the frame lifelines list.
268 *
269 * @param lifeline the lifeline to add
270 */
271 public void addLifeLine(Lifeline lifeline) {
272 fComputeMinMax = true;
273 if (lifeline == null) {
274 return;
275 }
276 // set the lifeline parent frame
277 lifeline.setFrame(this);
278 // Increate the frame lifeline counter
279 // and set the lifeline drawing order
280 lifeline.setIndex(getNewHorizontalIndex());
281 if (lifeline.hasTimeInfo()) {
282 fHasTimeInfo = true;
283 }
284 // add the lifeline to the lifelines list
285 addNode(lifeline);
286 }
287
288 /**
289 * Returns the first visible lifeline drawn in the view
290 *
291 * @return the first visible lifeline index
292 */
293 public int getFirstVisibleLifeline() {
294 if (!fHasChilden) {
295 return 0;
296 } else if (fIndexes.get(Lifeline.LIFELINE_TAG) != null) {
297 return ((Integer) fIndexes.get(Lifeline.LIFELINE_TAG)).intValue();
298 }
299 return 0;
300 }
301
302 /**
303 * Returns the first visible synchronous message drawn in the view
304 *
305 * @return the first visible synchronous message index
306 */
307 public int getFirstVisibleSyncMessage() {
308 if (!fHasChilden) {
309 return 0;
310 } else if (fIndexes.get(SyncMessage.SYNC_MESS_TAG) != null) {
311 return ((Integer) fIndexes.get(SyncMessage.SYNC_MESS_TAG)).intValue();
312 }
313 return 0;
314 }
315
316 /**
317 * Returns the first visible synchronous message return drawn in the view
318 *
319 * @return the first visible synchronous message return index
320 */
321 public int getFirstVisibleSyncMessageReturn() {
322 if (!fHasChilden) {
323 return 0;
324 } else if (fIndexes.get(SyncMessageReturn.SYNC_MESS_RET_TAG) != null) {
325 return ((Integer) fIndexes.get(SyncMessageReturn.SYNC_MESS_RET_TAG)).intValue();
326 }
327 return 0;
328 }
329
330 /**
331 * Returns the first visible synchronous message drawn in the view
332 *
333 * @return the first visible synchronous message index
334 */
335 public int getFirstVisibleAsyncMessage() {
336 if (!fHasChilden) {
337 return 0;
338 } else if (fIndexes.get(AsyncMessage.ASYNC_MESS_TAG) != null) {
339 return ((Integer) fIndexes.get(AsyncMessage.ASYNC_MESS_TAG)).intValue();
340 }
341 return 0;
342 }
343
344 /**
345 * Returns the first visible synchronous message return drawn in the view
346 *
347 * @return the first visible synchronous message return index
348 */
349 public int getFirstVisibleAsyncMessageReturn() {
350 if (!fHasChilden) {
351 return 0;
352 } else if (fIndexes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG) != null) {
353 return ((Integer) fIndexes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG)).intValue();
354 }
355 return 0;
356 }
357
358 /**
359 * Returns the list of execution occurrences.
360 *
361 * @return the list of execution occurrences
362 */
363 public List<SDTimeEvent> getExecutionOccurrencesWithTime() {
364 return fExecutionOccurrencesWithTime;
365 }
366
367 /**
368 * Inserts a lifeline after a given lifeline.
369 *
370 * @param toInsert A lifeline to insert
371 * @param after A lifelife the toInsert-lifeline will be inserted after.
372 */
373 public void insertLifelineAfter(Lifeline toInsert, Lifeline after) {
374 if ((toInsert == null)) {
375 return;
376 }
377 if (toInsert == after) {
378 return;
379 }
380 int insertPoint = 0;
381 if (after != null) {
382 insertPoint = after.getIndex();
383 }
384 int removePoint = toInsert.getIndex() - 1;
385 if (removePoint >= insertPoint) {
386 getLifelines().remove(removePoint);
387 }
388 getLifelines().add(insertPoint, toInsert);
389 if (removePoint < insertPoint) {
390 getLifelines().remove(removePoint);
391 }
392
393 if (removePoint >= insertPoint) {
394 toInsert.setIndex(insertPoint + 1);
395 } else {
396 toInsert.setIndex(insertPoint - 1);
397 }
398
399 insertPoint++;
400 if (removePoint >= insertPoint) {
401 for (int i = insertPoint; i < getLifelines().size(); i++) {
402 getLifeline(i).setIndex(i + 1);
403 }
404 } else {
405 for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) {
406 getLifeline(i).setIndex(i + 1);
407 }
408 }
409 }
410
411 /**
412 * Inserts a lifeline before a given lifeline.
413 *
414 * @param toInsert
415 * A lifeline to insert
416 * @param before
417 * A lifeline the toInsert-lifeline will be inserted before.
418 */
419 public void insertLifelineBefore(Lifeline toInsert, Lifeline before) {
420 if ((toInsert == null)) {
421 return;
422 }
423 if (toInsert == before) {
424 return;
425 }
426 int insertPoint = 0;
427 if (before != null) {
428 insertPoint = before.getIndex() - 1;
429 }
430 int removePoint = toInsert.getIndex() - 1;
431 if (removePoint >= insertPoint) {
432 getLifelines().remove(removePoint);
433 }
434 getLifelines().add(insertPoint, toInsert);
435 if (removePoint < insertPoint) {
436 getLifelines().remove(removePoint);
437 }
438
439 if (removePoint >= insertPoint) {
440 toInsert.setIndex(insertPoint + 1);
441 } else {
442 toInsert.setIndex(insertPoint - 1);
443 }
444
445 insertPoint++;
446 if (removePoint >= insertPoint) {
447 for (int i = insertPoint; i < getLifelines().size(); i++) {
448 getLifeline(i).setIndex(i + 1);
449 }
450 } else {
451 for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) {
452 getLifeline(i).setIndex(i + 1);
453 }
454 }
455 }
456
457 /**
458 * Gets the closer life line to the given x-coordinate.
459 *
460 * @param x A x coordinate
461 * @return the closer lifeline
462 */
463 public Lifeline getCloserLifeline(int x) {
464 int index = (x - Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN) / Metrics.swimmingLaneWidth() - 1;
465 if (index < 0) {
466 index = 0;
467 }
468 if (index >= getLifelines().size()) {
469 index = getLifelines().size() - 1;
470 }
471 Lifeline node1, node2, node3;
472 int dist1, dist2, dist3;
473 node1 = node2 = node3 = getLifeline(index);
474 dist1 = dist2 = dist3 = Math.abs(node1.getX() + node1.getWidth() / 2 - x);
475 if (index > 0) {
476 node2 = getLifeline(index - 1);
477 dist2 = Math.abs(node2.getX() + node2.getWidth() / 2 - x);
478 }
479 if (index < getLifelines().size() - 1) {
480 node3 = getLifeline(index + 1);
481 dist3 = Math.abs(node3.getX() + node3.getWidth() / 2 - x);
482 }
483 if (dist1 <= dist2 && dist1 <= dist3) {
484 return node1;
485 } else if (dist2 <= dist1 && dist2 <= dist3) {
486 return node2;
487 }
488 return node3;
489 }
490
491 /**
492 * Re-orders the given list of lifelines.
493 *
494 * @param list A list of lifelines to reorder.
495 */
496 public void reorder(List<?> list) {
497 for (int i = 0; i < list.size(); i++) {
498 if (list.get(i) instanceof Lifeline[]) {
499 Lifeline temp[] = (Lifeline[]) list.get(i);
500 if (temp.length == 2) {
501 if (temp[1] == null) {
502 insertLifelineAfter(temp[0], getLifeline(lifeLinesCount() - 1));
503 } else {
504 insertLifelineBefore(temp[0], temp[1]);
505 }
506 }
507 }
508 }
509 }
510
511 /**
512 * Resets the time compression information.
513 */
514 public void resetTimeCompression() {
515 fHighlightLifeline = null;
516 this.fStartEvent = 0;
517 this.fNbEvent = 0;
518 fHighlightColor = null;
519 }
520
521 /*
522 * (non-Javadoc)
523 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicFrame#computeMinMax()
524 */
525 @Override
526 protected void computeMinMax() {
527 List<SDTimeEvent> timeArray = buildTimeArray();
528 if ((timeArray == null) || timeArray.isEmpty()) {
529 return;
530 }
531 for (int i = 0; i < timeArray.size() - 1; i++) {
532 SDTimeEvent m1 = (SDTimeEvent) timeArray.get(i);
533 SDTimeEvent m2 = (SDTimeEvent) timeArray.get(i + 1);
534 if (SDViewPref.getInstance().excludeExternalTime() && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) {
535 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
536 BaseMessage mes2 = (BaseMessage) m2.getGraphNode();
537 if ((mes2.fStartLifeline == null) || (mes1.fEndLifeline == null)) {
538 continue;
539 }
540 }
541
542 updateMinMax(m1, m2);
543 }
544 }
545
546 /**
547 * Find the two graph nodes that are closest to this date, one just earlier, second just later. If date is before
548 * any graph node, bounds[0] is null and bounds[1] is the earliest. If date is after any graph node, bounds[1] is
549 * null and bounds[0] is the latest.
550 *
551 * @param dateToFind date to be found
552 * @param bounds a two items array that will receive bounds if found
553 * @return true if both bounds not null
554 */
555 public boolean findDateBounds(ITmfTimestamp dateToFind, ITimeRange bounds[]) {
556 if (hasTimeInfo()) {
557 List<SDTimeEvent> timeArray = buildTimeArray();
558
559 if ((timeArray == null) || timeArray.isEmpty()) {
560 return false;
561 }
562
563 bounds[0] = null;
564 bounds[1] = null;
565 for (int i = 0; i < timeArray.size(); i++) {
566 SDTimeEvent m = (SDTimeEvent) timeArray.get(i);
567 if (m.getTime().compareTo(dateToFind, true) > 0) {
568 bounds[1] = m.getGraphNode();
569 if (i > 0) {
570 bounds[0] = ((SDTimeEvent) timeArray.get(i - 1)).getGraphNode();
571 return true;
572 }
573 return false;
574 }
575 }
576 bounds[0] = ((SDTimeEvent) timeArray.get(timeArray.size() - 1)).getGraphNode();
577 }
578 return false;
579 }
580
581 /**
582 * Set whether time information is available or not
583 *
584 * @param value <code>true</code> for has time information else <code>false</code>
585 */
586 protected void setHasTimeInfo(boolean value) {
587 fHasTimeInfo = value;
588 }
589
590 /**
591 * Returns whether frame has time info or not.
592 *
593 * @return <code>true</code> whether frame has time info else <code>false</code>
594 */
595 public boolean hasTimeInfo() {
596 return fHasTimeInfo;
597 }
598
599 /**
600 * Highlights the time compression.
601 *
602 * @param lifeline A lifeline to highlight
603 * @param startEvent A start event number
604 * @param nbEvent A number of events
605 * @param color A color for highlighting
606 */
607 public void highlightTimeCompression(Lifeline lifeline, int startEvent, int nbEvent, IColor color) {
608 fHighlightLifeline = lifeline;
609 this.fStartEvent = startEvent;
610 this.fNbEvent = nbEvent;
611 fHighlightColor = color;
612 }
613
614 /**
615 * Set the lifeline categories which will be use during the lifelines creation
616 *
617 * @see Lifeline#setCategory(int)
618 * @param categories the lifeline categories array
619 */
620 public void setLifelineCategories(LifelineCategories[] categories) {
621 fLifelineCategories = Arrays.copyOf(categories, categories.length);
622 }
623
624 /**
625 * Returns the lifeline categories array set for the this frame
626 *
627 * @return the lifeline categories array or null if not set
628 */
629 public LifelineCategories[] getLifelineCategories() {
630 return Arrays.copyOf(fLifelineCategories, fLifelineCategories.length);
631 }
632
633 /**
634 * Adds a message to the Frame message list. Four kinds of syncMessages can be added:<br>
635 * - synchronous syncMessages<br>
636 * - synchronous syncMessages return<br>
637 * - asynchronous syncMessages<br>
638 * - asynchronous syncMessages return<br>
639 * For drawing performance reason, it is recommended to add synchronous syncMessages in the same order they should
640 * appear along the Y axis in the Frame.
641 *
642 * @param message the message to add
643 */
644 public void addMessage(BaseMessage message) {
645 addNode(message);
646 }
647
648 /*
649 * (non-Javadoc)
650 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicFrame#draw(org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC)
651 */
652 @Override
653 public void draw(IGC context) {
654 drawFrame(context);
655 if (!fHasChilden) {
656 return;
657 }
658
659 if (fHighlightLifeline != null) {
660 IColor backupColor = context.getBackground();
661 context.setBackground(SDViewPref.getInstance().getTimeCompressionSelectionColor());
662 int gy = fHighlightLifeline.getY() + fHighlightLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fStartEvent;
663 context.fillRectangle(Metrics.FRAME_H_MARGIN + 1, gy, fHighlightLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.FRAME_H_MARGIN, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fNbEvent);
664 context.setBackground(backupColor);
665 }
666 super.draw(context, false);
667 int lifelineArryStep = 1;
668 if (Metrics.swimmingLaneWidth() * context.getZoom() < Metrics.LIFELINE_SIGNIFICANT_HSPACING) {
669 lifelineArryStep = Math.round(Metrics.LIFELINE_SIGNIFICANT_HSPACING / (Metrics.swimmingLaneWidth() * context.getZoom()));
670 }
671 if (fIndexes.size() == 0) {
672 return;
673 }
674 int lifeLineDrawIndex = ((Integer) fIndexes.get(Lifeline.LIFELINE_TAG)).intValue();
675 for (int i = lifeLineDrawIndex; i < ((List<GraphNode>) fNodes.get(Lifeline.LIFELINE_TAG)).size(); i = i + lifelineArryStep) {
676 Lifeline toDraw = (Lifeline) ((List<GraphNode>) fNodes.get(Lifeline.LIFELINE_TAG)).get(i);
677 if (toDraw.getX() - Metrics.LIFELINE_SPACING / 2 > context.getContentsX() + context.getVisibleWidth()) {
678 break;
679 }
680 toDraw.drawName(context);
681
682 if (fHighlightLifeline != null) {
683 if (toDraw == fHighlightLifeline) {
684 toDraw.highlightExecOccurrenceRegion(context, fStartEvent, fNbEvent, fHighlightColor);
685 } else if ((toDraw.getIndex() < fHighlightLifeline.getIndex()) || ((toDraw.getIndex() < fHighlightLifeline.getIndex()))) {
686
687 int acIndex = toDraw.getExecOccurrenceDrawIndex();
688 // acIndex = first visible execution occurrence
689 // for drawing speed reason with only search on the visible subset
690 if (toDraw.getExecutions() != null) {
691 for (int index = acIndex; index < toDraw.getExecutions().size(); index++) {
692 BasicExecutionOccurrence exec = (BasicExecutionOccurrence) toDraw.getExecutions().get(index);
693 int tempEvent = fStartEvent;
694 for (int j = 0; j < fNbEvent; j++) {
695 if (((tempEvent >= exec.fStartEventOccurrence) && (tempEvent <= exec.fEndEventOccurrence) && (tempEvent + 1 >= exec.fStartEventOccurrence) && (tempEvent + 1 <= exec.fEndEventOccurrence))) {
696 toDraw.highlightExecOccurrenceRegion(context, tempEvent, 1, SDViewPref.getInstance().getTimeCompressionSelectionColor());
697 }
698 tempEvent = tempEvent + 1;
699 }
700 // if we are outside the visible area we stop right now
701 // This works because execution occurrences are ordered along the Y axis
702 if (exec.getY() > getY()) {
703 break;
704 }
705 }
706 }
707 }
708 }
709 }
710 }
711
712 /*
713 * (non-Javadoc)
714 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.BasicFrame#buildTimeArray()
715 */
716 @Override
717 protected List<SDTimeEvent> buildTimeArray() {
718
719 if (!fHasChilden) {
720 return new ArrayList<SDTimeEvent>();
721 }
722
723 List<SDTimeEvent> timeArray = super.buildTimeArray();
724 fExecutionOccurrencesWithTime = null;
725 if (getLifelines() != null) {
726 for (int i = 0; i < ((List<GraphNode>) fNodes.get(Lifeline.LIFELINE_TAG)).size(); i++) {
727 Lifeline lifeline = (Lifeline) ((List<GraphNode>) fNodes.get(Lifeline.LIFELINE_TAG)).get(i);
728 if (lifeline.hasTimeInfo() && lifeline.getExecutions() != null) {
729 for (Iterator<GraphNode> j = lifeline.getExecutions().iterator(); j.hasNext();) {
730 GraphNode o = j.next();
731 if (o instanceof ExecutionOccurrence) {
732 ExecutionOccurrence eo = (ExecutionOccurrence) o;
733 if (eo.hasTimeInfo()) {
734 int event = eo.getStartOccurrence();
735 ITmfTimestamp time = eo.getStartTime();
736 SDTimeEvent f = new SDTimeEvent(time, event, eo);
737 timeArray.add(f);
738 if (fExecutionOccurrencesWithTime == null) {
739 fExecutionOccurrencesWithTime = new ArrayList<SDTimeEvent>();
740 }
741 fExecutionOccurrencesWithTime.add(f);
742 event = eo.getEndOccurrence();
743 time = eo.getEndTime();
744 f = new SDTimeEvent(time, event, eo);
745 timeArray.add(f);
746 fExecutionOccurrencesWithTime.add(f);
747 }
748 }
749 }
750 }
751 }
752 }
753
754 if (fExecutionOccurrencesWithTime != null) {
755 SDTimeEvent[] temp = fExecutionOccurrencesWithTime.toArray(new SDTimeEvent[fExecutionOccurrencesWithTime.size()]);
756 Arrays.sort(temp, new TimeEventComparator());
757 fExecutionOccurrencesWithTime = Arrays.asList(temp);
758 }
759 SDTimeEvent[] temp = timeArray.toArray(new SDTimeEvent[timeArray.size()]);
760 Arrays.sort(temp, new TimeEventComparator());
761 timeArray = Arrays.asList(temp);
762 return timeArray;
763 }
764
765 /**
766 * Get the closer leaving message.
767 *
768 * @param lifeline A lifeline reference
769 * @param message A message reference
770 * @param list A list of graph nodes
771 * @param smallerEvent A smaller event flag
772 * @return the closer leaving message.
773 */
774 protected GraphNode getCloserLeavingMessage(Lifeline lifeline, BaseMessage message, List<GraphNode> list, boolean smallerEvent) {
775 if (list == null) {
776 return null;
777 }
778
779 if (!smallerEvent) {
780 int event = 0;
781 if (message != null) {
782 event = message.getEventOccurrence();
783 }
784 for (int i = 0; i < list.size(); i++) {
785 GraphNode node = (GraphNode) list.get(i);
786 if (node instanceof SyncMessage) {
787 SyncMessage syncNode = (SyncMessage) node;
788 if ((syncNode.getEventOccurrence() > event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) {
789 return node;
790 }
791 } else if (node instanceof AsyncMessage) {
792 AsyncMessage asyncNode = (AsyncMessage) node;
793 if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) {
794 return node;
795 }
796 }
797 }
798 } else {
799 int event = getMaxEventOccurrence();
800 if (message != null) {
801 if (message instanceof AsyncMessage) {
802 event = ((AsyncMessage) message).getStartOccurrence();
803 } else {
804 event = message.getEventOccurrence();
805 }
806 }
807 for (int i = list.size() - 1; i >= 0; i--) {
808 GraphNode node = (GraphNode) list.get(i);
809 if (node instanceof SyncMessage) {
810 SyncMessage syncNode = (SyncMessage) node;
811 if ((syncNode.getEventOccurrence() < event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message)) {
812 return node;
813 }
814 } else if (node instanceof AsyncMessage) {
815 AsyncMessage asyncNode = (AsyncMessage) node;
816 if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message)) {
817 return node;
818 }
819 }
820 }
821 }
822 return null;
823 }
824
825
826 /**
827 * Get the closer entering message.
828 *
829 * @param lifeline A lifeline reference
830 * @param message A message reference
831 * @param list A list of graph nodes
832 * @param smallerEvent A smaller event flag
833 * @return the closer entering message.
834 */
835 protected GraphNode getCloserEnteringMessage(Lifeline lifeline, BaseMessage message, List<GraphNode> list, boolean smallerEvent) {
836 if (list == null) {
837 return null;
838 }
839 if (!smallerEvent) {
840 int event = 0;
841 if (message != null) {
842 event = message.getEventOccurrence();
843 }
844 for (int i = 0; i < list.size(); i++) {
845 GraphNode node = (GraphNode) list.get(i);
846 if (node instanceof SyncMessage) {
847 SyncMessage syncNode = (SyncMessage) node;
848 if ((syncNode.getEventOccurrence() > event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) {
849 return node;
850 }
851 } else if (node instanceof AsyncMessage) {
852 AsyncMessage asyncNode = (AsyncMessage) node;
853 if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) {
854 return node;
855 }
856 }
857 }
858 } else {
859 int event = getMaxEventOccurrence();
860 if (message != null) {
861 if (message instanceof AsyncMessage) {
862 event = ((AsyncMessage) message).getStartOccurrence();
863 } else {
864 event = message.getEventOccurrence();
865 }
866 }
867 for (int i = list.size() - 1; i >= 0; i--) {
868 GraphNode node = (GraphNode) list.get(i);
869 if (node instanceof SyncMessage) {
870 SyncMessage syncNode = (SyncMessage) node;
871 if ((syncNode.getEventOccurrence() < event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message)) {
872 return node;
873 }
874 } else if (node instanceof AsyncMessage) {
875 AsyncMessage asyncNode = (AsyncMessage) node;
876 if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message)) {
877 return node;
878 }
879 }
880 }
881 }
882 return null;
883 }
884
885 /**
886 * Get distance of given event from given graph node.
887 *
888 * @param node A graph node reference.
889 * @param event A event number to check.
890 * @return distance of event from graph node.
891 */
892 protected int distanceFromEvent(GraphNode node, int event) {
893 int distance = 0;
894 if (node instanceof SyncMessage) {
895 distance = ((SyncMessage) node).getEventOccurrence() - event;
896 } else if (node instanceof AsyncMessage) {
897 int start = ((AsyncMessage) node).getStartOccurrence();
898 int end = ((AsyncMessage) node).getEndOccurrence();
899 if ((start - event) < (end - event)) {
900 distance = start - event;
901 } else {
902 distance = end - event;
903 }
904 }
905 return Math.abs(distance);
906 }
907
908 /**
909 * Get node from 2 given nodes that is close to event.
910 *
911 * @param node1 A first graph node
912 * @param node2 A second graph node
913 * @param event A event to check.
914 * @return graph node that is closer or <code>null</code>
915 */
916 protected GraphNode getCloserToEvent(GraphNode node1, GraphNode node2, int event) {
917 if ((node1 != null) && (node2 != null)) {
918 if (distanceFromEvent(node1, event) < distanceFromEvent(node2, event)) {
919 return node1;
920 } else {
921 return node2;
922 }
923 } else if (node1 != null) {
924 return node1;
925 } else if (node2 != null) {
926 return node2;
927 }
928 return null;
929 }
930
931 /**
932 * Get called message based on given start message.
933 *
934 * @param startMessage A start message to check.
935 * @return called message (graph node) or <code>null</code>
936 */
937 public GraphNode getCalledMessage(BaseMessage startMessage) {
938 int event = 0;
939 GraphNode result = null;
940 Lifeline lifeline = null;
941 if (startMessage != null) {
942 event = ((BaseMessage) startMessage).getEventOccurrence();
943 lifeline = ((BaseMessage) startMessage).getEndLifeline();
944 if (lifeline == null) {
945 lifeline = ((BaseMessage) startMessage).getStartLifeline();
946 }
947 }
948 if (lifeline == null) {
949 return null;
950 }
951 GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false);
952 GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false);
953 result = getCloserToEvent(message, messageReturn, event);
954 message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false);
955 result = getCloserToEvent(result, message, event);
956 messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false);
957 result = getCloserToEvent(result, messageReturn, event);
958 return result;
959 }
960
961 /**
962 * Get caller message based on given start message.
963 *
964 * @param startMessage A start message to check.
965 * @return called message (graph node) or <code>null</code>
966 */
967 public GraphNode getCallerMessage(BaseMessage startMessage) {
968 int event = getMaxEventOccurrence();
969 GraphNode result = null;
970 Lifeline lifeline = null;
971 if (startMessage != null) {
972 event = ((BaseMessage) startMessage).getEventOccurrence();
973 lifeline = ((BaseMessage) startMessage).getStartLifeline();
974 if (lifeline == null) {
975 lifeline = ((BaseMessage) startMessage).getEndLifeline();
976 }
977 }
978 if (lifeline == null) {
979 return null;
980 }
981 GraphNode message = getCloserEnteringMessage(lifeline, startMessage, getSyncMessages(), true);
982 GraphNode messageReturn = getCloserEnteringMessage(lifeline, startMessage, getSyncMessagesReturn(), true);
983 result = getCloserToEvent(message, messageReturn, event);
984 message = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessages(), true);
985 result = getCloserToEvent(result, message, event);
986 messageReturn = getCloserEnteringMessage(lifeline, startMessage, getAsyncMessagesReturn(), true);
987 result = getCloserToEvent(result, messageReturn, event);
988 return result;
989 }
990
991 /**
992 * Get next lifeline based on given message.
993 *
994 * @param lifeline A lifeline reference
995 * @param startMessage A start message to check
996 * @return next lifeline or <code>null</code>
997 */
998 public GraphNode getNextLifelineMessage(Lifeline lifeline, BaseMessage startMessage) {
999 int event = 0;
1000 if (startMessage != null) {
1001 event = ((BaseMessage) startMessage).getEventOccurrence();
1002 }
1003 if (lifeline == null) {
1004 return null;
1005 }
1006 GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), false);
1007 GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), false);
1008 GraphNode result = getCloserToEvent(message, messageReturn, event);
1009 message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), false);
1010 result = getCloserToEvent(result, message, event);
1011 messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), false);
1012 result = getCloserToEvent(result, messageReturn, event);
1013 return result;
1014 }
1015
1016 /**
1017 * Get previous lifeline based on given message.
1018 *
1019 * @param lifeline A lifeline reference
1020 * @param startMessage A start message to check.
1021 * @return previous lifeline or <code>null</code>
1022 */
1023 public GraphNode getPrevLifelineMessage(Lifeline lifeline, BaseMessage startMessage) {
1024 int event = getMaxEventOccurrence();
1025 if (startMessage != null) {
1026 if (startMessage instanceof AsyncMessage) {
1027 event = ((AsyncMessage) startMessage).getStartOccurrence();
1028 } else {
1029 event = startMessage.getEventOccurrence();
1030 }
1031 }
1032 if (lifeline == null) {
1033 return null;
1034 }
1035 GraphNode message = getCloserLeavingMessage(lifeline, startMessage, getSyncMessages(), true);
1036 GraphNode messageReturn = getCloserLeavingMessage(lifeline, startMessage, getSyncMessagesReturn(), true);
1037 GraphNode result = getCloserToEvent(message, messageReturn, event);
1038 message = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessages(), true);
1039 result = getCloserToEvent(result, message, event);
1040 messageReturn = getCloserLeavingMessage(lifeline, startMessage, getAsyncMessagesReturn(), true);
1041 result = getCloserToEvent(result, messageReturn, event);
1042 return result;
1043 }
1044
1045 /**
1046 * Get the first execution occurrence.
1047 *
1048 * @param lifeline A lifeline reference
1049 * @return the first execution occurrence of lifeline or <code>null</code>.
1050 */
1051 public BasicExecutionOccurrence getFirstExecution(Lifeline lifeline) {
1052 if (lifeline == null) {
1053 return null;
1054 }
1055 List<GraphNode> list = lifeline.getExecutions();
1056
1057 if ((list == null) || (list.isEmpty())) {
1058 return null;
1059 }
1060
1061 BasicExecutionOccurrence result = (BasicExecutionOccurrence) list.get(0);
1062 for (int i = 0; i < list.size(); i++) {
1063 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
1064 if ((e.getStartOccurrence() < result.getEndOccurrence())) {
1065 result = e;
1066 }
1067 }
1068 return result;
1069 }
1070
1071 /**
1072 * Get the previous execution occurrence relative to a given execution occurrence.
1073 *
1074 * @param exec A execution occurrence reference.
1075 * @return the previous execution occurrence of lifeline or <code>null</code>.
1076 */
1077 public BasicExecutionOccurrence getPrevExecOccurrence(BasicExecutionOccurrence exec) {
1078 if (exec == null) {
1079 return null;
1080 }
1081 Lifeline lifeline = exec.getLifeline();
1082 if (lifeline == null) {
1083 return null;
1084 }
1085 List<GraphNode> list = lifeline.getExecutions();
1086 if (list == null) {
1087 return null;
1088 }
1089 BasicExecutionOccurrence result = null;
1090 for (int i = 0; i < list.size(); i++) {
1091 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
1092 if ((e.getStartOccurrence() < exec.fStartEventOccurrence) && (result == null)) {
1093 result = e;
1094 }
1095 if ((e.getStartOccurrence() < exec.fStartEventOccurrence) && (e.getStartOccurrence() >= result.getEndOccurrence())) {
1096 result = e;
1097 }
1098 }
1099 return result;
1100 }
1101
1102 /**
1103 * Get the next execution occurrence relative to a given execution occurrence.
1104 *
1105 * @param exec A execution occurrence reference.
1106 * @return the next execution occurrence of lifeline or <code>null</code>.
1107 */
1108 public BasicExecutionOccurrence getNextExecOccurrence(BasicExecutionOccurrence exec) {
1109 if (exec == null) {
1110 return null;
1111 }
1112 Lifeline lifeline = exec.getLifeline();
1113 if (lifeline == null) {
1114 return null;
1115 }
1116 List<GraphNode> list = lifeline.getExecutions();
1117 if (list == null) {
1118 return null;
1119 }
1120 BasicExecutionOccurrence result = null;
1121 for (int i = 0; i < list.size(); i++) {
1122 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
1123 if ((e.getStartOccurrence() > exec.fStartEventOccurrence) && (result == null)) {
1124 result = e;
1125 }
1126 if ((e.getStartOccurrence() > exec.fStartEventOccurrence) && (e.getStartOccurrence() <= result.getEndOccurrence())) {
1127 result = e;
1128 }
1129 }
1130 return result;
1131 }
1132
1133 /**
1134 * Get the last execution occurrence.
1135 *
1136 * @param lifeline A lifeline reference.
1137 * @return the last execution occurrence of lifeline or <code>null</code>.
1138 */
1139 public BasicExecutionOccurrence getLastExecOccurrence(Lifeline lifeline) {
1140 if (lifeline == null) {
1141 return null;
1142 }
1143 List<GraphNode> list = lifeline.getExecutions();
1144 if (list == null) {
1145 return null;
1146 }
1147 BasicExecutionOccurrence result = null;
1148 for (int i = 0; i < list.size(); i++) {
1149 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
1150 if (result == null) {
1151 result = e;
1152 }
1153 if (e.getStartOccurrence() > result.getEndOccurrence()) {
1154 result = e;
1155 }
1156 }
1157 return result;
1158 }
1159 }
This page took 0.056844 seconds and 5 git commands to generate.