Fixed findbugs warnings in UML2SD of TMF UI
[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, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 * $Id: Frame.java,v 1.3 2008/01/24 02:28:49 apnan Exp $
8 *
9 * Contributors:
10 * IBM - Initial API and implementation
11 * Bernd Hufmann - Updated for TMF
12 **********************************************************************/
13 package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
21 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor;
22 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
23 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref;
24 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.util.TimeEventComparator;
25
26 /**
27 * The Frame class is the base sequence diagram graph nodes container.<br>
28 * For instance, only one frame can be drawn in the View.<br>
29 * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.<br>
30 * Only the graph node added to their representing list will be drawn.
31 *
32 * The lifelines are appended along the X axsis when added in a frame.<br>
33 * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.<br>
34 *
35 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details
36 * @author sveyrier
37 * @version 1.0
38 */
39 public class Frame extends BasicFrame {
40
41 protected Lifeline highlightLifeline = null;
42 protected int startEvent = 0;
43 protected int nbEvent = 0;
44 protected IColor highlightColor = null;
45
46 protected List<SDTimeEvent> executionOccurrencesWithTime;
47
48 protected LifelineCategories[] lifelineCategories = null;
49
50 /**
51 * Returns a list of all lifelines known by this frame. Known lifelines are the only one which can be displayed on
52 * screen.
53 *
54 * @return the lifelines list
55 */
56 protected List<GraphNode> getLifelines() {
57 if (!hasChilden)
58 return null;
59 else
60 return (List<GraphNode>) nodes.get(Lifeline.LIFELINE_TAG);
61 }
62
63 /**
64 * Returns the number of lifelines stored in the frame
65 *
66 * @return the number of lifelines
67 */
68 public int lifeLinesCount() {
69 List<GraphNode> lifelines = getLifelines();
70 if (lifelines != null)
71 return lifelines.size();
72 else
73 return 0;
74 }
75
76 /**
77 * Returns the lifeline at the given index in the lifelines array
78 *
79 * @param index the position in the lifeline array
80 * @return the lifeline
81 */
82 public Lifeline getLifeline(int index) {
83 if ((getLifelines() != null) && (index >= 0) && (index < lifeLinesCount()))
84 return (Lifeline) getLifelines().get(index);
85 return null;
86 }
87
88 /**
89 * Returns a list of syncMessages known by this frame. Known syncMessages are the only on which can be displayed on
90 * screen
91 *
92 * @return the syncMessages list
93 */
94 protected List<GraphNode> getSyncMessages() {
95 if (!hasChilden)
96 return null;
97 else
98 return (List<GraphNode>) nodes.get(SyncMessage.SYNC_MESS_TAG);
99 }
100
101 /**
102 * Returns the number of syncMessages stored in the frame
103 *
104 * @return the number of syncMessage
105 */
106 public int syncMessageCount() {
107 if (getSyncMessages() != null)
108 return getSyncMessages().size();
109 else
110 return 0;
111 }
112
113 /**
114 * Returns the syncMessage at the given index in the syncMessages array
115 *
116 * @param index the position in the syncMessages array
117 * @return the syncMessage
118 */
119 public SyncMessage getSyncMessage(int index) {
120 if ((getSyncMessages() != null) && (index >= 0) && (index < getSyncMessages().size()))
121 return (SyncMessage) getSyncMessages().get(index);
122 return null;
123 }
124
125 /**
126 * Returns a list of asyncMessages known by this frame. Known asyncMessages are the only on which can be displayed
127 * on screen
128 *
129 * @return the asyncMessages list
130 */
131 protected List<GraphNode> getAsyncMessages() {
132 if (!hasChilden)
133 return null;
134 else
135 return (List<GraphNode>) nodes.get(AsyncMessage.ASYNC_MESS_TAG);
136 }
137
138 /**
139 * Returns the number of asyncMessage stored in the frame
140 *
141 * @return the number of asyncMessage
142 */
143 public int asyncMessageCount() {
144 if (getAsyncMessages() != null)
145 return getAsyncMessages().size();
146 else
147 return 0;
148 }
149
150 /**
151 * Returns the asyncMessage at the given index in the asyncMessage array
152 *
153 * @param index the position in the asyncMessage array
154 * @return the asyncMessage
155 */
156 public AsyncMessage getAsyncMessage(int index) {
157 if ((getAsyncMessages() != null) && (index >= 0) && (index < getAsyncMessages().size()))
158 return (AsyncMessage) getAsyncMessages().get(index);
159 return null;
160 }
161
162 /**
163 * Returns a list of syncMessages return known by this frame. Known syncMessages return are the only on which can be
164 * displayed on screen
165 *
166 * @return the syncMessages return list
167 */
168 protected List<GraphNode> getSyncMessagesReturn() {
169 if (!hasChilden)
170 return null;
171 else
172 return (List<GraphNode>) nodes.get(SyncMessageReturn.SYNC_MESS_RET_TAG);
173 }
174
175 /**
176 * Returns the number of syncMessageReturn stored in the frame
177 *
178 * @return the number of syncMessageReturn
179 */
180 public int syncMessageReturnCount() {
181 if (getSyncMessagesReturn() != null)
182 return getSyncMessagesReturn().size();
183 else
184 return 0;
185 }
186
187 /**
188 * Returns the syncMessageReturn at the given index in the syncMessageReturn array
189 *
190 * @param index the position in the syncMessageReturn array
191 * @return the syncMessageReturn
192 */
193 public SyncMessageReturn getSyncMessageReturn(int index) {
194 if ((getSyncMessagesReturn() != null) && (index >= 0) && (index < getSyncMessagesReturn().size()))
195 return (SyncMessageReturn) getSyncMessagesReturn().get(index);
196 return null;
197 }
198
199 /**
200 * Returns a list of asyncMessageRetun known by this frame. Known asyncMessageRetun are the only on which can be
201 * displayed on screen
202 *
203 * @return the asyncMessageRetun list
204 */
205 protected List<GraphNode> getAsyncMessagesReturn() {
206 if (!hasChilden)
207 return null;
208 else
209 return (List<GraphNode>) nodes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG);
210 }
211
212 /**
213 * Returns the number of asyncMessageReturn stored in the frame
214 *
215 * @return the number of asyncMessageReturn
216 */
217 public int asyncMessageReturnCount() {
218 if (getAsyncMessagesReturn() != null)
219 return getAsyncMessagesReturn().size();
220 else
221 return 0;
222 }
223
224 /**
225 * Returns the asyncMessageReturn at the given index in the asyncMessageReturn array
226 *
227 * @param index the position in the asyncMessageReturn array
228 * @return the asyncMessageReturn
229 */
230 public AsyncMessageReturn getAsyncMessageReturn(int index) {
231 if ((getAsyncMessagesReturn() != null) && (index >= 0) && (index < getAsyncMessagesReturn().size()))
232 return (AsyncMessageReturn) getAsyncMessagesReturn().get(index);
233 return null;
234 }
235
236 /**
237 * Adds a lifeline to the frame lifelines list. The lifeline X drawing order depends on the lifeline addition order
238 * into the frame lifelines list.
239 *
240 * @param the lifeline to add
241 */
242 public void addLifeLine(Lifeline lifeLine) {
243 computeMinMax = true;
244 if (lifeLine == null)
245 return;
246 // set the lifeline parent frame
247 lifeLine.setFrame(this);
248 // Increate the frame lifeline counter
249 // and set the lifeline drawing order
250 lifeLine.setIndex(getNewHorizontalIndex());
251 if (lifeLine.hasTimeInfo()) {
252 timeInfo = true;
253 }
254 // add the lifeline to the lifelines list
255 addNode(lifeLine);
256 }
257
258 /**
259 * Returns the first visible lifeline drawn in the view
260 *
261 * @return the first visible lifeline index
262 */
263 public int getFirstVisibleLifeline() {
264 if (!hasChilden)
265 return 0;
266 else if (indexes.get(Lifeline.LIFELINE_TAG) != null)
267 return ((Integer) indexes.get(Lifeline.LIFELINE_TAG)).intValue();
268 else
269 return 0;
270 }
271
272 /**
273 * Returns the first visible synchronous message drawn in the view
274 *
275 * @return the first visible synchronous message index
276 */
277 public int getFirstVisibleSyncMessage() {
278 if (!hasChilden)
279 return 0;
280 else if (indexes.get(SyncMessage.SYNC_MESS_TAG) != null)
281 return ((Integer) indexes.get(SyncMessage.SYNC_MESS_TAG)).intValue();
282 else
283 return 0;
284 }
285
286 /**
287 * Returns the first visible synchronous message return drawn in the view
288 *
289 * @return the first visible synchronous message return index
290 */
291 public int getFirstVisibleSyncMessageReturn() {
292 if (!hasChilden)
293 return 0;
294 else if (indexes.get(SyncMessageReturn.SYNC_MESS_RET_TAG) != null)
295 return ((Integer) indexes.get(SyncMessageReturn.SYNC_MESS_RET_TAG)).intValue();
296 else
297 return 0;
298 }
299
300 /**
301 * Returns the first visible synchronous message drawn in the view
302 *
303 * @return the first visible synchronous message index
304 */
305 public int getFirstVisibleAsyncMessage() {
306 if (!hasChilden)
307 return 0;
308 else if (indexes.get(AsyncMessage.ASYNC_MESS_TAG) != null)
309 return ((Integer) indexes.get(AsyncMessage.ASYNC_MESS_TAG)).intValue();
310 else
311 return 0;
312 }
313
314 /**
315 * Returns the first visible synchronous message return drawn in the view
316 *
317 * @return the first visible synchronous message return index
318 */
319 public int getFirstVisibleAsyncMessageReturn() {
320 if (!hasChilden)
321 return 0;
322 else if (indexes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG) != null)
323 return ((Integer) indexes.get(AsyncMessageReturn.ASYNC_MESS_RET_TAG)).intValue();
324 else
325 return 0;
326 }
327
328 public List<SDTimeEvent> getExecutionOccurrencesWithTime() {
329 return executionOccurrencesWithTime;
330 }
331
332 public void insertLifelineAfter(Lifeline toInsert, Lifeline after) {
333 if ((toInsert == null))
334 return;
335 if (toInsert == after)
336 return;
337 int insertPoint = 0;
338 if (after != null)
339 insertPoint = after.getIndex();
340 int removePoint = toInsert.getIndex() - 1;
341 if (removePoint >= insertPoint)
342 getLifelines().remove(removePoint);
343 getLifelines().add(insertPoint, toInsert);
344 if (removePoint < insertPoint)
345 getLifelines().remove(removePoint);
346
347 if (removePoint >= insertPoint)
348 toInsert.setIndex(insertPoint + 1);
349 else
350 toInsert.setIndex(insertPoint - 1);
351
352 insertPoint++;
353 if (removePoint >= insertPoint) {
354 for (int i = insertPoint; i < getLifelines().size(); i++) {
355 getLifeline(i).setIndex(i + 1);
356 }
357 } else {
358 for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) {
359 getLifeline(i).setIndex(i + 1);
360 }
361 }
362 }
363
364 public void insertLifelineBefore(Lifeline toInsert, Lifeline before) {
365 if ((toInsert == null))
366 return;
367 if (toInsert == before)
368 return;
369 int insertPoint = 0;
370 if (before != null)
371 insertPoint = before.getIndex() - 1;
372 int removePoint = toInsert.getIndex() - 1;
373 if (removePoint >= insertPoint)
374 getLifelines().remove(removePoint);
375 getLifelines().add(insertPoint, toInsert);
376 if (removePoint < insertPoint)
377 getLifelines().remove(removePoint);
378
379 if (removePoint >= insertPoint)
380 toInsert.setIndex(insertPoint + 1);
381 else
382 toInsert.setIndex(insertPoint - 1);
383
384 insertPoint++;
385 if (removePoint >= insertPoint) {
386 for (int i = insertPoint; i < getLifelines().size(); i++) {
387 getLifeline(i).setIndex(i + 1);
388 }
389 } else {
390 for (int i = 0; i < insertPoint && i < getLifelines().size(); i++) {
391 getLifeline(i).setIndex(i + 1);
392 }
393 }
394 }
395
396 public Lifeline getCloserLifeline(int x) {
397 int index = (x - Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN) / Metrics.swimmingLaneWidth() - 1;
398 if (index < 0)
399 index = 0;
400 if (index >= getLifelines().size())
401 index = getLifelines().size() - 1;
402 Lifeline node1, node2, node3;
403 int dist1, dist2, dist3;
404 node1 = node2 = node3 = getLifeline(index);
405 dist1 = dist2 = dist3 = Math.abs(node1.getX() + node1.getWidth() / 2 - x);
406 if (index > 0) {
407 node2 = getLifeline(index - 1);
408 dist2 = Math.abs(node2.getX() + node2.getWidth() / 2 - x);
409 }
410 if (index < getLifelines().size() - 1) {
411 node3 = getLifeline(index + 1);
412 dist3 = Math.abs(node3.getX() + node3.getWidth() / 2 - x);
413 }
414 if (dist1 <= dist2 && dist1 <= dist3)
415 return node1;
416 else if (dist2 <= dist1 && dist2 <= dist3)
417 return node2;
418 else
419 return node3;
420 }
421
422 public void reorder(ArrayList<?> list) {
423 for (int i = 0; i < list.size(); i++) {
424 if (list.get(i) instanceof Lifeline[]) {
425 Lifeline temp[] = (Lifeline[]) list.get(i);
426 if (temp.length == 2) {
427 if (temp[1] == null) {
428 insertLifelineAfter(temp[0], getLifeline(lifeLinesCount() - 1));
429 } else
430 insertLifelineBefore(temp[0], temp[1]);
431 }
432 }
433 }
434 }
435
436 public void resetTimeCompression() {
437 highlightLifeline = null;
438 this.startEvent = 0;
439 this.nbEvent = 0;
440 highlightColor = null;
441 }
442
443 @Override
444 protected void computeMinMax() {
445 List<SDTimeEvent> timeArray = buildTimeArray();
446 if (timeArray == null)
447 return;
448 for (int i = 0; i < timeArray.size() - 1; i++) {
449 SDTimeEvent m1 = (SDTimeEvent) timeArray.get(i);
450 SDTimeEvent m2 = (SDTimeEvent) timeArray.get(i + 1);
451 if (SDViewPref.getInstance().excludeExternalTime())
452 if ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage)) {
453 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
454 BaseMessage mes2 = (BaseMessage) m2.getGraphNode();
455 if ((mes2.startLifeline == null) || (mes1.endLifeline == null))
456 continue;
457 }
458
459 updateMinMax(m1, m2);
460 }
461 }
462
463 /**
464 * Find the two graph nodes that are closest to this date, one just earlier, second just later. If date is before
465 * any graph node, bounds[0] is null and bounds[1] is the earliest. If date is after any graph node, bounds[1] is
466 * null and bounds[0] is the latest.
467 *
468 * @param dateToFind date to be found
469 * @param bounds a two items array that will receive bounds if found
470 * @return true if both bounds not null
471 */
472 public boolean findDateBounds(TmfTimestamp dateToFind, ITimeRange bounds[]) {
473 if (hasTimeInfo()) {
474 List<SDTimeEvent> timeArray = buildTimeArray();
475 bounds[0] = null;
476 bounds[1] = null;
477 for (int i = 0; i < timeArray.size(); i++) {
478 SDTimeEvent m = (SDTimeEvent) timeArray.get(i);
479 if (m.getTime().compareTo(dateToFind, true) > 0) {
480 bounds[1] = m.getGraphNode();
481 if (i > 0) {
482 bounds[0] = ((SDTimeEvent) timeArray.get(i - 1)).getGraphNode();
483 return true;
484 }
485 return false;
486 }
487 }
488 bounds[0] = ((SDTimeEvent) timeArray.get(timeArray.size() - 1)).getGraphNode();
489 }
490 return false;
491 }
492
493 protected void setHasTimeInfo(boolean value) {
494 timeInfo = value;
495 }
496
497 /**
498 * @return true if frame has time info else false
499 */
500 public boolean hasTimeInfo() {
501 return timeInfo;
502 }
503
504 /**
505 * @param lifeline
506 * @param startEvent
507 * @param nbEvent
508 * @param color
509 */
510 public void highlightTimeCompression(Lifeline lifeline, int startEvent, int nbEvent, IColor color) {
511 highlightLifeline = lifeline;
512 this.startEvent = startEvent;
513 this.nbEvent = nbEvent;
514 highlightColor = color;
515 }
516
517 /**
518 * Set the lifeline categories which will be use during the lifelines creation
519 *
520 * @see Lifeline#setCategory(int)
521 * @param categories the lifeline categories array
522 */
523 public void setLifelineCategories(LifelineCategories[] categories) {
524 lifelineCategories = Arrays.copyOf(categories, categories.length);
525 }
526
527 /**
528 * Returns the lifeline categories array set for the this frame
529 *
530 * @return the lifeline categories array or null if not set
531 */
532 public LifelineCategories[] getLifelineCategories() {
533 return Arrays.copyOf(lifelineCategories, lifelineCategories.length);
534 }
535
536 /**
537 * Adds a message to the Frame message list. Four kinds of syncMessages can be added:<br>
538 * - synchronous syncMessages<br>
539 * - synchronous syncMessages return<br>
540 * - asynchronous syncMessages<br>
541 * - asynchronous syncMessages return<br>
542 * For drawing performance reason, it is recommended to add synchronous syncMessages in the same order they should
543 * appear along the Y axis in the Frame.
544 *
545 * @param the message to add
546 */
547 public void addMessage(BaseMessage message) {
548 addNode(message);
549 }
550
551 @Override
552 public void draw(IGC context) {
553 drawFrame(context);
554 if (!hasChilden)
555 return;
556
557 if (highlightLifeline != null) {
558 IColor backupColor = context.getBackground();
559 context.setBackground(Frame.getUserPref().getTimeCompressionSelectionColor());
560 int gy = highlightLifeline.getY() + highlightLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent;
561 context.fillRectangle(Metrics.FRAME_H_MARGIN + 1, gy, highlightLifeline.getX() + Metrics.getLifelineWidth() / 2 - Metrics.FRAME_H_MARGIN, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * nbEvent);
562 context.setBackground(backupColor);
563 }
564 super.draw(context, false);
565 int lifelineArryStep = 1;
566 if (Metrics.swimmingLaneWidth() * context.getZoom() < Metrics.LIFELINE_SIGNIFICANT_HSPACING)
567 lifelineArryStep = Math.round(Metrics.LIFELINE_SIGNIFICANT_HSPACING / (Metrics.swimmingLaneWidth() * context.getZoom()));
568 if (indexes.size() == 0)
569 return;
570 int lifeLineDrawIndex = ((Integer) indexes.get(Lifeline.LIFELINE_TAG)).intValue();
571 for (int i = lifeLineDrawIndex; i < ((List<GraphNode>) nodes.get(Lifeline.LIFELINE_TAG)).size(); i = i + lifelineArryStep) {
572 Lifeline toDraw = (Lifeline) ((List<GraphNode>) nodes.get(Lifeline.LIFELINE_TAG)).get(i);
573 if (toDraw.getX() - Metrics.LIFELINE_SPACING / 2 > context.getContentsX() + context.getVisibleWidth())
574 break;
575 toDraw.drawName(context);
576
577 if (highlightLifeline != null) {
578 if (toDraw == highlightLifeline)
579 toDraw.highlightExecOccurrenceRegion(context, startEvent, nbEvent, highlightColor);
580 else if ((toDraw.getIndex() < highlightLifeline.getIndex()) || ((toDraw.getIndex() < highlightLifeline.getIndex()))) {
581
582 int acIndex = toDraw.getExecOccurrenceDrawIndex();
583 // acIndex = first visible execution occurrence
584 // for drawing speed reason with only search on the visible subset
585 if (toDraw.getExecutions() != null)
586 for (int index = acIndex; index < toDraw.getExecutions().size(); index++) {
587 BasicExecutionOccurrence exec = (BasicExecutionOccurrence) toDraw.getExecutions().get(index);
588 int tempEvent = startEvent;
589 for (int j = 0; j < nbEvent; j++) {
590 if (((tempEvent >= exec.startEventOccurrence) && (tempEvent <= exec.endEventOccurrence) && (tempEvent + 1 >= exec.startEventOccurrence) && (tempEvent + 1 <= exec.endEventOccurrence))) {
591 toDraw.highlightExecOccurrenceRegion(context, tempEvent, 1, Frame.getUserPref().getTimeCompressionSelectionColor());
592 }
593 tempEvent = tempEvent + 1;
594 }
595 // if we are outside the visible area we stop right now
596 // This works because execution occurrences are ordered along the Y axis
597 if (exec.getY() > getY())
598 break;
599 }
600 }
601 }
602 }
603 }
604
605 @Override
606 protected List<SDTimeEvent> buildTimeArray() {
607 if (!hasChilden)
608 return null;
609 try {
610 List<SDTimeEvent> timeArray = super.buildTimeArray();
611 executionOccurrencesWithTime = null;
612 if (getLifelines() != null)
613 for (int i = 0; i < ((List<GraphNode>) nodes.get(Lifeline.LIFELINE_TAG)).size(); i++) {
614 Lifeline l = (Lifeline) ((List<GraphNode>) nodes.get(Lifeline.LIFELINE_TAG)).get(i);
615 if (l.hasTimeInfo() && l.getExecutions() != null) {
616 for (Iterator<GraphNode> j = l.getExecutions().iterator(); j.hasNext();) {
617 GraphNode o = j.next();
618 if (o instanceof ExecutionOccurrence) {
619 ExecutionOccurrence eo = (ExecutionOccurrence) o;
620 if (eo.hasTimeInfo()) {
621 int event = eo.getStartOccurrence();
622 TmfTimestamp time = eo.getStartTime();
623 SDTimeEvent f = new SDTimeEvent(time, event, eo);
624 timeArray.add(f);
625 if (executionOccurrencesWithTime == null) {
626 executionOccurrencesWithTime = new ArrayList<SDTimeEvent>();
627 }
628 executionOccurrencesWithTime.add(f);
629 event = eo.getEndOccurrence();
630 time = eo.getEndTime();
631 f = new SDTimeEvent(time, event, eo);
632 timeArray.add(f);
633 executionOccurrencesWithTime.add(f);
634 }
635 }
636 }
637 }
638 }
639
640 if (executionOccurrencesWithTime != null) {
641 SDTimeEvent[] temp = executionOccurrencesWithTime.toArray(new SDTimeEvent[0]);
642 Arrays.sort(temp, new TimeEventComparator());
643 executionOccurrencesWithTime = Arrays.asList(temp);
644 }
645 SDTimeEvent[] temp = timeArray.toArray(new SDTimeEvent[0]);
646 Arrays.sort(temp, new TimeEventComparator());
647 timeArray = Arrays.asList(temp);
648 return timeArray;
649 } catch (Exception e) {
650 e.printStackTrace();
651 return null;
652 }
653
654 }
655
656 protected GraphNode getCloserLeavingMessage(Lifeline lifeline, BaseMessage message, List<GraphNode> list, boolean smallerEvent) {
657 if (list == null)
658 return null;
659 if (smallerEvent == false) {
660 int event = 0;
661 if (message != null)
662 event = message.getEventOccurrence();
663 for (int i = 0; i < list.size(); i++) {
664 GraphNode node = (GraphNode) list.get(i);
665 if (node instanceof SyncMessage) {
666 SyncMessage syncNode = (SyncMessage) node;
667 if ((syncNode.getEventOccurrence() > event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message))
668 return node;
669 } else if (node instanceof AsyncMessage) {
670 AsyncMessage asyncNode = (AsyncMessage) node;
671 if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message))
672 return node;
673 }
674 }
675 } else {
676 int event = getMaxEventOccurrence();
677 if (message != null)
678 if (message instanceof AsyncMessage) {
679 event = ((AsyncMessage) message).getStartOccurrence();
680 } else
681 event = message.getEventOccurrence();
682 for (int i = list.size() - 1; i >= 0; i--) {
683 GraphNode node = (GraphNode) list.get(i);
684 if (node instanceof SyncMessage) {
685 SyncMessage syncNode = (SyncMessage) node;
686 if ((syncNode.getEventOccurrence() < event) && (syncNode.getStartLifeline() == lifeline) && !syncNode.isSameAs(message))
687 return node;
688 } else if (node instanceof AsyncMessage) {
689 AsyncMessage asyncNode = (AsyncMessage) node;
690 if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getStartLifeline() == lifeline) && !asyncNode.isSameAs(message))
691 return node;
692 }
693 }
694 }
695 return null;
696 }
697
698 protected GraphNode getCloserEnteringMessage(Lifeline lifeline, BaseMessage message, List<GraphNode> list, boolean smallerEvent) {
699 if (list == null)
700 return null;
701 if (smallerEvent == false) {
702 int event = 0;
703 if (message != null)
704 event = message.getEventOccurrence();
705 for (int i = 0; i < list.size(); i++) {
706 GraphNode node = (GraphNode) list.get(i);
707 if (node instanceof SyncMessage) {
708 SyncMessage syncNode = (SyncMessage) node;
709 if ((syncNode.getEventOccurrence() > event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message))
710 return node;
711 } else if (node instanceof AsyncMessage) {
712 AsyncMessage asyncNode = (AsyncMessage) node;
713 if ((asyncNode.getStartOccurrence() > event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message))
714 return node;
715 }
716 }
717 } else {
718 int event = getMaxEventOccurrence();
719 if (message != null)
720 if (message instanceof AsyncMessage) {
721 event = ((AsyncMessage) message).getStartOccurrence();
722 } else
723 event = message.getEventOccurrence();
724 for (int i = list.size() - 1; i >= 0; i--) {
725 GraphNode node = (GraphNode) list.get(i);
726 if (node instanceof SyncMessage) {
727 SyncMessage syncNode = (SyncMessage) node;
728 if ((syncNode.getEventOccurrence() < event) && (syncNode.getEndLifeline() == lifeline) && !syncNode.isSameAs(message))
729 return node;
730 } else if (node instanceof AsyncMessage) {
731 AsyncMessage asyncNode = (AsyncMessage) node;
732 if ((asyncNode.getStartOccurrence() < event) && (asyncNode.getEndLifeline() == lifeline) && !asyncNode.isSameAs(message))
733 return node;
734 }
735 }
736 }
737 return null;
738 }
739
740 protected int distanceFromEvent(GraphNode node, int event) {
741 int distance = 0;
742 if (node instanceof SyncMessage)
743 distance = ((SyncMessage) node).getEventOccurrence() - event;
744 else if (node instanceof AsyncMessage) {
745 int start = ((AsyncMessage) node).getStartOccurrence();
746 int end = ((AsyncMessage) node).getEndOccurrence();
747 if ((start - event) < (end - event))
748 distance = start - event;
749 else
750 distance = end - event;
751 }
752 return Math.abs(distance);
753 }
754
755 protected GraphNode getCloserToEvent(GraphNode node1, GraphNode node2, int event) {
756 if ((node1 != null) && (node2 != null)) {
757 if (distanceFromEvent(node1, event) < distanceFromEvent(node2, event))
758 return node1;
759 else
760 return node2;
761 } else if (node1 != null)
762 return node1;
763 else if (node2 != null)
764 return node2;
765 else
766 return null;
767 }
768
769 public GraphNode getCalledMessage(BaseMessage StartMessage) {
770 int event = 0;
771 GraphNode result = null;
772 Lifeline lifeline = null;
773 if (StartMessage != null) {
774 event = ((BaseMessage) StartMessage).getEventOccurrence();
775 lifeline = ((BaseMessage) StartMessage).getEndLifeline();
776 if (lifeline == null)
777 lifeline = ((BaseMessage) StartMessage).getStartLifeline();
778 }
779 if (lifeline == null)
780 return null;
781 GraphNode message = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessages(), false);
782 GraphNode messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessagesReturn(), false);
783 result = getCloserToEvent(message, messageReturn, event);
784 message = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessages(), false);
785 result = getCloserToEvent(result, message, event);
786 messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessagesReturn(), false);
787 result = getCloserToEvent(result, messageReturn, event);
788 return result;
789 }
790
791 public GraphNode getCallerMessage(BaseMessage StartMessage) {
792 int event = getMaxEventOccurrence();
793 GraphNode result = null;
794 Lifeline lifeline = null;
795 if (StartMessage != null) {
796 event = ((BaseMessage) StartMessage).getEventOccurrence();
797 lifeline = ((BaseMessage) StartMessage).getStartLifeline();
798 if (lifeline == null)
799 lifeline = ((BaseMessage) StartMessage).getEndLifeline();
800 }
801 if (lifeline == null)
802 return null;
803 GraphNode message = getCloserEnteringMessage(lifeline, StartMessage, getSyncMessages(), true);
804 GraphNode messageReturn = getCloserEnteringMessage(lifeline, StartMessage, getSyncMessagesReturn(), true);
805 result = getCloserToEvent(message, messageReturn, event);
806 message = getCloserEnteringMessage(lifeline, StartMessage, getAsyncMessages(), true);
807 result = getCloserToEvent(result, message, event);
808 messageReturn = getCloserEnteringMessage(lifeline, StartMessage, getAsyncMessagesReturn(), true);
809 result = getCloserToEvent(result, messageReturn, event);
810 return result;
811 }
812
813 public GraphNode getNextLifelineMessage(Lifeline lifeline, BaseMessage StartMessage) {
814 int event = 0;
815 if (StartMessage != null)
816 event = ((BaseMessage) StartMessage).getEventOccurrence();
817 if (lifeline == null)
818 return null;
819 GraphNode message = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessages(), false);
820 GraphNode messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessagesReturn(), false);
821 GraphNode result = getCloserToEvent(message, messageReturn, event);
822 message = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessages(), false);
823 result = getCloserToEvent(result, message, event);
824 messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessagesReturn(), false);
825 result = getCloserToEvent(result, messageReturn, event);
826 return result;
827 }
828
829 public BasicExecutionOccurrence getFirstExecution(Lifeline lifeline) {
830 if (lifeline == null)
831 return null;
832 List<GraphNode> list = lifeline.getExecutions();
833 if (list == null)
834 return null;
835 if (list.size() == 0)
836 return null;
837 BasicExecutionOccurrence result = (BasicExecutionOccurrence) list.get(0);
838 for (int i = 0; i < list.size(); i++) {
839 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
840 if ((e.getStartOccurrence() < result.getEndOccurrence()))
841 result = e;
842 }
843 return result;
844 }
845
846 public BasicExecutionOccurrence getPrevExecOccurrence(BasicExecutionOccurrence exec) {
847 if (exec == null)
848 return null;
849 Lifeline lifeline = exec.getLifeline();
850 if (lifeline == null)
851 return null;
852 List<GraphNode> list = lifeline.getExecutions();
853 if (list == null)
854 return null;
855 BasicExecutionOccurrence result = null;
856 for (int i = 0; i < list.size(); i++) {
857 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
858 if ((e.getStartOccurrence() < exec.startEventOccurrence) && (result == null))
859 result = e;
860 if ((e.getStartOccurrence() < exec.startEventOccurrence) && (e.getStartOccurrence() >= result.getEndOccurrence()))
861 result = e;
862 }
863 return result;
864 }
865
866 public BasicExecutionOccurrence getNextExecOccurrence(BasicExecutionOccurrence exec) {
867 if (exec == null)
868 return null;
869 Lifeline lifeline = exec.getLifeline();
870 if (lifeline == null)
871 return null;
872 List<GraphNode> list = lifeline.getExecutions();
873 if (list == null)
874 return null;
875 BasicExecutionOccurrence result = null;
876 for (int i = 0; i < list.size(); i++) {
877 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
878 if ((e.getStartOccurrence() > exec.startEventOccurrence) && (result == null))
879 result = e;
880 if ((e.getStartOccurrence() > exec.startEventOccurrence) && (e.getStartOccurrence() <= result.getEndOccurrence()))
881 result = e;
882 }
883 return result;
884 }
885
886 public BasicExecutionOccurrence getLastExecOccurrence(Lifeline lifeline) {
887 if (lifeline == null)
888 return null;
889 List<GraphNode> list = lifeline.getExecutions();
890 if (list == null)
891 return null;
892 BasicExecutionOccurrence result = null;
893 for (int i = 0; i < list.size(); i++) {
894 BasicExecutionOccurrence e = (BasicExecutionOccurrence) list.get(i);
895 if (result == null)
896 result = e;
897 if (e.getStartOccurrence() > result.getEndOccurrence())
898 result = e;
899 }
900 return result;
901 }
902
903 public GraphNode getPrevLifelineMessage(Lifeline lifeline, BaseMessage StartMessage) {
904 int event = getMaxEventOccurrence();
905 if (StartMessage != null)
906 if (StartMessage instanceof AsyncMessage) {
907 event = ((AsyncMessage) StartMessage).getStartOccurrence();
908 } else
909 event = StartMessage.getEventOccurrence();
910 if (lifeline == null)
911 return null;
912 GraphNode message = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessages(), true);
913 GraphNode messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getSyncMessagesReturn(), true);
914 GraphNode result = getCloserToEvent(message, messageReturn, event);
915 message = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessages(), true);
916 result = getCloserToEvent(result, message, event);
917 messageReturn = getCloserLeavingMessage(lifeline, StartMessage, getAsyncMessagesReturn(), true);
918 result = getCloserToEvent(result, messageReturn, event);
919 return result;
920 }
921 }
This page took 0.051849 seconds and 6 git commands to generate.