Merge "BUG-461 Test transformation of rpc input using XmlDocumentUtils"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 29 Jul 2014 09:25:01 +0000 (09:25 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 29 Jul 2014 09:25:01 +0000 (09:25 +0000)
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/InstanceIdentifierForXmlCodec.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtilsTest.java [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/org/opendaylight/yangtools/yang/data/impl/codec/xml/rpc-test.yang [new file with mode: 0644]

index 6051b2681388aeb09fbf3213cba99d5ec33c259d..cb9667792808e99bc8004355d1f729a8052564ba 100644 (file)
@@ -149,7 +149,7 @@ public final class InstanceIdentifierForXmlCodec {
         } catch (URISyntaxException e) {
             throw new IllegalArgumentException("It wasn't possible to convert " + namespaceStr + " to URI object.");
         } catch (NullPointerException e) {
-            throw new IllegalArgumentException("I wasn't possible to get namespace for prefix " + prefix);
+            throw new IllegalArgumentException("It wasn't possible to get namespace for prefix " + prefix);
         }
 
         Module module = schemaContext.findModuleByNamespaceAndRevision(namespace, null);
index 262a48a93385579c74061d497ea11c0abcdcb18a..02f020c47fdc98307eb4ad2cf9aff0621cfb9529 100644 (file)
@@ -184,8 +184,17 @@ public class XmlDocumentUtils {
 
     public static Node<?> toDomNode(final Element xmlElement, final Optional<DataSchemaNode> schema,
             final Optional<XmlCodecProvider> codecProvider) {
+        return toDomNode(xmlElement, schema, codecProvider, Optional.<SchemaContext>absent());
+    }
+
+    public static Node<?> toDomNode(final Element xmlElement, final Optional<DataSchemaNode> schema,
+            final Optional<XmlCodecProvider> codecProvider, final Optional<SchemaContext> schemaContext) {
         if (schema.isPresent()) {
-            return toNodeWithSchema(xmlElement, schema.get(), codecProvider.or(XmlUtils.DEFAULT_XML_CODEC_PROVIDER));
+            if(schemaContext.isPresent()) {
+                return toNodeWithSchema(xmlElement, schema.get(), codecProvider.or(XmlUtils.DEFAULT_XML_CODEC_PROVIDER), schemaContext.get());
+            } else {
+                return toNodeWithSchema(xmlElement, schema.get(), codecProvider.or(XmlUtils.DEFAULT_XML_CODEC_PROVIDER));
+            }
         }
         return toDomNode(xmlElement);
     }
@@ -220,10 +229,11 @@ public class XmlDocumentUtils {
         if (codec != null) {
             value = codec.deserialize(text);
         }
+        final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(schema.getType());
 
-        if (schema.getType() instanceof org.opendaylight.yangtools.yang.model.util.InstanceIdentifier) {
+        if (baseType instanceof org.opendaylight.yangtools.yang.model.util.InstanceIdentifier) {
             value = InstanceIdentifierForXmlCodec.deserialize(xmlElement,schemaCtx);
-        } else if(schema.getType() instanceof IdentityrefTypeDefinition){
+        } else if(baseType instanceof IdentityrefTypeDefinition){
             value = InstanceIdentifierForXmlCodec.toIdentity(xmlElement.getTextContent(), xmlElement, schemaCtx);
         }
 
@@ -274,8 +284,8 @@ public class XmlDocumentUtils {
     }
 
     private static void checkQName(final Element xmlElement, final QName qName) {
-        checkState(Objects.equal(xmlElement.getNamespaceURI(), qName.getNamespace().toString()));
-        checkState(qName.getLocalName().equals(xmlElement.getLocalName()));
+        checkState(Objects.equal(xmlElement.getNamespaceURI(), qName.getNamespace().toString()),  "Not equal: %s to: %s for: %s and: %s", qName.getNamespace(), xmlElement.getNamespaceURI(), qName, xmlElement);
+        checkState(qName.getLocalName().equals(xmlElement.getLocalName()), "Not equal: %s to: %s for: %s and: %s", qName.getLocalName(), xmlElement.getLocalName(), qName, xmlElement);
     }
 
     public static final Optional<DataSchemaNode> findFirstSchema(final QName qname, final Iterable<DataSchemaNode> dataSchemaNode) {
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtilsTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtilsTest.java
new file mode 100644 (file)
index 0000000..97469fe
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.impl.codec.xml;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteSource;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import junit.framework.Assert;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class XmlDocumentUtilsTest {
+
+    private static final DocumentBuilderFactory BUILDERFACTORY;
+
+    static {
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        factory.setCoalescing(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
+        BUILDERFACTORY = factory;
+    }
+
+    public static final String XML_CONTENT = "<input xmlns=\"urn:opendaylight:controller:rpc:test\">\n" +
+            "<a>value</a>\n" +
+            "<ref xmlns:ltha=\"urn:opendaylight:controller:rpc:test\">/ltha:cont/ltha:l[ltha:id='id']</ref>\n" +
+            "</input>";
+
+    private SchemaContext schema;
+    private RpcDefinition testRpc;
+
+    @Before
+    public void setUp() throws Exception {
+        final ByteSource byteSource = new ByteSource() {
+            @Override
+            public InputStream openStream() throws IOException {
+                return XmlDocumentUtilsTest.this.getClass().getResourceAsStream("rpc-test.yang");
+            }
+        };
+        schema = new YangParserImpl().parseSources(Lists.newArrayList(byteSource));
+        final Module rpcTestModule = schema.getModules().iterator().next();
+        testRpc = rpcTestModule.getRpcs().iterator().next();
+    }
+
+    @Test
+    public void testRpcInputTransform() throws Exception {
+
+        final Document inputDocument = readXmlToDocument(XML_CONTENT);
+        final Element input = inputDocument.getDocumentElement();
+
+        final CompositeNode node = inputXmlToCompositeNode(input);
+        final SimpleNode<?> refParsed = node.getSimpleNodesByName("ref").iterator().next();
+        Assert.assertEquals(InstanceIdentifier.class, refParsed.getValue().getClass());
+        final Document serializedDocument = inputCompositeNodeToXml(node);
+
+        XMLUnit.compareXML(inputDocument, serializedDocument);
+    }
+
+    public static Document readXmlToDocument(final String xmlContent) throws SAXException, IOException {
+        return readXmlToDocument(new ByteArrayInputStream(xmlContent.getBytes(Charsets.UTF_8)));
+    }
+
+    public static Document readXmlToDocument(final InputStream xmlContent) throws SAXException, IOException {
+        final DocumentBuilder dBuilder;
+        try {
+            dBuilder = BUILDERFACTORY.newDocumentBuilder();
+        } catch (final ParserConfigurationException e) {
+            throw new IllegalStateException("Failed to parse XML document", e);
+        }
+        final Document doc = dBuilder.parse(xmlContent);
+
+        doc.getDocumentElement().normalize();
+        return doc;
+    }
+
+    public Document inputCompositeNodeToXml(final CompositeNode cNode)
+            throws UnsupportedDataTypeException {
+        return XmlDocumentUtils.toDocument(cNode, testRpc.getInput(), XmlDocumentUtils.defaultValueCodecProvider());
+    }
+
+    public CompositeNode inputXmlToCompositeNode(final Element e) {
+        return (CompositeNode) XmlDocumentUtils.toDomNode(e, Optional.<DataSchemaNode>of(testRpc.getInput()),
+                Optional.of(XmlDocumentUtils.defaultValueCodecProvider()), Optional.of(schema));
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/org/opendaylight/yangtools/yang/data/impl/codec/xml/rpc-test.yang b/yang/yang-data-impl/src/test/resources/org/opendaylight/yangtools/yang/data/impl/codec/xml/rpc-test.yang
new file mode 100644 (file)
index 0000000..94596f3
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+module rpc-test {
+    yang-version 1;
+    namespace "urn:opendaylight:controller:rpc:test";
+    prefix "rpct";
+
+    revision 2014-07-28 {
+       description "Initial test";
+    }
+
+    container cont {
+
+        list l {
+            key "id";
+
+            leaf id {
+                type string;
+            }
+        }
+    }
+
+    typedef custom-instance-identifier {
+        type instance-identifier;
+    }
+
+    rpc test {
+        input {
+            leaf a {
+                type string;
+            }
+
+            leaf ref {
+                type custom-instance-identifier;
+            }
+        }
+    }
+
+
+}