1 package org.opendaylight.yangtools.yang.data.impl.codec.xml;
3 import com.google.common.base.Preconditions;
6 import java.util.Map.Entry;
8 import javax.xml.stream.XMLStreamException;
9 import javax.xml.stream.XMLStreamWriter;
11 import org.opendaylight.yangtools.yang.common.QName;
12 import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
13 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
14 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.Node;
16 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
17 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
18 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
19 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
20 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 public class XmlStreamUtils {
31 private static final Logger LOG = LoggerFactory.getLogger(XmlStreamUtils.class);
33 public static void writeDataDocument(final XMLStreamWriter writer, final CompositeNode data, final SchemaNode schema, final XmlCodecProvider codecProvider) throws XMLStreamException {
34 // final Boolean repairing = (Boolean) writer.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
35 // Preconditions.checkArgument(repairing == true, "XML Stream Writer has to be repairing namespaces");
37 writer.writeStartDocument();
38 writeData(writer, data, schema, codecProvider);
39 writer.writeEndDocument();
43 public static void writeDataDocument(final XMLStreamWriter writer, final CompositeNode data, final XmlCodecProvider codecProvider) throws XMLStreamException {
44 writeDataDocument(writer, data, null, codecProvider);
47 public static void write(final XMLStreamWriter writer, final InstanceIdentifier id) throws XMLStreamException {
48 Preconditions.checkNotNull(writer, "Writer may not be null");
49 Preconditions.checkNotNull(id, "Variable should contain instance of instance identifier and can't be null");
51 final RandomPrefix prefixes = new RandomPrefix();
52 final String str = XmlUtils.encodeIdentifier(prefixes, id);
54 for (Entry<URI, String> e: prefixes.getPrefixes()) {
55 writer.writeNamespace(e.getValue(), e.getKey().toString());
57 writer.writeCharacters(str);
60 public static void writeData(final XMLStreamWriter writer, final Node<?> data, final SchemaNode schema, final XmlCodecProvider codecProvider) throws XMLStreamException {
61 final QName qname = data.getNodeType();
62 final String pfx = qname.getPrefix() != null ? qname.getPrefix() : "";
64 if (qname.getNamespace() != null) {
65 ns = qname.getNamespace().toString();
70 writer.writeStartElement(pfx, qname.getLocalName(), ns);
71 if (data instanceof AttributesContainer && ((AttributesContainer) data).getAttributes() != null) {
72 for (Entry<QName, String> attribute : ((AttributesContainer) data).getAttributes().entrySet()) {
73 writer.writeAttribute(attribute.getKey().getNamespace().toString(), attribute.getKey().getLocalName(), attribute.getValue());
77 if (data instanceof SimpleNode<?>) {
79 if (schema instanceof LeafListSchemaNode) {
80 writeValue(writer, ((LeafListSchemaNode) schema).getType(), codecProvider, data.getValue());
81 } else if (schema instanceof LeafSchemaNode) {
82 writeValue(writer, ((LeafSchemaNode) schema).getType(), codecProvider, data.getValue());
84 Object value = data.getValue();
86 writer.writeCharacters(String.valueOf(value));
91 for (Node<?> child : ((CompositeNode) data).getValue()) {
92 DataSchemaNode childSchema = null;
93 if (schema instanceof DataNodeContainer) {
94 childSchema = SchemaUtils.findFirstSchema(child.getNodeType(), ((DataNodeContainer) schema).getChildNodes()).orNull();
95 if (LOG.isDebugEnabled()) {
96 if (childSchema == null) {
97 LOG.debug("Probably the data node \"{}\" does not conform to schema", child == null ? "" : child.getNodeType().getLocalName());
102 writeData(writer, child, childSchema, codecProvider);
106 writer.writeEndElement();
109 public static void writeValue(final XMLStreamWriter writer, final TypeDefinition<?> type, final XmlCodecProvider codecProvider, final Object nodeValue) throws XMLStreamException {
110 TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
111 if (baseType instanceof IdentityrefTypeDefinition) {
112 if (nodeValue instanceof QName) {
113 QName value = (QName) nodeValue;
115 if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
116 prefix = value.getPrefix();
119 writer.writeNamespace(prefix, value.getNamespace().toString());
120 writer.writeCharacters(prefix + ':' + value.getLocalName());
122 Object value = nodeValue;
123 LOG.debug("Value of {}:{} is not instance of QName but is {}", baseType.getQName().getNamespace(),
124 baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
126 writer.writeCharacters(String.valueOf(value));
129 } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
130 if (nodeValue instanceof InstanceIdentifier) {
131 write(writer, (InstanceIdentifier)nodeValue);
133 Object value = nodeValue;
134 LOG.debug("Value of {}:{} is not instance of InstanceIdentifier but is {}", baseType.getQName()
136 baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
138 writer.writeCharacters(String.valueOf(value));
142 if (nodeValue != null) {
143 final TypeDefinitionAwareCodec<Object, ?> codec = codecProvider.codecFor(baseType);
147 text = codec.serialize(nodeValue);
148 } catch (ClassCastException e) {
149 LOG.error("Provided node value {} did not have type {} required by mapping. Using stream instead.", nodeValue, baseType, e);
150 text = String.valueOf(nodeValue);
153 LOG.error("Failed to find codec for {}, falling back to using stream", baseType);
154 text = String.valueOf(nodeValue);
156 writer.writeCharacters(text);