61adfd8b371dd0e00b2371f946c23304b6a81bc3
[yangtools.git] /
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.codec.xml;
9
10 import static org.hamcrest.CoreMatchers.instanceOf;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14
15 import java.io.StringWriter;
16 import java.util.Collection;
17 import javax.xml.stream.XMLOutputFactory;
18 import javax.xml.stream.XMLStreamReader;
19 import javax.xml.stream.XMLStreamWriter;
20 import javax.xml.transform.dom.DOMResult;
21 import javax.xml.transform.dom.DOMSource;
22 import org.custommonkey.xmlunit.Diff;
23 import org.custommonkey.xmlunit.DifferenceListener;
24 import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener;
25 import org.custommonkey.xmlunit.XMLAssert;
26 import org.custommonkey.xmlunit.XMLUnit;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.junit.runners.Parameterized;
30 import org.opendaylight.yangtools.util.xml.UntrustedXML;
31 import org.opendaylight.yangtools.yang.data.api.schema.AnydataNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
33 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
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.ImmutableNormalizedNodeStreamWriter;
37 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
38 import org.opendaylight.yangtools.yang.data.util.ImmutableNormalizedAnydata;
39 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
40 import org.opendaylight.yangtools.yang.model.spi.DefaultSchemaTreeInference;
41 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
42 import org.w3c.dom.Document;
43
44 @RunWith(Parameterized.class)
45 public class AnydataSerializeTest extends AbstractAnydataTest {
46
47     @Parameterized.Parameters(name = "{0}")
48     public static Collection<Object[]> data() {
49         return TestFactories.junitParameters();
50     }
51
52     private final XMLOutputFactory factory;
53
54     public AnydataSerializeTest(final String factoryMode, final XMLOutputFactory factory) {
55         this.factory = factory;
56     }
57
58     @Test
59     public void testDOMAnydata() throws Exception {
60         final StringWriter writer = new StringWriter();
61         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(writer);
62
63         final NormalizedNodeStreamWriter xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(
64             xmlStreamWriter, SCHEMA_CONTEXT);
65         final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(
66             xmlNormalizedNodeStreamWriter);
67         normalizedNodeWriter.write(Builders.anydataBuilder(DOMSourceAnydata.class)
68             .withNodeIdentifier(FOO_NODEID)
69             .withValue(toDOMSource("<bar xmlns=\"test-anydata\"/>"))
70             .build());
71         normalizedNodeWriter.flush();
72
73         final String serializedXml = writer.toString();
74         assertEquals("<foo xmlns=\"test-anydata\"><bar xmlns=\"test-anydata\"></bar></foo>", serializedXml);
75     }
76
77     @Test
78     public void testXmlParseAnydata() throws Exception {
79         // deserialization
80         final XMLStreamReader reader
81                 = UntrustedXML.createXMLStreamReader(loadResourcesAsInputStream("/test-anydata.xml"));
82
83         final var result = new NormalizationResultHolder();
84         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
85         final var xmlParser = XmlParserStream.create(streamWriter, Inference.ofDataTreePath(SCHEMA_CONTEXT, FOO_QNAME));
86         xmlParser.parse(reader);
87
88         final var transformedInput = result.getResult().data();
89         assertThat(transformedInput, instanceOf(AnydataNode.class));
90         AnydataNode<?> anydataNode = (AnydataNode<?>) transformedInput;
91
92         // serialization
93         final StringWriter writer = new StringWriter();
94         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(writer);
95         final NormalizedNodeStreamWriter xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(
96                 xmlStreamWriter, SCHEMA_CONTEXT);
97         final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(
98                 xmlNormalizedNodeStreamWriter);
99         normalizedNodeWriter.write(transformedInput);
100         normalizedNodeWriter.flush();
101
102         final String serializedXml = writer.toString();
103         final String deserializeXml = getXmlFromDOMSource(((DOMSourceAnydata) anydataNode.body()).getSource());
104         assertFalse(serializedXml.isEmpty());
105
106         // Check if is Serialize Node same as Deserialize Node
107         XMLUnit.setIgnoreWhitespace(true);
108         XMLUnit.setNormalize(true);
109         final Diff diff = new Diff(deserializeXml, serializedXml);
110         final DifferenceListener differenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
111         diff.overrideDifferenceListener(differenceListener);
112
113         XMLAssert.assertXMLEqual(diff, true);
114     }
115
116     @Test
117     public void testAnydataLoadFromXML() throws Exception {
118         // Load XML file
119         Document doc = loadXmlDocument("/test-anydata.xml");
120         final DOMSource domSource = new DOMSource(doc.getDocumentElement());
121
122         //Load XML from file and write it with xmlParseStream
123         final DOMResult domResult = new DOMResult(UntrustedXML.newDocumentBuilder().newDocument());
124         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(domResult);
125         final NormalizedNodeStreamWriter streamWriter = XMLStreamNormalizedNodeStreamWriter.create(
126                 xmlStreamWriter, SCHEMA_CONTEXT);
127         final XMLStreamReader reader = new DOMSourceXMLStreamReader(domSource);
128         final XmlParserStream xmlParser = XmlParserStream.create(streamWriter,
129             Inference.ofDataTreePath(SCHEMA_CONTEXT, FOO_QNAME));
130
131         xmlParser.parse(reader);
132         xmlParser.flush();
133
134         //Set XML comparing
135         XMLUnit.setIgnoreWhitespace(true);
136         XMLUnit.setNormalize(true);
137
138         // Check diff
139         final String expectedXml = toString(doc.getDocumentElement());
140         final String serializedXml = toString(domResult.getNode());
141         final Diff diff = new Diff(expectedXml, serializedXml);
142         final DifferenceListener differenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
143         diff.overrideDifferenceListener(differenceListener);
144
145         XMLAssert.assertXMLEqual(diff, true);
146     }
147
148     @Test
149     public void testAnydataSerialization() throws Exception {
150         //Get XML Data.
151         Document doc = loadXmlDocument("/test-anydata.xml");
152         final DOMSource domSource = new DOMSource(doc.getDocumentElement());
153
154         //Create NormalizedNodeResult
155         final var normalizedResult = new NormalizationResultHolder();
156         final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(normalizedResult);
157
158         //Initialize Reader with XML file
159         final XMLStreamReader reader = new DOMSourceXMLStreamReader(domSource);
160         final XmlParserStream xmlParser = XmlParserStream.create(streamWriter,
161             Inference.ofDataTreePath(SCHEMA_CONTEXT, FOO_QNAME));
162         xmlParser.parse(reader);
163         xmlParser.flush();
164
165         //Get Result
166         final var node = normalizedResult.getResult().data();
167         assertThat(node, instanceOf(AnydataNode.class));
168         final AnydataNode<?> anydataResult = (AnydataNode<?>) node;
169
170         //Get Result in formatted String
171         assertThat(anydataResult.body(), instanceOf(DOMSourceAnydata.class));
172         final String serializedXml = getXmlFromDOMSource(((DOMSourceAnydata)anydataResult.body()).getSource());
173         final String expectedXml = toString(doc.getDocumentElement());
174
175         //Looking for difference in Serialized xml and in Loaded XML
176         final Diff diff = new Diff(expectedXml, serializedXml);
177         final DifferenceListener differenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
178         diff.overrideDifferenceListener(differenceListener);
179
180         XMLAssert.assertXMLEqual(diff, true);
181     }
182
183     @Test
184     public void testSiblingSerialize() throws Exception {
185         final StringWriter writer = new StringWriter();
186         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(writer);
187
188         final NormalizedNodeStreamWriter xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(
189             xmlStreamWriter, SCHEMA_CONTEXT);
190         final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(
191             xmlNormalizedNodeStreamWriter);
192         normalizedNodeWriter.write(Builders.containerBuilder()
193             .withNodeIdentifier(CONT_NODEID)
194             .withChild(Builders.anydataBuilder(DOMSourceAnydata.class)
195                 .withNodeIdentifier(CONT_ANY_NODEID)
196                 .withValue(toDOMSource("<bar xmlns=\"test-anydata\"/>"))
197                 .build())
198             .withChild(CONT_LEAF)
199             .build());
200         normalizedNodeWriter.flush();
201
202         final String serializedXml = writer.toString();
203         assertEquals("<cont xmlns=\"test-anydata\"><cont-any><bar xmlns=\"test-anydata\"></bar></cont-any>"
204                 + "<cont-leaf>abc</cont-leaf></cont>", serializedXml);
205     }
206
207     @Test
208     public void testNormalizedSerialize() throws Exception {
209         final StringWriter writer = new StringWriter();
210         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(writer);
211
212         final NormalizedNodeStreamWriter xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(
213             xmlStreamWriter, SCHEMA_CONTEXT);
214         final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(
215             xmlNormalizedNodeStreamWriter);
216         normalizedNodeWriter.write(Builders.containerBuilder()
217             .withNodeIdentifier(CONT_NODEID)
218             .withChild(Builders.anydataBuilder(NormalizedAnydata.class)
219                 .withNodeIdentifier(CONT_ANY_NODEID)
220                 .withValue(new ImmutableNormalizedAnydata(
221                     DefaultSchemaTreeInference.of(SCHEMA_CONTEXT, Absolute.of(CONT_QNAME)),
222                     Builders.containerBuilder().withNodeIdentifier(CONT_NODEID).build()))
223                 .build())
224             .build());
225         normalizedNodeWriter.flush();
226
227         final String serializedXml = writer.toString();
228         assertEquals("<cont xmlns=\"test-anydata\"><cont-any><cont/></cont-any></cont>", serializedXml);
229     }
230 }