1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.tests;
\r
14 import java.util.Collection;
\r
15 import java.util.HashMap;
\r
16 import java.util.HashSet;
\r
17 import java.util.Map;
\r
18 import java.util.Set;
\r
20 import org.simantics.scenegraph.INode;
\r
21 import org.simantics.scenegraph.ParentNode;
\r
22 import org.simantics.scenegraph.g2d.G2DParentNode;
\r
23 import org.simantics.scenegraph.g2d.G2DSceneGraph;
\r
24 import org.simantics.scenegraph.g2d.IG2DNode;
\r
27 * @author Tuukka Lehtonen
\r
29 public class SceneGraphComparator {
\r
31 private Map<INode, INode> aChildrenDiffer = new HashMap<INode, INode>();
\r
32 private Map<INode, INode> bChildrenDiffer = new HashMap<INode, INode>();
\r
33 private Set<Pair<INode, INode>> different = new HashSet<Pair<INode, INode>>();
\r
38 public SceneGraphComparator(INode a, INode b) {
\r
43 public void analyze() {
\r
44 analyze(a.getParent(), a, b.getParent(), b);
\r
47 public boolean equal() {
\r
48 return aChildrenDiffer.isEmpty() && bChildrenDiffer.isEmpty() && different.isEmpty();
\r
51 private void analyze(ParentNode<?> pa, INode a, ParentNode<?> pb, INode b) {
\r
54 if (!equals(a, b)) {
\r
55 different.add(Pair.<INode, INode>make(a, b));
\r
56 if (pa != null && pb != null) {
\r
57 aChildrenDiffer.put(pa, pb);
\r
58 bChildrenDiffer.put(pb, pa);
\r
62 if (a instanceof ParentNode<?>) {
\r
63 ParentNode<?> ppa = (ParentNode<?>) a;
\r
64 ParentNode<?> ppb = (ParentNode<?>) b;
\r
66 Collection<String> aids = ppa.getNodeIds();
\r
67 Collection<String> bids = ppb.getNodeIds();
\r
68 if (!aids.equals(bids)) {
\r
69 aChildrenDiffer.put(ppa, ppb);
\r
70 bChildrenDiffer.put(ppb, ppa);
\r
73 // Both nodes have an identically named set of child nodes.
\r
74 if (a instanceof G2DParentNode) {
\r
75 IG2DNode[] sac = ((G2DParentNode) a).getSortedNodes();
\r
76 IG2DNode[] sbc = ((G2DParentNode) b).getSortedNodes();
\r
77 for (int i = 0; i < sac.length; ++i) {
\r
78 analyze(ppa, sac[i], ppb, sbc[i]);
\r
81 for (String id : aids) {
\r
82 INode ac = ppa.getNode(id);
\r
83 INode bc = ppb.getNode(id);
\r
84 analyze(ppa, ac, ppb, bc);
\r
90 private boolean equals(INode a, INode b) {
\r
91 Class<?> clazz = a.getClass();
\r
92 if (!clazz.equals(b.getClass()))
\r
95 // TODO: use reflection to compare field by field
\r
96 // ignore transient fields
\r
97 // ignore Node.id field
\r
103 public String toString() {
\r
105 return "no differences";
\r
106 StringBuilder sb = new StringBuilder();
\r
107 sb.append("Differences between nodes:\n");
\r
108 for (Pair<INode, INode> p : different) {
\r
109 sb.append(p.first.getClass().getSimpleName()).append(p.first).append("\nvs.\n").append(p.second.getClass().getSimpleName()).append(p.second).append("\n");
\r
111 return sb.toString();
\r
114 public static void main(String[] args) {
\r
115 G2DSceneGraph sg1 = new G2DSceneGraph();
\r
116 G2DSceneGraph sg2 = new G2DSceneGraph();
\r
118 SceneGraphComparator sgc = new SceneGraphComparator(sg1, sg1);
\r
120 System.out.println(sgc);
\r
121 sgc = new SceneGraphComparator(sg1, sg2);
\r
123 System.out.println(sgc);
\r