Promote SchemaTracker to NormalizedNodeInferenceStack
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / XMLStreamNormalizedNodeStreamWriter.java
index cfa7e032952fb86d6110bd3a451ad35284c82802..f0b688cd14c20abffa91b42629df9c5321c88e6f 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.codec.xml;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
 import com.google.common.collect.ImmutableMap;
 import java.io.IOException;
 import java.util.Map.Entry;
@@ -19,20 +20,20 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.dom.DOMSource;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.ObjectExtensions;
-import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadataStreamWriter;
+import org.opendaylight.yangtools.rfc7952.data.api.StreamWriterMetadataExtension;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangConstants;
 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.AnydataExtension;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriterExtension;
-import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.data.util.NormalizedNodeInferenceStack;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveStatementInference;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Node;
@@ -51,15 +52,10 @@ import org.w3c.dom.Node;
  * removed in a future version.
  */
 public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements NormalizedNodeStreamWriter,
-        NormalizedMetadataStreamWriter, AnydataExtension {
+        StreamWriterMetadataExtension {
     private static final Logger LOG = LoggerFactory.getLogger(XMLStreamNormalizedNodeStreamWriter.class);
     private static final Set<String> BROKEN_ATTRIBUTES = ConcurrentHashMap.newKeySet();
 
-    @SuppressWarnings("rawtypes")
-    static final ObjectExtensions.Factory<XMLStreamNormalizedNodeStreamWriter, NormalizedNodeStreamWriter,
-        NormalizedNodeStreamWriterExtension> EXTENSIONS_BUILDER = ObjectExtensions.factory(
-            XMLStreamNormalizedNodeStreamWriter.class, NormalizedMetadataStreamWriter.class, AnydataExtension.class);
-
     private final @NonNull StreamWriterFacade facade;
 
     XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer) {
@@ -70,38 +66,88 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
      * Create a new writer with the specified context as its root.
      *
      * @param writer Output {@link XMLStreamWriter}
-     * @param context Associated {@link SchemaContext}.
+     * @param context Associated {@link EffectiveModelContext}.
      * @return A new {@link NormalizedNodeStreamWriter}
      */
     public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer,
-            final SchemaContext context) {
-        return create(writer, context, context);
+            final EffectiveModelContext context) {
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context,
+            NormalizedNodeInferenceStack.of(context));
     }
 
     /**
      * Create a new writer with the specified context and rooted at the specified node.
      *
      * @param writer Output {@link XMLStreamWriter}
-     * @param context Associated {@link SchemaContext}.
-     * @param rootNode Root node
+     * @param inference root node inference
      * @return A new {@link NormalizedNodeStreamWriter}
      */
-    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
-            final DataNodeContainer rootNode) {
-        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, SchemaTracker.create(rootNode));
+    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer,
+            final EffectiveStatementInference inference) {
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, inference.getEffectiveModelContext(),
+            NormalizedNodeInferenceStack.of(inference));
     }
 
     /**
      * Create a new writer with the specified context and rooted in the specified schema path.
      *
      * @param writer Output {@link XMLStreamWriter}
-     * @param context Associated {@link SchemaContext}.
+     * @param context Associated {@link EffectiveModelContext}.
      * @param path path
      * @return A new {@link NormalizedNodeStreamWriter}
      */
-    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer, final SchemaContext context,
-            final SchemaPath path) {
-        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context, SchemaTracker.create(context, path));
+    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer,
+            final EffectiveModelContext context, final SchemaPath path) {
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context,
+            NormalizedNodeInferenceStack.of(context, path));
+    }
+
+    /**
+     * Create a new writer with the specified context and rooted in the specified schema path.
+     *
+     * @param writer Output {@link XMLStreamWriter}
+     * @param context Associated {@link EffectiveModelContext}.
+     * @param path path
+     * @return A new {@link NormalizedNodeStreamWriter}
+     */
+    public static @NonNull NormalizedNodeStreamWriter create(final XMLStreamWriter writer,
+            final EffectiveModelContext context, final Absolute path) {
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context,
+            NormalizedNodeInferenceStack.of(context, path));
+    }
+
+    /**
+     * Create a new writer with the specified context and rooted in the specified operation's input.
+     *
+     * @param writer Output {@link XMLStreamWriter}
+     * @param context Associated {@link EffectiveModelContext}.
+     * @param operationPath Parent operation (RPC or action) path.
+     * @return A new {@link NormalizedNodeStreamWriter}
+     */
+    public static @NonNull NormalizedNodeStreamWriter forInputOf(final XMLStreamWriter writer,
+            final EffectiveModelContext context, final Absolute operationPath) {
+        return forOperation(writer, context, operationPath,
+            YangConstants.operationInputQName(operationPath.lastNodeIdentifier().getModule()));
+    }
+
+    /**
+     * Create a new writer with the specified context and rooted in the specified operation's output.
+     *
+     * @param writer Output {@link XMLStreamWriter}
+     * @param context Associated {@link EffectiveModelContext}.
+     * @param operationPath Parent operation (RPC or action) path.
+     * @return A new {@link NormalizedNodeStreamWriter}
+     */
+    public static @NonNull NormalizedNodeStreamWriter forOutputOf(final XMLStreamWriter writer,
+            final EffectiveModelContext context, final Absolute operationPath) {
+        return forOperation(writer, context, operationPath,
+            YangConstants.operationOutputQName(operationPath.lastNodeIdentifier().getModule()));
+    }
+
+    private static @NonNull NormalizedNodeStreamWriter forOperation(final XMLStreamWriter writer,
+            final EffectiveModelContext context, final Absolute operationPath, final QName qname) {
+        return new SchemaAwareXMLStreamNormalizedNodeStreamWriter(writer, context,
+            NormalizedNodeInferenceStack.ofOperation(context, operationPath, qname));
     }
 
     /**
@@ -118,7 +164,7 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
 
     @Override
     public final ClassToInstanceMap<NormalizedNodeStreamWriterExtension> getExtensions() {
-        return EXTENSIONS_BUILDER.newInstance(this);
+        return ImmutableClassToInstanceMap.of(StreamWriterMetadataExtension.class, this);
     }
 
     abstract void startAnydata(NodeIdentifier name);
@@ -159,31 +205,22 @@ public abstract class XMLStreamNormalizedNodeStreamWriter<T> implements Normaliz
 
     final void anydataValue(final Object value) throws IOException {
         if (value instanceof DOMSourceAnydata) {
-            anydataValue(((DOMSourceAnydata) value).getSource());
+            try {
+                facade.anydataWriteStreamReader(((DOMSourceAnydata) value).toStreamReader());
+            } catch (XMLStreamException e) {
+                throw new IOException("Unable to transform anydata value: " + value, e);
+            }
         } else if (value instanceof NormalizedAnydata) {
-            anydataValue((NormalizedAnydata) value);
+            try {
+                facade.emitNormalizedAnydata((NormalizedAnydata) value);
+            } catch (XMLStreamException e) {
+                throw new IOException("Unable to emit anydata value: " + value, e);
+            }
         } else {
             throw new IllegalStateException("Unexpected anydata value " + value);
         }
     }
 
-    private void anydataValue(final DOMSource domSource) throws IOException {
-        final Node domNode = requireNonNull(domSource.getNode());
-        try {
-            facade.anydataWriteStreamReader(new DOMSourceXMLStreamReader(domSource));
-        } catch (XMLStreamException e) {
-            throw new IOException("Unable to transform anyXml value: " + domNode, e);
-        }
-    }
-
-    private void anydataValue(final NormalizedAnydata anydata) throws IOException {
-        try {
-            facade.emitNormalizedAnydata(anydata);
-        } catch (XMLStreamException e) {
-            throw new IOException("Unable to emit anydata value: " + anydata, e);
-        }
-    }
-
     final void anyxmlValue(final DOMSource domSource) throws IOException {
         if (domSource != null) {
             final Node domNode = requireNonNull(domSource.getNode());