--- /dev/null
+/*
+ * 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<QName, String> attributes) throws IOException, IllegalArgumentException;
+
+ void leafSetEntryNode(Object value, Map<QName, String> attributes) throws IOException, IllegalArgumentException;
+
+ void startContainerNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint, Map<QName, String> attributes) throws IOException, IllegalArgumentException;
+
+ void startUnkeyedListItem(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint, Map<QName, String> attributes) throws IOException, IllegalStateException;
+
+ void startMapEntryNode(YangInstanceIdentifier.NodeIdentifierWithPredicates identifier, int childSizeHint, Map<QName, String> attributes) throws IOException, IllegalArgumentException;
+}
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;
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;
}
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) {
*/
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;
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;
* 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();
}
/**
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);
}
}
}
+ private void writeElement(final QName qname, final SchemaNode schemaNode, final Object value, final Map<QName, String> 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);
writeElement(schema.getQName(), schema, value);
}
+ @Override
+ public void leafNode(final NodeIdentifier name, final Object value, final Map<QName, String> attributes) throws IOException {
+ final LeafSchemaNode schema = tracker.leafNode(name);
+ writeElement(schema.getQName(), schema, value, attributes);
+ }
+
+ @Override
+ public void leafSetEntryNode(final Object value, final Map<QName, String> 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<QName, String> attributes) throws IOException, IllegalArgumentException {
+ startContainerNode(name, childSizeHint);
+ writeAttributes(attributes);
+ }
+
+ @Override
+ public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint, final Map<QName, String> attributes) throws IOException, IllegalStateException {
+ startUnkeyedListItem(name, childSizeHint);
+ writeAttributes(attributes);
+ }
+
+ @Override
+ public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint, final Map<QName, String> attributes) throws IOException, IllegalArgumentException {
+ startMapEntryNode(identifier, childSizeHint);
+ writeAttributes(attributes);
+ }
+
+ private void writeAttributes(final Map<QName, String> attributes) throws IOException {
+ for (final Map.Entry<QName, String> 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);