Skip to content

Commit

Permalink
incremental: allow dangling elements.
Browse files Browse the repository at this point in the history
Now instead of failing and throwing an exception whenever a KGraph with
referenced nodes, ports, or edges, which are not in the graph directly
via containment, this tries to still add the elements or display an
error message, but continue doing the best possible out of the faulty
graph. This way the update is way more robust for such graphs.
# Conflicts:
#	plugins/de.cau.cs.kieler.klighd.incremental/src/de/cau/cs/kieler/klighd/incremental/merge/KGraphMerger.java
  • Loading branch information
NiklasRentzCAU committed Aug 6, 2020
1 parent 43a9ea6 commit c5f6bb4
Showing 1 changed file with 59 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2016 by
* Copyright 2016,2020 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -21,6 +21,7 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.eclipse.elk.graph.properties.IProperty;
import org.eclipse.emf.common.util.EList;
Expand All @@ -46,9 +47,13 @@
/**
* Recursively merge two KGraphs.
*
* @author csp
* @author csp, nre
*/
public class KGraphMerger {

private static String INVALID_MOVE_MESSAGE = "Cannot move element to an out of bounds position in the reference " +
"list. Check if the synthesis leaves references to elements that are not in the graph via containment or if there "+
"is an error in this code. The graph may not be mapped correctly now.";

/** The comparison to merge. */
private KComparison comparison;
Expand Down Expand Up @@ -112,7 +117,9 @@ private void removeNode(final KNode node) {
for (KPort port : node.getPorts()) {
port.getEdges().clear();
}
node.getParent().getChildren().remove(node);
if (node.getParent() != null) {
node.getParent().getChildren().remove(node);
}
}

/**
Expand All @@ -121,10 +128,13 @@ private void removeNode(final KNode node) {
private void handleAddedNodes() {
// Before adding the nodes we have to make sure they are added in the same order as they appear in the
// containment list of their parent to ensure correct generation and mapping of ID-less elements.
comparison.getAddedNodes().stream().sorted(
// Add parent-less nodes first, then the sorted nodes with parents.
Stream<KNode> nodesWithoutParent = comparison.getAddedNodes().stream().filter((KNode n) -> n.getParent() == null);
Stream<KNode> nodesWithParent = comparison.getAddedNodes().stream().filter((KNode n) -> n.getParent() != null);
Stream.concat(nodesWithoutParent, nodesWithParent.sorted(
(KNode n1, KNode n2) -> n1.getParent().getChildren().indexOf(n1)
- n2.getParent().getChildren().indexOf(n2)
).forEachOrdered(
)).forEachOrdered(
(KNode node) -> addNode(node)
);
// Add edges after adding the nodes to ensure that all targets are available.
Expand All @@ -142,14 +152,25 @@ private void handleAddedNodes() {
*/
private void addNode(final KNode node) {
if (node.getParent() == null) {
throw new RuntimeException(
"Couldn't add new node " + node + "to base model:\nNode has no parent.");
// A connected node that is however not contained is added to the new model. Handle this in a special case
// and just copy the node and add it to the base adapter, without putting it into the base model directly.
if (comparison.lookupBaseNode(node) == null) {
KNode copiedNode = EcoreUtil.copy(node);
comparison.getBaseAdapter().generateIDs(copiedNode);
}
return;
}
// Otherwise, the node has a parent, so add the node to that.
KNode baseParent = comparison.lookupBaseNode(node.getParent());
if (baseParent == null) {
// The new node's parent is missing in the base model as well.
// Add it and its children (including this node) first.
addNode(node.getParent());
if (!comparison.getAddedNodes().contains(node.getParent())) {
// The new node's parent is missing in the base model as well and is not scheduled to be added
// otherwise. Add it and its children (including this node), but leave a warning that there might be an
// issue.
System.err.println(this.getClass().getName() + ": There is a unknown node to be added to the base "
+ "graph. Trying to continue, but this may cause further errors.");
addNode(node.getParent());
}
} else {
if (comparison.lookupBaseNode(node) == null) {
int oldPosition = node.getParent().getChildren().indexOf(node);
Expand Down Expand Up @@ -443,6 +464,10 @@ private void updatePosition(KNode baseNode, KNode newNode) {
int newPosition = newNode.getParent().getChildren().indexOf(newNode);
int oldPosition = baseNode.getParent().getChildren().indexOf(baseNode);
if (newPosition != oldPosition) {
if (newPosition >= baseNode.getParent().getChildren().size()) {
newPosition = baseNode.getParent().getChildren().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseNode.getParent().getChildren().move(newPosition, oldPosition);
}
}
Expand All @@ -459,6 +484,10 @@ private void updatePosition(KPort basePort, KPort newPort) {
int newPosition = newPort.getNode().getPorts().indexOf(newPort);
int oldPosition = basePort.getNode().getPorts().indexOf(basePort);
if (newPosition != oldPosition) {
if (newPosition >= basePort.getNode().getPorts().size()) {
newPosition = basePort.getNode().getPorts().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
basePort.getNode().getPorts().move(newPosition, oldPosition);
}
}
Expand All @@ -475,6 +504,10 @@ private void updatePosition(KLabel baseLabel, KLabel newLabel) {
int newPosition = newLabel.getParent().getLabels().indexOf(newLabel);
int oldPosition = baseLabel.getParent().getLabels().indexOf(baseLabel);
if (newPosition != oldPosition) {
if (newPosition >= baseLabel.getParent().getLabels().size()) {
newPosition = baseLabel.getParent().getLabels().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseLabel.getParent().getLabels().move(newPosition, oldPosition);
}
}
Expand All @@ -492,27 +525,43 @@ private void updatePosition(KEdge baseEdge, KEdge newEdge) {
int newPosition = newEdge.getSource().getOutgoingEdges().indexOf(newEdge);
int oldPosition = baseEdge.getSource().getOutgoingEdges().indexOf(baseEdge);
if (newPosition != oldPosition) {
if (newPosition >= baseEdge.getSource().getOutgoingEdges().size()) {
newPosition = baseEdge.getSource().getOutgoingEdges().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseEdge.getSource().getOutgoingEdges().move(newPosition, oldPosition);
}
}
if (baseEdge.getTarget() != null && newEdge.getTarget() != null) {
int newPosition = newEdge.getTarget().getIncomingEdges().indexOf(newEdge);
int oldPosition = baseEdge.getTarget().getIncomingEdges().indexOf(baseEdge);
if (newPosition != oldPosition) {
if (newPosition >= baseEdge.getTarget().getIncomingEdges().size()) {
newPosition = baseEdge.getTarget().getIncomingEdges().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseEdge.getTarget().getIncomingEdges().move(newPosition, oldPosition);
}
}
if (baseEdge.getSourcePort() != null && newEdge.getSourcePort() != null) {
int newPosition = newEdge.getSourcePort().getEdges().indexOf(newEdge);
int oldPosition = baseEdge.getSourcePort().getEdges().indexOf(baseEdge);
if (newPosition != oldPosition) {
if (newPosition >= baseEdge.getSourcePort().getEdges().size()) {
newPosition = baseEdge.getSourcePort().getEdges().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseEdge.getSourcePort().getEdges().move(newPosition, oldPosition);
}
}
if (baseEdge.getTargetPort() != null && newEdge.getTargetPort() != null) {
int newPosition = newEdge.getTargetPort().getEdges().indexOf(newEdge);
int oldPosition = baseEdge.getTargetPort().getEdges().indexOf(baseEdge);
if (newPosition != oldPosition) {
if (newPosition >= baseEdge.getTargetPort().getEdges().size()) {
newPosition = baseEdge.getTargetPort().getEdges().size() - 1;
System.err.println(this.getClass().getName() + ": " + INVALID_MOVE_MESSAGE);
}
baseEdge.getTargetPort().getEdges().move(newPosition, oldPosition);
}
}
Expand Down

0 comments on commit c5f6bb4

Please sign in to comment.