2 * Copyright (c) 2014 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
9 package org.opendaylight.yangtools.yang.data.impl.codec.xml;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import com.google.common.base.Optional;
15 import com.google.common.collect.Maps;
16 import java.io.ByteArrayOutputStream;
19 import java.net.URISyntaxException;
20 import java.util.AbstractMap;
21 import java.util.Arrays;
23 import javax.xml.stream.XMLOutputFactory;
24 import javax.xml.stream.XMLStreamWriter;
25 import org.custommonkey.xmlunit.Diff;
26 import org.custommonkey.xmlunit.XMLUnit;
27 import org.junit.BeforeClass;
28 import org.junit.Ignore;
29 import org.junit.Test;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.common.QNameModule;
32 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
33 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.Module;
36 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
37 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
39 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
40 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
41 import org.opendaylight.yangtools.yang.model.util.StringType;
42 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
43 import org.w3c.dom.Document;
45 public class XmlStreamUtilsTest {
47 public static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
49 private static SchemaContext schemaContext;
50 private static Module leafRefModule;
53 public static void initialize() throws URISyntaxException {
54 final YangParserImpl yangParser = new YangParserImpl();
55 final File file = new File(XmlStreamUtils.class.getResource("/leafref-test.yang").toURI());
56 schemaContext = yangParser.parseFiles(Arrays.asList(file));
57 assertNotNull(schemaContext);
58 assertEquals(1,schemaContext.getModules().size());
59 leafRefModule = schemaContext.getModules().iterator().next();
60 assertNotNull(leafRefModule);
65 public void testWriteAttribute() throws Exception {
66 final ByteArrayOutputStream out = new ByteArrayOutputStream();
67 final XMLStreamWriter writer = XML_OUTPUT_FACTORY.createXMLStreamWriter(out);
68 writer.writeStartElement("element");
70 QName name = getAttrQName("namespace", "2012-12-12", "attr", Optional.of("prefix"));
71 final Map.Entry<QName, String> attributeEntry = new AbstractMap.SimpleEntry<>(name, "value");
73 name = getAttrQName("namespace2", "2012-12-12", "attr", Optional.<String>absent());
74 final Map.Entry<QName, String> attributeEntryNoPrefix = new AbstractMap.SimpleEntry<>(name, "value");
76 final RandomPrefix randomPrefix = new RandomPrefix();
77 XmlStreamUtils.writeAttribute(writer, attributeEntry, randomPrefix);
78 XmlStreamUtils.writeAttribute(writer, attributeEntryNoPrefix, randomPrefix);
80 writer.writeEndElement();
84 final String xmlAsString = new String(out.toByteArray());
86 final Map<String, String> mappedPrefixes = mapPrefixed(randomPrefix.getPrefixes());
87 assertEquals(2, mappedPrefixes.size());
88 final String randomPrefixValue = mappedPrefixes.get("namespace2");
90 final String expectedXmlAsString = "<element xmlns:a=\"namespace\" a:attr=\"value\" xmlns:" + randomPrefixValue + "=\"namespace2\" " + randomPrefixValue + ":attr=\"value\"></element>";
92 XMLUnit.setIgnoreAttributeOrder(true);
93 final Document control = XMLUnit.buildControlDocument(expectedXmlAsString);
94 final Document test = XMLUnit.buildTestDocument(xmlAsString);
95 final Diff diff = XMLUnit.compareXML(control, test);
97 final boolean identical = diff.identical();
98 assertTrue("Xml differs: " + diff.toString(), identical);
102 * One leafref reference to other leafref via relative references
105 public void testLeafRefRelativeChaining() {
106 getTargetNodeForLeafRef("leafname3",StringType.class);
110 public void testLeafRefRelative() {
111 getTargetNodeForLeafRef("pointToStringLeaf",StringType.class);
115 public void testLeafRefAbsoluteWithSameTarget() {
116 getTargetNodeForLeafRef("absname",InstanceIdentifierType.class);
120 * Tests relative path with double point inside path (e. g. "../../lf:interface/../lf:cont2/lf:stringleaf")
122 @Ignore //ignored because this isn't implemented
124 public void testLeafRefWithDoublePointInPath() {
125 getTargetNodeForLeafRef("lf-with-double-point-inside",StringType.class);
129 public void testLeafRefRelativeAndAbsoluteWithSameTarget() {
130 final TypeDefinition<?> targetNodeForAbsname = getTargetNodeForLeafRef("absname",InstanceIdentifierType.class);
131 final TypeDefinition<?> targetNodeForRelname = getTargetNodeForLeafRef("relname",InstanceIdentifierType.class);
132 assertEquals(targetNodeForAbsname, targetNodeForRelname);
135 private TypeDefinition<?> getTargetNodeForLeafRef(final String nodeName, final Class<?> clas) {
136 final LeafSchemaNode schemaNode = findSchemaNodeWithLeafrefType(leafRefModule, nodeName);
137 assertNotNull(schemaNode);
138 final LeafrefTypeDefinition leafrefTypedef = findLeafrefType(schemaNode);
139 assertNotNull(leafrefTypedef);
140 final TypeDefinition<?> targetBaseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypedef, schemaContext, schemaNode);
141 assertEquals("Wrong class found.", clas, targetBaseType.getClass());
142 return targetBaseType;
145 private static Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
146 final Map<String, String> mappedPrefixes = Maps.newHashMap();
147 for (final Map.Entry<URI, String> prefix : prefixes) {
148 mappedPrefixes.put(prefix.getKey().toString(), prefix.getValue());
150 return mappedPrefixes;
153 private static QName getAttrQName(final String namespace, final String revision, final String localName, final Optional<String> prefix) {
154 if (prefix.isPresent()) {
155 final QName moduleQName = QName.create(namespace, revision, "module");
156 final QNameModule module = QNameModule.create(moduleQName.getNamespace(), moduleQName.getRevision());
157 return QName.create(module, localName);
159 return QName.create(namespace, revision, localName);
163 private LeafSchemaNode findSchemaNodeWithLeafrefType(final DataNodeContainer module, final String nodeName) {
164 for (final DataSchemaNode childNode : module.getChildNodes()) {
165 if (childNode instanceof DataNodeContainer) {
166 LeafSchemaNode leafrefFromRecursion = findSchemaNodeWithLeafrefType((DataNodeContainer)childNode, nodeName);
167 if (leafrefFromRecursion != null) {
168 return leafrefFromRecursion;
170 } else if (childNode.getQName().getLocalName().equals(nodeName) && childNode instanceof LeafSchemaNode) {
171 final TypeDefinition<?> leafSchemaNodeType = ((LeafSchemaNode)childNode).getType();
172 if (leafSchemaNodeType instanceof LeafrefTypeDefinition) {
173 return (LeafSchemaNode)childNode;
180 private static LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
181 final TypeDefinition<?> type = schemaNode.getType();
182 if (type instanceof LeafrefTypeDefinition) {
183 return (LeafrefTypeDefinition)type;