Loading tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/FeatureSpec.java 0 → 100644 +18 −0 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; public class FeatureSpec { private String name; private boolean value; public FeatureSpec(String name, boolean value) { super(); this.name = name; this.value = value; } public String getName() { return name; } public boolean getValue() { return value; } } No newline at end of file tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/ParserErrorHandler.java 0 → 100644 +39 −0 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import java.util.ArrayList; import java.util.List; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class ParserErrorHandler implements ErrorHandler { private List<SAXParseException> errors = new ArrayList<>(); private List<SAXParseException> warnings = new ArrayList<>(); @Override public void error(SAXParseException err) throws SAXException { errors.add(err); throw err; } @Override public void fatalError(SAXParseException err) throws SAXException { errors.add(err); throw err; } @Override public void warning(SAXParseException warn) throws SAXException { warnings.add(warn); } public List<SAXParseException> getErrors() { return errors; } public List<SAXParseException> getWarnings() { return warnings; } } No newline at end of file tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/XmlDiff.java +152 −2 Original line number Diff line number Diff line Loading @@ -9,12 +9,27 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.custommonkey.xmlunit.DetailedDiff; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.Difference; import org.custommonkey.xmlunit.DifferenceEngine; import org.custommonkey.xmlunit.DifferenceListener; import org.custommonkey.xmlunit.XMLUnit; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** This class implements an algorithm to compare two XML files. Loading @@ -24,7 +39,28 @@ import org.xml.sax.SAXException; * */ public class XmlDiff { public static class IgnoreSchemePrefix implements DifferenceListener { @Override public int differenceFound(Difference difference) { int id = difference.getId(); if (id == DifferenceEngine.NAMESPACE_PREFIX_ID /*|| id == DifferenceEngine.NAMESPACE_URI_ID */ ) { return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } return RETURN_ACCEPT_DIFFERENCE; } @Override public void skippedComparison(Node control, Node test) { } } protected File referenceXmlFile; private List<File> xsdFiles; private Schema schemes = null; private DocumentBuilderFactory xmlParserFactory; /** Initialize the diff engine. * Loading @@ -42,7 +78,19 @@ public class XmlDiff { this(new File(referenceXmlFile), xsdFileNames, xsdSearchPath); } public XmlDiff(File file, Object xsdFileNames, Object xsdSearchPath) { /** Initialize the diff engine. * * If {@code xsdFileNames} is <code>null</code> then the value of {@code xsdSearchPath} * is ignored. * * @param file path to the reference XML file * @param xsdFileNames optional list of XSD files relevant for the reference XML file. * May be <code>null</code>. * @param xsdSearchPath optional list of folder names and/or URIs where to look for XSD files. * May be <code>null</code>. * */ public XmlDiff(File file, String[] xsdFileNames, String[] xsdSearchPath) { this.referenceXmlFile = file; if (!this.referenceXmlFile.exists()) { throw new IllegalArgumentException("No such file: " + this.referenceXmlFile.getAbsolutePath()); Loading @@ -51,6 +99,22 @@ public class XmlDiff { throw new IllegalArgumentException("Can't read: " + this.referenceXmlFile.getAbsolutePath()); } xmlParserFactory = DocumentBuilderFactory.newInstance(); xmlParserFactory.setIgnoringComments(true); xmlParserFactory.setCoalescing(true); xmlParserFactory.setIgnoringElementContentWhitespace(true); xsdFiles = new ArrayList<File>(); List<String> missing; missing = findXsdFiles(xsdFileNames, xsdSearchPath); if (missing != null) { throw new IllegalArgumentException("Missing XSD files " + missing + " in search path " + Arrays.toString(xsdSearchPath)); } if (xsdFiles.size() > 0) { addXmlSchemas(); } } /** Compare an XML document against the reference one. Loading Loading @@ -82,11 +146,20 @@ public class XmlDiff { return diff(rd, input, diffDetails); } /*********************************************************************** * * Private methods * ***********************************************************************/ private boolean diff(Reader expected, Reader actual, StringBuilder diffDetails) throws XmlDiffError { Diff differ = null; try { differ = new Diff(expected, actual); // differ = new Diff(expected, actual); differ = createDiffer(expected, actual); } catch (SAXException e) { throw new XmlDiffError("Failed to parse XML", e); } catch (IOException e) { Loading @@ -113,4 +186,81 @@ public class XmlDiff { } return result; } private void addXmlSchemas() { SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Source[] schemaSources = new Source[xsdFiles.size()]; for (int i = 0; i < schemaSources.length; i++) { schemaSources[i] = new StreamSource(xsdFiles.get(i)); } try { schemes = schemaFactory.newSchema(schemaSources); } catch (SAXException e) { throw new IllegalArgumentException("Failed to parse a schema file", e); } if (schemes != null) { xmlParserFactory.setSchema(schemes); xmlParserFactory.setValidating(false); xmlParserFactory.setNamespaceAware(true); } } private List<String> findXsdFiles(String[] xsdFileNames, String[] xsdSearchPath) { if (xsdFileNames == null || xsdFileNames.length == 0) { return null; } List<String> missing = new ArrayList<String>(); if (xsdSearchPath == null || xsdSearchPath.length == 0) { for (String name : xsdFileNames) { File guess = new File(name); if (guess.exists()) { xsdFiles.add(guess); } else { missing.add(name); } } } else { for (String fileName : xsdFileNames) { boolean found = false; for (String path: xsdSearchPath) { File guess = new File(path, fileName); if (guess.exists()) { xsdFiles.add(guess); found = true; break; } } if (!found) { missing.add(fileName); } } } return (missing.size() > 0) ? missing : null; } private Document parseXml(Reader inReader, String kind) throws SAXException, IOException, XmlDiffError { ParserErrorHandler handler = new ParserErrorHandler(); DocumentBuilder parser; try { parser = xmlParserFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new RuntimeException("Internal error: failed to create an XML parser", e); } parser.setErrorHandler(handler); InputSource input = new InputSource(inReader); Document result = parser.parse(input); if (handler.getErrors().size() > 0) { throw new XmlDiffError("Failed to parse " + kind + ": " + handler.getErrors()); } return result; } private Diff createDiffer(Reader control, Reader test) throws SAXException, IOException, XmlDiffError { Document controlDoc = parseXml(control, "sample XML file"); Document testDoc = parseXml(test, "generated XML document"); Diff result = new Diff(controlDoc, testDoc); result.overrideDifferenceListener(new IgnoreSchemePrefix()); return result; } } tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff2.java→tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff_002.java +5 −5 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; Loading @@ -9,9 +11,7 @@ import java.io.Reader; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestDiff2 { public class TestDiff_002 { public static String FILE_base = "Pos_070401_AttributeElementDefinition_001_01_base.xml"; public static String FILE_whitespace = "Pos_070401_AttributeElementDefinition_001_02_whitespace.xml"; public static String FILE_comment = "Pos_070401_AttributeElementDefinition_001_03_comment.xml"; Loading @@ -29,7 +29,7 @@ public class TestDiff2 { @Before public void setUp() throws IOException { root = new File("xml/002"); differ = new XmlDiff(new File(root, FILE_base), null, null); differ = new XmlDiff(new File(root, FILE_base), new String[]{FILE_xsd}, new String[]{"xml/002"}); errors = new StringBuilder(); } Loading tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff3.java→tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff_003.java +26 −4 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; Loading @@ -11,8 +10,11 @@ import org.junit.Test; import static org.junit.Assert.*; public class TestDiff3 { public static String FILE_base = "Pos_07060101_extending_simple_content_001.xml"; public class TestDiff_003 { public static String XSD_FILE = "003_grammar.xsd"; public static String FILE_without_ns = "xml_without_ns.xml"; public static String FILE_with_ns = "xml_with_ns.xml"; public static String FILE_base = FILE_without_ns; public static String FILE_ttwb = "generated_ttwb.xml"; public static String FILE_tc = "generated_tc.xml"; Loading @@ -24,10 +26,20 @@ public class TestDiff3 { @Before public void setUp() throws IOException { root = new File("xml/003"); differ = new XmlDiff(new File(root, FILE_base), null, null); differ = new XmlDiff(new File(root, FILE_base), new String[]{XSD_FILE}, new String[]{"xml/003"}); errors = new StringBuilder(); } @Test public void test_self() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_base)); boolean v = differ.diff(actual, errors); assertEquals("", errors.toString()); assertTrue(v); } @Test public void test_ttwb() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_ttwb)); Loading @@ -46,4 +58,14 @@ public class TestDiff3 { assertFalse(v); assertTrue(errors.toString().contains("attribute")); } @Test public void test_nons_vs_withns() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_without_ns)); boolean v = differ.diff(actual, errors); assertEquals("", errors.toString()); assertTrue(v); } } Loading
tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/FeatureSpec.java 0 → 100644 +18 −0 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; public class FeatureSpec { private String name; private boolean value; public FeatureSpec(String name, boolean value) { super(); this.name = name; this.value = value; } public String getName() { return name; } public boolean getValue() { return value; } } No newline at end of file
tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/ParserErrorHandler.java 0 → 100644 +39 −0 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import java.util.ArrayList; import java.util.List; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class ParserErrorHandler implements ErrorHandler { private List<SAXParseException> errors = new ArrayList<>(); private List<SAXParseException> warnings = new ArrayList<>(); @Override public void error(SAXParseException err) throws SAXException { errors.add(err); throw err; } @Override public void fatalError(SAXParseException err) throws SAXException { errors.add(err); throw err; } @Override public void warning(SAXParseException warn) throws SAXException { warnings.add(warn); } public List<SAXParseException> getErrors() { return errors; } public List<SAXParseException> getWarnings() { return warnings; } } No newline at end of file
tools/XmlDiff/src/org/etsi/mts/ttcn/part9/xmldiff/XmlDiff.java +152 −2 Original line number Diff line number Diff line Loading @@ -9,12 +9,27 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.custommonkey.xmlunit.DetailedDiff; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.Difference; import org.custommonkey.xmlunit.DifferenceEngine; import org.custommonkey.xmlunit.DifferenceListener; import org.custommonkey.xmlunit.XMLUnit; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** This class implements an algorithm to compare two XML files. Loading @@ -24,7 +39,28 @@ import org.xml.sax.SAXException; * */ public class XmlDiff { public static class IgnoreSchemePrefix implements DifferenceListener { @Override public int differenceFound(Difference difference) { int id = difference.getId(); if (id == DifferenceEngine.NAMESPACE_PREFIX_ID /*|| id == DifferenceEngine.NAMESPACE_URI_ID */ ) { return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } return RETURN_ACCEPT_DIFFERENCE; } @Override public void skippedComparison(Node control, Node test) { } } protected File referenceXmlFile; private List<File> xsdFiles; private Schema schemes = null; private DocumentBuilderFactory xmlParserFactory; /** Initialize the diff engine. * Loading @@ -42,7 +78,19 @@ public class XmlDiff { this(new File(referenceXmlFile), xsdFileNames, xsdSearchPath); } public XmlDiff(File file, Object xsdFileNames, Object xsdSearchPath) { /** Initialize the diff engine. * * If {@code xsdFileNames} is <code>null</code> then the value of {@code xsdSearchPath} * is ignored. * * @param file path to the reference XML file * @param xsdFileNames optional list of XSD files relevant for the reference XML file. * May be <code>null</code>. * @param xsdSearchPath optional list of folder names and/or URIs where to look for XSD files. * May be <code>null</code>. * */ public XmlDiff(File file, String[] xsdFileNames, String[] xsdSearchPath) { this.referenceXmlFile = file; if (!this.referenceXmlFile.exists()) { throw new IllegalArgumentException("No such file: " + this.referenceXmlFile.getAbsolutePath()); Loading @@ -51,6 +99,22 @@ public class XmlDiff { throw new IllegalArgumentException("Can't read: " + this.referenceXmlFile.getAbsolutePath()); } xmlParserFactory = DocumentBuilderFactory.newInstance(); xmlParserFactory.setIgnoringComments(true); xmlParserFactory.setCoalescing(true); xmlParserFactory.setIgnoringElementContentWhitespace(true); xsdFiles = new ArrayList<File>(); List<String> missing; missing = findXsdFiles(xsdFileNames, xsdSearchPath); if (missing != null) { throw new IllegalArgumentException("Missing XSD files " + missing + " in search path " + Arrays.toString(xsdSearchPath)); } if (xsdFiles.size() > 0) { addXmlSchemas(); } } /** Compare an XML document against the reference one. Loading Loading @@ -82,11 +146,20 @@ public class XmlDiff { return diff(rd, input, diffDetails); } /*********************************************************************** * * Private methods * ***********************************************************************/ private boolean diff(Reader expected, Reader actual, StringBuilder diffDetails) throws XmlDiffError { Diff differ = null; try { differ = new Diff(expected, actual); // differ = new Diff(expected, actual); differ = createDiffer(expected, actual); } catch (SAXException e) { throw new XmlDiffError("Failed to parse XML", e); } catch (IOException e) { Loading @@ -113,4 +186,81 @@ public class XmlDiff { } return result; } private void addXmlSchemas() { SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Source[] schemaSources = new Source[xsdFiles.size()]; for (int i = 0; i < schemaSources.length; i++) { schemaSources[i] = new StreamSource(xsdFiles.get(i)); } try { schemes = schemaFactory.newSchema(schemaSources); } catch (SAXException e) { throw new IllegalArgumentException("Failed to parse a schema file", e); } if (schemes != null) { xmlParserFactory.setSchema(schemes); xmlParserFactory.setValidating(false); xmlParserFactory.setNamespaceAware(true); } } private List<String> findXsdFiles(String[] xsdFileNames, String[] xsdSearchPath) { if (xsdFileNames == null || xsdFileNames.length == 0) { return null; } List<String> missing = new ArrayList<String>(); if (xsdSearchPath == null || xsdSearchPath.length == 0) { for (String name : xsdFileNames) { File guess = new File(name); if (guess.exists()) { xsdFiles.add(guess); } else { missing.add(name); } } } else { for (String fileName : xsdFileNames) { boolean found = false; for (String path: xsdSearchPath) { File guess = new File(path, fileName); if (guess.exists()) { xsdFiles.add(guess); found = true; break; } } if (!found) { missing.add(fileName); } } } return (missing.size() > 0) ? missing : null; } private Document parseXml(Reader inReader, String kind) throws SAXException, IOException, XmlDiffError { ParserErrorHandler handler = new ParserErrorHandler(); DocumentBuilder parser; try { parser = xmlParserFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new RuntimeException("Internal error: failed to create an XML parser", e); } parser.setErrorHandler(handler); InputSource input = new InputSource(inReader); Document result = parser.parse(input); if (handler.getErrors().size() > 0) { throw new XmlDiffError("Failed to parse " + kind + ": " + handler.getErrors()); } return result; } private Diff createDiffer(Reader control, Reader test) throws SAXException, IOException, XmlDiffError { Document controlDoc = parseXml(control, "sample XML file"); Document testDoc = parseXml(test, "generated XML document"); Diff result = new Diff(controlDoc, testDoc); result.overrideDifferenceListener(new IgnoreSchemePrefix()); return result; } }
tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff2.java→tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff_002.java +5 −5 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; Loading @@ -9,9 +11,7 @@ import java.io.Reader; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestDiff2 { public class TestDiff_002 { public static String FILE_base = "Pos_070401_AttributeElementDefinition_001_01_base.xml"; public static String FILE_whitespace = "Pos_070401_AttributeElementDefinition_001_02_whitespace.xml"; public static String FILE_comment = "Pos_070401_AttributeElementDefinition_001_03_comment.xml"; Loading @@ -29,7 +29,7 @@ public class TestDiff2 { @Before public void setUp() throws IOException { root = new File("xml/002"); differ = new XmlDiff(new File(root, FILE_base), null, null); differ = new XmlDiff(new File(root, FILE_base), new String[]{FILE_xsd}, new String[]{"xml/002"}); errors = new StringBuilder(); } Loading
tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff3.java→tools/XmlDiff/tests/org/etsi/mts/ttcn/part9/xmldiff/TestDiff_003.java +26 −4 Original line number Diff line number Diff line package org.etsi.mts.ttcn.part9.xmldiff; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; Loading @@ -11,8 +10,11 @@ import org.junit.Test; import static org.junit.Assert.*; public class TestDiff3 { public static String FILE_base = "Pos_07060101_extending_simple_content_001.xml"; public class TestDiff_003 { public static String XSD_FILE = "003_grammar.xsd"; public static String FILE_without_ns = "xml_without_ns.xml"; public static String FILE_with_ns = "xml_with_ns.xml"; public static String FILE_base = FILE_without_ns; public static String FILE_ttwb = "generated_ttwb.xml"; public static String FILE_tc = "generated_tc.xml"; Loading @@ -24,10 +26,20 @@ public class TestDiff3 { @Before public void setUp() throws IOException { root = new File("xml/003"); differ = new XmlDiff(new File(root, FILE_base), null, null); differ = new XmlDiff(new File(root, FILE_base), new String[]{XSD_FILE}, new String[]{"xml/003"}); errors = new StringBuilder(); } @Test public void test_self() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_base)); boolean v = differ.diff(actual, errors); assertEquals("", errors.toString()); assertTrue(v); } @Test public void test_ttwb() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_ttwb)); Loading @@ -46,4 +58,14 @@ public class TestDiff3 { assertFalse(v); assertTrue(errors.toString().contains("attribute")); } @Test public void test_nons_vs_withns() throws IOException, XmlDiffError { actual = new FileReader(new File(root, FILE_without_ns)); boolean v = differ.diff(actual, errors); assertEquals("", errors.toString()); assertTrue(v); } }