Rename XmlStreamUtils
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / SchemaAwareXMLStreamNormalizedNodeStreamWriter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.yangtools.yang.data.codec.xml;
10
11 import com.google.common.base.Strings;
12 import java.io.IOException;
13 import java.util.Collections;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import javax.annotation.Nonnull;
17 import javax.xml.stream.XMLStreamException;
18 import javax.xml.stream.XMLStreamWriter;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
24 import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
25 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
33
34 final class SchemaAwareXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<SchemaNode> {
35     private final SchemaTracker tracker;
36     private final XMLStreamWriterUtils streamUtils;
37
38     private SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context,
39                                                            final SchemaPath path) {
40         super(writer);
41         this.tracker = SchemaTracker.create(context, path);
42         this.streamUtils = XMLStreamWriterUtils.create(context);
43     }
44
45     static NormalizedNodeStreamWriter newInstance(final XMLStreamWriter writer, final SchemaContext context,
46             final SchemaPath path) {
47         return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, path);
48     }
49
50     @Override
51     protected void writeAttributes(@Nonnull final Map<QName, String> attributes) throws IOException {
52         for (final Entry<QName, String> qNameStringEntry : attributes.entrySet()) {
53             try {
54                 final String namespace = qNameStringEntry.getKey().getNamespace().toString();
55
56                 if (Strings.isNullOrEmpty(namespace)) {
57                     writer.writeAttribute(qNameStringEntry.getKey().getLocalName(), qNameStringEntry.getValue());
58                 } else {
59                     writer.writeAttribute(namespace, qNameStringEntry.getKey().getLocalName(), qNameStringEntry.getValue());
60                 }
61             } catch (final XMLStreamException e) {
62                 throw new IOException("Unable to emit attribute " + qNameStringEntry, e);
63             }
64         }
65     }
66
67     @Override
68     protected void writeValue(final XMLStreamWriter xmlWriter, final QName qname, @Nonnull final Object value,
69             final SchemaNode schemaNode) throws IOException, XMLStreamException {
70         streamUtils.writeValue(xmlWriter, schemaNode, value, qname.getModule());
71     }
72
73     @Override
74     protected void startList(final NodeIdentifier name) {
75         tracker.startList(name);
76     }
77
78     @Override
79     protected void startListItem(final PathArgument name) throws IOException {
80         tracker.startListItem(name);
81         startElement(name.getNodeType());
82     }
83
84     @Override
85     protected void endNode(final XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {
86         final Object schema = tracker.endNode();
87         if (schema instanceof ListSchemaNode) {
88             // For lists, we only emit end element on the inner frame
89             final Object parent = tracker.getParent();
90             if (parent == schema) {
91                 xmlWriter.writeEndElement();
92             }
93         } else if (schema instanceof ContainerSchemaNode) {
94             // Emit container end element
95             xmlWriter.writeEndElement();
96         }
97     }
98
99     @Override
100     public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
101         final LeafSchemaNode schema = tracker.leafNode(name);
102         writeElement(schema.getQName(), value, Collections.emptyMap(), schema);
103     }
104
105     @Override
106     public void leafNode(NodeIdentifier name, Object value, Map<QName, String> attributes) throws IOException {
107         final LeafSchemaNode schema = tracker.leafNode(name);
108         writeElement(schema.getQName(), value, attributes, schema);
109     }
110
111     @Override
112     public void leafSetEntryNode(final QName name, final Object value, final Map<QName, String> attributes)
113             throws IOException {
114         final LeafListSchemaNode schema = tracker.leafSetEntryNode(name);
115         writeElement(schema.getQName(), value, attributes, schema);
116     }
117
118     @Override
119     public void leafSetEntryNode(final QName name, final Object value) throws IOException {
120         final LeafListSchemaNode schema = tracker.leafSetEntryNode(name);
121         writeElement(schema.getQName(), value, Collections.emptyMap(), schema);
122     }
123     @Override
124     public void startLeafSet(final NodeIdentifier name, final int childSizeHint) {
125         tracker.startLeafSet(name);
126     }
127
128     @Override
129     public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) {
130         tracker.startLeafSet(name);
131     }
132
133     @Override
134     public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
135         final SchemaNode schema = tracker.startContainerNode(name);
136         startElement(schema.getQName());
137     }
138
139     @Override
140     public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) {
141         tracker.startChoiceNode(name);
142     }
143
144     @Override
145     public void startAugmentationNode(final AugmentationIdentifier identifier) {
146         tracker.startAugmentationNode(identifier);
147     }
148
149     @Override
150     public void startYangModeledAnyXmlNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
151         final SchemaNode schema = tracker.startYangModeledAnyXmlNode(name);
152         startElement(schema.getQName());
153     }
154
155     @Override
156     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
157         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
158         anyxmlNode(schema.getQName(), value);
159     }
160 }