From d1dd191ea54dcd3952cf4e68aa8661fb51d2b99b Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 18 Nov 2014 09:52:38 +0100 Subject: [PATCH] BUG-2304 Fix SchemaContextUtil for augmented nodes. 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 Signed-off-by: Jozef Gloncak --- .../XMLStreamNormalizedNodeStreamWriter.java | 24 +++++++++++++----- .../data/impl/codec/xml/XmlDocumentUtils.java | 25 +++++++++++++------ .../yang/model/util/SchemaContextUtil.java | 12 ++++++--- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java index 97f676ae69..7f2c3019d3 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java @@ -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) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java index eb76a4c56d..3fcb5784f7 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java @@ -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; diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java index f451b4155e..132edfc347 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java @@ -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) { -- 2.36.6