Fixed RESTConf support for identity-ref build-in datatype
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / rest / impl / XmlMapper.java
index 39525f85994966c71dae3ba2f186a7ebcdf9707f..f580b3216c83351ace4110455255db320f717a4c 100644 (file)
@@ -7,6 +7,9 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
@@ -22,12 +25,16 @@ 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import com.google.common.base.Preconditions;
 
 public class XmlMapper {
+    
+    private final Logger logger = LoggerFactory.getLogger(XmlMapper.class); 
 
     public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
         Preconditions.checkNotNull(data);
@@ -55,7 +62,6 @@ public class XmlMapper {
             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());
@@ -69,10 +75,15 @@ public class XmlMapper {
             }
         } 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");
+                DataSchemaNode childSchema = null;
+                if(schema != null){
+                    childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes());
+                    if (logger.isDebugEnabled()) {
+                        if (childSchema == null) {
+                            logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName())
+                                    + "\" is not conform to schema");
+                        }
+                    }
                 }
                 itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema));
             }
@@ -84,10 +95,21 @@ public class XmlMapper {
 
         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());
+        if (baseType instanceof IdentityrefTypeDefinition) {
+            if (node.getValue() instanceof QName) {
+                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
+                IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
+                String prefix = "x";
+                if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
+                    prefix = value.getPrefix();
+                }
+                element.setAttribute("xmlns:" + prefix, value.getNamespace());
+                element.setTextContent(prefix + ":" + value.getValue());
+            } else {
+                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                element.setTextContent(String.valueOf(node.getValue()));
+            }
         } else {
             Object value = node.getValue();
             if (value != null) {
@@ -97,14 +119,16 @@ public class XmlMapper {
     }
 
     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;
+        if (dataSchemaNode != null && node != null) {
+            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;
+                        }
                     }
                 }
             }