2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.codec.xml;
11 import javax.xml.stream.XMLOutputFactory;
12 import javax.xml.transform.dom.DOMResult;
13 import org.custommonkey.xmlunit.Diff;
14 import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener;
15 import org.custommonkey.xmlunit.XMLAssert;
16 import org.custommonkey.xmlunit.XMLUnit;
17 import org.junit.jupiter.api.AfterAll;
18 import org.junit.jupiter.api.BeforeAll;
19 import org.junit.jupiter.api.BeforeEach;
20 import org.junit.jupiter.params.ParameterizedTest;
21 import org.junit.jupiter.params.provider.ArgumentsSource;
22 import org.opendaylight.yangtools.util.xml.UntrustedXML;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.common.QNameModule;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
27 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
29 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
30 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
31 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
33 public class NormalizedNodesToXmlTest extends AbstractXmlTest {
34 private QNameModule bazModule;
36 private QName outerContainer;
38 private QName myContainer1;
39 private QName myKeyedList;
40 private QName myKeyLeaf;
41 private QName myLeafInList1;
42 private QName myLeafInList2;
43 private QName myLeaf1;
44 private QName myLeafList;
46 private QName myContainer2;
47 private QName innerContainer;
48 private QName myLeaf2;
49 private QName myLeaf3;
50 private QName myChoice;
51 private QName myLeafInCase2;
53 private QName myContainer3;
54 private QName myDoublyKeyedList;
55 private QName myFirstKeyLeaf;
56 private QName mySecondKeyLeaf;
57 private QName myLeafInList3;
59 private static EffectiveModelContext SCHEMA_CONTEXT;
62 static void beforeClass() {
63 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResource("/baz.yang");
67 static void afterClass() {
68 SCHEMA_CONTEXT = null;
73 bazModule = QNameModule.of("baz-namespace");
75 outerContainer = QName.create(bazModule, "outer-container");
77 myContainer1 = QName.create(bazModule, "my-container-1");
78 myKeyedList = QName.create(bazModule, "my-keyed-list");
79 myKeyLeaf = QName.create(bazModule, "my-key-leaf");
80 myLeafInList1 = QName.create(bazModule, "my-leaf-in-list-1");
81 myLeafInList2 = QName.create(bazModule, "my-leaf-in-list-2");
82 myLeaf1 = QName.create(bazModule, "my-leaf-1");
83 myLeafList = QName.create(bazModule, "my-leaf-list");
85 myContainer2 = QName.create(bazModule, "my-container-2");
86 innerContainer = QName.create(bazModule, "inner-container");
87 myLeaf2 = QName.create(bazModule, "my-leaf-2");
88 myLeaf3 = QName.create(bazModule, "my-leaf-3");
89 myChoice = QName.create(bazModule, "my-choice");
90 myLeafInCase2 = QName.create(bazModule, "my-leaf-in-case-2");
92 myContainer3 = QName.create(bazModule, "my-container-3");
93 myDoublyKeyedList = QName.create(bazModule, "my-doubly-keyed-list");
94 myFirstKeyLeaf = QName.create(bazModule, "my-first-key-leaf");
95 mySecondKeyLeaf = QName.create(bazModule, "my-second-key-leaf");
96 myLeafInList3 = QName.create(bazModule, "my-leaf-in-list-3");
99 @ParameterizedTest(name = "{0}")
100 @ArgumentsSource(TestFactories.class)
101 void testNormalizedNodeToXmlSerialization(final String factoryMode, final XMLOutputFactory factory)
103 final var doc = loadDocument("/baz.xml");
104 final var domResult = new DOMResult(UntrustedXML.newDocumentBuilder().newDocument());
105 final var xmlStreamWriter = factory.createXMLStreamWriter(domResult);
106 final var xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlStreamWriter,
108 final var normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(xmlNormalizedNodeStreamWriter);
110 normalizedNodeWriter.write(buildOuterContainerNode());
112 XMLUnit.setIgnoreWhitespace(true);
113 XMLUnit.setNormalize(true);
115 final String expectedXml = toString(doc.getDocumentElement());
116 final String serializedXml = toString(domResult.getNode());
117 final Diff diff = new Diff(expectedXml, serializedXml);
118 diff.overrideDifferenceListener(new IgnoreTextAndAttributeValuesDifferenceListener());
120 XMLAssert.assertXMLEqual(diff, true);
123 private ContainerNode buildOuterContainerNode() {
124 return ImmutableNodes.newContainerBuilder()
125 .withNodeIdentifier(new NodeIdentifier(outerContainer))
126 .withChild(ImmutableNodes.newContainerBuilder()
127 .withNodeIdentifier(new NodeIdentifier(myContainer1))
128 .withChild(ImmutableNodes.newSystemMapBuilder()
129 .withNodeIdentifier(new NodeIdentifier(myKeyedList))
130 .withChild(ImmutableNodes.newMapEntryBuilder()
131 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue1"))
132 .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue1"))
133 .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue2"))
135 .withChild(ImmutableNodes.newMapEntryBuilder()
136 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue2"))
137 .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue12"))
138 .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue22"))
141 .withChild(ImmutableNodes.leafNode(myLeaf1, "value1"))
142 .withChild(ImmutableNodes.newSystemLeafSetBuilder()
143 .withNodeIdentifier(new NodeIdentifier(myLeafList))
144 .withChild(ImmutableNodes.leafSetEntry(myLeafList, "lflvalue1"))
145 .withChild(ImmutableNodes.leafSetEntry(myLeafList, "lflvalue2"))
148 .withChild(ImmutableNodes.newContainerBuilder()
149 .withNodeIdentifier(new NodeIdentifier(myContainer2))
150 .withChild(ImmutableNodes.newContainerBuilder()
151 .withNodeIdentifier(new NodeIdentifier(innerContainer))
152 .withChild(ImmutableNodes.leafNode(myLeaf2, "value2"))
154 .withChild(ImmutableNodes.leafNode(myLeaf3, "value3"))
155 .withChild(ImmutableNodes.newChoiceBuilder()
156 .withNodeIdentifier(new NodeIdentifier(myChoice))
157 .withChild(ImmutableNodes.leafNode(myLeafInCase2, "case2value"))
160 .withChild(ImmutableNodes.newContainerBuilder()
161 .withNodeIdentifier(new NodeIdentifier(myContainer3))
162 .withChild(ImmutableNodes.newSystemMapBuilder()
163 .withNodeIdentifier(new NodeIdentifier(myDoublyKeyedList))
164 .withChild(ImmutableNodes.newMapEntryBuilder()
165 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myDoublyKeyedList,
166 Map.of(myFirstKeyLeaf, "listkeyvalue1", mySecondKeyLeaf, "listkeyvalue2")))
167 .withChild(ImmutableNodes.leafNode(myLeafInList3, "listleafvalue1"))