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;
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.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;
* 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) {
* 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));
}
/**
@Override
public final ClassToInstanceMap<NormalizedNodeStreamWriterExtension> getExtensions() {
- return EXTENSIONS_BUILDER.newInstance(this);
+ return ImmutableClassToInstanceMap.of(StreamWriterMetadataExtension.class, this);
}
abstract void startAnydata(NodeIdentifier name);
}
}
- final 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);
+ final void anydataValue(final Object value) throws IOException {
+ if (value instanceof DOMSourceAnydata) {
+ try {
+ facade.anydataWriteStreamReader(((DOMSourceAnydata) value).toStreamReader());
+ } catch (XMLStreamException e) {
+ throw new IOException("Unable to transform anydata value: " + value, e);
+ }
+ } else if (value instanceof NormalizedAnydata) {
+ 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);
}
}
@Override
public final boolean startAnydataNode(final NodeIdentifier name, final Class<?> objectModel) throws IOException {
- if (DOMSource.class.isAssignableFrom(objectModel)) {
+ if (DOMSourceAnydata.class.isAssignableFrom(objectModel)
+ || NormalizedAnydata.class.isAssignableFrom(objectModel)) {
startAnydata(name);
startElement(name.getNodeType());
return true;