You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2015/06/07 01:18:38 UTC

svn commit: r1683967 [2/3] - in /webservices/axiom/trunk: ./ axiom-api/ axiom-api/src/test/java/org/apache/axiom/om/ axiom-api/src/test/java/org/apache/axiom/om/impl/serialize/ axiom-compat/ axiom-compat/src/test/java/org/apache/axiom/om/impl/jaxp/ imp...

Added: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomTraverser.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomTraverser.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomTraverser.java (added)
+++ webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomTraverser.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMComment;
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMDocType;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMEntityReference;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMProcessingInstruction;
+import org.apache.axiom.om.OMText;
+import org.apache.axiom.truth.xml.Event;
+import org.apache.axiom.truth.xml.Traverser;
+import org.apache.axiom.truth.xml.TraverserException;
+
+final class AxiomTraverser implements Traverser {
+    private final OMContainer root;
+    private final boolean expandEntityReferences;
+    private OMNode node;
+    private boolean visited;
+
+    AxiomTraverser(OMContainer root, boolean expandEntityReferences) {
+        this.root = root;
+        this.expandEntityReferences = expandEntityReferences;
+    }
+
+    @Override
+    public Event next() throws TraverserException {
+        if (node == null) {
+            if (root instanceof OMDocument) {
+                node = ((OMDocument)root).getFirstOMChild();
+            } else {
+                node = (OMElement)root;
+            }
+        } else if (!visited && node instanceof OMElement) {
+            OMNode firstChild = ((OMElement)node).getFirstOMChild();
+            if (firstChild != null) {
+                node = firstChild;
+            } else {
+                visited = true;
+            }
+        } else {
+            OMNode nextSibling = node.getNextOMSibling();
+            if (node == root) {
+                return null;
+            } else if (nextSibling != null) {
+                node = nextSibling;
+                visited = false;
+            } else {
+                OMContainer parent = node.getParent();
+                if (parent instanceof OMDocument) {
+                    return null;
+                } else {
+                    node = (OMElement)parent;
+                    visited = true;
+                }
+            }
+        }
+        switch (node.getType()) {
+            case OMNode.DTD_NODE:
+                return Event.DOCUMENT_TYPE;
+            case OMNode.ELEMENT_NODE:
+                return visited ? Event.END_ELEMENT : Event.START_ELEMENT;
+            case OMNode.TEXT_NODE:
+                return Event.TEXT;
+            case OMNode.SPACE_NODE:
+                return Event.WHITESPACE;
+            case OMNode.ENTITY_REFERENCE_NODE:
+                if (expandEntityReferences) {
+                    throw new UnsupportedOperationException();
+                } else {
+                    return Event.ENTITY_REFERENCE;
+                }
+            case OMNode.COMMENT_NODE:
+                return Event.COMMENT;
+            case OMNode.CDATA_SECTION_NODE:
+                return Event.CDATA_SECTION;
+            case OMNode.PI_NODE:
+                return Event.PROCESSING_INSTRUCTION;
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public String getRootName() {
+        return ((OMDocType)node).getRootName();
+    }
+
+    @Override
+    public String getPublicId() {
+        return ((OMDocType)node).getPublicId();
+    }
+
+    @Override
+    public String getSystemId() {
+        return ((OMDocType)node).getSystemId();
+    }
+
+    @Override
+    public QName getQName() {
+        return ((OMElement)node).getQName();
+    }
+
+    @Override
+    public Map<QName,String> getAttributes() {
+        Map<QName,String> attributes = null;
+        for (Iterator it = ((OMElement)node).getAllAttributes(); it.hasNext(); ) {
+            OMAttribute attr = (OMAttribute)it.next();
+            if (attributes == null) {
+                attributes = new HashMap<QName,String>();
+            }
+            attributes.put(attr.getQName(), attr.getAttributeValue());
+        }
+        return attributes;
+    }
+
+    @Override
+    public Map<String, String> getNamespaces() {
+        Map<String,String> namespaces = null;
+        for (Iterator it = ((OMElement)node).getAllDeclaredNamespaces(); it.hasNext(); ) {
+            OMNamespace ns = (OMNamespace)it.next();
+            if (namespaces == null) {
+                namespaces = new HashMap<String,String>();
+            }
+            namespaces.put(ns.getPrefix(), ns.getNamespaceURI());
+        }
+        return namespaces;
+    }
+
+    @Override
+    public String getText() {
+        switch (node.getType()) {
+            case OMNode.TEXT_NODE:
+            case OMNode.SPACE_NODE:
+            case OMNode.CDATA_SECTION_NODE:
+                return ((OMText)node).getText();
+            case OMNode.COMMENT_NODE:
+                return ((OMComment)node).getValue();
+            default:
+                throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public String getEntityName() {
+        return ((OMEntityReference)node).getName();
+    }
+
+    @Override
+    public String getPITarget() {
+        return ((OMProcessingInstruction)node).getTarget();
+    }
+
+    @Override
+    public String getPIData() {
+        return ((OMProcessingInstruction)node).getValue();
+    }
+}

Propchange: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomTraverser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXML.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXML.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXML.java (added)
+++ webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXML.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.truth.xml.Traverser;
+import org.apache.axiom.truth.xml.XML;
+
+final class AxiomXML implements XML {
+    private final OMContainer root;
+
+    AxiomXML(OMContainer root) {
+        this.root = root;
+    }
+
+    @Override
+    public Traverser createTraverser(boolean expandEntityReferences) {
+        return new AxiomTraverser(root, expandEntityReferences);
+    }
+}

Propchange: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXML.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXMLFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXMLFactory.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXMLFactory.java (added)
+++ webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXMLFactory.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.truth.xml.XML;
+import org.apache.axiom.truth.xml.XMLFactory;
+
+public class AxiomXMLFactory implements XMLFactory<OMContainer> {
+    @Override
+    public Class<OMContainer> getExpectedType() {
+        return OMContainer.class;
+    }
+
+    @Override
+    public XML createXML(OMContainer root) {
+        return new AxiomXML(root);
+    }
+}

Propchange: webservices/axiom/trunk/testing/axiom-truth/src/main/java/org/apache/axiom/truth/AxiomXMLFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/axiom-truth/src/main/resources/META-INF/services/org.apache.axiom.truth.xml.XMLFactory
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-truth/src/main/resources/META-INF/services/org.apache.axiom.truth.xml.XMLFactory?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/axiom-truth/src/main/resources/META-INF/services/org.apache.axiom.truth.xml.XMLFactory (added)
+++ webservices/axiom/trunk/testing/axiom-truth/src/main/resources/META-INF/services/org.apache.axiom.truth.xml.XMLFactory Sat Jun  6 23:18:36 2015
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.axiom.truth.AxiomXMLFactory

Modified: webservices/axiom/trunk/testing/dom-testsuite/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/pom.xml?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/pom.xml (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/pom.xml Sat Jun  6 23:18:36 2015
@@ -40,8 +40,9 @@
             <artifactId>junit</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.google.truth</groupId>
-            <artifactId>truth</artifactId>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>xml-truth</artifactId>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
@@ -70,10 +71,6 @@
             <artifactId>saxon-dom</artifactId>
         </dependency>
         <dependency>
-            <groupId>xmlunit</groupId>
-            <artifactId>xmlunit</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.aspectj</groupId>
             <artifactId>aspectjrt</artifactId>
         </dependency>

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java Sat Jun  6 23:18:36 2015
@@ -18,12 +18,13 @@
  */
 package org.apache.axiom.ts.dom.document;
 
+import static com.google.common.truth.Truth.assertAbout;
+import static org.apache.axiom.truth.xml.XMLTruth.xml;
+
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.axiom.ts.dom.DOMTestCase;
 import org.apache.axiom.ts.xml.XMLSample;
-import org.custommonkey.xmlunit.XMLAssert;
-import org.custommonkey.xmlunit.XMLUnit;
 import org.w3c.dom.Document;
 
 public class TestCloneNode extends DOMTestCase {
@@ -38,6 +39,9 @@ public class TestCloneNode extends DOMTe
     protected void runTest() throws Throwable {
         Document document = dbf.newDocumentBuilder().parse(file.getUrl().toString());
         Document document2 = (Document)document.cloneNode(true);
-        XMLAssert.assertXMLIdentical(XMLUnit.compareXML(document, document2), true);
+        assertAbout(xml())
+                .that(xml(document2))
+                .treatingElementContentWhitespaceAsText()
+                .hasSameContentAs(xml(document));
     }
 }

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java Sat Jun  6 23:18:36 2015
@@ -18,6 +18,9 @@
  */
 package org.apache.axiom.ts.dom.document;
 
+import static com.google.common.truth.Truth.assertAbout;
+import static org.apache.axiom.truth.xml.XMLTruth.xml;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.Transformer;
@@ -25,8 +28,6 @@ import javax.xml.transform.dom.DOMResult
 import javax.xml.transform.dom.DOMSource;
 
 import org.apache.axiom.testutils.suite.XSLTImplementation;
-import org.custommonkey.xmlunit.XMLAssert;
-import org.custommonkey.xmlunit.XMLUnit;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -41,7 +42,7 @@ public class TestTransformerWithIdentity
         DocumentBuilder builder = dbf.newDocumentBuilder();
         
         Document document = builder.newDocument();
-        Element root = document.createElement("root");
+        Element root = document.createElementNS("", "root");
         Element element = document.createElementNS("urn:mynamespace", "element1");
         element.setAttribute("att", "testValue");
         element.appendChild(document.createTextNode("test"));
@@ -53,6 +54,9 @@ public class TestTransformerWithIdentity
         Document output = builder.newDocument();
         Transformer transformer = xsltImplementation.newTransformerFactory().newTransformer(new DOMSource(stylesheet));
         transformer.transform(new DOMSource(document), new DOMResult(output));
-        XMLAssert.assertXMLIdentical(XMLUnit.compareXML(document, output), true);
+        assertAbout(xml())
+                .that(xml(output))
+                .ignoringNamespaceDeclarations()
+                .hasSameContentAs(xml(document));
     }
 }

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java Sat Jun  6 23:18:36 2015
@@ -18,6 +18,9 @@
  */
 package org.apache.axiom.ts.dom.document;
 
+import static com.google.common.truth.Truth.assertAbout;
+import static org.apache.axiom.truth.xml.XMLTruth.xml;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.Transformer;
@@ -25,8 +28,6 @@ import javax.xml.transform.dom.DOMResult
 import javax.xml.transform.dom.DOMSource;
 
 import org.apache.axiom.testutils.suite.XSLTImplementation;
-import org.custommonkey.xmlunit.XMLAssert;
-import org.custommonkey.xmlunit.XMLUnit;
 import org.w3c.dom.Document;
 
 public class TestTransformerWithStylesheet extends TransformerTestCase {
@@ -43,12 +44,9 @@ public class TestTransformerWithStyleshe
         Document actual = builder.newDocument();
         Transformer transformer = xsltImplementation.newTransformerFactory().newTransformer(new DOMSource(stylesheet));
         transformer.transform(new DOMSource(input), new DOMResult(actual));
-        boolean oldIgnoreWhitespace = XMLUnit.getIgnoreWhitespace();
-        XMLUnit.setIgnoreWhitespace(true);
-        try {
-            XMLAssert.assertXMLEqual(expected, actual);
-        } finally {
-            XMLUnit.setIgnoreWhitespace(oldIgnoreWhitespace);
-        }
+        assertAbout(xml())
+                .that(xml(actual))
+                .ignoringWhitespace()
+                .hasSameContentAs(xml(expected));
     }
 }

Modified: webservices/axiom/trunk/testing/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/pom.xml?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/pom.xml (original)
+++ webservices/axiom/trunk/testing/pom.xml Sat Jun  6 23:18:36 2015
@@ -43,6 +43,7 @@
         <module>spring-ws-testsuite</module>
         <module>testutils</module>
         <module>xml-testsuite</module>
+        <module>xml-truth</module>
     </modules>
 
     <build>

Modified: webservices/axiom/trunk/testing/testutils/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/testutils/pom.xml?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/testutils/pom.xml (original)
+++ webservices/axiom/trunk/testing/testutils/pom.xml Sat Jun  6 23:18:36 2015
@@ -56,17 +56,6 @@
             <artifactId>truth</artifactId>
         </dependency>
         <dependency>
-            <groupId>xmlunit</groupId>
-            <artifactId>xmlunit</artifactId>
-        </dependency>
-        <dependency>
-            <!-- This should not be necessary, but XMLAssertEx contains code that fails on some Java runtimes,
-                 presumably because of a bug in the DOM implementation. Therefore we use a well defined
-                 version of Xerces. -->
-            <groupId>xerces</groupId>
-            <artifactId>xercesImpl</artifactId>
-        </dependency>
-        <dependency>
             <!-- We use this only for LDAP like filters -->
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>

Modified: webservices/axiom/trunk/testing/xml-testsuite/src/main/java/org/apache/axiom/ts/xml/XMLSample.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-testsuite/src/main/java/org/apache/axiom/ts/xml/XMLSample.java?rev=1683967&r1=1683966&r2=1683967&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/xml-testsuite/src/main/java/org/apache/axiom/ts/xml/XMLSample.java (original)
+++ webservices/axiom/trunk/testing/xml-testsuite/src/main/java/org/apache/axiom/ts/xml/XMLSample.java Sat Jun  6 23:18:36 2015
@@ -20,11 +20,17 @@ package org.apache.axiom.ts.xml;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import org.apache.axiom.testing.multiton.Instances;
+import org.w3c.dom.Document;
 
 public class XMLSample extends MessageSample {
     /**
@@ -37,6 +43,20 @@ public class XMLSample extends MessageSa
      */
     public static final XMLSample LARGE = new XMLSample("large.xml");
     
+    public static final XMLSample ENTITY_REFERENCE_NESTED = new XMLSample("entity-reference-nested.xml");
+    
+    private static final DocumentBuilder documentBuilder;
+    
+    static {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        try {
+            documentBuilder = factory.newDocumentBuilder();
+        } catch (ParserConfigurationException ex) {
+            throw new Error(ex);
+        }
+    }
+    
     private final String name;
     private XMLSampleProperties properties;
     
@@ -87,6 +107,19 @@ public class XMLSample extends MessageSa
         return getProperties().hasEntityReferences();
     }
 
+    public final Document getDocument() {
+        try {
+            InputStream in = getInputStream();
+            try {
+                return documentBuilder.parse(in);
+            } finally {
+                in.close();
+            }
+        } catch (Exception ex) {
+            throw new Error(ex);
+        }
+    }
+    
     @Instances
     private static XMLSample[] instances() throws IOException {
         BufferedReader in = new BufferedReader(new InputStreamReader(

Propchange: webservices/axiom/trunk/testing/xml-truth/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sat Jun  6 23:18:36 2015
@@ -0,0 +1,4 @@
+.project
+.settings
+.classpath
+target

Added: webservices/axiom/trunk/testing/xml-truth/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/pom.xml?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/pom.xml (added)
+++ webservices/axiom/trunk/testing/xml-truth/pom.xml Sat Jun  6 23:18:36 2015
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements. See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership. The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License. You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ws.commons.axiom</groupId>
+        <artifactId>testing</artifactId>
+        <version>1.2.15-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>xml-truth</artifactId>
+
+    <name>Google Truth extension for XML</name>
+    <url>http://ws.apache.org/axiom/</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.truth</groupId>
+            <artifactId>truth</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.woodstox</groupId>
+            <artifactId>woodstox-core-asl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>xml-testsuite</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>xerces</groupId>
+            <artifactId>xercesImpl</artifactId>
+        </dependency>
+    </dependencies>
+</project>

Propchange: webservices/axiom/trunk/testing/xml-truth/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/CoalescingFilter.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/CoalescingFilter.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/CoalescingFilter.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/CoalescingFilter.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+final class CoalescingFilter extends Filter {
+    private Event savedEvent;
+    private String savedText;
+    
+    CoalescingFilter(Traverser parent) {
+        super(parent);
+    }
+
+    @Override
+    public Event next() throws TraverserException {
+        savedText = null;
+        if (savedEvent != null) {
+            Event event = savedEvent;
+            savedEvent = null;
+            return event;
+        } else {
+            Event event = super.next();
+            if (event == Event.TEXT || event == Event.WHITESPACE) {
+                String text = super.getText();
+                StringBuilder buffer = null;
+                Event nextEvent;
+                while ((nextEvent = super.next()) == event) {
+                    if (buffer == null) {
+                        buffer = new StringBuilder(text);
+                    }
+                    buffer.append(super.getText());
+                }
+                savedEvent = nextEvent;
+                savedText = buffer == null ? text : buffer.toString();
+            }
+            return event;
+        }
+    }
+
+    @Override
+    public String getText() {
+        return savedText != null ? savedText : super.getText();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/CoalescingFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMTraverser.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMTraverser.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMTraverser.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMTraverser.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+import com.google.common.base.Strings;
+
+final class DOMTraverser implements Traverser {
+    private final Node root;
+    private final boolean expandEntityReferences;
+    private Node node;
+    private boolean descend;
+    
+    DOMTraverser(Node root, boolean expandEntityReferences) {
+        this.root = root;
+        this.expandEntityReferences = expandEntityReferences;
+        if (root.getNodeType() == Node.DOCUMENT_NODE) {
+            node = root;
+            descend = true;
+        }
+    }
+
+    @Override
+    public Event next() {
+        while (true) {
+            boolean visited;
+            if (node == null) {
+                node = root;
+                visited = false;
+            } else if (descend) {
+                Node firstChild = node.getFirstChild();
+                if (firstChild != null) {
+                    node = firstChild;
+                    visited = false;
+                } else {
+                    visited = true;
+                }
+            } else {
+                Node nextSibling = node.getNextSibling();
+                if (node == root) {
+                    return null;
+                } else if (nextSibling != null) {
+                    node = nextSibling;
+                    visited = false;
+                } else {
+                    node = node.getParentNode();
+                    visited = true;
+                }
+            }
+            switch (node.getNodeType()) {
+                case Node.DOCUMENT_NODE:
+                    return null;
+                case Node.DOCUMENT_TYPE_NODE:
+                    descend = false;
+                    return Event.DOCUMENT_TYPE;
+                case Node.ELEMENT_NODE:
+                    if (!visited) {
+                        descend = true;
+                        return Event.START_ELEMENT;
+                    } else {
+                        descend = false;
+                        return Event.END_ELEMENT;
+                    }
+                case Node.TEXT_NODE:
+                    descend = false;
+                    return ((Text)node).isElementContentWhitespace() ? Event.WHITESPACE : Event.TEXT;
+                case Node.ENTITY_REFERENCE_NODE:
+                    if (expandEntityReferences) {
+                        descend = !visited;
+                        break;
+                    } else {
+                        descend = false;
+                        return Event.ENTITY_REFERENCE;
+                    }
+                case Node.COMMENT_NODE:
+                    descend = false;
+                    return Event.COMMENT;
+                case Node.CDATA_SECTION_NODE:
+                    descend = false;
+                    return Event.CDATA_SECTION;
+                case Node.PROCESSING_INSTRUCTION_NODE:
+                    descend = false;
+                    return Event.PROCESSING_INSTRUCTION;
+                default:
+                    throw new IllegalStateException();
+            }
+        }
+    }
+    
+    @Override
+    public String getRootName() {
+        return ((DocumentType)node).getName();
+    }
+
+    @Override
+    public String getPublicId() {
+        return ((DocumentType)node).getPublicId();
+    }
+
+    @Override
+    public String getSystemId() {
+        return ((DocumentType)node).getSystemId();
+    }
+
+    private static QName getQName(Node node) {
+        String localName = node.getLocalName();
+        if (localName == null) {
+            return new QName(node.getNodeName());
+        } else {
+            return new QName(node.getNamespaceURI(), node.getLocalName(), Strings.nullToEmpty(node.getPrefix()));
+        }
+    }
+    
+    @Override
+    public QName getQName() {
+        return getQName(node);
+    }
+
+    @Override
+    public Map<QName,String> getAttributes() {
+        Map<QName,String> result = null;
+        NamedNodeMap attributes = node.getAttributes();
+        for (int i=0; i<attributes.getLength(); i++) {
+            Attr attr = (Attr)attributes.item(i);
+            if (!XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attr.getNamespaceURI())) {
+                if (result == null) {
+                    result = new HashMap<QName,String>();
+                }
+                result.put(getQName(attr), attr.getValue());
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Map<String,String> getNamespaces() {
+        Map<String,String> result = null;
+        NamedNodeMap attributes = node.getAttributes();
+        for (int i=0; i<attributes.getLength(); i++) {
+            Attr attr = (Attr)attributes.item(i);
+            if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attr.getNamespaceURI())) {
+                if (result == null) {
+                    result = new HashMap<String,String>();
+                }
+                String prefix = attr.getPrefix();
+                result.put(XMLConstants.XMLNS_ATTRIBUTE.equals(prefix) ? attr.getLocalName() : "", attr.getValue());
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String getText() {
+        return node.getNodeValue();
+    }
+
+    @Override
+    public String getEntityName() {
+        return node.getNodeName();
+    }
+
+    @Override
+    public String getPITarget() {
+        return ((ProcessingInstruction)node).getTarget();
+    }
+
+    @Override
+    public String getPIData() {
+        return ((ProcessingInstruction)node).getData();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMTraverser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMXML.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMXML.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMXML.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMXML.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import org.w3c.dom.Node;
+
+final class DOMXML implements XML {
+    private final Node root;
+    
+    DOMXML(Node root) {
+        this.root = root;
+    }
+
+    @Override
+    public Traverser createTraverser(boolean expandEntityReferences) {
+        return new DOMTraverser(root, expandEntityReferences);
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/DOMXML.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Event.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Event.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Event.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Event.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+public enum Event {
+    DOCUMENT_TYPE,
+    START_ELEMENT,
+    END_ELEMENT,
+    TEXT,
+    WHITESPACE,
+    ENTITY_REFERENCE,
+    COMMENT,
+    CDATA_SECTION,
+    PROCESSING_INSTRUCTION
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Event.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Filter.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Filter.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Filter.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Filter.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+class Filter implements Traverser {
+    private final Traverser parent;
+    
+    Filter(Traverser parent) {
+        this.parent = parent;
+    }
+
+    @Override
+    public Event next() throws TraverserException {
+        return parent.next();
+    }
+
+    @Override
+    public String getRootName() {
+        return parent.getRootName();
+    }
+
+    @Override
+    public String getPublicId() {
+        return parent.getPublicId();
+    }
+
+    @Override
+    public String getSystemId() {
+        return parent.getSystemId();
+    }
+
+    @Override
+    public QName getQName() {
+        return parent.getQName();
+    }
+
+    @Override
+    public Map<QName,String> getAttributes() {
+        return parent.getAttributes();
+    }
+
+    @Override
+    public Map<String,String> getNamespaces() {
+        return parent.getNamespaces();
+    }
+
+    @Override
+    public String getText() {
+        return parent.getText();
+    }
+
+    @Override
+    public String getEntityName() {
+        return parent.getEntityName();
+    }
+
+    @Override
+    public String getPITarget() {
+        return parent.getPITarget();
+    }
+
+    @Override
+    public String getPIData() {
+        return parent.getPIData();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Filter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/RedundantNamespaceDeclarationFilter.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/RedundantNamespaceDeclarationFilter.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/RedundantNamespaceDeclarationFilter.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/RedundantNamespaceDeclarationFilter.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+
+final class RedundantNamespaceDeclarationFilter extends Filter {
+    private static final Map<String,String> implicitNamespaces;
+    
+    static {
+        implicitNamespaces = new HashMap<String,String>();
+        implicitNamespaces.put("", "");
+        implicitNamespaces.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
+        implicitNamespaces.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
+    }
+    
+    private final List<Map<String,String>> stack;
+    
+    RedundantNamespaceDeclarationFilter(Traverser parent) {
+        super(parent);
+        stack = new ArrayList<Map<String,String>>(10);
+        stack.add(implicitNamespaces);
+    }
+
+    private String lookupNamespaceURI(String prefix) {
+        for (int i=stack.size()-1; i>=0; i--) {
+            Map<String,String> namespaces = stack.get(i);
+            if (namespaces != null) {
+                String namespaceURI = namespaces.get(prefix);
+                if (namespaceURI != null) {
+                    return namespaceURI;
+                }
+            }
+        }
+        return null;
+    }
+    
+    @Override
+    public Event next() throws TraverserException {
+        Event event = super.next();
+        if (event == Event.START_ELEMENT) {
+            Map<String,String> namespaces = super.getNamespaces();
+            if (namespaces != null) {
+                for (Iterator<Map.Entry<String,String>> it = namespaces.entrySet().iterator(); it.hasNext(); ) {
+                    Map.Entry<String,String> namespace = it.next();
+                    if (namespace.getValue().equals(lookupNamespaceURI(namespace.getKey()))) {
+                        it.remove();
+                    }
+                }
+                if (namespaces.isEmpty()) {
+                    namespaces = null;
+                }
+            }
+            stack.add(namespaces);
+        } else if (event == Event.END_ELEMENT) {
+            stack.remove(stack.size()-1);
+        }
+        return event;
+    }
+
+    @Override
+    public Map<String,String> getNamespaces() {
+        return stack.get(stack.size()-1);
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/RedundantNamespaceDeclarationFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXTraverser.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXTraverser.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXTraverser.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXTraverser.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.codehaus.stax2.DTDInfo;
+
+import com.google.common.base.Strings;
+
+final class StAXTraverser implements Traverser {
+    private final XMLStreamReader reader;
+
+    StAXTraverser(XMLStreamReader reader) {
+        this.reader = reader;
+    }
+    
+    @Override
+    public Event next() throws TraverserException {
+        try {
+            if (reader.hasNext()) {
+                switch (reader.next()) {
+                    case XMLStreamReader.DTD:
+                        return Event.DOCUMENT_TYPE;
+                    case XMLStreamReader.START_ELEMENT:
+                        return Event.START_ELEMENT;
+                    case XMLStreamReader.END_ELEMENT:
+                        return Event.END_ELEMENT;
+                    case XMLStreamReader.CHARACTERS:
+                        return Event.TEXT;
+                    case XMLStreamReader.SPACE:
+                        return Event.WHITESPACE;
+                    case XMLStreamReader.ENTITY_REFERENCE:
+                        return Event.ENTITY_REFERENCE;
+                    case XMLStreamReader.COMMENT:
+                        return Event.COMMENT;
+                    case XMLStreamReader.CDATA:
+                        return Event.CDATA_SECTION;
+                    case XMLStreamReader.PROCESSING_INSTRUCTION:
+                        return Event.PROCESSING_INSTRUCTION;
+                    case XMLStreamReader.END_DOCUMENT:
+                        return null;
+                    default:
+                        throw new IllegalStateException();
+                }
+            } else {
+                return null;
+            }
+        } catch (XMLStreamException ex) {
+            throw new TraverserException(ex);
+        }
+    }
+
+    @Override
+    public String getRootName() {
+        return ((DTDInfo)reader).getDTDRootName();
+    }
+
+    @Override
+    public String getPublicId() {
+        return ((DTDInfo)reader).getDTDPublicId();
+    }
+
+    @Override
+    public String getSystemId() {
+        return ((DTDInfo)reader).getDTDSystemId();
+    }
+
+    @Override
+    public QName getQName() {
+        return reader.getName();
+    }
+
+    @Override
+    public Map<QName,String> getAttributes() {
+        int attributeCount = reader.getAttributeCount();
+        if (attributeCount == 0) {
+            return null;
+        } else {
+            Map<QName,String> attributes = new HashMap<QName,String>();
+            for (int i=0; i<attributeCount; i++) {
+                attributes.put(reader.getAttributeName(i), reader.getAttributeValue(i));
+            }
+            return attributes;
+        }
+    }
+
+    @Override
+    public Map<String,String> getNamespaces() {
+        int namespaceCount = reader.getNamespaceCount();
+        if (namespaceCount == 0) {
+            return null;
+        } else {
+            Map<String,String> namespaces = new HashMap<String,String>();
+            for (int i=0; i<namespaceCount; i++) {
+                namespaces.put(Strings.nullToEmpty(reader.getNamespacePrefix(i)), reader.getNamespaceURI(i));
+            }
+            return namespaces;
+        }
+    }
+
+    @Override
+    public String getText() {
+        return reader.getText();
+    }
+
+    @Override
+    public String getEntityName() {
+        return reader.getLocalName();
+    }
+
+    @Override
+    public String getPITarget() {
+        return reader.getPITarget();
+    }
+
+    @Override
+    public String getPIData() {
+        return reader.getPIData();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXTraverser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXXML.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXXML.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXXML.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXXML.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import com.ctc.wstx.stax.WstxInputFactory;
+
+abstract class StAXXML implements XML {
+    @Override
+    public final Traverser createTraverser(boolean expandEntityReferences) throws TraverserException {
+        WstxInputFactory factory = new WstxInputFactory();
+        factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.valueOf(expandEntityReferences));
+        factory.setProperty(WstxInputFactory.P_AUTO_CLOSE_INPUT, Boolean.TRUE);
+        factory.setProperty(WstxInputFactory.P_REPORT_PROLOG_WHITESPACE, Boolean.TRUE);
+        factory.setProperty(WstxInputFactory.P_REPORT_CDATA, Boolean.TRUE);
+        try {
+            return new StAXTraverser(createXMLStreamReader(factory));
+        } catch (XMLStreamException ex) {
+            throw new TraverserException(ex);
+        }
+    }
+    
+    abstract XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException;
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/StAXXML.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Traverser.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Traverser.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Traverser.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Traverser.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+// TODO: add a close method
+public interface Traverser {
+    Event next() throws TraverserException;
+    String getRootName();
+    String getPublicId();
+    String getSystemId();
+    QName getQName();
+    
+    /**
+     * Get the attributes for the current element. Only valid if the last call to {@link #next()}
+     * returned {@link Event#START_ELEMENT}.
+     * 
+     * @return the attributes of the element, or <code>null</code> if the element has no attributes
+     */
+    Map<QName,String> getAttributes();
+    
+    /**
+     * Get the namespace declarations for the current element. Only valid if the last call to
+     * {@link #next()} returned {@link Event#START_ELEMENT}. Namespace declarations for the default
+     * namespace are represented using an empty string as prefix.
+     * 
+     * @return the namespace declarations of the element, or <code>null</code> if the element has no
+     *         namespace declarations
+     */
+    Map<String,String> getNamespaces();
+    
+    String getText();
+    String getEntityName();
+    String getPITarget();
+    String getPIData();
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/Traverser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/TraverserException.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/TraverserException.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/TraverserException.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/TraverserException.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+public class TraverserException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    TraverserException(Throwable cause) {
+        super(cause);
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/TraverserException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XML.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XML.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XML.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XML.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+public interface XML {
+    Traverser createTraverser(boolean expandEntityReferences) throws TraverserException;
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XML.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLFactory.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLFactory.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLFactory.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+public interface XMLFactory<T> {
+    Class<T> getExpectedType();
+    XML createXML(T object);
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLSubject.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLSubject.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLSubject.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLSubject.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.Subject;
+
+public final class XMLSubject extends Subject<XMLSubject,XML> {
+    private final Set<Event> ignoredEvents = new HashSet<Event>();
+    private boolean ignoreWhitespace;
+    private boolean ignoreWhitespaceInPrologAndEpilog;
+    private boolean ignorePrologAndEpilog;
+    private boolean ignoreNamespaceDeclarations;
+    private boolean ignoreNamespacePrefixes;
+    private boolean ignoreRedundantNamespaceDeclarations;
+    private boolean expandEntityReferences;
+    private boolean treatWhitespaceAsText;
+    
+    XMLSubject(FailureStrategy failureStrategy, XML subject) {
+        super(failureStrategy, subject);
+    }
+
+    public XMLSubject ignoringComments() {
+        ignoredEvents.add(Event.COMMENT);
+        return this;
+    }
+    
+    public XMLSubject ignoringElementContentWhitespace() {
+        ignoredEvents.add(Event.WHITESPACE);
+        return this;
+    }
+    
+    public XMLSubject ignoringWhitespace() {
+        ignoredEvents.add(Event.WHITESPACE);
+        ignoreWhitespace = true;
+        return this;
+    }
+    
+    public XMLSubject ignoringWhitespaceInPrologAndEpilog() {
+        ignoreWhitespaceInPrologAndEpilog = true;
+        return this;
+    }
+    
+    public XMLSubject ignoringPrologAndEpilog() {
+        ignorePrologAndEpilog = true;
+        return this;
+    }
+    
+    /**
+     * Ignore all namespace declarations.
+     * 
+     * @return <code>this</code>
+     */
+    public XMLSubject ignoringNamespaceDeclarations() {
+        ignoreNamespaceDeclarations = true;
+        return this;
+    }
+    
+    public XMLSubject ignoringNamespacePrefixes() {
+        ignoreNamespacePrefixes = true;
+        return this;
+    }
+    
+    /**
+     * Ignore redundant namespace declarations. A namespace declaration is considered redundant if
+     * its presence doesn't modify the namespace context.
+     * 
+     * @return <code>this</code>
+     */
+    public XMLSubject ignoringRedundantNamespaceDeclarations() {
+        ignoreRedundantNamespaceDeclarations = true;
+        return this;
+    }
+    
+    public XMLSubject expandingEntityReferences() {
+        return expandingEntityReferences(true);
+    }
+    
+    public XMLSubject expandingEntityReferences(boolean value) {
+        expandEntityReferences = value;
+        return this;
+    }
+    
+    public XMLSubject treatingElementContentWhitespaceAsText() {
+        treatWhitespaceAsText = true;
+        return this;
+    }
+    
+    private Traverser createTraverser(XML xml) throws TraverserException {
+        Traverser traverser = xml.createTraverser(expandEntityReferences);
+        if (ignoreWhitespaceInPrologAndEpilog || ignorePrologAndEpilog) {
+            final boolean onlyWhitespace = !ignorePrologAndEpilog;
+            traverser = new Filter(traverser) {
+                private int depth;
+
+                @Override
+                public Event next() throws TraverserException {
+                    Event event;
+                    while ((event = super.next()) != null) {
+                        switch (event) {
+                            case START_ELEMENT:
+                                depth++;
+                                break;
+                            case END_ELEMENT:
+                                depth--;
+                                break;
+                            default:
+                                if (onlyWhitespace) {
+                                    break;
+                                }
+                                // Fall through
+                            case WHITESPACE:
+                                if (depth == 0) {
+                                    continue;
+                                }
+                        }
+                        break;
+                    }
+                    return event;
+                }
+            };
+        }
+        if (!ignoredEvents.isEmpty()) {
+            traverser = new Filter(traverser) {
+                @Override
+                public Event next() throws TraverserException {
+                    Event event;
+                    while (ignoredEvents.contains(event = super.next())) {
+                        // loop
+                    }
+                    return event;
+                }
+            };
+        }
+        traverser = new CoalescingFilter(traverser);
+        if (ignoreWhitespace) {
+            traverser = new Filter(traverser) {
+                @Override
+                public Event next() throws TraverserException {
+                    Event event = super.next();
+                    if (event == Event.TEXT) {
+                        String text = getText();
+                        for (int i=0; i<text.length(); i++) {
+                            if (" \r\n\t".indexOf(text.charAt(i)) == -1) {
+                                return Event.TEXT;
+                            }
+                        }
+                        return super.next();
+                    } else {
+                        return event;
+                    }
+                }
+            };
+        }
+        if (treatWhitespaceAsText) {
+            traverser = new Filter(traverser) {
+                @Override
+                public Event next() throws TraverserException {
+                    Event event = super.next();
+                    return event == Event.WHITESPACE ? Event.TEXT : event;
+                }
+            };
+        }
+        if (ignoreRedundantNamespaceDeclarations && !ignoreNamespaceDeclarations) {
+            traverser = new RedundantNamespaceDeclarationFilter(traverser);
+        }
+        return traverser;
+    }
+    
+    private static Map<QName,String> extractPrefixes(Set<QName> qnames) {
+        Map<QName,String> result = new HashMap<QName,String>();
+        for (QName qname : qnames) {
+            result.put(qname, qname.getPrefix());
+        }
+        return result;
+    }
+    
+    public void hasSameContentAs(XML other) {
+        try {
+            Traverser actual = createTraverser(getSubject());
+            Traverser expected = createTraverser(other);
+            while (true) {
+                Event actualEvent = actual.next();
+                Event expectedEvent = expected.next();
+                assertThat(actualEvent).isEqualTo(expectedEvent);
+                if (expectedEvent == null) {
+                    break;
+                }
+                switch (expectedEvent) {
+                    case DOCUMENT_TYPE:
+                        assertThat(actual.getRootName()).isEqualTo(expected.getRootName());
+                        assertThat(actual.getPublicId()).isEqualTo(expected.getPublicId());
+                        assertThat(actual.getSystemId()).isEqualTo(expected.getSystemId());
+                        break;
+                    case START_ELEMENT:
+                        QName actualQName = actual.getQName();
+                        Map<QName,String> actualAttributes = actual.getAttributes();
+                        QName expectedQName = expected.getQName();
+                        Map<QName,String> expectedAttributes = expected.getAttributes();
+                        assertThat(actualQName).isEqualTo(expectedQName);
+                        assertThat(actualAttributes).isEqualTo(expectedAttributes);
+                        if (!ignoreNamespacePrefixes) {
+                            assertThat(actualQName.getPrefix()).isEqualTo(expectedQName.getPrefix());
+                            if (expectedAttributes != null) {
+                                assertThat(extractPrefixes(actualAttributes.keySet())).isEqualTo(extractPrefixes(expectedAttributes.keySet()));
+                            }
+                        }
+                        if (!ignoreNamespaceDeclarations) {
+                            assertThat(actual.getNamespaces()).isEqualTo(expected.getNamespaces());
+                        }
+                        break;
+                    case END_ELEMENT:
+                        break;
+                    case TEXT:
+                    case WHITESPACE:
+                    case COMMENT:
+                    case CDATA_SECTION:
+                        assertThat(actual.getText()).isEqualTo(expected.getText());
+                        break;
+                    case ENTITY_REFERENCE:
+                        if (expandEntityReferences) {
+                            throw new IllegalStateException();
+                        }
+                        assertThat(actual.getEntityName()).isEqualTo(expected.getEntityName());
+                        break;
+                    case PROCESSING_INSTRUCTION:
+                        assertThat(actual.getPITarget()).isEqualTo(expected.getPITarget());
+                        assertThat(actual.getPIData()).isEqualTo(expected.getPIData());
+                        break;
+                    default:
+                        throw new IllegalStateException();
+                }
+            }
+        } catch (TraverserException ex) {
+            // TODO: check how to fail properly
+            throw new RuntimeException(ex);
+        }
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLSubject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.ServiceLoader;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.SubjectFactory;
+
+public final class XMLTruth {
+    private static final SubjectFactory<XMLSubject,XML> SUBJECT_FACTORY = new SubjectFactory<XMLSubject,XML>() {
+        @Override
+        public XMLSubject getSubject(FailureStrategy fs, XML that) {
+            return new XMLSubject(fs, that);
+        }
+        
+    };
+    
+    @SuppressWarnings("rawtypes")
+    private static final ServiceLoader<XMLFactory> factoryLoader = ServiceLoader.load(
+            XMLFactory.class, XMLTruth.class.getClassLoader());
+    
+    private XMLTruth() {}
+
+    public static SubjectFactory<XMLSubject,XML> xml() {
+        return SUBJECT_FACTORY;
+    }
+
+    public static XML xml(Document document) {
+        return new DOMXML(document);
+    }
+
+    public static XML xml(Element element) {
+        return new DOMXML(element);
+    }
+
+    public static XML xml(final InputSource is) {
+        final StreamSource source = new StreamSource();
+        source.setInputStream(is.getByteStream());
+        source.setReader(is.getCharacterStream());
+        source.setPublicId(is.getPublicId());
+        source.setSystemId(is.getSystemId());
+        return new StAXXML() {
+            @Override
+            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                return factory.createXMLStreamReader(source);
+            }
+        };
+    }
+    
+    public static XML xml(final InputStream in) {
+        return new StAXXML() {
+            @Override
+            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                return factory.createXMLStreamReader(in);
+            }
+        };
+    }
+
+    public static XML xml(final Reader reader) {
+        return new StAXXML() {
+            @Override
+            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                return factory.createXMLStreamReader(reader);
+            }
+        };
+    }
+
+    public static XML xml(final URL url) {
+        return new StAXXML() {
+            @Override
+            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                return factory.createXMLStreamReader(new StreamSource(url.toString()));
+            }
+        };
+    }
+
+    public static XML xml(String xml) {
+        return xml(new StringReader(xml));
+    }
+    
+    public static XML xml(byte[] bytes) {
+        return xml(new ByteArrayInputStream(bytes));
+    }
+    
+    public static XML xml(Object object) {
+        for (XMLFactory<?> factory : factoryLoader) {
+            if (factory.getExpectedType().isInstance(object)) {
+                return xml(factory, object);
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+    
+    private static <T> XML xml(XMLFactory<T> factory, Object object) {
+        return factory.createXML(factory.getExpectedType().cast(object));
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMCompareTest.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMCompareTest.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMCompareTest.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMCompareTest.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static org.apache.axiom.testing.multiton.Multiton.getInstances;
+import static org.apache.axiom.truth.xml.XMLTruth.xml;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestSuite;
+
+import org.apache.axiom.testutils.suite.MatrixTestCase;
+import org.apache.axiom.testutils.suite.MatrixTestSuiteBuilder;
+import org.apache.axiom.ts.xml.XMLSample;
+import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl;
+
+public class DOMCompareTest extends MatrixTestCase {
+    private XMLSample sample;
+    private boolean expandEntityReferences;
+
+    public DOMCompareTest(XMLSample sample, boolean expandEntityReferences) {
+        this.sample = sample;
+        this.expandEntityReferences = expandEntityReferences;
+        addTestParameter("sample", sample.getName());
+        addTestParameter("expandEntityReferences", expandEntityReferences);
+    }
+    
+    @Override
+    protected void runTest() throws Throwable {
+        DocumentBuilderFactory factory = new DocumentBuilderFactoryImpl();
+        factory.setNamespaceAware(true);
+        // If necessary, let DOMTraverser expand entity references
+        factory.setExpandEntityReferences(false);
+        assertAbout(xml())
+                .that(xml(factory.newDocumentBuilder().parse(sample.getUrl().toString())))
+                .ignoringWhitespaceInPrologAndEpilog()
+                .expandingEntityReferences(expandEntityReferences)
+                .hasSameContentAs(xml(sample.getUrl()));
+    }
+
+    public static TestSuite suite() {
+        return new MatrixTestSuiteBuilder() {
+            @Override
+            protected void addTests() {
+                for (XMLSample sample : getInstances(XMLSample.class)) {
+                    addTest(new DOMCompareTest(sample, true));
+                    addTest(new DOMCompareTest(sample, false));
+                }
+            }
+        }.build();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMCompareTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMTraverserTest.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMTraverserTest.java?rev=1683967&view=auto
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMTraverserTest.java (added)
+++ webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMTraverserTest.java Sat Jun  6 23:18:36 2015
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.truth.xml;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.apache.axiom.ts.xml.XMLSample;
+import org.junit.Test;
+
+public class DOMTraverserTest {
+    @Test
+    public void testEntityReferenceExpansion() throws Exception {
+        Traverser t = new CoalescingFilter(new DOMTraverser(XMLSample.ENTITY_REFERENCE_NESTED.getDocument(), true));
+        assertThat(t.next()).isEqualTo(Event.DOCUMENT_TYPE);
+        assertThat(t.next()).isEqualTo(Event.START_ELEMENT);
+        assertThat(t.next()).isEqualTo(Event.TEXT);
+        assertThat(t.getText().trim()).isEqualTo("A B C");
+        assertThat(t.next()).isEqualTo(Event.END_ELEMENT);
+        assertThat(t.next()).isNull();
+    }
+}

Propchange: webservices/axiom/trunk/testing/xml-truth/src/test/java/org/apache/axiom/truth/xml/DOMTraverserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native