From c13036931c60458dfd78875ecd0ac3bb1610c7f6 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 10 Mar 2015 11:50:10 +0100 Subject: [PATCH] Add support for attributes int NN stream writer Change-Id: I51dc747763a65dee5145a33657eaf7223945d096 Signed-off-by: Maros Marsalek --- .../NormalizedNodeStreamAttributeWriter.java | 29 ++++++++ .../schema/stream/NormalizedNodeWriter.java | 28 +++++-- .../XMLStreamNormalizedNodeStreamWriter.java | 74 +++++++++++++++++-- 3 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeStreamAttributeWriter.java diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeStreamAttributeWriter.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeStreamAttributeWriter.java new file mode 100644 index 0000000000..ca0e3428bb --- /dev/null +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeStreamAttributeWriter.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.data.api.schema.stream; + +import java.io.IOException; +import java.util.Map; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; + +/** + * Extension to the NormalizedNodeStreamWriter with attribute support + */ +public interface NormalizedNodeStreamAttributeWriter extends NormalizedNodeStreamWriter { + + void leafNode(YangInstanceIdentifier.NodeIdentifier name, Object value, Map attributes) throws IOException, IllegalArgumentException; + + void leafSetEntryNode(Object value, Map attributes) throws IOException, IllegalArgumentException; + + void startContainerNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint, Map attributes) throws IOException, IllegalArgumentException; + + void startUnkeyedListItem(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint, Map attributes) throws IOException, IllegalStateException; + + void startMapEntryNode(YangInstanceIdentifier.NodeIdentifierWithPredicates identifier, int childSizeHint, Map attributes) throws IOException, IllegalArgumentException; +} diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeWriter.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeWriter.java index 6a19b45f37..7b567f6423 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeWriter.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeWriter.java @@ -14,15 +14,12 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; - import java.io.Closeable; import java.io.Flushable; import java.io.IOException; import java.util.Collection; import java.util.Set; - import javax.xml.stream.XMLStreamReader; - import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode; @@ -137,11 +134,19 @@ public class NormalizedNodeWriter implements Closeable, Flushable { private boolean wasProcessAsSimpleNode(final NormalizedNode node) throws IOException { if (node instanceof LeafSetEntryNode) { final LeafSetEntryNode nodeAsLeafList = (LeafSetEntryNode)node; - writer.leafSetEntryNode(nodeAsLeafList.getValue()); + if(writer instanceof NormalizedNodeStreamAttributeWriter) { + ((NormalizedNodeStreamAttributeWriter) writer).leafSetEntryNode(nodeAsLeafList.getValue(), nodeAsLeafList.getAttributes()); + } else { + writer.leafSetEntryNode(nodeAsLeafList.getValue()); + } return true; } else if (node instanceof LeafNode) { final LeafNode nodeAsLeaf = (LeafNode)node; - writer.leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue()); + if(writer instanceof NormalizedNodeStreamAttributeWriter) { + ((NormalizedNodeStreamAttributeWriter) writer).leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue(), nodeAsLeaf.getAttributes()); + } else { + writer.leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue()); + } return true; } else if (node instanceof AnyXmlNode) { final AnyXmlNode anyXmlNode = (AnyXmlNode)node; @@ -169,14 +174,23 @@ public class NormalizedNodeWriter implements Closeable, Flushable { } protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException { - writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue())); + if(writer instanceof NormalizedNodeStreamAttributeWriter) { + ((NormalizedNodeStreamAttributeWriter) writer) + .startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()), node.getAttributes()); + } else { + writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue())); + } return writeChildren(node.getValue()); } private boolean wasProcessedAsCompositeNode(final NormalizedNode node) throws IOException { if (node instanceof ContainerNode) { final ContainerNode n = (ContainerNode) node; - writer.startContainerNode(n.getIdentifier(), childSizeHint(n.getValue())); + if(writer instanceof NormalizedNodeStreamAttributeWriter) { + ((NormalizedNodeStreamAttributeWriter) writer).startContainerNode(n.getIdentifier(), childSizeHint(n.getValue()), n.getAttributes()); + } else { + writer.startContainerNode(n.getIdentifier(), childSizeHint(n.getValue())); + } return writeChildren(n.getValue()); } if (node instanceof MapEntryNode) { 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 ddc8076d61..e8e2f92722 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 @@ -7,10 +7,12 @@ */ package org.opendaylight.yangtools.yang.data.impl.codec.xml; -import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX; - import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import java.io.IOException; +import java.io.StringWriter; +import java.util.Map; +import javax.xml.XMLConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.opendaylight.yangtools.yang.common.QName; @@ -19,6 +21,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.Augmentat import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamAttributeWriter; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; @@ -35,16 +38,18 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition; * A {@link NormalizedNodeStreamWriter} which translates the events into an * {@link XMLStreamWriter}, resulting in a RFC 6020 XML encoding. */ -public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter { +public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamAttributeWriter { private final XMLStreamWriter writer; private final SchemaTracker tracker; private final XmlStreamUtils streamUtils; + private RandomPrefix randomPrefix; 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); + randomPrefix = new RandomPrefix(); } /** @@ -72,9 +77,9 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode private void writeStartElement( QName qname) throws XMLStreamException { String ns = qname.getNamespace().toString(); - writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns); + writer.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, qname.getLocalName(), ns); if(writer.getNamespaceContext() != null) { - String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX); + String parentNs = writer.getNamespaceContext().getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX); if (!ns.equals(parentNs)) { writer.writeDefaultNamespace(ns); } @@ -105,6 +110,19 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode } } + private void writeElement(final QName qname, final SchemaNode schemaNode, final Object value, final Map attributes) throws IOException { + try { + writeStartElement(qname); + writeAttributes(attributes); + if (value != null) { + streamUtils.writeValue(writer, schemaNode, value); + } + writer.writeEndElement(); + } catch (XMLStreamException e) { + throw new IOException("Failed to emit element", e); + } + } + private void startElement(final QName qname) throws IOException { try { writeStartElement(qname); @@ -128,6 +146,52 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode writeElement(schema.getQName(), schema, value); } + @Override + public void leafNode(final NodeIdentifier name, final Object value, final Map attributes) throws IOException { + final LeafSchemaNode schema = tracker.leafNode(name); + writeElement(schema.getQName(), schema, value, attributes); + } + + @Override + public void leafSetEntryNode(final Object value, final Map attributes) throws IOException, IllegalArgumentException { + final LeafListSchemaNode schema = tracker.leafSetEntryNode(); + writeElement(schema.getQName(), schema, value, attributes); + } + + @Override + public void startContainerNode(final NodeIdentifier name, final int childSizeHint, final Map attributes) throws IOException, IllegalArgumentException { + startContainerNode(name, childSizeHint); + writeAttributes(attributes); + } + + @Override + public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint, final Map attributes) throws IOException, IllegalStateException { + startUnkeyedListItem(name, childSizeHint); + writeAttributes(attributes); + } + + @Override + public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint, final Map attributes) throws IOException, IllegalArgumentException { + startMapEntryNode(identifier, childSizeHint); + writeAttributes(attributes); + } + + private void writeAttributes(final Map attributes) throws IOException { + for (final Map.Entry qNameStringEntry : attributes.entrySet()) { + try { + final String namespace = qNameStringEntry.getKey().getNamespace().toString(); + if(Strings.isNullOrEmpty(namespace)) { + writer.writeAttribute(qNameStringEntry.getKey().getLocalName(), qNameStringEntry.getValue()); + } else { + final String prefix = randomPrefix.encodePrefix(qNameStringEntry.getKey().getNamespace()); + writer.writeAttribute(prefix, namespace, qNameStringEntry.getKey().getLocalName(), qNameStringEntry.getValue()); + } + } catch (final XMLStreamException e) { + throw new IOException("Unable to emit attribute " + qNameStringEntry, e); + } + } + } + @Override public void startLeafSet(final NodeIdentifier name, final int childSizeHint) { tracker.startLeafSet(name); -- 2.36.6