package org.eclipse.uml2.diagram.sequence.internal.layout.model; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.uml2.diagram.sequence.internal.layout.GeometryConstants; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsDiagram; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsElement; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsElementPropertyAccess; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsLink; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsLinkEnumeration; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsNode; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsNodeEnumeration; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.HorizontalConstraint; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineElement; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.SDVerticalLayoutInput; import org.eclipse.uml2.diagram.sequence.internal.missed.MissedMethods; import org.eclipse.uml2.uml.CombinedFragment; import org.eclipse.uml2.uml.Interaction; import org.eclipse.uml2.uml.InteractionOperand; import org.eclipse.uml2.uml.InteractionUse; import org.eclipse.uml2.uml.Lifeline; /** * Stateful model. Data structure to implement layout. Updated from gde events. * */ public class SDLayoutModel { public SDLayoutModel(AbsDiagram gdeDiagram, boolean readInitialData, LmAlienElement.Factory alienElementfactory, Config diagramConfig, RootElementsGetter interactionEntityGetter) { //System.out.println("[SDLayoutModel.SDLayoutModel] debug"); myGdeDiagram = gdeDiagram; myDiagramEntity = gdeDiagram.getInteraction(); if (myDiagramEntity == null) { throw new RuntimeException("Cannot get diagram entity"); //$NON-NLS-1$ } myAlienElementfactory = alienElementfactory; if (interactionEntityGetter == null) { interactionEntityGetter = new RootElementsGetter() { public Interaction getInteractionEntity() { return myDiagramEntity; } public View getInteractionView() { return myGdeDiagram.getInteractionView(); } public AbsNode getRootNode() { return myGdeDiagram.getRootNode(); } }; } myRootElementsGetter = interactionEntityGetter; //myUniqueNameService = UniqueNameService.Util.getService(model); myLmOwner = new LmOwnerImpl(diagramConfig); if (readInitialData) { initialFill(); } { // fake lifeline (very long) LMFakeLifeLine fakeLifeLine = new LMFakeLifeLine(GeometryConstants.Lifeline.MINIMUM_HEIGHT); myLifeLinesArray.add(fakeLifeLine); myTopLineConstraint.getLifeLineElementsList().add(fakeLifeLine.getFirstLifeLineElement()); fakeLifeLine.getFirstLifeLineElement().setHorizontalConstraint(myTopLineConstraint); myBottomLineConstraint.getLifeLineElementsList().add(fakeLifeLine.getLastLifeLineElement()); fakeLifeLine.getLastLifeLineElement().setHorizontalConstraint(myBottomLineConstraint); } } public interface Config { } public interface RootElementsGetter { Interaction getInteractionEntity(); View getInteractionView(); AbsNode getRootNode(); } public LmObjectsResolver getLmObjectsResolver() { return myLmObjectsResolver; } public SdLayoutModelAddRemoveProcessor newAddRemoveProcessor() { if (myAddRemoveElementsProcessor != null) { throw new IllegalStateException("Previous AddRemoveProcessor hasn't finished yet"); //$NON-NLS-1$ } myAddRemoveElementsProcessor = new AddRemoveElementsProcessor(); return myAddRemoveElementsProcessor; } public SDVerticalLayoutInput getSDVerticalLayoutInput() { return new SDVerticalLayoutInputImpl(this); } public List getLifeLinesList() { return myLifeLinesArrayImmutable; } public LMFrameContainer getRootFrameContainer() { return myRootFramesContainer; } public List getBadElementsList() { return myBadElements; } void addBracketToContainer(LMLifeLineBracket lifeLineBracket, LMBracketContainer bracketContainer) { bracketContainer.getChildBracketsList().add(lifeLineBracket); lifeLineBracket.setContainer(bracketContainer); } public State getState() { return myState; } public class State { public boolean isConstructionCompleted() { return myConstructionCompleted; } void setConstructionCompleted(boolean constructionCompleted) { myConstructionCompleted = constructionCompleted; } private boolean myConstructionCompleted = true; } private class AddRemoveElementsProcessor implements SdLayoutModelAddRemoveProcessor { public boolean processAddedGdeNode(AbsNode gdeNode) { assert isProcessorActive(); //System.out.println("[AddRemoveElementsProcessor] processAddedGdeNode gdeNode = " + gdeNode); if (myGdeElement2lmElement.get(gdeNode) != null) { /* // assert Object lmGenObject = myGdeElement2lmElement.get(gdeNode); if (lmGenObject instanceof LMLifeLineBracket) { LMLifeLineBracket testLifeLineBracket = (LMLifeLineBracket) lmGenObject; GdeElement parentElement = gdeNode.getParentGdeElement(); Object parentContainerX = myGdeElement2lmElement.get(parentElement); if (parentContainerX != testLifeLineBracket.getContainer()) { throw new RuntimeException(parentContainerX+" != "+testLifeLineBracket.getContainer()); } } */ return false; } final EObject nodeEntity = gdeNode.getModelEntity(); //System.out.println("[SDLayoutModel.processAddedGdeNode] nodeEntity="+Util.toString(nodeEntity)); if (nodeEntity == null) { return addAlienGdeNode(gdeNode); } AbsElement parentGdeElement = gdeNode.getParentGdeElement(); if (myRootElementsGetter.getRootNode().equals(parentGdeElement)) { //System.out.println("[SDLayoutModel.processAddedGdeNode] parent -- diagram"); //if (gdeNode.getProperty(SdLayoutConstants.VIEWMAPPED_AS_ALIEN_SHORTCUT) != null) { if (AbsElementPropertyAccess.getInstance().isViewmappedAsAlienShortcut(gdeNode)) { //System.out.println("[SDLayoutModel.processAddedGdeNode] bad note"); addBadNode(gdeNode); return true; } // if (myMetainfo.hasMetaclass(nodeEntity, SD20_Lifeline.METACLASS)) { // //System.out.println("[SDLayoutModel.processAddedGdeNode] add lifeline"); // addLifeLine(gdeNode, nodeEntity); // return true; // } else if (myMetainfo.hasMetaclass(nodeEntity, SD20_Int_Frame.METACLASS)) { // LMFrame lmFrame = addFrame(gdeNode, nodeEntity, null); // return lmFrame != null; // } else if (myMetainfo.hasMetaclass(nodeEntity, SD20_Int_InvocationSpecification.METACLASS)) { // LMFoundInvocationOccurence lmFoundInvocationOccurence = addFoundInvocationOccurence(gdeNode, nodeEntity, null); // return lmFoundInvocationOccurence != null; // } if (nodeEntity instanceof Lifeline) { //System.out.println("[SDLayoutModel.processAddedGdeNode] add lifeline"); addLifeLine(gdeNode, nodeEntity); return true; } else if (MissedMethods._arcasMetamodelSpecific().isFrame(nodeEntity)) { LMFrame lmFrame = addFrame(gdeNode, nodeEntity, null); return lmFrame != null; } else if (MissedMethods._arcasMetamodelSpecific().isFoundMessageInvocation(nodeEntity)) { LMFoundInvocationOccurence lmFoundInvocationOccurence = addFoundInvocationOccurence(gdeNode, nodeEntity, null); return lmFoundInvocationOccurence != null; } return addAlienGdeNode(gdeNode); } else { //System.out.println("[SDLayoutModel.processAddedGdeNode] should be bracket"); Object parentLmElement; { if (parentGdeElement instanceof AbsNode == false) { return addAlienGdeNode(gdeNode); } AbsNode parentGdeNode = (AbsNode) parentGdeElement; parentLmElement = myGdeElement2lmElement.get(parentGdeNode); if (parentLmElement == null) { return addAlienGdeNode(gdeNode); } } if (parentLmElement instanceof LMBracketContainer) { LMBracketContainer lmBracketContainer = (LMBracketContainer)parentLmElement; LMLifeLineBracket lmLifeLineBracket = lmBracketContainer.createChildBracketInstance(gdeNode, gdeNode.getReference()); if (lmLifeLineBracket == null) { return false; } lmBracketContainer.getChildBracketsList().add(lmLifeLineBracket); addPossibleUnorderedContainter(lmBracketContainer); lmLifeLineBracket.setContainer(lmBracketContainer); myGdeElement2lmElement.put(gdeNode, lmLifeLineBracket); //System.out.println("[SDLayoutModel.processAddedGdeNode] PUT "+gdeNode+" "+lmLifeLineBracket); return true; } else if (parentLmElement instanceof LMFrame) { LMFrame parentLMFrame = (LMFrame) parentLmElement; return addChildToFrame(parentLMFrame, gdeNode, nodeEntity); } else { return addAlienGdeNode(gdeNode); } } } private boolean addAlienGdeNode(AbsNode gdeNode) { myGdeElement2lmElement.put(gdeNode, myAlienElementfactory.createAlienNode(gdeNode)); return true; } private LMLifeLine addLifeLine(AbsNode lifeLineNode, EObject lifeLineEntity) { //System.out.println("[SDLayoutModel.addLifeLine] debug"); if (myGdeElement2lmElement.get(lifeLineNode) != null) { throw new RuntimeException("Lifeline gde element already added to model: "+lifeLineNode); //$NON-NLS-1$ } //TODO: uncomment when getInteractionEntity() result is valid if (lifeLineEntity.eContainer() != getInteractionEntity()) { addBadNode(lifeLineNode); return null; } LMLifeLine lmLifeLine = new LMLifeLine(lifeLineNode, LmBracketsMetamodel.LIFE_LINE_META_OBJECT, myLmOwner); //System.out.println("[SDLayoutModel.addLifeLine] lifeline created"); myGdeElement2lmElement.put(lifeLineNode, lmLifeLine); myLifeLinesArray.add(lmLifeLine); addPossibleUnorderedContainter(myLifeLinesArray); if (READ_GDE_CONTENT_MYSELF) { readBrackets(lifeLineNode, lmLifeLine, LmBracketsMetamodel.LIFE_LINE_META_OBJECT); } //System.out.println("[SDLayoutModel.addLifeLine] add to constraint"); myTopLineConstraint.getLifeLineElementsList().add(lmLifeLine.getFirstLifeLineElement()); lmLifeLine.getFirstLifeLineElement().setHorizontalConstraint(myTopLineConstraint); myBottomLineConstraint.getLifeLineElementsList().add(lmLifeLine.getLastLifeLineElement()); lmLifeLine.getLastLifeLineElement().setHorizontalConstraint(myBottomLineConstraint); return lmLifeLine; } private boolean addChildToFrame(LMFrame parentLMFrame, AbsNode gdeNode, EObject nodeEntity) { //System.out.println("[SDLayoutModel.processAddedGdeNode] parent is lm frame: "+parentLMFrame); if (MissedMethods._arcasMetamodelSpecific().isFrame(nodeEntity)) { LMFrame lmFrame = addFrame(gdeNode, nodeEntity, parentLMFrame); //System.out.println("[SDLayoutModel.processAddedGdeNode] frame added: "+lmFrame); return lmFrame != null; } else if (MissedMethods._arcasMetamodelSpecific().isFoundMessageInvocation(nodeEntity)) { LMFoundInvocationOccurence lmFoundInvocationOccurence = addFoundInvocationOccurence(gdeNode, nodeEntity, parentLMFrame); return lmFoundInvocationOccurence != null; } else { return addAlienGdeNode(gdeNode); } } private LMFrame addFrame(AbsNode frameNode, EObject frameEntity, LMFrame parentFrame) { //System.out.println("[SDLayoutModel.addFrame] frameNode="+frameNode); //System.out.println("[SDLayoutModel.addFrame] parentFrame="+parentFrame); if (myGdeElement2lmElement.get(frameNode) != null) { throw new RuntimeException("Frame gde element already added to model: "+frameNode); //$NON-NLS-1$ } if (parentFrame == null && frameEntity.eContainer() != getInteractionEntity()) { addBadNode(frameNode); return null; } LMFrame lmFrame; //System.out.println("[SDLayoutModel.addFrame] trying "+Util.toString(frameEntity)); if (frameEntity instanceof CombinedFragment) { lmFrame = new LMCombinedFragment(frameNode); } else if (frameEntity instanceof InteractionUse) { lmFrame = new LMInteractionOccurence(frameNode); } else if (frameEntity instanceof InteractionOperand) { lmFrame = new LMInteractionOperand(frameNode); } else { return null; } //System.out.println("[SDLayoutModel.addFrame] lmFrame="+lmFrame); myGdeElement2lmElement.put(frameNode, lmFrame); if (parentFrame == null) { myRootFramesContainer.addChildFrame(lmFrame); } else { parentFrame.addChildFrame(lmFrame); } if (READ_GDE_CONTENT_MYSELF) { readFrameChildren(frameNode, lmFrame); } return lmFrame; } private void readFrameChildren(AbsNode frameNode, LMFrame lmFrame) { for (AbsNodeEnumeration nodeEnum = frameNode.subnodes(); nodeEnum.hasMoreElements(); ) { AbsNode nextNode = nodeEnum.nextGdeNode(); EObject nodeEntity = nextNode.getModelEntity(); if (nodeEntity != null) { addChildToFrame(lmFrame, nextNode, nodeEntity); } } } private LMFoundInvocationOccurence addFoundInvocationOccurence(AbsNode invocationNode, EObject invocationEntity, LMFrame parentFrame) { //System.out.println("[SDLayoutModel.addFrame] frameNode="+frameNode); //System.out.println("[SDLayoutModel.addFrame] parentFrame="+parentFrame); if (myGdeElement2lmElement.get(invocationNode) != null) { throw new RuntimeException("Found invocation gde element already added to model: "+invocationNode); //$NON-NLS-1$ } if (parentFrame == null && invocationEntity.eContainer() != getInteractionEntity()) { addBadNode(invocationNode); return null; } LMFoundInvocationOccurence lmFoundInvocationOccurence; //System.out.println("[SDLayoutModel.addFrame] trying "+Util.toString(frameEntity)); if (MissedMethods._arcasMetamodelSpecific().isFoundMessageInvocation(invocationEntity)) { lmFoundInvocationOccurence = new LMFoundInvocationOccurence(invocationNode, parentFrame); } else { return null; } //System.out.println("[SDLayoutModel.addFrame] lmFrame="+lmFrame); myGdeElement2lmElement.put(invocationNode, lmFoundInvocationOccurence); if (parentFrame == null) { myRootFramesContainer.addChildFoundInvocation(lmFoundInvocationOccurence); } else { parentFrame.addChildFoundInvocation(lmFoundInvocationOccurence); } return lmFoundInvocationOccurence; } LMBadElement.Node addBadNode(AbsNode gdeNode) { LMBadElement.Node badNode = new LMBadElement.Node(gdeNode); myBadElements.add(badNode); myGdeElement2lmElement.put(gdeNode, badNode); return badNode; } private void readBrackets(AbsNode gdeNode, LMBracketContainer bracketContainer, BracketMetaObject bracketMetaObject) { for (AbsNodeEnumeration nodeEnum = gdeNode.subnodes(); nodeEnum.hasMoreElements(); ) { AbsNode subNode1 = nodeEnum.nextGdeNode(); View subNodeReference = subNode1.getReference(); if (subNodeReference == null) { continue; } BracketMetaObject childMetaObject = bracketMetaObject.getChildBracketMetaObject(subNodeReference); if (childMetaObject == null) { continue; } if (myGdeElement2lmElement.get(subNode1) != null) { throw new RuntimeException("GdeNode already added to model"); //$NON-NLS-1$ } LMLifeLineBracket lifeLineBracket = childMetaObject.createChildBracket(subNode1, myLmOwner); if (lifeLineBracket != null) { addBracketToContainer(lifeLineBracket, bracketContainer); //new Exception("PUT "+subNode1+" "+lifeLineBracket).printStackTrace(System.out); // System.out.println("[SDLayoutModel.readBrackets] PUT "+subNode1+" "+lifeLineBracket); myGdeElement2lmElement.put(subNode1, lifeLineBracket); readBrackets(subNode1, lifeLineBracket, childMetaObject); } } bracketContainer.reorderAfterReading(); } public boolean processAddedGdeLink(AbsLink gdeLink) { assert isProcessorActive(); //System.out.println("[SDLayoutModel.processAddedLink] gdeLink="+gdeLink); if (myGdeElement2lmElement.get(gdeLink) != null) { //throw new RuntimeException("GdeLink already added"); //$NON-NLS-1$ return false; } if (MissedMethods._arcasMetamodelSpecific().isAlienLink(gdeLink)) { return addedAlienLink(gdeLink); } if (MissedMethods._arcasMetamodelSpecific().isMessageLink(gdeLink)) { //EObject linkEntity = gdeLink.getModelEntity(); //System.out.println("[SDLayoutModel.processAddedLink] should be message"); AbsElement gdeSource = gdeLink.getSource(); AbsElement gdeDestination = gdeLink.getDestination(); Object sourceLMObject = myGdeElement2lmElement.get(gdeSource); Object destinationLMObject = myGdeElement2lmElement.get(gdeDestination); boolean isCallMessage; LMReceiveMessageEnd lmReceiveMessageEnd; LMSendMessageEnd lmSendMessageEnd; //System.out.println("[SDLayoutModel.processAddedLink] trying source/destination"); if (destinationLMObject instanceof LMReceiveMessageEnd && sourceLMObject instanceof LMSendMessageEnd) { isCallMessage = true; lmReceiveMessageEnd = (LMReceiveMessageEnd) destinationLMObject; lmSendMessageEnd = (LMSendMessageEnd) sourceLMObject; } else if (sourceLMObject instanceof LMReceiveMessageEnd && destinationLMObject instanceof LMSendMessageEnd) { isCallMessage = false; lmReceiveMessageEnd = (LMReceiveMessageEnd) sourceLMObject; lmSendMessageEnd = (LMSendMessageEnd) destinationLMObject; } else { //System.out.println("[SDLayoutModel.processAddedLink] didn't matched"); return false; } LMMessage lmMessage; LMMessageEnd.Positioning sendPositioning = lmSendMessageEnd.getPositioning(); LMMessageEnd.Positioning receivePositioning = lmReceiveMessageEnd.getPositioning(); if (sendPositioning instanceof LMMessageEnd.FloatingPositioning) { //System.out.println("[SDLayoutModel.processAddedLink] send is floating"); LMMessageEnd.FloatingPositioning floatingPositioning = (LMMessageEnd.FloatingPositioning)sendPositioning; if (receivePositioning instanceof LMReceiveMessageEnd.HorizontalPositioning == false) { //System.out.println("[SDLayoutModel.processAddedLink] bad receive positioning"); return false; } LMReceiveMessageEnd.HorizontalPositioning receiveHorizontalPositioning = (LMReceiveMessageEnd.HorizontalPositioning)receivePositioning; LMFoundMessage foundMessage = new LMFoundMessage(gdeLink, isCallMessage); foundMessage.setSendMessageEnd(lmSendMessageEnd, floatingPositioning); foundMessage.setReceiveMessageEnd(lmReceiveMessageEnd, receiveHorizontalPositioning); lmMessage = foundMessage; //System.out.println("[SDLayoutModel.processAddedLink] found message created"); } else { if (sendPositioning instanceof LMSendMessageEnd.HorizontalPositioning == false) { return false; } if (receivePositioning instanceof LMReceiveMessageEnd.HorizontalPositioning == false) { return false; } boolean isAsynchronous = MissedMethods._arcasMetamodelSpecific().isAsynchonousMessage(gdeLink); LMSendMessageEnd.HorizontalPositioning sendHorizontalPositioning = (LMSendMessageEnd.HorizontalPositioning)sendPositioning; LMReceiveMessageEnd.HorizontalPositioning receiveHorizontalPositioning = (LMReceiveMessageEnd.HorizontalPositioning)receivePositioning; if (sendHorizontalPositioning.getLifeLine() == receiveHorizontalPositioning.getLifeLine() && receiveHorizontalPositioning.getLifeLine() != null) { LMSelfMessage selfMessage = new LMSelfMessage(gdeLink, isCallMessage, isAsynchronous); LMMessageEnd.VerticalConstraintedPositioning sendVerticalPositioning = (LMMessageEnd.VerticalConstraintedPositioning)sendPositioning; LMMessageEnd.VerticalConstraintedPositioning receiveVerticalPositioning = (LMMessageEnd.VerticalConstraintedPositioning)receivePositioning; selfMessage.setSendMessageEnd(lmSendMessageEnd, sendVerticalPositioning, sendHorizontalPositioning); selfMessage.setReceiveMessageEnd(lmReceiveMessageEnd, receiveVerticalPositioning, receiveHorizontalPositioning); lmMessage = selfMessage; } else { if (isCallMessage) { if (sendPositioning instanceof LMMessageEnd.VerticalConstraintedPositioning == false) { return false; } if (receivePositioning instanceof LMMessageEnd.VerticalConstraintedPositioning == false) { return false; } LMMessageEnd.VerticalConstraintedPositioning sendVerticalPositioning = (LMMessageEnd.VerticalConstraintedPositioning)sendPositioning; LMMessageEnd.VerticalConstraintedPositioning receiveVerticalPositioning = (LMMessageEnd.VerticalConstraintedPositioning)receivePositioning; LMCallMessage lmCallMessage; if (isAsynchronous) { lmCallMessage = new LMCallMessageAsynch(gdeLink); } else { lmCallMessage = new LMCallMessageSynch(gdeLink); } lmCallMessage.setSendMessageEnd(lmSendMessageEnd, sendVerticalPositioning, sendHorizontalPositioning); lmCallMessage.setReceiveMessageEnd(lmReceiveMessageEnd, receiveVerticalPositioning, receiveHorizontalPositioning); lmMessage = lmCallMessage; } else { LMReturnMessage lmReturnMessage = new LMReturnMessage(gdeLink, MissedMethods._arcasMetamodelSpecific().isAsynchonousMessage(gdeLink)); lmReturnMessage.setSendMessageEnd(lmSendMessageEnd, sendHorizontalPositioning); lmReturnMessage.setReceiveMessageEnd(lmReceiveMessageEnd, receiveHorizontalPositioning); lmMessage = lmReturnMessage; } } } //System.out.println("[SDLayoutModel.processAddedLink] lmMessage = "+lmMessage); lmReceiveMessageEnd.addMessage(lmMessage); lmSendMessageEnd.addMessage(lmMessage); //System.out.println("[SDLayoutModel.processAddedLink] lmSendMessageEnd="+lmSendMessageEnd); //System.out.println("[SDLayoutModel.processAddedLink] lmReceiveMessageEnd="+lmReceiveMessageEnd); lmMessage.becomeLayoutConstraint(true); myGdeElement2lmElement.put(gdeLink, lmMessage); return true; } else if (MissedMethods._arcasMetamodelSpecific().isMountingLink(gdeLink)) { //System.out.println("[SDLayoutModel.processAddedLink] mounting link found : "+gdeLink); AbsElement gdeSource = gdeLink.getSource(); AbsElement gdeDestination = gdeLink.getDestination(); Object sourceLMObject = myGdeElement2lmElement.get(gdeSource); Object destinationLMObject = myGdeElement2lmElement.get(gdeDestination); if (sourceLMObject instanceof LMMountingRegion == false) { //System.out.println("[SDLayoutModel.processAddedLink] problem 1"); return false; } if (destinationLMObject instanceof LMFrame == false) { //System.out.println("[SDLayoutModel.processAddedLink] problem 2"); return false; } LMMountingRegion sourceMoutingPoint = (LMMountingRegion) sourceLMObject; LMFrame destinationFrame = (LMFrame) destinationLMObject; if (sourceMoutingPoint.getMountingLink() != null) { addBadLink(gdeLink); return true; } LMMountingLink mountingLink = new LMMountingLink(gdeLink); mountingLink.setMountingRegion(sourceMoutingPoint); mountingLink.setFrame(destinationFrame); sourceMoutingPoint.setMountLink(mountingLink); destinationFrame.addMountingLink(mountingLink); myGdeElement2lmElement.put(gdeLink, mountingLink); //System.out.println("[SDLayoutModel.processAddedLink] created"); return true; } else { return addedAlienLink(gdeLink); } } boolean addedAlienLink(AbsLink gdeLink) { myGdeElement2lmElement.put(gdeLink, myAlienElementfactory.createAlienLink(gdeLink)); return true; } LMBadElement.Link addBadLink(AbsLink gdeLink) { LMBadElement.Link badLink = new LMBadElement.Link(gdeLink); myBadElements.add(badLink); myGdeElement2lmElement.put(gdeLink, badLink); return badLink; } public boolean processRemovedGdeNode(AbsNode gdeNode) { assert isProcessorActive(); //System.out.println("[SDLayoutModel.processRemovedGdeNode] gdeNode="+gdeNode); Object lmObject = myGdeElement2lmElement.get(gdeNode); //System.out.println("[SDLayoutModel.processRemovedGdeNode] lmObject="+lmObject); if (lmObject == null) { return false; } if (lmObject instanceof LMLifeLine) { LMLifeLine lmLifeLine = (LMLifeLine) lmObject; removeLifeLine(lmLifeLine); return true; } else if (lmObject instanceof LMFrame) { LMFrame lmFrame = (LMFrame) lmObject; removeFrame(lmFrame); return true; } else if (lmObject instanceof LMFoundInvocationOccurence) { LMFoundInvocationOccurence lmFoundInvocationOccurence = (LMFoundInvocationOccurence) lmObject; removeFoundInvocationOccurence(lmFoundInvocationOccurence); return true; } else if (lmObject instanceof LMLifeLineBracket) { LMLifeLineBracket bracket1 = (LMLifeLineBracket) lmObject; LMBracketContainer container = bracket1.getContainer(); if (container == null) { throw new RuntimeException("Container is null"); //$NON-NLS-1$ } removeBracket(bracket1); container.getChildBracketsList().remove(bracket1); return true; } else if (lmObject instanceof LMBadElement.Node) { LMBadElement.Node badNode = (LMBadElement.Node)lmObject; removeBadElement(badNode); return true; } else if (lmObject instanceof LmAlienElement) { LmAlienElement alienElement = (LmAlienElement) lmObject; alienElement.dispose(); myGdeElement2lmElement.remove(gdeNode); return true; } else { throw new RuntimeException("Remove "+lmObject+": unknown element"); //$NON-NLS-1$ //$NON-NLS-2$ } } private void removeLifeLine(LMLifeLine lmLifeLine) { if (!lmLifeLine.getChildBracketsList().isEmpty()) { for (Iterator it=lmLifeLine.getChildBracketsList().iterator(); it.hasNext(); ) { LMLifeLineBracket bracket1 = (LMLifeLineBracket) it.next(); removeBracket(bracket1); } lmLifeLine.getChildBracketsList().removeAll(); } myTopLineConstraint.getLifeLineElementsList().remove(lmLifeLine.getFirstLifeLineElement()); lmLifeLine.getFirstLifeLineElement().setHorizontalConstraint(null); myBottomLineConstraint.getLifeLineElementsList().remove(lmLifeLine.getLastLifeLineElement()); lmLifeLine.getLastLifeLineElement().setHorizontalConstraint(null); AbsNode lifeLineNode = lmLifeLine.getGdeNode(); myGdeElement2lmElement.remove(lifeLineNode); myLifeLinesArray.remove(lmLifeLine); addPossibleUnorderedContainter(myLifeLinesArray); } private void removeFrame(LMFrame lmFrame) { disposeFrameBranch(lmFrame); lmFrame.delete(); } private void disposeFrameBranch(LMFrame lmFrame) { List lmMountingLinks = Collections.list(lmFrame.mountingLinks()); for (Iterator it = lmMountingLinks.iterator(); it.hasNext(); ) { LMMountingLink mountingLink1 = (LMMountingLink) it.next(); removeMountingLink(mountingLink1); } AbsNode combinedFragmentNode = lmFrame.getGdeNode(); myGdeElement2lmElement.remove(combinedFragmentNode); } private void removeFoundInvocationOccurence(LMFoundInvocationOccurence lmFoundInvocationOccurence) { lmFoundInvocationOccurence.delete(); myGdeElement2lmElement.remove(lmFoundInvocationOccurence.getGdeNode()); } private void removeBracket(LMLifeLineBracket lifeLineBracket) { if (!lifeLineBracket.getChildBracketsList().isEmpty()) { for (Iterator it=lifeLineBracket.getChildBracketsList().iterator(); it.hasNext(); ) { LMLifeLineBracket bracket1 = (LMLifeLineBracket) it.next(); removeBracket(bracket1); } lifeLineBracket.getChildBracketsList().removeAll(); } if (lifeLineBracket instanceof LMGenCallOccurence) { LMGenCallOccurence lmGenCallOccurence = (LMGenCallOccurence) lifeLineBracket; List topLinks = lmGenCallOccurence.getTopBoundaryLifeLineElement().getLMMesssagesList(); List bottomLinks = lmGenCallOccurence.getBottomBoundaryLifeLineElement().getLMMesssagesList(); if (!topLinks.isEmpty()) { //System.out.println("[AddRemoveElementsProcessor] removeBracket " + topLinks); //$NON-NLS-1$ throw new RuntimeException("still there are messages: "+topLinks); //$NON-NLS-1$ } if (!bottomLinks.isEmpty()) { //System.out.println("[AddRemoveElementsProcessor] removeBracket " + topLinks); //$NON-NLS-1$ throw new RuntimeException("still there are messages: "+bottomLinks); //$NON-NLS-1$ } // ArrayList messagesToRemove = new ArrayList(topLinks.size()+bottomLinks.size()); // messagesToRemove.addAll(topLinks); // messagesToRemove.addAll(bottomLinks); // // for (int i=0; i<messagesToRemove.size(); i++) { // LMMessage lmMessage = (LMMessage) messagesToRemove.get(i); // removeMessageLink(lmMessage); // } } else if (lifeLineBracket instanceof LMMountingRegion) { LMMountingRegion mountingPoint = (LMMountingRegion) lifeLineBracket; LMMountingLink mountingLink = mountingPoint.getMountingLink(); if (mountingLink != null) { removeMountingLink(mountingLink); } } AbsNode bracketNode = lifeLineBracket.getGdeNode(); myGdeElement2lmElement.remove(bracketNode); lifeLineBracket.setContainer(null); } public boolean processRemovedGdeLink(AbsLink gdeLink) { assert isProcessorActive(); //System.out.println("[SDLayoutModel.processRemovedGdeLink] gdeLink="+gdeLink); Object lmElement = myGdeElement2lmElement.get(gdeLink); //System.out.println("[SDLayoutModel.processRemovedGdeLink] lmElement="+lmElement); if (lmElement == null) { return false; } if (lmElement instanceof LMMessage) { LMMessage lmMessage = (LMMessage) lmElement; removeMessageLink(lmMessage); return true; } else if (lmElement instanceof LMMountingLink){ removeMountingLink((LMMountingLink)lmElement); return true; } else if (lmElement instanceof LMBadElement.Link) { removeBadElement((LMBadElement.Link)lmElement); return true; } else if (lmElement instanceof LmAlienElement) { LmAlienElement alienElement = (LmAlienElement) lmElement; alienElement.dispose(); myGdeElement2lmElement.remove(gdeLink); return true; } else { throw new RuntimeException("Remove "+lmElement+": todo"); //$NON-NLS-1$ //$NON-NLS-2$ } } private void removeMessageLink(LMMessage lmMessage) { //System.out.println("[SDLayoutModel.removeMessageLink] lmMessage="+lmMessage); if (lmMessage == null) { throw new IllegalArgumentException("lmMessage=null"); //$NON-NLS-1$ } if (lmMessage.isLayoutConstraint()) { lmMessage.becomeLayoutConstraint(false); } lmMessage.getReceiveMessageEnd().removeMessage(lmMessage); lmMessage.getSendMessageEnd().removeMessage(lmMessage); lmMessage.resetReceiveMessageEnd(); lmMessage.resetSendMessageEnd(); myGdeElement2lmElement.remove(lmMessage.getGdeLink()); } private void removeMountingLink(LMMountingLink lmMountingLink) { lmMountingLink.getFrame().removeMountingLink(lmMountingLink); lmMountingLink.getMountingRegion().setMountLink(null); lmMountingLink.setFrame(null); lmMountingLink.setMountingRegion(null); myGdeElement2lmElement.remove(lmMountingLink.getGdeLink()); } private void removeBadElement(LMBadElement badElement) { boolean res = myBadElements.remove(badElement); if (!res) { throw new RuntimeException("Cannot delete bad element from list"); //$NON-NLS-1$ } myGdeElement2lmElement.remove(badElement.getGdeElement()); } private void addPossibleUnorderedContainter(SelfReorderable bracketContainer) { myPossibleUnorderedContainers.add(bracketContainer); } public void finish() { assert isProcessorActive(); try { for (Iterator<SelfReorderable> it = myPossibleUnorderedContainers.iterator(); it.hasNext(); ) { SelfReorderable bracketContainer = it.next(); bracketContainer.reorderChildElements(); } myPossibleUnorderedContainers.clear(); updateLifelineCreationDestruction(); } finally { myAddRemoveElementsProcessor = null; } } private void updateLifelineCreationDestruction() { for (Iterator it = myLifeLinesArray.listIterator(1); it.hasNext();) { LMLifeLine lifeLine = (LMLifeLine) it.next(); lifeLine.updateCreationDestruction(); } } private boolean isProcessorActive() { return myAddRemoveElementsProcessor == this; } private Set<SelfReorderable> myPossibleUnorderedContainers = new HashSet<SelfReorderable>(); } private void initialFill() { myState.setConstructionCompleted(false); try { SdLayoutModelAddRemoveProcessor addRemoveElementsProcessor = newAddRemoveProcessor(); //System.out.println("[SDLayoutModel.initialFill] INITIAL FILL"); List allNodes = new ArrayList(); for (AbsNodeEnumeration nodeEnum = myRootElementsGetter.getRootNode().subnodes(); nodeEnum.hasMoreElements(); ) { AbsNode subNode1 = nodeEnum.nextGdeNode(); readNodesRecursively(subNode1, allNodes); } for (int i = 0; i<allNodes.size(); i++) { AbsNode subNode1 = (AbsNode) allNodes.get(i); addRemoveElementsProcessor.processAddedGdeNode(subNode1); } for (AbsLinkEnumeration linkEnum = myGdeDiagram.links(); linkEnum.hasMoreElements(); ) { AbsLink gdeLink1 = linkEnum.nextGdeLink(); addRemoveElementsProcessor.processAddedGdeLink(gdeLink1); } addRemoveElementsProcessor.finish(); } finally { myState.setConstructionCompleted(true); } } private void readNodesRecursively(AbsNode absNode, Collection collection) { collection.add(absNode); for (AbsNodeEnumeration nodeEnum = absNode.subnodes(); nodeEnum.hasMoreElements(); ) { AbsNode subNode1 = nodeEnum.nextGdeNode(); readNodesRecursively(subNode1, collection); } } private Interaction getInteractionEntity() { return myRootElementsGetter.getInteractionEntity(); } private final Map myGdeElement2lmElement = new HashMap(); private final Interaction myDiagramEntity; private final AbsDiagram myGdeDiagram; //private final UniqueNameService myUniqueNameService; /** * First element must be LMFakeLifeline */ private final LifelinesArray myLifeLinesArray = new LifelinesArray(); private final LMFrameContainer myRootFramesContainer = new LMFrameContainer(); private final List myLifeLinesArrayImmutable = Collections.unmodifiableList(myLifeLinesArray); private final List myBadElements = new ArrayList(); private final State myState = new State(); private final LmObjectsResolver myLmObjectsResolver = new LmObjectsResolver() { public Object getLmObject(AbsElement gdeElement) { return myGdeElement2lmElement.get(gdeElement); } }; private AddRemoveElementsProcessor myAddRemoveElementsProcessor = null; private final RootElementsGetter myRootElementsGetter; private final LmOwner myLmOwner; private final LmAlienElement.Factory myAlienElementfactory; private static class LmOwnerImpl implements LmOwner { LmOwnerImpl(Config config) { //myReorderAgainstModel = Boolean.TRUE.toString().equals(ideConfig.getProperty(REORDER_AGAINST_MODEL_NOT_GDE, null)); myReorderAgainstModel = true; } public boolean reorderAgainstModelNotGde() { return myReorderAgainstModel; } private final boolean myReorderAgainstModel; //private static String REORDER_AGAINST_MODEL_NOT_GDE = "option.sequenceDiagram20.debug.reorderAgainstModelNotGde"; } private final HorizontalConstraintImpl myTopLineConstraint = new HorizontalConstraintImpl("topline"); //$NON-NLS-1$ private final HorizontalConstraintImpl myBottomLineConstraint = new HorizontalConstraintImpl("bottomline"); //$NON-NLS-1$ private static class HorizontalConstraintImpl implements HorizontalConstraint { HorizontalConstraintImpl(String debugName) { myDebugName = debugName; } ArrayList getModifiableElementsList() { return myLifeLineElementsList; } public List getLifeLineElementsList() { return myLifeLineElementsList; } public void elementIsResolved(LifeLineElement lifeLineElement) { } public void elementIsViolated(LifeLineElement lifeLineElement) { } public String toString() { return "[HorizontalConstraintImpl:"+myDebugName+/*":"+myLifeLineElementsList+*/"]"; //$NON-NLS-1$ //$NON-NLS-2$ } private final ArrayList myLifeLineElementsList = new ArrayList(); private final String myDebugName; } private class LifelinesArray extends ArrayList implements SelfReorderable { public void reorderChildElements() { List allButFirstList = this.subList(1, size()); List<Integer> oldIndexes = SdLayoutUtil.getReorderAgainstModel(allButFirstList, myRootElementsGetter.getInteractionView()); SdLayoutUtil.reorderList(oldIndexes, allButFirstList); } } /** * This property controls, if layout model should itself read children of added node. It doesn't seem to be necessary, but it did in Trinity. */ private final static boolean READ_GDE_CONTENT_MYSELF = false; }