svn commit: r16798 - trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram

Bob Tarling <[email protected]>
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: bobtarling
Date: 2009-02-15 08:45:06-0800
New Revision: 16798

Modified:
   trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigActivation.java
   trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigClassifierRole.java
   trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigLifeLine.java
   trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigMessage.java
   trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/ModeCreateMessage.java

Log:
Defect 5691: Manage activations as best we can for callbacks

Modified: trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigActivation.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigActivation.java?view=diff&pathrev=16798&r1=16797&r2=16798
==============================================================================
--- trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigActivation.java	(original)
+++ trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigActivation.java	2009-02-15 08:45:06-0800
@@ -142,6 +142,14 @@
         return destroyFig != null;
     }
     
+    /**
+     * Return true if the given message should signal the end of this
+     * activation.
+     * This is true if the message is a return message pointing the
+     * other way to the activator.
+     * @param messageFig
+     * @return
+     */
     public boolean isActivatorEnd(FigMessage messageFig) {
         if (messageFig == null) {
             throw new IllegalArgumentException(
@@ -151,8 +159,15 @@
             return false;
         }
         if (activatingMessage == null) {
-            return true;
+            return false;
         }
-        return messageFig.getDestFigNode() == activatingMessage.getSourceFigNode();
+        // We know this is a return action now. It must be pointing the
+        // opposite way to the activator.
+        return activatingMessage.getSourceFigNode()
+            == messageFig.getDestFigNode();
+    }
+    
+    public FigMessage getActivatingMessage() {
+        return activatingMessage;
     }
 }
\ No newline at end of file

Modified: trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigClassifierRole.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigClassifierRole.java?view=diff&pathrev=16798&r1=16797&r2=16798
==============================================================================
--- trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigClassifierRole.java	(original)
+++ trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigClassifierRole.java	2009-02-15 08:45:06-0800
@@ -29,6 +29,7 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.log4j.Logger;
@@ -220,7 +221,7 @@
      * @return a figmessage.
      */
     private FigMessage getFirstCreateFigMessage() {
-        List<FigMessage> messages = getCompleteMessages();
+        List<FigMessage> messages = getFigMessages();
         FigMessage createMessage = null;
         for (FigMessage message : messages) {
             if (message.getDestFigNode().equals(this)
@@ -331,15 +332,15 @@
     }
     
     /**
-     * Return all message edges that are complete (ie the user has finished
-     * drawing).
+     * Return an ordered list of message edges that are complete (ie the user
+     * has finished drawing). Messages are ordered from top to bottom.
      * @return A list with all the messages that are complete
      */
-    private List<FigMessage> getCompleteMessages() {
-        List<FigMessage> completeMessages = new ArrayList<FigMessage>(10);
+    public List<FigMessage> getFigMessages() {
+        final List<FigMessage> completeMessages = new ArrayList<FigMessage>(10);
         for (Object o : getFigEdges()) {
             if (o instanceof FigMessage) {
-                FigMessage fm = (FigMessage) o;
+                final FigMessage fm = (FigMessage) o;
                 if (fm.getPoints().length > 1
                         && fm.getDestFigNode() != null
                         && fm.getSourceFigNode() != null) {
@@ -347,11 +348,12 @@
                 }
             }
         }
+        Collections.sort(completeMessages, new FigMessageComparator());
         return completeMessages;
     }
     
     void createActivations() {
-        lifeLineFig.createActivations(getCompleteMessages());
+        lifeLineFig.createActivations(getFigMessages());
         forceRepaintShadow();
     }
     

Modified: trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigLifeLine.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigLifeLine.java?view=diff&pathrev=16798&r1=16797&r2=16798
==============================================================================
--- trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigLifeLine.java	(original)
+++ trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigLifeLine.java	2009-02-15 08:45:06-0800
@@ -125,60 +125,74 @@
                     null);
         }
         
+        // This counts the number of repeated call/returns that take place
+        // after the first activation. This shouldn't be required once
+        // we handle stacked activations better and once issue 5692 and 5693
+        // are sorted.
+        int activationsCount = 0;
+        //
+        
         for (FigMessage figMessage : figMessages) {
             int ySender = 0;
             
             if (!figMessage.isSelfMessage()) {
-                if (currentActivation == null
-                        && isIncoming(figMessage)
-                        && figMessage.isCallAction()) {
-                    // if we are the dest and is a call action, create the 
-                    // activation, but don't add it until the height is set.
-                    ySender = figMessage.getFinalY();
-                    currentActivation = createActivationFig(
-                            getOwner(), 
-                            lineFig.getX(), 
-                            ySender, 
-                            0, 
-                            0,
-                            getSettings(),
-                            figMessage);
-                } else if (currentActivation == null
-                        && isIncoming(figMessage)
-                        && figMessage.isCreateAction()) {
-                    // if we are the destination of a create action,
-                    // create the entire activation, because we should
-                    // need the destroy X
-                    currentActivation = createActivationFig(
-                            getOwner(),
-                            lineFig.getX(),
-                            lineFig.getY(),
-                            0,
-                            0,
-                            getSettings(),
-                            figMessage);
-                } else if (currentActivation != null
-                        && isOutgoing(figMessage)
-                        && currentActivation.isActivatorEnd(figMessage)) {
-                    // if we are the source of a return action
-                    // the activation ends here.
-                    ySender = figMessage.getStartY();
-                    currentActivation.setHeight(
-                            ySender - currentActivation.getY());
-                    newActivations.add(currentActivation);
-                    currentActivation = null;
-                } else if (currentActivation != null
-                        && isOutgoing(figMessage)
-                        && figMessage.isDestroyAction()) {
-                    // if we are the target of a destroy action
-                    // the figlifeline ends here and we add the activation
-                    ySender = figMessage.getFinalY();
-                    currentActivation.setHeight(
-                            ySender - currentActivation.getY());
-                    currentActivation.setDestroy(true);
-                    lineFig.setHeight(ySender - getY());
-                    newActivations.add(currentActivation);
-                    currentActivation = null;
+                if (isIncoming(figMessage)) {
+                    if (currentActivation == null) {
+                        if (figMessage.isCallAction()) {
+                            // if we are the dest and is a call action, create the 
+                            // activation, but don't add it until the height is set.
+                            ySender = figMessage.getFinalY();
+                            currentActivation = createActivationFig(
+                                    getOwner(), 
+                                    lineFig.getX(), 
+                                    ySender, 
+                                    0, 
+                                    0,
+                                    getSettings(),
+                                    figMessage);
+                            activationsCount++;
+                        } else if (figMessage.isCreateAction()) {
+                            // if we are the destination of a create action,
+                            // create the entire activation
+                            currentActivation = createActivationFig(
+                                    getOwner(),
+                                    lineFig.getX(),
+                                    lineFig.getY(),
+                                    0,
+                                    0,
+                                    getSettings(),
+                                    figMessage);
+                            activationsCount++;
+                        }
+                    } else if (figMessage.isCallAction()
+                                && isSameClassifierRoles(
+                                        currentActivation.getActivatingMessage(),
+                                        figMessage)) {
+                        activationsCount++;
+                    }
+                }
+                
+                if (isOutgoing(figMessage) && currentActivation != null) {
+                    if (currentActivation.isActivatorEnd(figMessage)
+                            && --activationsCount == 0) {
+                        // if we are the source of a return action
+                        // the activation ends here.
+                        ySender = figMessage.getStartY();
+                        currentActivation.setHeight(
+                                ySender - currentActivation.getY());
+                        newActivations.add(currentActivation);
+                        currentActivation = null;
+                    } else if (figMessage.isDestroyAction()) {
+                        // if we are the target of a destroy action
+                        // the figlifeline ends here and we add the activation
+                        ySender = figMessage.getFinalY();
+                        currentActivation.setHeight(
+                                ySender - currentActivation.getY());
+                        currentActivation.setDestroy(true);
+                        lineFig.setHeight(ySender - getY());
+                        newActivations.add(currentActivation);
+                        currentActivation = null;
+                    }
                 }
             }
         }
@@ -196,6 +210,14 @@
         return newActivations;
     }
     
+    private boolean isSameClassifierRoles(
+            final FigMessage mess1,
+            final FigMessage mess2) {
+        return mess1 != null
+                && mess1.getDestFigNode() == mess2.getDestFigNode()
+                && mess1.getSourceFigNode() == mess2.getSourceFigNode();
+    }
+    
     /**
      * Return true if the given message fig is pointing in to this lifeline.
      * @param messageFig

Modified: trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigMessage.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigMessage.java?view=diff&pathrev=16798&r1=16797&r2=16798
==============================================================================
--- trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigMessage.java	(original)
+++ trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/FigMessage.java	2009-02-15 08:45:06-0800
@@ -26,10 +26,12 @@
 
 import java.awt.Color;
 import java.awt.Point;
-import java.beans.PropertyChangeEvent;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.log4j.Logger;
 import org.argouml.model.Model;
 import org.argouml.model.UmlChangeEvent;
 import org.argouml.notation.NotationProviderFactory2;
@@ -51,6 +53,10 @@
 public class FigMessage extends FigEdgeModelElement {
 
     private static final long serialVersionUID = -2961220746360335159L;
+    
+    private static final Logger LOG =
+        Logger.getLogger(FigEdgeModelElement.class);
+    
     private FigTextGroup textGroup; 
 
     /**
@@ -339,7 +345,41 @@
         Set<Object[]> listeners = new HashSet<Object[]>();
         listeners.add(new Object[] {getOwner(), "remove"});
         listeners.add(new Object[] {getAction(), "isAsynchronous"});
-        updateElementListeners(listeners);
+        try {
+            updateElementListeners(listeners);
+        } catch (Exception e) {
+            // This call seems not very robust. Yet to determine cause.
+            LOG.error("Exception caught", e);
+        }
     }
     
+    /**
+     * Determines the activator of this message based on the message position
+     * in relation to other messages.
+     * <p>Currently this only manages return messages. Any other message type
+     * returns with no action taking place.
+     * <p>The activator is set to the first call or create message found above
+     * this message.
+     * @return the activator that has been applied to the message.
+     */
+    public Object determineActivator() {
+        final FigClassifierRole fcr = (FigClassifierRole) getSourceNode();
+        final List<FigMessage> messageFigs = fcr.getFigMessages();
+        final Iterator<FigMessage> it = messageFigs.iterator();
+        Object activator = null;
+        while (it.hasNext()) {
+            FigMessage messageFig = it.next();
+            if ((messageFig.isCreateAction() || messageFig.isCallAction())
+                    && messageFig.getDestNode() == fcr) {
+                activator = messageFig.getOwner();
+            } else if (messageFig == this) {
+                Model.getCollaborationsHelper().setActivator(
+                        getOwner(), activator);
+                return activator;
+            } else if (messageFig.isReturnAction()) {
+                activator = null;
+            }
+        }
+        return null;
+    }
 }

Modified: trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/ModeCreateMessage.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/ModeCreateMessage.java?view=diff&pathrev=16798&r1=16797&r2=16798
==============================================================================
--- trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/ModeCreateMessage.java	(original)
+++ trunk/src/argouml-core-diagrams-sequence2/src/org/argouml/sequence2/diagram/ModeCreateMessage.java	2009-02-15 08:45:06-0800
@@ -90,6 +90,11 @@
         ensureSpace(figMessage);
         
         if (figMessage.isCallAction()) {
+            // Auto-create a return message for a call message
+            
+            // TODO: Maybe a return message already exists. Check first and
+            // and if the first found has no activator then set this call
+            // message as the activator and skip the code below.
             
             // get the source of the return message
             final Object returnMessageSource =
@@ -106,6 +111,10 @@
                     Model.getMetaTypes().getMessage(),
                     Model.getMetaTypes().getReturnAction());
             
+            // Correct the activator value
+            Model.getCollaborationsHelper().setActivator(
+                    returnMessage, message);
+            
             final LayerPerspective layer = 
                 (LayerPerspective) editor.getLayerManager().getActiveLayer();
             
@@ -144,6 +153,8 @@
             // contained poly
             FigPoly poly = (FigPoly) returnEdge.getFig();
             poly.setComplete(true);
+        } else if (figMessage.isReturnAction()) {
+            figMessage.determineActivator();
         }
         
         dcr.createActivations();
@@ -160,7 +171,6 @@
      * @param figMessage
      */
     private void ensureSpace(final FigMessage figMessage) {
-        
         // Make sure there is the minimum gap above the message being drawn
         final FigMessage firstMessageAbove = getNearestMessage(
                 (FigClassifierRole) getSourceFigNode(),
@@ -178,6 +188,7 @@
         }
         
         // Make sure there is the minimum gap below the message being drawn
+        LOG.info("Looking for minimum space below");
         final FigMessage firstMessageBelow = getNearestMessage(
                 (FigClassifierRole) getSourceFigNode(),
                 figMessage,

------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=1165586

To unsubscribe from this discussion, e-mail: [[email protected]].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.