BUG-2304 Fix SchemaContextUtil for augmented nodes. 85/12785/5
authorJozef Gloncak <jgloncak@cisco.com>
Tue, 18 Nov 2014 08:52:38 +0000 (09:52 +0100)
committerJozef Gloncak <jgloncak@cisco.com>
Wed, 19 Nov 2014 10:22:44 +0000 (11:22 +0100)
Also keep backwards compatibility for invalid leafrefs
+ Fix the serialization in XMLStreamNormalizedNodeStreamWriter (btw. interesting name for a class)

Change-Id: I46cfcef46c97267c7e9b5bfebe03e42e9071e1e7
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java

index 97f676ae69bd62636764d138ea74e2ee4a678fb9..7f2c3019d35af9356115f33ff3ecc3da77e7a20f 100644 (file)
@@ -36,14 +36,15 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
  * {@link XMLStreamWriter}, resulting in a RFC 6020 XML encoding.
  */
 public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
-    private static final XmlStreamUtils UTILS = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER);
 
     private final XMLStreamWriter writer;
     private final SchemaTracker tracker;
+    private final XmlStreamUtils streamUtils;
 
     private XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context, final SchemaPath path) {
         this.writer = Preconditions.checkNotNull(writer);
         this.tracker = SchemaTracker.create(context, path);
+        this.streamUtils = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, context);
     }
 
     /**
@@ -82,7 +83,19 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
         try {
             writeStartElement(qname);
             if (value != null) {
-                UTILS.writeValue(writer, type, value);
+                streamUtils.writeValue(writer, type, value);
+            }
+            writer.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to emit element", e);
+        }
+    }
+
+    private void writeElement(final QName qname, final SchemaNode schemaNode, final Object value) throws IOException {
+        try {
+            writeStartElement(qname);
+            if (value != null) {
+                streamUtils.writeValue(writer, schemaNode, value);
             }
             writer.writeEndElement();
         } catch (XMLStreamException e) {
@@ -110,8 +123,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     @Override
     public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
         final LeafSchemaNode schema = tracker.leafNode(name);
-
-        writeElement(schema.getQName(), schema.getType(), value);
+        writeElement(schema.getQName(), schema, value);
     }
 
     @Override
@@ -122,7 +134,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     @Override
     public void leafSetEntryNode(final Object value) throws IOException {
         final LeafListSchemaNode schema = tracker.leafSetEntryNode();
-        writeElement(schema.getQName(), schema.getType(), value);
+        writeElement(schema.getQName(), schema, value);
     }
 
     @Override
@@ -173,7 +185,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
         try {
             writeStartElement(qname);
             if (value != null) {
-                UTILS.writeValue(writer, (Node<?>)value, schema);
+                streamUtils.writeValue(writer, (Node<?>)value, schema);
             }
             writer.writeEndElement();
         } catch (XMLStreamException e) {
index eb76a4c56dedc328082c9e18f47fcdfcf28ffda3..3fcb5784f7d44a55a123d9909ca1f466fc428325 100644 (file)
@@ -9,12 +9,6 @@ package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -56,7 +50,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Attr;
@@ -64,6 +60,13 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+
 public class XmlDocumentUtils {
     private static class ElementWithSchemaContext {
         Element element;
@@ -267,7 +270,13 @@ public class XmlDocumentUtils {
 
     private static Object resolveValueFromSchemaType(final Element xmlElement, final DataSchemaNode schema, final TypeDefinition<?> type,
         final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
-        final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+
+        TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+        if (baseType instanceof LeafrefTypeDefinition) {
+            final LeafrefTypeDefinition leafrefTypeDefinition = (LeafrefTypeDefinition) baseType;
+            baseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypeDefinition, schemaCtx, schema);
+        }
+
         final String text = xmlElement.getTextContent();
         final Object value;
 
@@ -276,7 +285,7 @@ public class XmlDocumentUtils {
         } else if (baseType instanceof IdentityrefTypeDefinition) {
             value = InstanceIdentifierForXmlCodec.toIdentity(text, xmlElement, schemaCtx);
         } else {
-            final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(type);
+            final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(baseType);
             if (codec == null) {
                 LOG.info("No codec for schema {}, falling back to text", schema);
                 value = text;
index f451b4155e1ec323f6a592c87a7bc35440dcebea..132edfc347bdb7dd2405aefd755cfc832a118bd9 100644 (file)
@@ -513,8 +513,7 @@ public final class SchemaContextUtil {
             Preconditions.checkArgument(module != null, "Failed to resolve xpath: no module found for prefix %s in module %s",
                     modulePrefix, parentModule.getName());
 
-            // FIXME: Module should have a QNameModule handle
-            return QName.create(module.getNamespace(), module.getRevision(), prefixedName.next());
+            return QName.create(module.getQNameModule(), prefixedName.next());
         } else {
             return QName.create(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
         }
@@ -626,7 +625,7 @@ public final class SchemaContextUtil {
      *            Schema Context
      * @param schema
      *            Schema Node
-     * @return
+     * @return recursively found type definition this leafref is pointing to or null if the xpath is incorrect (null is there to preserve backwards compatibility)
      */
     public static TypeDefinition<?> getBaseTypeForLeafRef(final LeafrefTypeDefinition typeDefinition, final SchemaContext schemaContext, final SchemaNode schema) {
         RevisionAwareXPath pathStatement = typeDefinition.getPathStatement();
@@ -641,6 +640,13 @@ public final class SchemaContextUtil {
             dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule, schema, pathStatement);
         }
 
+        // FIXME this is just to preserve backwards compatibility since yangtools do not mind wrong leafref xpaths
+        // and current expected behaviour for such cases is to just use pure string
+        // This should throw an exception about incorrect XPath in leafref
+        if(dataSchemaNode == null) {
+            return null;
+        }
+
         final TypeDefinition<?> targetTypeDefinition = typeDefinition(dataSchemaNode);
 
         if(targetTypeDefinition instanceof LeafrefTypeDefinition) {