Move NormalizedNode builders
[yangtools.git] / yang / yang-data-codec-xml / src / test / java / org / opendaylight / yangtools / yang / data / codec / xml / XmlStreamUtilsTest.java
index 80883180c92a66029d46264fa260f9b62fdf2b8d..b0fd191b3ad7d783eeb8c61718fbf9b3a0d496a8 100644 (file)
@@ -5,58 +5,53 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.yangtools.yang.data.codec.xml;
 
 import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.AbstractMap;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
+import java.io.IOException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.w3c.dom.Document;
 
 public class XmlStreamUtilsTest {
+    @FunctionalInterface
+    interface XMLStreamWriterConsumer {
+        void accept(XMLStreamWriter writer) throws XMLStreamException;
+    }
 
-    public static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
-
-    private static SchemaContext schemaContext;
+    private static EffectiveModelContext schemaContext;
     private static Module leafRefModule;
 
     @BeforeClass
-    public static void initialize() throws URISyntaxException, FileNotFoundException, ReactorException {
+    public static void initialize() {
         schemaContext = YangParserTestUtils.parseYangResource("/leafref-test.yang");
         assertNotNull(schemaContext);
         assertEquals(1, schemaContext.getModules().size());
@@ -64,67 +59,50 @@ public class XmlStreamUtilsTest {
         assertNotNull(leafRefModule);
     }
 
-    @Test
-    public void testWriteAttribute() throws Exception {
-        final ByteArrayOutputStream out = new ByteArrayOutputStream();
-        final XMLStreamWriter writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
-        writer.writeStartElement("element");
-
-        QName name = getAttrQName("namespace", "2012-12-12", "attr", Optional.of("prefix"));
-        final Map.Entry<QName, String> attributeEntry = new AbstractMap.SimpleEntry<>(name, "value");
-
-        name = getAttrQName("namespace2", "2012-12-12", "attr", Optional.empty());
-        final Map.Entry<QName, String> attributeEntryNoPrefix = new AbstractMap.SimpleEntry<>(name, "value");
-
-        final RandomPrefix randomPrefix = new RandomPrefix(null);
-        XMLStreamWriterUtils.writeAttribute(writer, attributeEntry, randomPrefix);
-        XMLStreamWriterUtils.writeAttribute(writer, attributeEntryNoPrefix, randomPrefix);
-
-        writer.writeEndElement();
-        writer.close();
-        out.close();
+    @AfterClass
+    public static void cleanup() {
+        leafRefModule = null;
+        schemaContext = null;
+    }
 
-        final String xmlAsString = new String(out.toByteArray());
+    @Test
+    public void testWriteIdentityRef() throws Exception {
+        final QNameModule parent = QNameModule.create(XMLNamespace.of("parent:uri"), Revision.of("2000-01-01"));
 
-        final Map<String, String> mappedPrefixes = mapPrefixed(randomPrefix.getPrefixes());
-        assertEquals(2, mappedPrefixes.size());
-        final String randomPrefixValue = mappedPrefixes.get("namespace2");
+        String xmlAsString = createXml(writer -> {
+            writer.writeStartElement("element");
+            final StreamWriterFacade facade = new StreamWriterFacade(writer);
+            facade.writeCharacters(XMLStreamWriterUtils.encode(facade, QName.create(parent, "identity"), parent));
+            facade.flush();
+            writer.writeEndElement();
+        });
 
-        final String expectedXmlAsString = "<element xmlns:a=\"namespace\" a:attr=\"value\" xmlns:" + randomPrefixValue
-                + "=\"namespace2\" " + randomPrefixValue + ":attr=\"value\"></element>";
+        assertThat(xmlAsString, containsString("element>identity"));
 
-        XMLUnit.setIgnoreAttributeOrder(true);
-        final Document control = XMLUnit.buildControlDocument(expectedXmlAsString);
-        final Document test = XMLUnit.buildTestDocument(xmlAsString);
-        final Diff diff = XMLUnit.compareXML(control, test);
+        xmlAsString = createXml(writer -> {
+            writer.writeStartElement("elementDifferent");
+            final StreamWriterFacade facade = new StreamWriterFacade(writer);
+            facade.writeCharacters(XMLStreamWriterUtils.encode(facade, QName.create("different:namespace", "identity"),
+                parent));
+            facade.flush();
+            writer.writeEndElement();
+        });
 
-        final boolean identical = diff.identical();
-        assertTrue("Xml differs: " + diff.toString(), identical);
+        final Pattern prefixedIdentityPattern = Pattern.compile(".*\"different:namespace\">(.*):identity.*");
+        final Matcher matcher = prefixedIdentityPattern.matcher(xmlAsString);
+        assertTrue("Xml: " + xmlAsString + " should match: " + prefixedIdentityPattern, matcher.matches());
     }
 
-    @Test
-    public void testWriteIdentityRef() throws Exception {
+    private static String createXml(final XMLStreamWriterConsumer consumer) throws XMLStreamException, IOException {
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
-        final XMLStreamWriter writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
-
-        writer.writeStartElement("element");
-        final QNameModule parent = QNameModule.create(URI.create("parent:uri"), Revision.of("2000-01-01"));
-        XMLStreamWriterUtils.write(writer, null, QName.create(parent, "identity"), parent);
-        writer.writeEndElement();
+        final XMLStreamWriter writer = TestFactories.DEFAULT_OUTPUT_FACTORY.createXMLStreamWriter(out);
 
-        writer.writeStartElement("elementDifferent");
-        XMLStreamWriterUtils.write(writer, null, QName.create("different:namespace", "identity"), parent);
-        writer.writeEndElement();
+        consumer.accept(writer);
 
         writer.close();
         out.close();
 
-        final String xmlAsString = new String(out.toByteArray()).replaceAll("\\s*", "");
-        assertThat(xmlAsString, containsString("element>identity"));
-
-        final Pattern prefixedIdentityPattern = Pattern.compile(".*\"different:namespace\">(.*):identity.*");
-        final Matcher matcher = prefixedIdentityPattern.matcher(xmlAsString);
-        assertTrue("Xml: " + xmlAsString + " should match: " + prefixedIdentityPattern, matcher.matches());
+        return new String(out.toByteArray()).replaceAll("\\s*", "");
     }
 
     /**
@@ -132,17 +110,17 @@ public class XmlStreamUtilsTest {
      */
     @Test
     public void testLeafRefRelativeChaining() {
-        getTargetNodeForLeafRef("leafname3", StringTypeDefinition.class);
+        getTargetNodeForLeafRef(StringTypeDefinition.class, "cont3", "leafname3");
     }
 
     @Test
     public void testLeafRefRelative() {
-        getTargetNodeForLeafRef("pointToStringLeaf", StringTypeDefinition.class);
+        getTargetNodeForLeafRef(StringTypeDefinition.class, "pointToStringLeaf");
     }
 
     @Test
     public void testLeafRefAbsoluteWithSameTarget() {
-        getTargetNodeForLeafRef("absname", InstanceIdentifierTypeDefinition.class);
+        getTargetNodeForLeafRef(InstanceIdentifierTypeDefinition.class, "absname");
     }
 
     /**
@@ -152,70 +130,29 @@ public class XmlStreamUtilsTest {
     @Ignore
     @Test
     public void testLeafRefWithDoublePointInPath() {
-        getTargetNodeForLeafRef("lf-with-double-point-inside", StringTypeDefinition.class);
+        getTargetNodeForLeafRef(StringTypeDefinition.class, "lf-with-double-point-inside");
     }
 
     @Test
     public void testLeafRefRelativeAndAbsoluteWithSameTarget() {
-        final TypeDefinition<?> targetNodeForAbsname = getTargetNodeForLeafRef("absname",
-            InstanceIdentifierTypeDefinition.class);
-        final TypeDefinition<?> targetNodeForRelname = getTargetNodeForLeafRef("relname",
-            InstanceIdentifierTypeDefinition.class);
-        assertEquals(targetNodeForAbsname, targetNodeForRelname);
+        assertSame(getTargetNodeForLeafRef(InstanceIdentifierTypeDefinition.class, "absname"),
+            getTargetNodeForLeafRef(InstanceIdentifierTypeDefinition.class, "relname"));
     }
 
-    private TypeDefinition<?> getTargetNodeForLeafRef(final String nodeName, final Class<?> clas) {
-        final LeafSchemaNode schemaNode = findSchemaNodeWithLeafrefType(leafRefModule, nodeName);
-        assertNotNull(schemaNode);
-        final LeafrefTypeDefinition leafrefTypedef = findLeafrefType(schemaNode);
-        assertNotNull(leafrefTypedef);
-        final TypeDefinition<?> targetBaseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypedef, schemaContext,
-                schemaNode);
-        assertTrue("Wrong class found.", clas.isInstance(targetBaseType));
-        return targetBaseType;
-    }
-
-    private static Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
-        final Map<String, String> mappedPrefixes = new HashMap<>();
-        for (final Map.Entry<URI, String> prefix : prefixes) {
-            mappedPrefixes.put(prefix.getKey().toString(), prefix.getValue());
-        }
-        return mappedPrefixes;
-    }
-
-    private static QName getAttrQName(final String namespace, final String revision, final String localName,
-            final Optional<String> prefix) {
-        if (prefix.isPresent()) {
-            final QName moduleQName = QName.create(namespace, revision, "module");
-            final QNameModule module = QNameModule.create(moduleQName.getNamespace(), moduleQName.getRevision());
-            return QName.create(module, localName);
+    private static TypeDefinition<?> getTargetNodeForLeafRef(final Class<?> clas, final String... names) {
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(schemaContext);
+        stack.enterDataTree(QName.create(leafRefModule.getQNameModule(), "cont2"));
+        for (String name : names) {
+            stack.enterDataTree(QName.create(leafRefModule.getQNameModule(), name));
         }
-        return QName.create(namespace, revision, localName);
-    }
 
-    private LeafSchemaNode findSchemaNodeWithLeafrefType(final DataNodeContainer module, final String nodeName) {
-        for (final DataSchemaNode childNode : module.getChildNodes()) {
-            if (childNode instanceof DataNodeContainer) {
-                LeafSchemaNode leafrefFromRecursion = findSchemaNodeWithLeafrefType((DataNodeContainer) childNode,
-                        nodeName);
-                if (leafrefFromRecursion != null) {
-                    return leafrefFromRecursion;
-                }
-            } else if (childNode.getQName().getLocalName().equals(nodeName) && childNode instanceof LeafSchemaNode) {
-                final TypeDefinition<?> leafSchemaNodeType = ((LeafSchemaNode) childNode).getType();
-                if (leafSchemaNodeType instanceof LeafrefTypeDefinition) {
-                    return (LeafSchemaNode) childNode;
-                }
-            }
-        }
-        return null;
-    }
+        final EffectiveStatement<?, ?> leaf = stack.currentStatement();
+        assertThat(leaf, instanceOf(LeafSchemaNode.class));
+        final TypeDefinition<? extends TypeDefinition<?>> type = ((TypedDataSchemaNode) leaf).getType();
+        assertThat(type, instanceOf(LeafrefTypeDefinition.class));
 
-    private static LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
-        final TypeDefinition<?> type = schemaNode.getType();
-        if (type instanceof LeafrefTypeDefinition) {
-            return (LeafrefTypeDefinition) type;
-        }
-        return null;
+        final TypeDefinition<?> resolved = stack.resolveLeafref((LeafrefTypeDefinition) type);
+        assertThat(resolved, instanceOf(clas));
+        return resolved;
     }
 }