package org.eclipse.uml2.diagram.sequence.internal.layout.model; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Stack; import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsNode; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.HorizontalConstraint; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLine; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineElement; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineIterator; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.OrderingConstraint; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.SDVerticalLayoutInput; import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineElement.Position; import org.eclipse.uml2.diagram.sequence.internal.missed.EmptyEnumeration; /** * */ public class SDVerticalLayoutInputImpl implements SDVerticalLayoutInput { interface LifeLineSupply { LifeLine getVerticalLayoutLifeLine(); } public SDVerticalLayoutInputImpl(SDLayoutModel sdLayoutModel) { mySDLayoutModel = sdLayoutModel; } /** * Vertical layout input always contain virtual lifeline, which constraints minimum * length of other lifelines. */ public boolean doesContainNonvirtual() { return mySDLayoutModel.getLifeLinesList().size() != 1; } public Enumeration lifeLines() { List lmLifelines = mySDLayoutModel.getLifeLinesList(); List resultList = new ArrayList(lmLifelines.size()); for (Iterator it = lmLifelines.iterator(); it.hasNext(); ) { final LifeLineSupply lifeLineSupply1 = (LifeLineSupply) it.next(); resultList.add(lifeLineSupply1.getVerticalLayoutLifeLine()); } return Collections.enumeration(resultList); } public interface NullFreeIterator { Object next(); } public static abstract class NullFreeIteratorForArray implements NullFreeIterator { protected NullFreeIteratorForArray() { this(-1); } protected NullFreeIteratorForArray(int arraySize) { myArraySize = arraySize; } protected abstract Object get(int pos); public Object next() { if (myPos == myArraySize) { return null; } Object result = get(myPos); if (result != null) { myPos++; } return result; } private int myPos = 0; private final int myArraySize; } public static class NullFreeIteratorWrapper implements NullFreeIterator { protected NullFreeIteratorWrapper(Iterator iterator) { myIterator = iterator; } public Object next() { if (myIterator.hasNext()) { return myIterator.next(); } else { return null; } } private final Iterator myIterator; } static class ContainerPosition implements Position { public int getPositionValue() { return myValue; } public void setPositionValue(int pos) { myValue = pos; } public boolean isVirtual() { return false; } public boolean isFirstPrioritedPosition() { return false; } public boolean isLastPrioritedPosition() { return false; } private int myValue; } static abstract class ElementTopPosition implements Position { public ElementTopPosition(AbsNode gdeNode) { myGdeNode = gdeNode; } public int getPositionValue() { return myGdeNode.getY(); } public void setPositionValue(int pos) { myGdeNode.setY(pos); } private final AbsNode myGdeNode; } static abstract class ElementBottomPosition implements Position { public ElementBottomPosition(AbsNode gdeNode) { myGdeNode = gdeNode; } public int getPositionValue() { return myGdeNode.getY() + myGdeNode.getHeight(); } public void setPositionValue(int pos) { myGdeNode.setHeight(pos - myGdeNode.getY()); } private final AbsNode myGdeNode; } static abstract class LifeLineElementSizeAdapter implements LifeLineElement { public LifeLineElementSizeAdapter(int pointOffset, int size) { myPointOffset = pointOffset; mySize = size; } public void optimizeSize() { //do nothing by default } public int getPointOffset() { return myPointOffset; } public int getSize() { return mySize; } public Enumeration beforeConstraints() { return EmptyEnumeration.getEnumeration(); } public Enumeration afterConstraints() { return EmptyEnumeration.getEnumeration(); } private final int myPointOffset; private final int mySize; } static abstract class LifeLineElementGen extends LifeLineElementSizeAdapter { public LifeLineElementGen(int pointOffset, int size) { super(pointOffset, size); } public HorizontalConstraint getHorizontalConstraint() { return myHorizontalConstraint; } public void setHorizontalConstraint(HorizontalConstraint constraint) { if (myHorizontalConstraint != null && constraint != null) { throw new IllegalStateException("Cannot set horizontal constraint, already has one"); //$NON-NLS-1$ } myHorizontalConstraint = constraint; } private HorizontalConstraint myHorizontalConstraint = null; } static class LifeLineElementGenAdapter extends LifeLineElementGen { protected LifeLineElementGenAdapter(int pointOffset, int size, LifeLineElement.Position position, final LMLifeLineBracket lifeLineBracket) { this(pointOffset , size , position , new LifeLineSupply() { public LifeLine getVerticalLayoutLifeLine() { return lifeLineBracket.getLifeLine().getVerticalLayoutLifeLine(); } } ); } protected LifeLineElementGenAdapter(int pointOffset, int size, LifeLineElement.Position position, LifeLineSupply lifeLineSupply) { super(pointOffset, size); myPosition = position; myLifeLineSupply = lifeLineSupply; } public LifeLine getLifeLine() { return myLifeLineSupply.getVerticalLayoutLifeLine(); } public Position getPosition() { return myPosition; } private final LifeLineElement.Position myPosition; private final LifeLineSupply myLifeLineSupply; } static class OrderingConstraintHolder { public Enumeration afterConstraints() { if (myAfterConstraints == null) { return Collections.enumeration(Collections.EMPTY_LIST); } else { return Collections.enumeration(myAfterConstraints); } } public Enumeration beforeConstraints() { if (myBeforeConstraints == null) { return Collections.enumeration(Collections.EMPTY_LIST); } else { return Collections.enumeration(myBeforeConstraints); } } public void addAfterConstraint(OrderingConstraint orderingConstraint) { if (myAfterConstraints == null) { myAfterConstraints = new ArrayList(2); } myAfterConstraints.add(orderingConstraint); } public void addBeforeConstraint(OrderingConstraint orderingConstraint) { if (myBeforeConstraints == null) { myBeforeConstraints = new ArrayList(2); } myBeforeConstraints.add(orderingConstraint); } public void removeAfterConstraint(OrderingConstraint orderingConstraint) { if (myAfterConstraints == null) { throw new RuntimeException("Cannot remove constraint"); //$NON-NLS-1$ } if (!myAfterConstraints.remove(orderingConstraint)) { throw new RuntimeException("Cannot remove constraint"); //$NON-NLS-1$ } } public void removeBeforeConstraint(OrderingConstraint orderingConstraint) { if (myBeforeConstraints == null) { throw new RuntimeException("Cannot remove constraint"); //$NON-NLS-1$ } if (!myBeforeConstraints.remove(orderingConstraint)) { throw new RuntimeException("Cannot remove constraint"); //$NON-NLS-1$ } } private List myBeforeConstraints = null; private List myAfterConstraints = null; } public static class LifeLineIteratorImpl implements LifeLineIterator { public LifeLineIteratorImpl(NullFreeIterator nfIterator) { myNFIteratorStack.push(nfIterator); advance(); } public Integer nextClueValue() { if (myNextElement == null) { throw new NoSuchElementException(); } if (myClueAsked) { throw new IllegalStateException("Element should be asked now"); //$NON-NLS-1$ } myClueAsked = true; if (myNextClueValue == null) { return our1ClueValue; } else { return myNextClueValue; } } public LifeLineElement nextElement() { if (myNextElement == null) { throw new NoSuchElementException(); } if (!myClueAsked) { throw new IllegalStateException("Clue should be asked now"); //$NON-NLS-1$ } try { return myNextElement; } finally { advance(); myClueAsked = false; } } public boolean hasNext() { return myNextElement != null; } private void advance() { myNextClueValue = null; while (!myNFIteratorStack.empty()) { NullFreeIterator it1 = (NullFreeIterator) myNFIteratorStack.peek(); Object nextObject = it1.next(); if (nextObject == null) { myNFIteratorStack.pop(); } else if (nextObject instanceof NullFreeIterator) { myNFIteratorStack.push(nextObject); } else if (nextObject instanceof Integer) { Integer nextClueValue = (Integer)nextObject; if (myNextClueValue == null || myNextClueValue.intValue()<nextClueValue.intValue()) { myNextClueValue = nextClueValue; } } else { myNextElement = (LifeLineElement)nextObject; return; } } myNextElement = null; } private boolean myClueAsked = false; private Integer myNextClueValue; private LifeLineElement myNextElement; private final Stack myNFIteratorStack = new Stack(); } private final SDLayoutModel mySDLayoutModel; private final static Integer our1ClueValue = new Integer(1); // private static class HorizontalConstraintImpl implements HorizontalConstraint { // public List getLifeLineElementsList() { // return myImmutableList; // } // public List getLifeLineElementsMutableList() { // return myElementsList; // } // public void elementIsViolated(LifeLineElement lifeLineElement) { // System.out.println("[SDVerticalLayoutInputImpl] elementIsViolated"); // } // public void elementIsResolved(LifeLineElement lifeLineElement) { // } // // private List myElementsList = new ArrayList(); // private List myImmutableList = Collections.unmodifiableList(myElementsList); // } }