Merge "client IP/port definition in configuration separation new netconf.client prope...
authorEd Warnicke <eaw@cisco.com>
Wed, 4 Dec 2013 16:28:52 +0000 (16:28 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 4 Dec 2013 16:28:52 +0000 (16:28 +0000)
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/StructuredDataToXmlProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java [new file with mode: 0644]

index d0c007795263be5d8777ebd9af29774a8b47d0d9..fbddd05cafbaa6f5dd7808f31794cfb213a8deea 100644 (file)
@@ -25,7 +25,7 @@ import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -56,8 +56,9 @@ public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredD
         if (data == null) {
             throw new ResponseException(Response.Status.NOT_FOUND, "No data exists.");
         }
-
-        Document domTree = NodeUtils.buildShadowDomTree(data);
+        
+        XmlMapper xmlMapper = new XmlMapper();
+        Document domTree = xmlMapper.write(data, (DataNodeContainer) t.getSchema());
         try {
             TransformerFactory tf = TransformerFactory.newInstance();
             Transformer transformer = tf.newTransformer();
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java
new file mode 100644 (file)
index 0000000..39525f8
--- /dev/null
@@ -0,0 +1,119 @@
+package org.opendaylight.controller.sal.rest.impl;
+
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.YangNode;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.google.common.base.Preconditions;
+
+public class XmlMapper {
+
+    public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
+        Preconditions.checkNotNull(data);
+        Preconditions.checkNotNull(schema);
+
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        Document doc = null;
+        try {
+            DocumentBuilder bob = dbf.newDocumentBuilder();
+            doc = bob.newDocument();
+        } catch (ParserConfigurationException e) {
+            return null;
+        }
+
+        if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) {
+            doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema));
+            return doc;
+        } else {
+            throw new UnsupportedDataTypeException(
+                    "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+        }
+    }
+
+    private Element translateToXmlAndReturnRootElement(Document doc, Node<?> data, YangNode schema)
+            throws UnsupportedDataTypeException {
+        QName dataType = data.getNodeType();
+        Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
+
+        if (data instanceof SimpleNode<?>) {
+            if (schema instanceof LeafListSchemaNode) {
+                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType());
+            } else if (schema instanceof LeafSchemaNode) {
+                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType());
+            } else {
+                Object value = data.getValue();
+                if (value != null) {
+                    itemEl.setTextContent(String.valueOf(value));
+                }
+            }
+        } else { // CompositeNode
+            for (Node<?> child : ((CompositeNode) data).getChildren()) {
+                DataSchemaNode childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes());
+                if (childSchema == null) {
+                    throw new UnsupportedDataTypeException("Probably the data node \""
+                            + child.getNodeType().getLocalName() + "\" is not conform to schema");
+                }
+                itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema));
+            }
+        }
+        return itemEl;
+    }
+
+    private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type) {
+
+        TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+
+        if (baseType instanceof IdentityrefTypeDefinition && node.getValue() instanceof QName) {
+            QName value = (QName) node.getValue();
+            element.setAttribute("xmlns:x", value.getNamespace().toString());
+            element.setTextContent("x:" + value.getLocalName());
+        } else {
+            Object value = node.getValue();
+            if (value != null) {
+                element.setTextContent(String.valueOf(value));
+            }
+        }
+    }
+
+    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
+        for (DataSchemaNode dsn : dataSchemaNode) {
+            if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
+                return dsn;
+            } else if (dsn instanceof ChoiceNode) {
+                for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
+                    DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
+                    if (foundDsn != null) {
+                        return foundDsn;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+        return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
+    }
+
+}