| /********************************************************************** |
| * Copyright (c) 2005, 2014 IBM Corporation, Ericsson |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| * Bernd Hufmann - Updated for TMF |
| **********************************************************************/ |
| |
| package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core; |
| |
| import java.util.Comparator; |
| |
| import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; |
| import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; |
| import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC; |
| import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences; |
| import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref; |
| import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortSyncMessageComparator; |
| |
| /** |
| * A SyncMessage is a synchronous message which appear at the same event occurrence on both lifeline ends (sender and |
| * receiver).<br> |
| * A Sync message is usually drawn horizontally.<br> |
| * <br> |
| * <br> |
| * Usage example: |
| * |
| * <pre> |
| * Frame frame; |
| * Lifeline lifeLine1; |
| * Lifeline lifeLine2; |
| * |
| * SyncMessage message = new SyncMessage(); |
| * // Create a new event occurrence on each lifeline |
| * lifeline1.getNewOccurrenceIndex(); |
| * lifeline2.getNewOccurrenceIndex(); |
| * // Set the message sender and receiver |
| * message.setStartLifeline(lifeLine1); |
| * message.setEndLifline(lifeline2); |
| * message.setName("Message label"); |
| * // add the message to the frame |
| * frame.addMessage(message); |
| * </pre> |
| * |
| * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details |
| * @version 1.0 |
| * @author sveyrier |
| * |
| */ |
| public class SyncMessage extends BaseMessage implements ITimeRange { |
| |
| // ------------------------------------------------------------------------ |
| // Constants |
| // ------------------------------------------------------------------------ |
| /** |
| * The graphNode ID |
| */ |
| public static final String SYNC_MESS_TAG = "SyncMessage"; //$NON-NLS-1$ |
| |
| // ------------------------------------------------------------------------ |
| // Attributes |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * The associated message return |
| */ |
| private SyncMessageReturn fMessageReturn; |
| /** |
| * The time when the message occurs |
| */ |
| private ITmfTimestamp fEventTime = TmfTimestamp.fromSeconds(0); |
| /** |
| * Flag whether the message has time information available or not |
| */ |
| private boolean fHasTimeInfo = false; |
| |
| // ------------------------------------------------------------------------ |
| // Constructors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Default constructor |
| */ |
| public SyncMessage() { |
| setColorPrefId(ISDPreferences.PREF_SYNC_MESS); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Methods |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Ensure both lifelines have the same event occurrence (the greater found on each lifeline) |
| */ |
| protected void syncLifelinesEventOccurrence() { |
| if ((getStartLifeline() != null) && (getEndLifeline() != null)) { |
| int newIndex = 0; |
| if (getStartLifeline().getEventOccurrence() > getEndLifeline().getEventOccurrence()) { |
| newIndex = getStartLifeline().getEventOccurrence(); |
| } else { |
| newIndex = getEndLifeline().getEventOccurrence(); |
| } |
| getStartLifeline().setCurrentEventOccurrence(newIndex); |
| getEndLifeline().setCurrentEventOccurrence(newIndex); |
| setEventOccurrence(getStartLifeline().getEventOccurrence()); |
| } |
| } |
| |
| /** |
| * Set the lifeLine from which the message has been sent.<br> |
| * A new event occurrence will be created on this lifeLine.<br> |
| * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the |
| * event occurrence on each lifeline (the greater value will be used).<br> |
| * This synchronization is only done if the end lifeline has already been set. |
| * |
| * @param lifeline the message sender |
| */ |
| public void autoSetStartLifeline(Lifeline lifeline) { |
| lifeline.getNewEventOccurrence(); |
| setStartLifeline(lifeline); |
| } |
| |
| /** |
| * Set the lifeLine which has receiver the message.<br> |
| * A new EventOccurence will be create on this lifeLine.<br> |
| * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the |
| * event occurrence on each lifeline (the greater value will be used).<br> |
| * This synchronization is only done if the start lifeline has already been set. |
| * |
| * @param lifeline the message receiver |
| */ |
| public void autoSetEndLifeline(Lifeline lifeline) { |
| lifeline.getNewEventOccurrence(); |
| setEndLifeline(lifeline); |
| } |
| |
| /** |
| * Set the lifeLine which has receiver the message.<br> |
| * SyncMessage must occur at the same event occurrence on both lifeline, this method is responsible to synchronize the |
| * event occurrence on each lifeline (the greater value will be used).<br> |
| * This synchronization is only done if the start lifeline has already been set. |
| * |
| * @param lifeline the message receiver |
| */ |
| @Override |
| public void setStartLifeline(Lifeline lifeline) { |
| super.setStartLifeline(lifeline); |
| if ((getEndLifeline() == null)) { |
| setEventOccurrence(getStartLifeline().getEventOccurrence()); |
| } else { |
| syncLifelinesEventOccurrence(); |
| } |
| } |
| |
| /** |
| * Set the lifeLine which has receiver the message.<br> |
| * SyncMessage must occur at the same event occurrence on both lifelines, this method is responsible to synchronize the |
| * event occurrence on each lifeline (the greater value will be used).<br> |
| * This synchronization is only done if the start lifeline has already been set. |
| * |
| * @param lifeline the message receiver |
| */ |
| @Override |
| public void setEndLifeline(Lifeline lifeline) { |
| super.setEndLifeline(lifeline); |
| if ((getStartLifeline() == null)) { |
| setEventOccurrence(getEndLifeline().getEventOccurrence()); |
| } else { |
| syncLifelinesEventOccurrence(); |
| } |
| } |
| |
| /** |
| * Set the event occurrence when this message occurs.<br> |
| * |
| * @param occurrence the event occurrence to assign to this message.<br> |
| * @see Lifeline Lifeline for more event occurence details |
| */ |
| @Override |
| protected void setEventOccurrence(int occurrence) { |
| setStartOccurrence(occurrence); |
| setEndOccurrence(occurrence); |
| } |
| |
| /** |
| * Set the message return associated with this message. |
| * |
| * @param message the message return to associate |
| */ |
| protected void setMessageReturn(SyncMessageReturn message) { |
| fMessageReturn = message; |
| } |
| |
| /** |
| * Returns the syncMessageReturn associated to this syncMessage |
| * |
| * @return the message return |
| */ |
| public SyncMessageReturn getMessageReturn() { |
| return fMessageReturn; |
| } |
| |
| /** |
| * Set the time when the message occurs |
| * |
| * @param time the time when the message occurs |
| */ |
| public void setTime(ITmfTimestamp time) { |
| fEventTime = time; |
| fHasTimeInfo = true; |
| if (getStartLifeline() != null && getStartLifeline().getFrame() != null) { |
| getStartLifeline().getFrame().setHasTimeInfo(true); |
| } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) { |
| getEndLifeline().getFrame().setHasTimeInfo(true); |
| } |
| } |
| |
| @Override |
| public ITmfTimestamp getEndTime() { |
| return fEventTime; |
| } |
| |
| @Override |
| public ITmfTimestamp getStartTime() { |
| return fEventTime; |
| } |
| |
| @Override |
| public boolean hasTimeInfo() { |
| return fHasTimeInfo; |
| } |
| |
| @Override |
| public void draw(IGC context) { |
| if (!isVisible()) { |
| return; |
| } |
| |
| ISDPreferences pref = SDViewPref.getInstance(); |
| |
| // Draw it selected? |
| if (!isSelected()) { |
| context.setBackground(pref.getBackGroundColor(getColorPrefId())); |
| context.setForeground(pref.getForeGroundColor(getColorPrefId())); |
| } |
| super.draw(context); |
| } |
| |
| @Override |
| public boolean isVisible(int x, int y, int width, int height) { |
| if (getY() > y + height + |
| // take into account the message name drawn above the arrow |
| Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) { |
| return false; |
| } |
| |
| // UML2 lost/found message visibility special case |
| // Others visibility cases are perform in the ***common*** case |
| if ((getEndLifeline() == null && getStartLifeline() != null) || (getEndLifeline() != null && getStartLifeline() == null)) { |
| if (x + width > getX() + getWidth() && x < getX() + getWidth()) { |
| return true; |
| } |
| } |
| // ***Common*** syncMessages visibility |
| return super.isVisible(x, y, width, height); |
| } |
| |
| @Override |
| public Comparator<GraphNode> getComparator() { |
| return new SortSyncMessageComparator(); |
| } |
| |
| @Override |
| public String getArrayId() { |
| return SYNC_MESS_TAG; |
| } |
| |
| @Override |
| public boolean positiveDistanceToPoint(int x, int y) { |
| return (getY() > y); |
| } |
| } |