/******************************************************************************* * Copyright (c) 2007, 2010 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.scenegraph.tests; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.ParentNode; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.IG2DNode; /** * @author Tuukka Lehtonen */ public class SceneGraphComparator { private Map aChildrenDiffer = new HashMap(); private Map bChildrenDiffer = new HashMap(); private Set> different = new HashSet>(); private INode a; private INode b; public SceneGraphComparator(INode a, INode b) { this.a = a; this.b = b; } public void analyze() { analyze(a.getParent(), a, b.getParent(), b); } public boolean equal() { return aChildrenDiffer.isEmpty() && bChildrenDiffer.isEmpty() && different.isEmpty(); } private void analyze(ParentNode pa, INode a, ParentNode pb, INode b) { if (a == b) return; if (!equals(a, b)) { different.add(Pair.make(a, b)); if (pa != null && pb != null) { aChildrenDiffer.put(pa, pb); bChildrenDiffer.put(pb, pa); } return; } if (a instanceof ParentNode) { ParentNode ppa = (ParentNode) a; ParentNode ppb = (ParentNode) b; Collection aids = ppa.getNodeIds(); Collection bids = ppb.getNodeIds(); if (!aids.equals(bids)) { aChildrenDiffer.put(ppa, ppb); bChildrenDiffer.put(ppb, ppa); } // Both nodes have an identically named set of child nodes. if (a instanceof G2DParentNode) { IG2DNode[] sac = ((G2DParentNode) a).getSortedNodes(); IG2DNode[] sbc = ((G2DParentNode) b).getSortedNodes(); for (int i = 0; i < sac.length; ++i) { analyze(ppa, sac[i], ppb, sbc[i]); } } else { for (String id : aids) { INode ac = ppa.getNode(id); INode bc = ppb.getNode(id); analyze(ppa, ac, ppb, bc); } } } } private boolean equals(INode a, INode b) { Class clazz = a.getClass(); if (!clazz.equals(b.getClass())) return false; // TODO: use reflection to compare field by field // ignore transient fields // ignore Node.id field return true; } @Override public String toString() { if (equal()) return "no differences"; StringBuilder sb = new StringBuilder(); sb.append("Differences between nodes:\n"); for (Pair p : different) { sb.append(p.first.getClass().getSimpleName()).append(p.first).append("\nvs.\n").append(p.second.getClass().getSimpleName()).append(p.second).append("\n"); } return sb.toString(); } public static void main(String[] args) { G2DSceneGraph sg1 = new G2DSceneGraph(); G2DSceneGraph sg2 = new G2DSceneGraph(); SceneGraphComparator sgc = new SceneGraphComparator(sg1, sg1); sgc.analyze(); System.out.println(sgc); sgc = new SceneGraphComparator(sg1, sg2); sgc.analyze(); System.out.println(sgc); } }