| /** |
| * <copyright> |
| * |
| * Copyright (c) 2013, 2019 Willink Transformations and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * E.D.Willink - Initial API and implementation |
| * |
| * </copyright> |
| */ |
| package org.eclipse.qvtd.pivot.qvtschedule.impl; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.NotificationChain; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EClass; |
| |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.impl.ENotificationImpl; |
| import org.eclipse.emf.ecore.util.EObjectResolvingEList; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.jdt.annotation.NonNull; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.ocl.pivot.internal.ElementImpl; |
| import org.eclipse.ocl.pivot.internal.NamedElementImpl; |
| import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder; |
| import org.eclipse.qvtd.pivot.qvtbase.graphs.ToGraphHelper; |
| import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphNode; |
| import org.eclipse.qvtd.pivot.qvtschedule.Connection; |
| import org.eclipse.qvtd.pivot.qvtschedule.ConnectionEnd; |
| import org.eclipse.qvtd.pivot.qvtschedule.ConnectionRole; |
| import org.eclipse.qvtd.pivot.qvtschedule.MappingPartition; |
| import org.eclipse.qvtd.pivot.qvtschedule.Node; |
| import org.eclipse.qvtd.pivot.qvtschedule.Partition; |
| import org.eclipse.qvtd.pivot.qvtschedule.QVTschedulePackage; |
| import org.eclipse.qvtd.pivot.qvtschedule.Region; |
| import org.eclipse.qvtd.pivot.qvtschedule.Role; |
| import org.eclipse.qvtd.pivot.qvtschedule.RootRegion; |
| import org.eclipse.qvtd.pivot.qvtschedule.Symbolable; |
| import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil; |
| |
| import com.google.common.collect.Iterables; |
| |
| /** |
| * <!-- begin-user-doc --> |
| * An implementation of the model object '<em><b>Connection</b></em>'. |
| * <!-- end-user-doc --> |
| * <p> |
| * The following features are implemented: |
| * </p> |
| * <ul> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getSymbolName <em>Symbol Name</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getOwningRootRegion <em>Owning Root Region</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getConnectionRole <em>Connection Role</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getName <em>Name</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getSourceEnds <em>Source Ends</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getIntermediatePartitions <em>Intermediate Partitions</em>}</li> |
| * <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.ConnectionImpl#getCommonPartition <em>Common Partition</em>}</li> |
| * </ul> |
| * |
| * @generated |
| */ |
| public abstract class ConnectionImpl extends ElementImpl implements Connection { |
| /** |
| * The number of structural features of the '<em>Connection</em>' class. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| * @ordered |
| */ |
| public static final int CONNECTION_FEATURE_COUNT = ElementImpl.ELEMENT_FEATURE_COUNT + 7; |
| /** |
| * The number of operations of the '<em>Connection</em>' class. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| * @ordered |
| */ |
| public static final int CONNECTION_OPERATION_COUNT = ElementImpl.ELEMENT_OPERATION_COUNT + 0; |
| /** |
| * The default value of the '{@link #getSymbolName() <em>Symbol Name</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getSymbolName() |
| * @generated |
| * @ordered |
| */ |
| protected static final String SYMBOL_NAME_EDEFAULT = null; |
| /** |
| * The cached value of the '{@link #getSymbolName() <em>Symbol Name</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getSymbolName() |
| * @generated |
| * @ordered |
| */ |
| protected String symbolName = SYMBOL_NAME_EDEFAULT; |
| |
| /** |
| * The default value of the '{@link #getConnectionRole() <em>Connection Role</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getConnectionRole() |
| * @generated |
| * @ordered |
| */ |
| protected static final ConnectionRole CONNECTION_ROLE_EDEFAULT = ConnectionRole.UNDEFINED; |
| /** |
| * The cached value of the '{@link #getConnectionRole() <em>Connection Role</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getConnectionRole() |
| * @generated |
| * @ordered |
| */ |
| protected ConnectionRole connectionRole = CONNECTION_ROLE_EDEFAULT; |
| /** |
| * The default value of the '{@link #getName() <em>Name</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getName() |
| * @generated |
| * @ordered |
| */ |
| protected static final String NAME_EDEFAULT = null; |
| /** |
| * The cached value of the '{@link #getName() <em>Name</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getName() |
| * @generated |
| * @ordered |
| */ |
| protected String name = NAME_EDEFAULT; |
| |
| /** |
| * The cached value of the '{@link #getSourceEnds() <em>Source Ends</em>}' reference list. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getSourceEnds() |
| * @generated |
| * @ordered |
| */ |
| protected EList<ConnectionEnd> sourceEnds; |
| |
| /** |
| * The cached value of the '{@link #getIntermediatePartitions() <em>Intermediate Partitions</em>}' reference list. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getIntermediatePartitions() |
| * @generated |
| * @ordered |
| */ |
| protected EList<Partition> intermediatePartitions; |
| /** |
| * The cached value of the '{@link #getCommonPartition() <em>Common Partition</em>}' reference. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getCommonPartition() |
| * @generated |
| * @ordered |
| */ |
| protected Partition commonPartition; |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| protected ConnectionImpl() { |
| super(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| protected EClass eStaticClass() { |
| return QVTschedulePackage.Literals.CONNECTION; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void setSymbolName(String newSymbolName) { |
| String oldSymbolName = symbolName; |
| symbolName = newSymbolName; |
| if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 0, oldSymbolName, symbolName)); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public RootRegion getOwningRootRegion() { |
| if (eContainerFeatureID() != (ElementImpl.ELEMENT_FEATURE_COUNT + 1)) return null; |
| return (RootRegion)eInternalContainer(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public NotificationChain basicSetOwningRootRegion(RootRegion newOwningRootRegion, NotificationChain msgs) { |
| msgs = eBasicSetContainer((InternalEObject)newOwningRootRegion, ElementImpl.ELEMENT_FEATURE_COUNT + 1, msgs); |
| return msgs; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void setOwningRootRegion(RootRegion newOwningRootRegion) { |
| if (newOwningRootRegion != eInternalContainer() || (eContainerFeatureID() != (ElementImpl.ELEMENT_FEATURE_COUNT + 1) && newOwningRootRegion != null)) { |
| if (EcoreUtil.isAncestor(this, newOwningRootRegion)) |
| throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); |
| NotificationChain msgs = null; |
| if (eInternalContainer() != null) |
| msgs = eBasicRemoveFromContainer(msgs); |
| if (newOwningRootRegion != null) |
| msgs = ((InternalEObject)newOwningRootRegion).eInverseAdd(this, NamedElementImpl.NAMED_ELEMENT_FEATURE_COUNT + 6, RootRegion.class, msgs); |
| msgs = basicSetOwningRootRegion(newOwningRootRegion, msgs); |
| if (msgs != null) msgs.dispatch(); |
| } |
| else if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 1, newOwningRootRegion, newOwningRootRegion)); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public ConnectionRole getConnectionRole() { |
| return connectionRole; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void setConnectionRole(ConnectionRole newConnectionRole) { |
| ConnectionRole oldConnectionRole = connectionRole; |
| connectionRole = newConnectionRole == null ? CONNECTION_ROLE_EDEFAULT : newConnectionRole; |
| if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 2, oldConnectionRole, connectionRole)); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void setName(String newName) { |
| String oldName = name; |
| name = newName; |
| if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 3, oldName, name)); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public List<ConnectionEnd> getSourceEnds() { |
| if (sourceEnds == null) { |
| sourceEnds = new EObjectResolvingEList<ConnectionEnd>(ConnectionEnd.class, this, ElementImpl.ELEMENT_FEATURE_COUNT + 4); |
| } |
| return sourceEnds; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public List<Partition> getIntermediatePartitions() { |
| if (intermediatePartitions == null) { |
| intermediatePartitions = new EObjectResolvingEList<Partition>(Partition.class, this, ElementImpl.ELEMENT_FEATURE_COUNT + 5); |
| } |
| return intermediatePartitions; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public Partition getCommonPartition() { |
| if (commonPartition != null && commonPartition.eIsProxy()) { |
| InternalEObject oldCommonPartition = (InternalEObject)commonPartition; |
| commonPartition = (Partition)eResolveProxy(oldCommonPartition); |
| if (commonPartition != oldCommonPartition) { |
| if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.RESOLVE, ElementImpl.ELEMENT_FEATURE_COUNT + 6, oldCommonPartition, commonPartition)); |
| } |
| } |
| return commonPartition; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public Partition basicGetCommonPartition() { |
| return commonPartition; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void setCommonPartition(Partition newCommonPartition) { |
| Partition oldCommonPartition = commonPartition; |
| commonPartition = newCommonPartition; |
| if (eNotificationRequired()) |
| eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 6, oldCommonPartition, commonPartition)); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| if (eInternalContainer() != null) |
| msgs = eBasicRemoveFromContainer(msgs); |
| return basicSetOwningRootRegion((RootRegion)otherEnd, msgs); |
| } |
| return super.eInverseAdd(otherEnd, featureID, msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| return basicSetOwningRootRegion(null, msgs); |
| } |
| return super.eInverseRemove(otherEnd, featureID, msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) { |
| switch (eContainerFeatureID()) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| return eInternalContainer().eInverseRemove(this, NamedElementImpl.NAMED_ELEMENT_FEATURE_COUNT + 6, RootRegion.class, msgs); |
| } |
| return super.eBasicRemoveFromContainerFeature(msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public Object eGet(int featureID, boolean resolve, boolean coreType) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 0: |
| return getSymbolName(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| return getOwningRootRegion(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 2: |
| return getConnectionRole(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 3: |
| return getName(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 4: |
| return getSourceEnds(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 5: |
| return getIntermediatePartitions(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 6: |
| if (resolve) return getCommonPartition(); |
| return basicGetCommonPartition(); |
| } |
| return super.eGet(featureID, resolve, coreType); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public void eSet(int featureID, Object newValue) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 0: |
| setSymbolName((String)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| setOwningRootRegion((RootRegion)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 2: |
| setConnectionRole((ConnectionRole)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 3: |
| setName((String)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 4: |
| getSourceEnds().clear(); |
| getSourceEnds().addAll((Collection<? extends ConnectionEnd>)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 5: |
| getIntermediatePartitions().clear(); |
| getIntermediatePartitions().addAll((Collection<? extends Partition>)newValue); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 6: |
| setCommonPartition((Partition)newValue); |
| return; |
| } |
| super.eSet(featureID, newValue); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void eUnset(int featureID) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 0: |
| setSymbolName(SYMBOL_NAME_EDEFAULT); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| setOwningRootRegion((RootRegion)null); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 2: |
| setConnectionRole(CONNECTION_ROLE_EDEFAULT); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 3: |
| setName(NAME_EDEFAULT); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 4: |
| getSourceEnds().clear(); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 5: |
| getIntermediatePartitions().clear(); |
| return; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 6: |
| setCommonPartition((Partition)null); |
| return; |
| } |
| super.eUnset(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public boolean eIsSet(int featureID) { |
| switch (featureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 0: |
| return SYMBOL_NAME_EDEFAULT == null ? symbolName != null : !SYMBOL_NAME_EDEFAULT.equals(symbolName); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 1: |
| return getOwningRootRegion() != null; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 2: |
| return connectionRole != CONNECTION_ROLE_EDEFAULT; |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 3: |
| return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 4: |
| return sourceEnds != null && !sourceEnds.isEmpty(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 5: |
| return intermediatePartitions != null && !intermediatePartitions.isEmpty(); |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 6: |
| return commonPartition != null; |
| } |
| return super.eIsSet(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) { |
| if (baseClass == Symbolable.class) { |
| switch (derivedFeatureID) { |
| case ElementImpl.ELEMENT_FEATURE_COUNT + 0: return 0; |
| default: return -1; |
| } |
| } |
| return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) { |
| if (baseClass == Symbolable.class) { |
| switch (baseFeatureID) { |
| case 0: return ElementImpl.ELEMENT_FEATURE_COUNT + 0; |
| default: return -1; |
| } |
| } |
| return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass); |
| } |
| |
| |
| /** |
| * The indexes in the overall schedule at which this connection propagates additional values. |
| */ |
| private final @NonNull List<@NonNull Integer> passes = new ArrayList<>(); |
| |
| @Override |
| public boolean addPass(int pass) { |
| for (int i = 0; i < passes.size(); i++) { |
| Integer aPass = passes.get(i); |
| if (pass == aPass) { |
| return false; |
| } |
| if (pass < aPass) { |
| passes.add(i, pass); |
| return true; |
| } |
| } |
| passes.add(pass); |
| return true; |
| } |
| |
| @Override |
| public void appendEdgeAttributes(@NonNull ToGraphHelper toGraphHelper, @NonNull String sourceName, @NonNull String targetName) { |
| GraphStringBuilder s = toGraphHelper.getGraphStringBuilder(); |
| toGraphHelper.setColor(this); |
| /* if (isRegion2Region()) { |
| String indexText = getIndexText(); |
| if (indexText != null) { |
| s.setLabel(indexText); |
| } |
| } */ |
| String style = getConnectionRole().getStyle(); |
| if (style != null) { |
| s.setStyle(style); |
| } |
| String arrowhead = getConnectionRole().getArrowhead(); |
| if (arrowhead != null) { |
| s.setArrowhead(arrowhead); |
| } |
| s.setPenwidth(getConnectionRole().getPenwidth()); |
| s.appendAttributedEdge(sourceName, this, targetName); |
| } |
| |
| @Override |
| public void appendNode(@NonNull ToGraphHelper toGraphHelper, @NonNull String nodeName) { |
| GraphStringBuilder s = toGraphHelper.getGraphStringBuilder(); |
| String name = getName(); |
| String indexText = getIndexText(); |
| if (indexText != null) { |
| name = name + "\\n " + indexText; |
| } |
| s.setLabel(name); |
| s.setShape(getShape()); |
| String style = getStyle(); |
| if (style != null) { |
| s.setStyle(style); |
| } |
| toGraphHelper.setColor(this); |
| s.setPenwidth(getConnectionRole().getPenwidth()); |
| s.appendAttributedNode(nodeName); |
| } |
| |
| @Override |
| public void destroy() { |
| setCommonPartition(null); |
| getIntermediatePartitions().clear(); |
| getSourceEnds().clear(); |
| setOwningRootRegion(null); |
| } |
| |
| @Override |
| public @NonNull String getColor() { |
| return getConnectionRole().getColor(); |
| } |
| |
| @Override |
| public int getFirstPass() { |
| return passes.get(0); |
| } |
| |
| public @Nullable String getIndexText() { |
| StringBuilder s = null; |
| for (@NonNull Integer index : passes) { |
| if (s == null) { |
| s = new StringBuilder(); |
| } |
| else { |
| s.append(","); |
| } |
| s.append(index.toString()); |
| } |
| return s != null ? s.toString() : null; |
| } |
| |
| @Override |
| public int getLastPass() { |
| return passes.get(passes.size()-1); |
| } |
| |
| @Override |
| public @NonNull List<@NonNull Integer> getPasses() { |
| return passes; |
| } |
| |
| public @NonNull String getShape() { |
| return "ellipse"; |
| } |
| |
| @Override |
| public @NonNull GraphNode getEdgeSource() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public @Nullable String getStyle() { |
| return getConnectionRole().getStyle(); |
| } |
| |
| @Override |
| public @NonNull String getSymbolName() { |
| return QVTscheduleUtil.getName(this); |
| } |
| |
| @Override |
| public @NonNull GraphNode getEdgeTarget() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public String toString() { |
| return getSymbolName(); |
| } |
| |
| @Override |
| public @NonNull ConnectionEnd getSource(@NonNull Partition sourcePartition) { |
| @Nullable ConnectionEnd theSourceEnd = null; |
| for (@NonNull ConnectionEnd sourceEnd : QVTscheduleUtil.getSourceEnds(this)) { |
| Region sourceRegion = QVTscheduleUtil.getOwningRegion(sourceEnd); |
| Iterable<@NonNull MappingPartition> sourceRegionPartitions = QVTscheduleUtil.getRegionPartitions(sourceRegion); |
| if (Iterables.contains(sourceRegionPartitions, sourcePartition)) { |
| Role sourceRole = QVTscheduleUtil.getRole(sourcePartition, sourceEnd); |
| if ((sourceRole != null) && !sourceRole.isChecked()) { //(sourceRole.isNew() || sourceRole.isLoaded())) { |
| assert theSourceEnd == null; |
| theSourceEnd = sourceEnd; |
| } |
| } |
| } |
| assert theSourceEnd != null; |
| return theSourceEnd; |
| } |
| |
| @Override |
| public @NonNull Iterable<@NonNull Partition> getSourcePartitions() { |
| Set<@NonNull Partition> sourcePartitions = new HashSet<>(); |
| for (@NonNull ConnectionEnd sourceEnd : QVTscheduleUtil.getSourceEnds(this)) { |
| Region sourceRegion = QVTscheduleUtil.getOwningRegion(sourceEnd); |
| Iterable<@NonNull MappingPartition> sourceRegionPartitions = QVTscheduleUtil.getRegionPartitions(sourceRegion); |
| for (@NonNull MappingPartition sourcePartition : sourceRegionPartitions) { |
| if (QVTscheduleUtil.getMergedPartition(sourcePartition) == sourcePartition) { |
| Role sourceRole = QVTscheduleUtil.getRole(sourcePartition, sourceEnd); |
| if ((sourceRole != null) && !sourceRole.isChecked()) { // (sourceRole.isNew() || sourceRole.isLoaded())) { |
| sourcePartitions.add(sourcePartition); |
| } |
| } |
| } |
| } |
| return sourcePartitions; |
| } |
| |
| @Override |
| public @NonNull Iterable<@NonNull ConnectionEnd> getTargetConnectionEnds(@NonNull Partition targetPartition) { |
| List<@NonNull ConnectionEnd> targetConnectionEnds = new ArrayList<>(); |
| for (@NonNull ConnectionEnd targetConnectionEnd : getTargetEnds()) { |
| // Region region = QVTscheduleUtil.getOwningRegion(targetConnectionEnd); |
| // RegionAnalysis regionAnalysis = scheduleManager.getRegionAnalysis(region); |
| // Iterable<@NonNull Partition> partitions = regionAnalysis.getPartitions(); |
| // for (@NonNull Partition partition : partitions) { |
| Role role = QVTscheduleUtil.getRole(targetPartition, targetConnectionEnd); |
| if ((role != null) && role.isOld()) { |
| targetConnectionEnds.add(targetConnectionEnd); |
| } |
| // } |
| } |
| return targetConnectionEnds; |
| } |
| |
| @Override |
| public @NonNull ConnectionRole getTargetConnectionRole(@NonNull Partition targetPartition, @NonNull ConnectionEnd connectionEnd) { |
| ConnectionRole connectionRole = getTargetRole(connectionEnd); |
| assert connectionRole != null; |
| if (connectionRole.isPassed()) { |
| boolean isHead = targetPartition.isHead(connectionEnd); |
| if (!isHead) { |
| connectionRole = ConnectionRole.PREFERRED_NODE; |
| } |
| } |
| return connectionRole; |
| } |
| |
| @Override |
| public @NonNull Iterable<@NonNull Partition> getTargetPartitions() { |
| List<@NonNull Partition> targetPartitions = new ArrayList<>(); |
| for (@NonNull ConnectionEnd target : getTargetEnds()) { |
| Region region = QVTscheduleUtil.getOwningRegion(target); |
| Iterable<@NonNull MappingPartition> partitions = QVTscheduleUtil.getRegionPartitions(region); |
| for (@NonNull MappingPartition targetPartition : partitions) { |
| if (QVTscheduleUtil.getMergedPartition(targetPartition) == targetPartition) { |
| Role role = QVTscheduleUtil.getRole(targetPartition, target); |
| if ((role != null) && role.isOld() && !targetPartitions.contains(targetPartition)) { |
| boolean skipPartionedHead = false; |
| if (target instanceof Node) { |
| if (((Node)target).isHead() && !targetPartition.isHead(target)) { |
| skipPartionedHead = true; |
| } |
| } |
| if (!skipPartionedHead) { |
| targetPartitions.add(targetPartition); |
| } |
| } |
| } |
| } |
| } |
| return targetPartitions; |
| } |
| |
| public boolean isRegion2Region(@NonNull Map<@NonNull Region, @NonNull Integer> sourceRegion2count, @NonNull Map<@NonNull Region, @NonNull List<@NonNull ConnectionRole>> targetRegion2roles) { |
| return (sourceRegion2count.size() == 1) && (targetRegion2roles.size() == 1) && (targetRegion2roles.values().iterator().next().size() == 1); //(targetEnd2role.size() == 1); |
| } |
| |
| protected void mergeRole(@NonNull ConnectionRole connectionRoleEnum) { |
| // assert connectionRole != null; |
| if (getConnectionRole() == ConnectionRole.UNDEFINED) { |
| setConnectionRole(connectionRoleEnum); |
| } |
| else if (getConnectionRole() != connectionRoleEnum) { |
| setConnectionRole(getConnectionRole().merge(connectionRoleEnum)); |
| } |
| } |
| } //ConnectionImpl |