Binding2 runtime - Codecs impl - writers 05/58405/14
authorJakub Toth <jakub.toth@pantheon.tech>
Wed, 7 Jun 2017 10:18:19 +0000 (12:18 +0200)
committerJakub Toth <jakub.toth@pantheon.tech>
Tue, 13 Jun 2017 07:04:46 +0000 (07:04 +0000)
  * writers of Binding v2 and DOM for serializing data

Change-Id: I947f902f8acd97c67646b65750edf470f04ccc3e
Signed-off-by: Jakub Toth <jakub.toth@pantheon.tech>
binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/DataContainerCodecContext.java
binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/NodeCodecContext.java
binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/BindingToNormalizedStreamWriter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/ForwardingBindingStreamEventWriter.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/NormalizedNodeWithAddChildWriter.java [new file with mode: 0644]

index bb7b4b586c72249ba5bbff648474e84339ede5dd..6a707c3a12b9bc6f9899844760569c4e0b9f450f 100644 (file)
@@ -17,6 +17,7 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.opendaylight.mdsal.binding.javav2.dom.codec.api.codecs.BindingNormalizedNodeCachingCodec;
 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.MissingSchemaException;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.serializer.BindingToNormalizedStreamWriter;
 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
@@ -56,7 +57,7 @@ public abstract class DataContainerCodecContext<D extends TreeNode, T> extends N
     }
 
     @Override
-    protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
+    public YangInstanceIdentifier.PathArgument getDomPathArgument() {
         return prototype.getYangArg();
     }
 
@@ -154,9 +155,7 @@ public abstract class DataContainerCodecContext<D extends TreeNode, T> extends N
     }
 
     BindingStreamEventWriter createWriter(final NormalizedNodeStreamWriter domWriter) {
-
-        //TODO: streamWriter to come
-        throw new NotImplementedException();
+        return BindingToNormalizedStreamWriter.create(this, domWriter);
     }
 
     @Nonnull
index d53b3bcd5883720c1ba92f24740d36b7c6ba7926..2ff4499addfa0e5655618393c426d80a65f876e0 100644 (file)
@@ -47,7 +47,7 @@ public abstract class NodeCodecContext<D extends TreeNode> implements BindingTre
      *
      * @return DOM Path Argument of node
      */
-    protected abstract YangInstanceIdentifier.PathArgument getDomPathArgument();
+    public abstract YangInstanceIdentifier.PathArgument getDomPathArgument();
 
     /**
      *
diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/BindingToNormalizedStreamWriter.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/BindingToNormalizedStreamWriter.java
new file mode 100644 (file)
index 0000000..014e9c3
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.javav2.dom.codec.impl.serializer;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.CaseNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.KeyedListNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecContext;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.LeafNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.NodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Item;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
+import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+
+/**
+ * Stream event writer of Binding v2 representation.
+ */
+@Beta
+public final class BindingToNormalizedStreamWriter
+        implements BindingStreamEventWriter, Delegator<NormalizedNodeStreamWriter> {
+
+    private final Deque<NodeCodecContext<?>> schema = new ArrayDeque<>();
+    private final NormalizedNodeStreamWriter delegate;
+    private final NodeCodecContext<?> rootNodeSchema;
+
+    private BindingToNormalizedStreamWriter(final NodeCodecContext<?> rootNodeSchema,
+            final NormalizedNodeStreamWriter delegate) {
+        this.rootNodeSchema = Preconditions.checkNotNull(rootNodeSchema);
+        this.delegate = Preconditions.checkNotNull(delegate);
+    }
+
+    /**
+     * Create instance of Binding v2 representation writer.
+     *
+     * @param schema
+     *            - codec schema
+     * @param delegate
+     *            - DOM writer delegator
+     * @return instance of binding writer
+     */
+    public static BindingToNormalizedStreamWriter create(final NodeCodecContext<?> schema,
+            final NormalizedNodeStreamWriter delegate) {
+        return new BindingToNormalizedStreamWriter(schema, delegate);
+    }
+
+    private void emitSchema(final Object schema) {
+        delegate.nextDataSchemaNode((DataSchemaNode) schema);
+    }
+
+    /**
+     * Retrieves, but does not remove, the head of the queue represented by node
+     * codec context.
+     *
+     * @return head of queue
+     */
+    NodeCodecContext<?> current() {
+        return schema.peek();
+    }
+
+    private NodeIdentifier duplicateSchemaEnter() {
+        final NodeCodecContext<?> next;
+        if (current() == null) {
+            // Entry of first node
+            next = rootNodeSchema;
+        } else {
+            next = current();
+        }
+        this.schema.push(next);
+        return (NodeIdentifier) current().getDomPathArgument();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private <T extends YangInstanceIdentifier.PathArgument> T enter(final Class<?> name, final Class<T> identifier) {
+        final NodeCodecContext<?> next;
+        if (current() == null) {
+            // Entry of first node
+            next = rootNodeSchema;
+        } else {
+            Preconditions.checkArgument((current() instanceof DataContainerCodecContext), "Could not start node %s",
+                    name);
+            next = ((DataContainerCodecContext) current()).streamChild(name);
+        }
+        this.schema.push(next);
+        return (T) next.getDomPathArgument();
+    }
+
+    @SuppressWarnings("rawtypes")
+    private <T extends YangInstanceIdentifier.PathArgument> T enter(final String localName, final Class<T> identifier) {
+        final NodeCodecContext<?> current = current();
+        final NodeCodecContext<?> next = ((TreeNodeCodecContext) current).getLeafChild(localName);
+        this.schema.push(next);
+        @SuppressWarnings("unchecked")
+        final T arg = (T) next.getDomPathArgument();
+        return arg;
+    }
+
+    @Override
+    public NormalizedNodeStreamWriter getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public void endNode() throws IOException {
+        final NodeCodecContext<?> left = schema.pop();
+        // NormalizedNode writer does not have entry into case, but into choice
+        // so for leaving case, we do not emit endNode.
+        if (!(left instanceof CaseNodeCodecContext)) {
+            getDelegate().endNode();
+        }
+    }
+
+    private Map.Entry<NodeIdentifier, Object> serializeLeaf(final String localName, final Object value) {
+        Preconditions.checkArgument(current() instanceof TreeNodeCodecContext);
+
+        final TreeNodeCodecContext<?, ?> currentCasted = (TreeNodeCodecContext<?, ?>) current();
+        final LeafNodeCodecContext<?> leafContext = currentCasted.getLeafChild(localName);
+
+        final NodeIdentifier domArg = (NodeIdentifier) leafContext.getDomPathArgument();
+        final Object domValue = leafContext.getValueCodec().serialize(value);
+        emitSchema(leafContext.getSchema());
+        return new AbstractMap.SimpleEntry<>(domArg, domValue);
+    }
+
+    @Override
+    public void startleafNode(final String localName, final Object value) throws IOException {
+        final Entry<NodeIdentifier, Object> dom = serializeLeaf(localName, value);
+        getDelegate().leafNode(dom.getKey(), dom.getValue());
+    }
+
+    @Override
+    public void startAnyxmlNode(final String name, final Object value) throws IOException {
+        final Entry<NodeIdentifier, Object> dom = serializeLeaf(name, value);
+        getDelegate().anyxmlNode(dom.getKey(), dom.getValue());
+    }
+
+    @Override
+    public void startleafSetEntryNode(final Object value) throws IOException {
+        final LeafNodeCodecContext<?> ctx = (LeafNodeCodecContext<?>) current();
+        getDelegate().leafSetEntryNode(ctx.getSchema().getQName(), ctx.getValueCodec().serialize(value));
+    }
+
+    @Override
+    public void startAugmentationNode(final Class<? extends Augmentation<?>> augmentationType) throws IOException {
+        getDelegate().startAugmentationNode(enter(augmentationType, AugmentationIdentifier.class));
+    }
+
+    @Override
+    public void startCase(final Class<? extends TreeNode> caze, final int childSizeHint) {
+        enter(caze, NodeIdentifier.class);
+    }
+
+    @Override
+    public <T extends TreeNode> void startChoiceNode(final Item<T> choice, final int childSizeHint) throws IOException {
+        getDelegate().startChoiceNode(enter(choice.getType(), NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public void startContainerNode(final Class<? extends TreeNode> object, final int childSizeHint)
+            throws IOException {
+        getDelegate().startContainerNode(enter(object, NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public void startLeafSet(final String localName, final int childSizeHint) throws IOException {
+        final NodeIdentifier id = enter(localName, NodeIdentifier.class);
+        emitSchema(current().getSchema());
+        getDelegate().startLeafSet(id, childSizeHint);
+    }
+
+    @Override
+    public void startOrderedLeafSet(final String localName, final int childSizeHint) throws IOException {
+        getDelegate().startOrderedLeafSet(enter(localName, NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startMapEntryNode(final IdentifiableItem<I, T> keyValues,
+            final int childSizeHint) throws IOException {
+        duplicateSchemaEnter();
+        final NodeIdentifierWithPredicates identifier = ((KeyedListNodeCodecContext<?>) current()).serialize(keyValues);
+        getDelegate().startMapEntryNode(identifier, childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startMapNode(final IdentifiableItem<I, T> mapEntryType, final int childSizeHint)
+            throws IOException {
+        getDelegate().startMapNode(enter(mapEntryType.getType(), NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startOrderedMapNode(final IdentifiableItem<I, T> mapEntryType,
+            final int childSizeHint) throws IOException {
+        getDelegate().startOrderedMapNode(enter(mapEntryType.getType(), NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public void startUnkeyedList(final Class<? extends TreeNode> localName, final int childSizeHint)
+            throws IOException {
+        getDelegate().startUnkeyedList(enter(localName, NodeIdentifier.class), childSizeHint);
+    }
+
+    @Override
+    public void startUnkeyedListItem(final int childSizeHint) throws IOException {
+        getDelegate().startUnkeyedListItem(duplicateSchemaEnter(), childSizeHint);
+    }
+
+    @Override
+    public void flush() throws IOException {
+        getDelegate().flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        getDelegate().close();
+    }
+
+    @Override
+    public void startAnydataNode(final String name, final Object value) throws IOException {
+        // TODO will be done when https://bugs.opendaylight.org/show_bug.cgi?id=8516 is completed
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/ForwardingBindingStreamEventWriter.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/ForwardingBindingStreamEventWriter.java
new file mode 100644 (file)
index 0000000..bf11805
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.javav2.dom.codec.impl.serializer;
+
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Item;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingStreamEventWriter;
+import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
+
+/**
+ * Forwarding of event stream writer of Binding v2 representation.
+ */
+@Beta
+abstract class ForwardingBindingStreamEventWriter implements BindingStreamEventWriter {
+
+    protected abstract BindingStreamEventWriter delegate();
+
+    @Override
+    public void startleafNode(final String localName, final Object value) throws IOException {
+        delegate().startleafNode(localName, value);
+    }
+
+    @Override
+    public void startLeafSet(final String localName, final int childSizeHint) throws IOException {
+        delegate().startLeafSet(localName, childSizeHint);
+    }
+
+    @Override
+    public void startOrderedLeafSet(final String localName, final int childSizeHint) throws IOException {
+        delegate().startOrderedLeafSet(localName, childSizeHint);
+    }
+
+    @Override
+    public void startleafSetEntryNode(final Object value) throws IOException {
+        delegate().startleafSetEntryNode(value);
+    }
+
+    @Override
+    public void startContainerNode(final Class<? extends TreeNode> container, final int childSizeHint)
+            throws IOException {
+        delegate().startContainerNode(container, childSizeHint);
+    }
+
+    @Override
+    public void startUnkeyedList(final Class<? extends TreeNode> localName, final int childSizeHint)
+            throws IOException {
+        delegate().startUnkeyedList(localName, childSizeHint);
+    }
+
+    @Override
+    public void startUnkeyedListItem(final int childSizeHint) throws IOException {
+        delegate().startUnkeyedListItem(childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startMapNode(final IdentifiableItem<I, T> mapEntryType, final int childSizeHint)
+            throws IOException {
+        delegate().startMapNode(mapEntryType, childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startOrderedMapNode(final IdentifiableItem<I, T> mapEntryType,
+            final int childSizeHint) throws IOException {
+        delegate().startOrderedMapNode(mapEntryType, childSizeHint);
+    }
+
+    @Override
+    public <I extends TreeNode, T> void startMapEntryNode(final IdentifiableItem<I, T> keyValues,
+            final int childSizeHint) throws IOException {
+        delegate().startMapEntryNode(keyValues, childSizeHint);
+    }
+
+    @Override
+    public <T extends TreeNode> void startChoiceNode(final Item<T> choice, final int childSizeHint) throws IOException {
+        delegate().startChoiceNode(choice, childSizeHint);
+    }
+
+    @Override
+    public void startCase(final Class<? extends TreeNode> caze, final int childSizeHint) throws IOException {
+        delegate().startCase(caze, childSizeHint);
+    }
+
+    @Override
+    public void startAugmentationNode(final Class<? extends Augmentation<?>> augmentationType) throws IOException {
+        delegate().startAugmentationNode(augmentationType);
+    }
+
+    @Override
+    public void startAnyxmlNode(final String name, final Object value) throws IOException {
+        delegate().startAnyxmlNode(name, value);
+    }
+
+    @Override
+    public void startAnydataNode(final String name, final Object value) throws IOException {
+        delegate().startAnydataNode(name, value);
+    }
+
+    @Override
+    public void endNode() throws IOException {
+        delegate().endNode();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        delegate().flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        delegate().close();
+    }
+
+}
diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/NormalizedNodeWithAddChildWriter.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/NormalizedNodeWithAddChildWriter.java
new file mode 100644 (file)
index 0000000..f7a3e5d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.javav2.dom.codec.impl.serializer;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+
+/**
+ * Event Stream Writer based on Normalized Node tree representation with
+ * allowing to add children.
+ *
+ */
+@Beta
+final class NormalizedNodeWithAddChildWriter extends ImmutableNormalizedNodeStreamWriter {
+
+    /**
+     * Initialization writer based on {@link NormalizedNodeResult}.
+     *
+     * @param result
+     *            - result holder for writer
+     */
+    NormalizedNodeWithAddChildWriter(final NormalizedNodeResult result) {
+        super(result);
+    }
+
+    void addChild(final NormalizedNode<?, ?> child) {
+        this.writeChild(child);
+    }
+}
\ No newline at end of file