| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // 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: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.tester; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Stack; |
| |
| import org.eclipse.epf.common.utils.XMLUtil; |
| import org.eclipse.epf.library.tester.iface.TestTracer; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| /** |
| * Class to analyze the differneces between two library tester outputs |
| * |
| * @author Weiping Lu |
| * @since 1.0 |
| * |
| */ |
| public class OutputDiffAnalyzor { |
| |
| private boolean localDebug = false; |
| private TestTracer tracer; |
| private boolean needToAnalyze = true; |
| private File f1; |
| private File f2; |
| private Document d1; |
| private Document d2; |
| private int diffCount = 0; |
| private int elemComparedCount = 0; |
| |
| private static boolean excludeGuidFromName = true; |
| //May want to use feature classes directly instead of names later |
| private static String[] excludedFeatures = { |
| "guid", |
| "changeDate" |
| }; |
| |
| private static Set excludedFeatureSet = new HashSet(); |
| |
| static { |
| for (int i=0; i<excludedFeatures.length; i++) { |
| excludedFeatureSet.add(excludedFeatures[i]); |
| } |
| } |
| |
| public OutputDiffAnalyzor(TestTracer t, Document d1, Document d2, File f1, File f2) { |
| tracer = t; |
| this.f1 = f1; |
| this.f2 = f2; |
| this.d1 = d1 == null ? getDocument(f1) : d1; |
| this.d2 = d2 == null ? getDocument(f2) : d2; |
| } |
| |
| private Document getDocument(File file) { |
| if (file.exists()) { |
| try { |
| return XMLUtil.loadXml(file); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| return null; |
| } |
| |
| private void trace(String line) { |
| tracer.trace(line); |
| } |
| |
| private void analyze() { |
| trace("OutputDiffAnalyzor.analyze ->"); |
| trace("f1: " + f1.getAbsolutePath()); |
| trace("f2: " + f2.getAbsolutePath()); |
| trace(""); |
| analyze_(); |
| trace("OutputDiffAnalyzor.analyze <-"); |
| } |
| |
| private void analyze_() { |
| if (! needToAnalyze) { |
| trace("no need to analyse"); |
| return; |
| } |
| compareRoot(d1.getDocumentElement(), d2.getDocumentElement()); |
| needToAnalyze = false; |
| } |
| |
| // Top entry for method element comparison |
| public void compareRoot(Element root1, Element root2) { |
| diffCount = 0; |
| elemComparedCount = 1; |
| trace(""); |
| trace("compareRoot -> "); |
| |
| List elementList1 = collectElements(root1.getChildNodes()); |
| List elementList2 = collectElements(root2.getChildNodes()); |
| int sz1 = elementList1.size(); |
| int sz2 = elementList2.size(); |
| |
| if (sz1 != sz2) { |
| String msg = "root child elements: sz1 != sz2 -> " + Integer.toString(sz1) + " != " + Integer.toString(sz2); |
| logDiff(msg, root1, root2); |
| } |
| |
| int sz = sz1 < sz2 ? sz1 : sz2; |
| for (int i=0; i<sz; i++) { |
| compare((Element) elementList1.get(i), (Element) elementList2.get(i)); |
| } |
| |
| trace("compareRoot <- diffs: " + diffCount + ", elements: " + elemComparedCount + "\n"); |
| } |
| |
| private List collectElements(NodeList nodeList) { |
| List elements = new ArrayList(); |
| for (int i=0; i<nodeList.getLength(); i++) { |
| Node node = nodeList.item(i); |
| if (node instanceof Element) { |
| elements.add(node); |
| } |
| } |
| return elements; |
| } |
| |
| private void compare(Element node1, Element node2) { |
| trace("compare -> "); |
| compareInner(node1, node2); |
| trace("compare <- "); |
| } |
| |
| private void compareInner(Element node1, Element node2) { |
| elemComparedCount++; |
| if (localDebug) { |
| trace("compareInner, node1: " + outputString(node1)); |
| trace("compareInner, node2: " + outputString(node1)); |
| trace(""); |
| } |
| |
| attributeEquals(node1, node2); |
| |
| List elementList1 = collectElements(node1.getChildNodes()); |
| List elementList2 = collectElements(node2.getChildNodes()); |
| int sz1 = elementList1.size(); |
| int sz2 = elementList2.size(); |
| |
| if (sz1 != sz2) { |
| String msg = "Child elements: sz1 != sz2 -> " + Integer.toString(sz1) + " != " + Integer.toString(sz2); |
| logDiff(msg, node1, node2); |
| } |
| |
| int sz = sz1 < sz2 ? sz1 : sz2; |
| for (int i=0; i<sz; i++) { |
| compareInner((Element) elementList1.get(i), (Element) elementList2.get(i)); |
| } |
| } |
| |
| private boolean attributeEquals(Element node1, Element node2) { |
| boolean ret = true; |
| |
| NamedNodeMap atts1 = node1.getAttributes(); |
| NamedNodeMap atts2 = node2.getAttributes(); |
| int sz1 = atts1.getLength(); |
| int sz2 = atts2.getLength(); |
| if (sz1 != sz2) { |
| logDiff("Attributes: sz1 != sz2", node1, node2); |
| ret = false; |
| } |
| int sz = sz1 < sz2 ? sz1 : sz2; |
| for (int i=0; i<sz; i++) { |
| String attName = atts1.item(i).getNodeName(); |
| if (excludedFeatureSet.contains(attName)) { |
| continue; |
| } |
| String val1 = node1.getAttribute(attName); |
| String val2 = node2.getAttribute(attName); |
| if (attName.equals("name") && excludeGuidFromName) { |
| int ix = val1.indexOf(","); |
| if (ix > 0) { |
| val1 = val1.substring(0, ix); |
| } |
| ix = val2.indexOf(","); |
| if (ix > 0) { |
| val2 = val2.substring(0, ix); |
| } |
| } |
| if (! valueEquals(val1, val2)) { |
| String msg = attName + " values not the same!"; |
| logDiff(msg, node1, node2, val1, val2); |
| } |
| } |
| |
| return ret; |
| } |
| |
| private boolean valueEquals(Object val1, Object val2) { |
| if (val1 == null) { |
| val1 = ""; |
| } |
| |
| if (val2 == null) { |
| val2 = ""; |
| } |
| |
| if (val1 instanceof String) { |
| String str1 = (String) val1; |
| String str2 = (String) val2; |
| return str1.equals(str2); |
| } |
| |
| return false; |
| } |
| |
| |
| private void logDiff(String msg, Element node1, Element node2, Object val1, Object val2) { |
| log(msg, node1, node2, true); |
| String prompt = getDiffPrompt(); |
| trace(prompt + "val1: " + val1); |
| trace(prompt + "val2: " + val2); |
| trace(""); |
| } |
| |
| private int incDiffCount() { |
| return ++diffCount; |
| } |
| |
| private String getDiffPrompt() { |
| return "D_" + diffCount + "> "; |
| } |
| |
| private void logDiff(String msg, Element node1, Element node2) { |
| log(msg, node1, node2, true); |
| trace(""); |
| } |
| |
| private void log(String msg, Element node1, Element node2, boolean diff) { |
| if (diff) { |
| incDiffCount(); |
| } |
| String prompt = diff ? getDiffPrompt() : "Warning> "; |
| //trace(prompt + "path: " + pathString(node1)); |
| trace(prompt + "msg: " + msg); |
| trace(prompt + "node1: " + outputString(node1)); |
| trace(prompt + "node2: " + outputString(node2)); |
| } |
| |
| private String pathString(Element node) { |
| Stack paths = new Stack(); |
| Node currNode = node; |
| while (currNode != null && currNode instanceof Element) { |
| String name = ((Element) currNode).getAttribute("name"); |
| paths.push(name); |
| currNode = currNode.getParentNode(); |
| } |
| String ret = ""; |
| while(! paths.isEmpty()) { |
| ret += "/" + paths.pop(); |
| } |
| return ret; |
| } |
| |
| public boolean compare() { |
| analyze(); |
| return true; |
| } |
| |
| private String outputString(Element node) { |
| if (node == null) { |
| return null; |
| } |
| String type = node.getAttribute("type"); |
| return type + ": " + pathString(node); |
| } |
| |
| public int getDiffCount() { |
| return diffCount; |
| } |
| |
| public int getElemComparedCount() { |
| return elemComparedCount; |
| } |
| |
| |
| } |