summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
1e6c1c1)
In order to have control over when we output an element, we need
to make sure we know how the writer is being used.
Refactor XMLStreamNormalizedNodeStreamWriter interaction with its
subclasses so we know when we are leaking the writer -- which
happens only in writeValue().
JIRA: YANGTOOLS-927
Change-Id: I7e7bd62016e994a31fe6d69995e9d088746359da
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit
127cfbef06dec06721efc4fafe2e9ab551c644e6)
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
-import javax.annotation.Nonnull;
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.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
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.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-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;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
private final SchemaTracker tracker;
private final SchemaAwareXMLStreamWriterUtils streamUtils;
private final SchemaTracker tracker;
private final SchemaAwareXMLStreamWriterUtils streamUtils;
- private SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context,
+ SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context,
final SchemaPath path) {
super(writer);
this.tracker = SchemaTracker.create(context, path);
this.streamUtils = new SchemaAwareXMLStreamWriterUtils(context);
}
final SchemaPath path) {
super(writer);
this.tracker = SchemaTracker.create(context, path);
this.streamUtils = new SchemaAwareXMLStreamWriterUtils(context);
}
- static NormalizedNodeStreamWriter newInstance(final XMLStreamWriter writer, final SchemaContext context,
- final SchemaPath path) {
- return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, path);
- }
-
- protected void writeValue(final XMLStreamWriter xmlWriter, final QName qname, @Nonnull final Object value,
+ void writeValue(final XMLStreamWriter xmlWriter, final QName qname, final Object value,
final SchemaNode schemaNode) throws IOException, XMLStreamException {
streamUtils.writeValue(xmlWriter, schemaNode, value, qname.getModule());
}
@Override
final SchemaNode schemaNode) throws IOException, XMLStreamException {
streamUtils.writeValue(xmlWriter, schemaNode, value, qname.getModule());
}
@Override
- protected void startList(final NodeIdentifier name) {
+ void startList(final NodeIdentifier name) {
tracker.startList(name);
}
@Override
tracker.startList(name);
}
@Override
- protected void startListItem(final PathArgument name) throws IOException {
+ void startListItem(final PathArgument name) throws IOException {
tracker.startListItem(name);
startElement(name.getNodeType());
}
@Override
tracker.startListItem(name);
startElement(name.getNodeType());
}
@Override
- protected void endNode(final XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {
+ public void endNode() throws IOException {
final Object schema = tracker.endNode();
if (schema instanceof ListSchemaNode) {
// For lists, we only emit end element on the inner frame
final Object parent = tracker.getParent();
if (parent == schema) {
final Object schema = tracker.endNode();
if (schema instanceof ListSchemaNode) {
// For lists, we only emit end element on the inner frame
final Object parent = tracker.getParent();
if (parent == schema) {
- xmlWriter.writeEndElement();
}
} else if (schema instanceof ContainerSchemaNode) {
// Emit container end element
}
} else if (schema instanceof ContainerSchemaNode) {
// Emit container end element
- xmlWriter.writeEndElement();
import java.util.Collections;
import java.util.Deque;
import java.util.Map;
import java.util.Collections;
import java.util.Deque;
import java.util.Map;
-import javax.annotation.Nonnull;
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.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
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.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
final class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<Object> {
private enum ContainerType {
final class SchemalessXMLStreamNormalizedNodeStreamWriter extends XMLStreamNormalizedNodeStreamWriter<Object> {
private enum ContainerType {
private final Deque<ContainerType> containerTypeStack = new ArrayDeque<>();
private final Deque<ContainerType> containerTypeStack = new ArrayDeque<>();
- private SchemalessXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
+ SchemalessXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
- static NormalizedNodeStreamWriter newInstance(final XMLStreamWriter writer) {
- return new SchemalessXMLStreamNormalizedNodeStreamWriter(writer);
- }
-
@Override
public void leafNode(final NodeIdentifier name, final Object value, final Map<QName, String> attributes)
throws IOException {
@Override
public void leafNode(final NodeIdentifier name, final Object value, final Map<QName, String> attributes)
throws IOException {
- protected void writeValue(final XMLStreamWriter xmlWriter, final QName qname, @Nonnull final Object value,
- final Object context) throws XMLStreamException {
+ void writeValue(final XMLStreamWriter xmlWriter, final QName qname, final Object value, final Object context)
+ throws XMLStreamException {
xmlWriter.writeCharacters(value.toString());
}
@Override
xmlWriter.writeCharacters(value.toString());
}
@Override
- protected void startList(final NodeIdentifier name) {
+ void startList(final NodeIdentifier name) {
containerTypeStack.push(ContainerType.LIST);
}
@Override
containerTypeStack.push(ContainerType.LIST);
}
@Override
- protected void startListItem(final PathArgument name) throws IOException {
+ void startListItem(final PathArgument name) throws IOException {
containerTypeStack.push(ContainerType.LIST_ITEM);
startElement(name.getNodeType());
}
@Override
containerTypeStack.push(ContainerType.LIST_ITEM);
startElement(name.getNodeType());
}
@Override
- protected void endNode(final XMLStreamWriter xmlWriter) throws IOException, XMLStreamException {
+ public void endNode() throws IOException {
ContainerType type = containerTypeStack.pop();
switch (type) {
case CONTAINER:
case LIST_ITEM:
case ANY_XML:
ContainerType type = containerTypeStack.pop();
switch (type) {
case CONTAINER:
case LIST_ITEM:
case ANY_XML:
- xmlWriter.writeEndElement();
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stream.StreamResult;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
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.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
private static final Set<String> BROKEN_NAMESPACES = ConcurrentHashMap.newKeySet();
private static final Set<String> BROKEN_NAMESPACES = ConcurrentHashMap.newKeySet();
+ private final @NonNull XMLStreamWriter writer;
private final RandomPrefix prefixes;
private final RandomPrefix prefixes;
- final XMLStreamWriter writer;
XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
this.writer = requireNonNull(writer);
XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
this.writer = requireNonNull(writer);
*
* @return A new {@link NormalizedNodeStreamWriter}
*/
*
* @return A new {@link NormalizedNodeStreamWriter}
*/
- public static NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
+ public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
- return SchemaAwareXMLStreamNormalizedNodeStreamWriter.newInstance(writer, context, path);
+ return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, path);
*
* @return A new {@link NormalizedNodeStreamWriter}
*/
*
* @return A new {@link NormalizedNodeStreamWriter}
*/
- public static NormalizedNodeStreamWriter createSchemaless(final XMLStreamWriter writer) {
- return SchemalessXMLStreamNormalizedNodeStreamWriter.newInstance(writer);
+ public static @NonNull NormalizedNodeStreamWriter createSchemaless(final XMLStreamWriter writer) {
+ return new SchemalessXMLStreamNormalizedNodeStreamWriter(writer);
- abstract void writeValue(XMLStreamWriter xmlWriter, QName qname, @Nonnull Object value, T context)
+ abstract void writeValue(@NonNull XMLStreamWriter xmlWriter, QName qname, @NonNull Object value, T context)
throws IOException, XMLStreamException;
abstract void startList(NodeIdentifier name);
abstract void startListItem(PathArgument name) throws IOException;
throws IOException, XMLStreamException;
abstract void startList(NodeIdentifier name);
abstract void startListItem(PathArgument name) throws IOException;
- private void writeAttributes(@Nonnull final Map<QName, String> attributes) throws IOException {
+ private void writeAttributes(final @NonNull Map<QName, String> attributes) throws IOException {
for (final Entry<QName, String> entry : attributes.entrySet()) {
try {
final QName qname = entry.getKey();
for (final Entry<QName, String> entry : attributes.entrySet()) {
try {
final QName qname = entry.getKey();
- void writeElement(final QName qname, final Object value, @Nullable final Map<QName, String> attributes,
+ final void writeElement(final QName qname, final Object value, final @Nullable Map<QName, String> attributes,
final T context) throws IOException {
try {
writeStartElement(qname);
final T context) throws IOException {
try {
writeStartElement(qname);
- writeAttributes(attributes);
+ if (attributes != null) {
+ writeAttributes(attributes);
+ }
if (value != null) {
writeValue(writer, qname, value, context);
}
if (value != null) {
writeValue(writer, qname, value, context);
}
- void startElement(final QName qname) throws IOException {
+ final void startElement(final QName qname) throws IOException {
try {
writeStartElement(qname);
} catch (XMLStreamException e) {
try {
writeStartElement(qname);
} catch (XMLStreamException e) {
- void anyxmlNode(final QName qname, final Object value) throws IOException {
+ final void endElement() throws IOException {
+ try {
+ writer.writeEndElement();
+ } catch (XMLStreamException e) {
+ throw new IOException("Failed to end element", e);
+ }
+ }
+
+ final void anyxmlNode(final QName qname, final Object value) throws IOException {
if (value != null) {
checkArgument(value instanceof DOMSource, "AnyXML value must be DOMSource, not %s", value);
final DOMSource domSource = (DOMSource) value;
if (value != null) {
checkArgument(value instanceof DOMSource, "AnyXML value must be DOMSource, not %s", value);
final DOMSource domSource = (DOMSource) value;
- abstract void endNode(XMLStreamWriter xmlWriter) throws IOException, XMLStreamException;
-
- @Override
- public final void endNode() throws IOException {
- try {
- endNode(writer);
- } catch (XMLStreamException e) {
- throw new IOException("Failed to end element", e);
- }
- }
-
@Override
public final void close() throws IOException {
try {
@Override
public final void close() throws IOException {
try {