Allow emission of operation input/output
[yangtools.git] / codec / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / SchemaAwareXMLStreamNormalizedNodeStreamWriter.java
index 6168b96abb560c6860217829234beaea645563b1..2d73959ab08cb07e0070f11f6056b4928d231110 100644 (file)
@@ -8,7 +8,6 @@
  */
 package org.opendaylight.yangtools.yang.data.codec.xml;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.Objects.requireNonNull;
 
@@ -17,6 +16,7 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMSource;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.rfc7952.model.api.AnnotationSchemaNode;
 import org.opendaylight.yangtools.yang.common.AnnotationName;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -24,28 +24,37 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.util.NormalizedNodeStreamWriterStack;
-import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerLike;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnydataEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 
 final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
-        extends XMLStreamNormalizedNodeStreamWriter<TypedDataSchemaNode> implements EffectiveModelContextProvider {
+        extends XMLStreamNormalizedNodeStreamWriter<TypedDataSchemaNode> {
     private final NormalizedNodeStreamWriterStack tracker;
     private final SchemaAwareXMLStreamWriterUtils streamUtils;
 
-    SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final EffectiveModelContext context,
-            final NormalizedNodeStreamWriterStack tracker) {
-        super(writer);
+    private SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer,
+            final EffectiveModelContext modelContext, final NormalizedNodeStreamWriterStack tracker,
+            final @Nullable PreferredPrefixes pref) {
+        super(writer, pref);
         this.tracker = requireNonNull(tracker);
-        streamUtils = new SchemaAwareXMLStreamWriterUtils(context);
+        streamUtils = new SchemaAwareXMLStreamWriterUtils(modelContext, pref);
+    }
+
+    SchemaAwareXMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer,
+            final EffectiveModelContext modelContext, final NormalizedNodeStreamWriterStack tracker,
+            final boolean modelPrefixes) {
+        this(writer, modelContext, tracker, modelPrefixes ? new PreferredPrefixes.Shared(modelContext) : null);
     }
 
     @Override
@@ -58,16 +67,19 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
     @Override
     String encodeAnnotationValue(final ValueWriter xmlWriter, final QName qname, final Object value)
             throws XMLStreamException {
-        final var optAnnotation = AnnotationSchemaNode.find(streamUtils.getEffectiveModelContext(),
-            new AnnotationName(qname));
+        final var optAnnotation = AnnotationSchemaNode.find(streamUtils.modelContext(), new AnnotationName(qname));
         if (optAnnotation.isPresent()) {
             return streamUtils.encodeValue(xmlWriter, resolveType(optAnnotation.orElseThrow().getType()), value,
                 qname.getModule());
         }
 
-        checkArgument(!qname.getRevision().isPresent(), "Failed to find bound annotation %s", qname);
-        checkArgument(value instanceof String, "Invalid non-string value %s for unbound annotation %s", value, qname);
-        return (String) value;
+        if (qname.getRevision().isPresent()) {
+            throw new IllegalArgumentException("Failed to find bound annotation " + qname);
+        }
+        if (value instanceof String str) {
+            return str;
+        }
+        throw new IllegalArgumentException("Invalid non-string value " + value + " for unbound annotation " + qname);
     }
 
     @Override
@@ -83,15 +95,16 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
 
     @Override
     public void endNode() throws IOException {
-        final Object schema = tracker.endNode();
-        if (schema instanceof ListSchemaNode || schema instanceof LeafListSchemaNode) {
+        final var schema = tracker.endNode();
+        if (schema instanceof ListEffectiveStatement || schema instanceof LeafListEffectiveStatement) {
             // For lists, we only emit end element on the inner frame
-            final Object parent = tracker.getParent();
-            if (parent == schema) {
+            if (tracker.currentStatement() == schema) {
                 endElement();
             }
-        } else if (schema instanceof ContainerLike || schema instanceof LeafSchemaNode
-                || schema instanceof AnydataSchemaNode || schema instanceof AnyxmlSchemaNode) {
+        } else if (schema instanceof ContainerEffectiveStatement || schema instanceof LeafEffectiveStatement
+                || schema instanceof AnydataEffectiveStatement || schema instanceof AnyxmlEffectiveStatement
+                || schema instanceof InputEffectiveStatement || schema instanceof OutputEffectiveStatement
+                || schema instanceof NotificationEffectiveStatement) {
             endElement();
         }
     }
@@ -139,17 +152,12 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
         return false;
     }
 
-    @Override
-    public EffectiveModelContext getEffectiveModelContext() {
-        return streamUtils.getEffectiveModelContext();
-    }
-
     @Override
     public void scalarValue(final Object value) throws IOException {
-        final Object current = tracker.getParent();
-        if (current instanceof TypedDataSchemaNode) {
-            writeValue(value, (TypedDataSchemaNode) current);
-        } else if (current instanceof AnydataSchemaNode) {
+        final var current = tracker.currentStatement();
+        if (current instanceof TypedDataSchemaNode typedSchema) {
+            writeValue(value, typedSchema);
+        } else if (current instanceof AnydataEffectiveStatement) {
             anydataValue(value);
         } else {
             throw new IllegalStateException("Unexpected scalar value " + value + " with " + current);
@@ -158,8 +166,8 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
 
     @Override
     public void domSourceValue(final DOMSource value) throws IOException {
-        final Object current = tracker.getParent();
-        checkState(current instanceof AnyxmlSchemaNode, "Unexpected value %s with %s", value, current);
+        final var current = tracker.currentStatement();
+        checkState(current instanceof AnyxmlEffectiveStatement, "Unexpected value %s with %s", value, current);
         anyxmlValue(value);
     }
 
@@ -169,9 +177,9 @@ final class SchemaAwareXMLStreamNormalizedNodeStreamWriter
     }
 
     private @NonNull TypeDefinition<?> resolveType(final @NonNull TypeDefinition<?> type) throws XMLStreamException {
-        if (type instanceof LeafrefTypeDefinition) {
+        if (type instanceof LeafrefTypeDefinition leafref) {
             try {
-                return tracker.resolveLeafref((LeafrefTypeDefinition) type);
+                return tracker.resolveLeafref(leafref);
             } catch (IllegalArgumentException e) {
                 throw new XMLStreamException("Cannot resolve type " + type, e);
             }