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;
10 import java.io.IOException;
11 import java.util.Collection;
13 import javax.xml.stream.XMLOutputFactory;
14 import javax.xml.stream.XMLStreamException;
15 import javax.xml.transform.dom.DOMResult;
16 import org.custommonkey.xmlunit.Diff;
17 import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener;
18 import org.custommonkey.xmlunit.XMLAssert;
19 import org.custommonkey.xmlunit.XMLUnit;
20 import org.junit.AfterClass;
21 import org.junit.Before;
22 import org.junit.BeforeClass;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.Parameterized;
26 import org.opendaylight.yangtools.util.xml.UntrustedXML;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.common.QNameModule;
29 import org.opendaylight.yangtools.yang.common.XMLNamespace;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
33 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
37 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
38 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
39 import org.xml.sax.SAXException;
41 @RunWith(Parameterized.class)
42 public class NormalizedNodesToXmlTest extends AbstractXmlTest {
43 @Parameterized.Parameters(name = "{0}")
44 public static Collection<Object[]> data() {
45 return TestFactories.junitParameters();
48 private QNameModule bazModule;
50 private QName outerContainer;
52 private QName myContainer1;
53 private QName myKeyedList;
54 private QName myKeyLeaf;
55 private QName myLeafInList1;
56 private QName myLeafInList2;
57 private QName myLeaf1;
58 private QName myLeafList;
60 private QName myContainer2;
61 private QName innerContainer;
62 private QName myLeaf2;
63 private QName myLeaf3;
64 private QName myChoice;
65 private QName myLeafInCase2;
67 private QName myContainer3;
68 private QName myDoublyKeyedList;
69 private QName myFirstKeyLeaf;
70 private QName mySecondKeyLeaf;
71 private QName myLeafInList3;
73 private static EffectiveModelContext SCHEMA_CONTEXT;
75 private final XMLOutputFactory factory;
77 public NormalizedNodesToXmlTest(final String factoryMode, final XMLOutputFactory factory) {
78 this.factory = factory;
82 public static void beforeClass() {
83 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResource("/baz.yang");
87 public static void afterClass() {
88 SCHEMA_CONTEXT = null;
93 bazModule = QNameModule.create(XMLNamespace.of("baz-namespace"));
95 outerContainer = QName.create(bazModule, "outer-container");
97 myContainer1 = QName.create(bazModule, "my-container-1");
98 myKeyedList = QName.create(bazModule, "my-keyed-list");
99 myKeyLeaf = QName.create(bazModule, "my-key-leaf");
100 myLeafInList1 = QName.create(bazModule, "my-leaf-in-list-1");
101 myLeafInList2 = QName.create(bazModule, "my-leaf-in-list-2");
102 myLeaf1 = QName.create(bazModule, "my-leaf-1");
103 myLeafList = QName.create(bazModule, "my-leaf-list");
105 myContainer2 = QName.create(bazModule, "my-container-2");
106 innerContainer = QName.create(bazModule, "inner-container");
107 myLeaf2 = QName.create(bazModule, "my-leaf-2");
108 myLeaf3 = QName.create(bazModule, "my-leaf-3");
109 myChoice = QName.create(bazModule, "my-choice");
110 myLeafInCase2 = QName.create(bazModule, "my-leaf-in-case-2");
112 myContainer3 = QName.create(bazModule, "my-container-3");
113 myDoublyKeyedList = QName.create(bazModule, "my-doubly-keyed-list");
114 myFirstKeyLeaf = QName.create(bazModule, "my-first-key-leaf");
115 mySecondKeyLeaf = QName.create(bazModule, "my-second-key-leaf");
116 myLeafInList3 = QName.create(bazModule, "my-leaf-in-list-3");
120 public void testNormalizedNodeToXmlSerialization() throws XMLStreamException, IOException, SAXException {
121 final var doc = loadDocument("/baz.xml");
122 final var domResult = new DOMResult(UntrustedXML.newDocumentBuilder().newDocument());
123 final var xmlStreamWriter = factory.createXMLStreamWriter(domResult);
124 final var xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlStreamWriter,
126 final var normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(xmlNormalizedNodeStreamWriter);
128 normalizedNodeWriter.write(buildOuterContainerNode());
130 XMLUnit.setIgnoreWhitespace(true);
131 XMLUnit.setNormalize(true);
133 final String expectedXml = toString(doc.getDocumentElement());
134 final String serializedXml = toString(domResult.getNode());
135 final Diff diff = new Diff(expectedXml, serializedXml);
136 diff.overrideDifferenceListener(new IgnoreTextAndAttributeValuesDifferenceListener());
138 XMLAssert.assertXMLEqual(diff, true);
141 private ContainerNode buildOuterContainerNode() {
142 return Builders.containerBuilder()
143 .withNodeIdentifier(new NodeIdentifier(outerContainer))
144 .withChild(Builders.containerBuilder()
145 .withNodeIdentifier(new NodeIdentifier(myContainer1))
146 .withChild(Builders.mapBuilder()
147 .withNodeIdentifier(new NodeIdentifier(myKeyedList))
148 .withChild(Builders.mapEntryBuilder()
149 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue1"))
150 .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue1"))
151 .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue2"))
153 .withChild(Builders.mapEntryBuilder()
154 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myKeyedList, myKeyLeaf, "listkeyvalue2"))
155 .withChild(ImmutableNodes.leafNode(myLeafInList1, "listleafvalue12"))
156 .withChild(ImmutableNodes.leafNode(myLeafInList2, "listleafvalue22"))
159 .withChild(ImmutableNodes.leafNode(myLeaf1, "value1"))
160 .withChild(Builders.leafSetBuilder()
161 .withNodeIdentifier(new NodeIdentifier(myLeafList))
162 .withChild(Builders.leafSetEntryBuilder()
163 .withNodeIdentifier(new NodeWithValue<>(myLeafList, "lflvalue1"))
164 .withValue("lflvalue1")
166 .withChild(Builders.leafSetEntryBuilder()
167 .withNodeIdentifier(new NodeWithValue<>(myLeafList, "lflvalue2"))
168 .withValue("lflvalue2")
172 .withChild(Builders.containerBuilder()
173 .withNodeIdentifier(new NodeIdentifier(myContainer2))
174 .withChild(Builders.containerBuilder()
175 .withNodeIdentifier(new NodeIdentifier(innerContainer))
176 .withChild(ImmutableNodes.leafNode(myLeaf2, "value2"))
178 .withChild(ImmutableNodes.leafNode(myLeaf3, "value3"))
179 .withChild(Builders.choiceBuilder()
180 .withNodeIdentifier(new NodeIdentifier(myChoice))
181 .withChild(ImmutableNodes.leafNode(myLeafInCase2, "case2value"))
184 .withChild(Builders.containerBuilder()
185 .withNodeIdentifier(new NodeIdentifier(myContainer3))
186 .withChild(Builders.mapBuilder()
187 .withNodeIdentifier(new NodeIdentifier(myDoublyKeyedList))
188 .withChild(Builders.mapEntryBuilder()
189 .withNodeIdentifier(NodeIdentifierWithPredicates.of(myDoublyKeyedList,
190 Map.of(myFirstKeyLeaf, "listkeyvalue1", mySecondKeyLeaf, "listkeyvalue2")))
191 .withChild(ImmutableNodes.leafNode(myLeafInList3, "listleafvalue1"))