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>
* {@link XMLStreamWriter}, resulting in a RFC 6020 XML encoding.
*/
public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
* {@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 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);
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);
try {
writeStartElement(qname);
if (value != null) {
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) {
}
writer.writeEndElement();
} catch (XMLStreamException e) {
@Override
public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
final LeafSchemaNode schema = tracker.leafNode(name);
@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
public void leafSetEntryNode(final Object value) throws IOException {
final LeafListSchemaNode schema = tracker.leafSetEntryNode();
@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);
try {
writeStartElement(qname);
if (value != null) {
try {
writeStartElement(qname);
if (value != null) {
- UTILS.writeValue(writer, (Node<?>)value, schema);
+ streamUtils.writeValue(writer, (Node<?>)value, schema);
}
writer.writeEndElement();
} catch (XMLStreamException e) {
}
writer.writeEndElement();
} catch (XMLStreamException e) {
import static com.google.common.base.Preconditions.checkState;
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;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
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.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.InstanceIdentifierType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
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;
public class XmlDocumentUtils {
private static class ElementWithSchemaContext {
Element element;
private static Object resolveValueFromSchemaType(final Element xmlElement, final DataSchemaNode schema, final TypeDefinition<?> type,
final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
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;
final String text = xmlElement.getTextContent();
final Object value;
} else if (baseType instanceof IdentityrefTypeDefinition) {
value = InstanceIdentifierForXmlCodec.toIdentity(text, xmlElement, schemaCtx);
} else {
} 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;
if (codec == null) {
LOG.info("No codec for schema {}, falling back to text", schema);
value = text;
Preconditions.checkArgument(module != null, "Failed to resolve xpath: no module found for prefix %s in module %s",
modulePrefix, parentModule.getName());
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);
}
} else {
return QName.create(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
}
* Schema Context
* @param schema
* Schema Node
* Schema Context
* @param schema
* Schema Node
+ * @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();
*/
public static TypeDefinition<?> getBaseTypeForLeafRef(final LeafrefTypeDefinition typeDefinition, final SchemaContext schemaContext, final SchemaNode schema) {
RevisionAwareXPath pathStatement = typeDefinition.getPathStatement();
dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule, schema, pathStatement);
}
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) {
final TypeDefinition<?> targetTypeDefinition = typeDefinition(dataSchemaNode);
if(targetTypeDefinition instanceof LeafrefTypeDefinition) {