X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram.connection%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fconnection%2Fdelta%2FRouteGraphDelta.java;fp=bundles%2Forg.simantics.diagram.connection%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fconnection%2Fdelta%2FRouteGraphDelta.java;h=4079d3a6da18b9bff5a216edde8816c5823d6326;hp=6288febeffd70b77d40f9888290cdc09c4510109;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/delta/RouteGraphDelta.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/delta/RouteGraphDelta.java index 6288febef..4079d3a6d 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/delta/RouteGraphDelta.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/delta/RouteGraphDelta.java @@ -1,275 +1,275 @@ -/******************************************************************************* - * Copyright (c) 2011 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.diagram.connection.delta; - -import gnu.trove.map.hash.THashMap; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; - -import org.simantics.diagram.connection.RouteGraph; -import org.simantics.diagram.connection.RouteLine; -import org.simantics.diagram.connection.RouteLink; -import org.simantics.diagram.connection.RoutePoint; -import org.simantics.diagram.connection.RouteTerminal; - -/** - * Calculates the delta between two route graphs. Only - * persistent lines are used in the computation. Lines, - * links and terminals are matched by their data attribute. - * If data is null, the node is not matched any node in - * the other node. Two lines differ, if they have a - * different orientation or position. Two terminals differ, - * if they are linked to different route lines ({@link RouteTerminal#getLine()}). - * @author Hannu Niemistö - */ -public class RouteGraphDelta implements Serializable { - - private static final long serialVersionUID = 5011201407852172263L; - - ArrayList linesOnlyInLeft = new ArrayList(); - ArrayList linesOnlyInRight = new ArrayList(); - ArrayList linesThatDiffer = new ArrayList(); - ArrayList linksOnlyInLeft = new ArrayList(); - ArrayList linksOnlyInRight = new ArrayList(); - ArrayList terminalsOnlyInLeft = new ArrayList(); - ArrayList terminalsOnlyInRight = new ArrayList(); - ArrayList terminalsThatDiffer = new ArrayList(); - - public static class RouteLinePair implements Serializable { - private static final long serialVersionUID = 382349562756381086L; - - public final RouteLine left; - public final RouteLine right; - - public RouteLinePair(RouteLine left, RouteLine right) { - this.left = left; - this.right = right; - } - } - - public static class RouteTerminalPair implements Serializable { - private static final long serialVersionUID = 5286896101190626944L; - - public final RouteTerminal left; - public final RouteTerminal right; - - public RouteTerminalPair(RouteTerminal left, RouteTerminal right) { - this.left = left; - this.right = right; - } - } - - public Collection getLinesOnlyInLeft() { - return linesOnlyInLeft; - } - - public Collection getLinesOnlyInRight() { - return linesOnlyInRight; - } - - public ArrayList getLinesThatDiffer() { - return linesThatDiffer; - } - - public Collection getLinksOnlyInLeft() { - return linksOnlyInLeft; - } - - public Collection getLinksOnlyInRight() { - return linksOnlyInRight; - } - - public ArrayList getTerminalsOnlyInLeft() { - return terminalsOnlyInLeft; - } - - public ArrayList getTerminalsOnlyInRight() { - return terminalsOnlyInRight; - } - - public ArrayList getTerminalsThatDiffer() { - return terminalsThatDiffer; - } - - private static class KeyPair { - final Object a; - final Object b; - - public KeyPair(Object a, Object b) { - this.a = a; - this.b = b; - } - - @Override - public int hashCode() { - return 31*a.hashCode() + b.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(obj == this) - return true; - if(obj == null || obj.getClass() != KeyPair.class) - return false; - KeyPair other = (KeyPair)obj; - return a.equals(other.a) && b.equals(other.b); - } - } - - public RouteGraphDelta(RouteGraph left, RouteGraph right) { - { - THashMap lineMap = - new THashMap(); - for(RouteLine line : left.getLines()) { - Object data = line.getData(); - if(data == null) - linesOnlyInLeft.add(line); - else - lineMap.put(data, line); - } - for(RouteLine line : right.getLines()) { - Object data = line.getData(); - if(data == null) - linesOnlyInRight.add(line); - else { - RouteLine other =lineMap.remove(data); - if(other == null) - linesOnlyInRight.add(line); - else if(line.getPosition() != other.getPosition() || - line.isHorizontal() != other.isHorizontal()) - linesThatDiffer.add(new RouteLinePair(other, line)); - } - } - linesOnlyInLeft.addAll(lineMap.values()); - } - { - THashMap linkMap = - new THashMap(); - for(RouteLine a : left.getLines()) { - for(RoutePoint point : a.getPoints()) { - if(!(point instanceof RouteLink)) - continue; - RouteLink link = (RouteLink)point; - RouteLine b = link.getB(); - if(a == link.getA() && !b.isTransient()) { - Object dataA = a.getData(); - Object dataB = b.getData(); - if(dataA == null || dataB == null) - linksOnlyInLeft.add(link); - else - linkMap.put(new KeyPair(dataA, dataB), link); - } - } - } - for(RouteLine a : right.getLines()) { - for(RoutePoint point : a.getPoints()) { - if(!(point instanceof RouteLink)) - continue; - RouteLink link = (RouteLink)point; - RouteLine b = link.getB(); - if(a == link.getA() && !b.isTransient()) { - Object dataA = a.getData(); - Object dataB = b.getData(); - if(dataA == null || dataB == null - || (linkMap.remove(new KeyPair(dataA, dataB)) == null - && linkMap.remove(new KeyPair(dataB, dataA)) == null)) - linksOnlyInRight.add(link); - } - } - } - linksOnlyInLeft.addAll(linkMap.values()); - } - { - THashMap terminalMap = - new THashMap(); - for(RouteTerminal terminal : left.getTerminals()) { - Object data = terminal.getData(); - if(data == null) - terminalsOnlyInLeft.add(terminal); - else - terminalMap.put(data, terminal); - } - for(RouteTerminal terminal : right.getTerminals()) { - Object data = terminal.getData(); - if(data == null) - terminalsOnlyInRight.add(terminal); - else { - RouteTerminal other = terminalMap.remove(data); - if(other == null) - terminalsOnlyInRight.add(terminal); - else if(!terminalsEqual(other, terminal)) - terminalsThatDiffer.add(new RouteTerminalPair(other, terminal)); - } - } - terminalsOnlyInLeft.addAll(terminalMap.values()); - } - } - - private static boolean terminalsEqual(RouteTerminal left, RouteTerminal right) { - if(left == null) - return right == null; - if(right == null) - return false; - RouteLine leftLine = left.getLine(); - RouteLine rightLine = right.getLine(); - if(leftLine == null) - return rightLine == null; - if(rightLine == null) - return false; - Object leftData = leftLine.getData(); - Object rightData = rightLine.getData(); - if(leftData == null || rightData == null) - return false; // if both lines have null data, they are still not equal - return leftData.equals(rightData); - } - - public void print() { - System.out.println("=== Delta ==="); - if(!linesOnlyInLeft.isEmpty() || !linksOnlyInLeft.isEmpty() - || !terminalsOnlyInLeft.isEmpty()) { - System.out.println("Only in the left route graph:"); - for(RouteLine line : linesOnlyInLeft) - System.out.println(" line " + line.getData()); - for(RouteLink link : linksOnlyInLeft) - System.out.println(" <" + link.getA().getData() + "," + link.getB().getData() + ">"); - for(RouteTerminal terminal : terminalsOnlyInLeft) - System.out.println(" terminal " + terminal.getData()); - } - if(!linesOnlyInRight.isEmpty() || !linksOnlyInRight.isEmpty() - || !terminalsOnlyInRight.isEmpty()) { - System.out.println("Only in the right route graph:"); - for(RouteLine line : linesOnlyInRight) - System.out.println(" line " + line.getData()); - for(RouteLink link : linksOnlyInRight) - System.out.println(" <" + link.getA().getData() + "," + link.getB().getData() + ">"); - for(RouteTerminal terminal : terminalsOnlyInRight) - System.out.println(" terminal " + terminal.getData()); - } - if(!linesThatDiffer.isEmpty() || !terminalsThatDiffer.isEmpty()) { - System.out.println("Differing:"); - for(RouteLinePair pair : linesThatDiffer) - System.out.println(" " + pair.left.getData() + " <> " + pair.right.getData()); - for(RouteTerminalPair pair : terminalsThatDiffer) - System.out.println(" " + pair.left.getData() + " (" + pair.left.getX() + "," + pair.left.getY() + ") <> " + pair.right.getData() + " (" + pair.right.getX() + "," + pair.right.getY() + ")"); - } - } - - public boolean isEmpty() { - return - linesOnlyInLeft.isEmpty() && linksOnlyInLeft.isEmpty() && terminalsOnlyInLeft.isEmpty() && - linesOnlyInRight.isEmpty() && linksOnlyInRight.isEmpty() && terminalsOnlyInRight.isEmpty() && - linesThatDiffer.isEmpty() && terminalsThatDiffer.isEmpty(); - } - -} +/******************************************************************************* + * Copyright (c) 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.diagram.connection.delta; + +import gnu.trove.map.hash.THashMap; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.diagram.connection.RouteGraph; +import org.simantics.diagram.connection.RouteLine; +import org.simantics.diagram.connection.RouteLink; +import org.simantics.diagram.connection.RoutePoint; +import org.simantics.diagram.connection.RouteTerminal; + +/** + * Calculates the delta between two route graphs. Only + * persistent lines are used in the computation. Lines, + * links and terminals are matched by their data attribute. + * If data is null, the node is not matched any node in + * the other node. Two lines differ, if they have a + * different orientation or position. Two terminals differ, + * if they are linked to different route lines ({@link RouteTerminal#getLine()}). + * @author Hannu Niemistö + */ +public class RouteGraphDelta implements Serializable { + + private static final long serialVersionUID = 5011201407852172263L; + + ArrayList linesOnlyInLeft = new ArrayList(); + ArrayList linesOnlyInRight = new ArrayList(); + ArrayList linesThatDiffer = new ArrayList(); + ArrayList linksOnlyInLeft = new ArrayList(); + ArrayList linksOnlyInRight = new ArrayList(); + ArrayList terminalsOnlyInLeft = new ArrayList(); + ArrayList terminalsOnlyInRight = new ArrayList(); + ArrayList terminalsThatDiffer = new ArrayList(); + + public static class RouteLinePair implements Serializable { + private static final long serialVersionUID = 382349562756381086L; + + public final RouteLine left; + public final RouteLine right; + + public RouteLinePair(RouteLine left, RouteLine right) { + this.left = left; + this.right = right; + } + } + + public static class RouteTerminalPair implements Serializable { + private static final long serialVersionUID = 5286896101190626944L; + + public final RouteTerminal left; + public final RouteTerminal right; + + public RouteTerminalPair(RouteTerminal left, RouteTerminal right) { + this.left = left; + this.right = right; + } + } + + public Collection getLinesOnlyInLeft() { + return linesOnlyInLeft; + } + + public Collection getLinesOnlyInRight() { + return linesOnlyInRight; + } + + public ArrayList getLinesThatDiffer() { + return linesThatDiffer; + } + + public Collection getLinksOnlyInLeft() { + return linksOnlyInLeft; + } + + public Collection getLinksOnlyInRight() { + return linksOnlyInRight; + } + + public ArrayList getTerminalsOnlyInLeft() { + return terminalsOnlyInLeft; + } + + public ArrayList getTerminalsOnlyInRight() { + return terminalsOnlyInRight; + } + + public ArrayList getTerminalsThatDiffer() { + return terminalsThatDiffer; + } + + private static class KeyPair { + final Object a; + final Object b; + + public KeyPair(Object a, Object b) { + this.a = a; + this.b = b; + } + + @Override + public int hashCode() { + return 31*a.hashCode() + b.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) + return true; + if(obj == null || obj.getClass() != KeyPair.class) + return false; + KeyPair other = (KeyPair)obj; + return a.equals(other.a) && b.equals(other.b); + } + } + + public RouteGraphDelta(RouteGraph left, RouteGraph right) { + { + THashMap lineMap = + new THashMap(); + for(RouteLine line : left.getLines()) { + Object data = line.getData(); + if(data == null) + linesOnlyInLeft.add(line); + else + lineMap.put(data, line); + } + for(RouteLine line : right.getLines()) { + Object data = line.getData(); + if(data == null) + linesOnlyInRight.add(line); + else { + RouteLine other =lineMap.remove(data); + if(other == null) + linesOnlyInRight.add(line); + else if(line.getPosition() != other.getPosition() || + line.isHorizontal() != other.isHorizontal()) + linesThatDiffer.add(new RouteLinePair(other, line)); + } + } + linesOnlyInLeft.addAll(lineMap.values()); + } + { + THashMap linkMap = + new THashMap(); + for(RouteLine a : left.getLines()) { + for(RoutePoint point : a.getPoints()) { + if(!(point instanceof RouteLink)) + continue; + RouteLink link = (RouteLink)point; + RouteLine b = link.getB(); + if(a == link.getA() && !b.isTransient()) { + Object dataA = a.getData(); + Object dataB = b.getData(); + if(dataA == null || dataB == null) + linksOnlyInLeft.add(link); + else + linkMap.put(new KeyPair(dataA, dataB), link); + } + } + } + for(RouteLine a : right.getLines()) { + for(RoutePoint point : a.getPoints()) { + if(!(point instanceof RouteLink)) + continue; + RouteLink link = (RouteLink)point; + RouteLine b = link.getB(); + if(a == link.getA() && !b.isTransient()) { + Object dataA = a.getData(); + Object dataB = b.getData(); + if(dataA == null || dataB == null + || (linkMap.remove(new KeyPair(dataA, dataB)) == null + && linkMap.remove(new KeyPair(dataB, dataA)) == null)) + linksOnlyInRight.add(link); + } + } + } + linksOnlyInLeft.addAll(linkMap.values()); + } + { + THashMap terminalMap = + new THashMap(); + for(RouteTerminal terminal : left.getTerminals()) { + Object data = terminal.getData(); + if(data == null) + terminalsOnlyInLeft.add(terminal); + else + terminalMap.put(data, terminal); + } + for(RouteTerminal terminal : right.getTerminals()) { + Object data = terminal.getData(); + if(data == null) + terminalsOnlyInRight.add(terminal); + else { + RouteTerminal other = terminalMap.remove(data); + if(other == null) + terminalsOnlyInRight.add(terminal); + else if(!terminalsEqual(other, terminal)) + terminalsThatDiffer.add(new RouteTerminalPair(other, terminal)); + } + } + terminalsOnlyInLeft.addAll(terminalMap.values()); + } + } + + private static boolean terminalsEqual(RouteTerminal left, RouteTerminal right) { + if(left == null) + return right == null; + if(right == null) + return false; + RouteLine leftLine = left.getLine(); + RouteLine rightLine = right.getLine(); + if(leftLine == null) + return rightLine == null; + if(rightLine == null) + return false; + Object leftData = leftLine.getData(); + Object rightData = rightLine.getData(); + if(leftData == null || rightData == null) + return false; // if both lines have null data, they are still not equal + return leftData.equals(rightData); + } + + public void print() { + System.out.println("=== Delta ==="); + if(!linesOnlyInLeft.isEmpty() || !linksOnlyInLeft.isEmpty() + || !terminalsOnlyInLeft.isEmpty()) { + System.out.println("Only in the left route graph:"); + for(RouteLine line : linesOnlyInLeft) + System.out.println(" line " + line.getData()); + for(RouteLink link : linksOnlyInLeft) + System.out.println(" <" + link.getA().getData() + "," + link.getB().getData() + ">"); + for(RouteTerminal terminal : terminalsOnlyInLeft) + System.out.println(" terminal " + terminal.getData()); + } + if(!linesOnlyInRight.isEmpty() || !linksOnlyInRight.isEmpty() + || !terminalsOnlyInRight.isEmpty()) { + System.out.println("Only in the right route graph:"); + for(RouteLine line : linesOnlyInRight) + System.out.println(" line " + line.getData()); + for(RouteLink link : linksOnlyInRight) + System.out.println(" <" + link.getA().getData() + "," + link.getB().getData() + ">"); + for(RouteTerminal terminal : terminalsOnlyInRight) + System.out.println(" terminal " + terminal.getData()); + } + if(!linesThatDiffer.isEmpty() || !terminalsThatDiffer.isEmpty()) { + System.out.println("Differing:"); + for(RouteLinePair pair : linesThatDiffer) + System.out.println(" " + pair.left.getData() + " <> " + pair.right.getData()); + for(RouteTerminalPair pair : terminalsThatDiffer) + System.out.println(" " + pair.left.getData() + " (" + pair.left.getX() + "," + pair.left.getY() + ") <> " + pair.right.getData() + " (" + pair.right.getX() + "," + pair.right.getY() + ")"); + } + } + + public boolean isEmpty() { + return + linesOnlyInLeft.isEmpty() && linksOnlyInLeft.isEmpty() && terminalsOnlyInLeft.isEmpty() && + linesOnlyInRight.isEmpty() && linksOnlyInRight.isEmpty() && terminalsOnlyInRight.isEmpty() && + linesThatDiffer.isEmpty() && terminalsThatDiffer.isEmpty(); + } + +}