From: Jakub Toth Date: Wed, 7 Jun 2017 10:18:19 +0000 (+0200) Subject: Binding2 runtime - Codecs impl - writers X-Git-Tag: release/nitrogen~131 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=182edc606d56e26d66297de10fae48ea63756072;p=mdsal.git Binding2 runtime - Codecs impl - writers * writers of Binding v2 and DOM for serializing data Change-Id: I947f902f8acd97c67646b65750edf470f04ccc3e Signed-off-by: Jakub Toth --- diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/DataContainerCodecContext.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/DataContainerCodecContext.java index bb7b4b586c..6a707c3a12 100644 --- a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/DataContainerCodecContext.java +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/DataContainerCodecContext.java @@ -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 extends N } @Override - protected YangInstanceIdentifier.PathArgument getDomPathArgument() { + public YangInstanceIdentifier.PathArgument getDomPathArgument() { return prototype.getYangArg(); } @@ -154,9 +155,7 @@ public abstract class DataContainerCodecContext extends N } BindingStreamEventWriter createWriter(final NormalizedNodeStreamWriter domWriter) { - - //TODO: streamWriter to come - throw new NotImplementedException(); + return BindingToNormalizedStreamWriter.create(this, domWriter); } @Nonnull diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/NodeCodecContext.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/NodeCodecContext.java index d53b3bcd58..2ff4499add 100644 --- a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/NodeCodecContext.java +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/NodeCodecContext.java @@ -47,7 +47,7 @@ public abstract class NodeCodecContext 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 index 0000000000..014e9c3a1e --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/BindingToNormalizedStreamWriter.java @@ -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 { + + private final Deque> 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 enter(final Class name, final Class 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 enter(final String localName, final Class 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 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 dom = serializeLeaf(localName, value); + getDelegate().leafNode(dom.getKey(), dom.getValue()); + } + + @Override + public void startAnyxmlNode(final String name, final Object value) throws IOException { + final Entry 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> augmentationType) throws IOException { + getDelegate().startAugmentationNode(enter(augmentationType, AugmentationIdentifier.class)); + } + + @Override + public void startCase(final Class caze, final int childSizeHint) { + enter(caze, NodeIdentifier.class); + } + + @Override + public void startChoiceNode(final Item choice, final int childSizeHint) throws IOException { + getDelegate().startChoiceNode(enter(choice.getType(), NodeIdentifier.class), childSizeHint); + } + + @Override + public void startContainerNode(final Class 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 void startMapEntryNode(final IdentifiableItem keyValues, + final int childSizeHint) throws IOException { + duplicateSchemaEnter(); + final NodeIdentifierWithPredicates identifier = ((KeyedListNodeCodecContext) current()).serialize(keyValues); + getDelegate().startMapEntryNode(identifier, childSizeHint); + } + + @Override + public void startMapNode(final IdentifiableItem mapEntryType, final int childSizeHint) + throws IOException { + getDelegate().startMapNode(enter(mapEntryType.getType(), NodeIdentifier.class), childSizeHint); + } + + @Override + public void startOrderedMapNode(final IdentifiableItem mapEntryType, + final int childSizeHint) throws IOException { + getDelegate().startOrderedMapNode(enter(mapEntryType.getType(), NodeIdentifier.class), childSizeHint); + } + + @Override + public void startUnkeyedList(final Class 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 index 0000000000..bf11805acd --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/ForwardingBindingStreamEventWriter.java @@ -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 container, final int childSizeHint) + throws IOException { + delegate().startContainerNode(container, childSizeHint); + } + + @Override + public void startUnkeyedList(final Class localName, final int childSizeHint) + throws IOException { + delegate().startUnkeyedList(localName, childSizeHint); + } + + @Override + public void startUnkeyedListItem(final int childSizeHint) throws IOException { + delegate().startUnkeyedListItem(childSizeHint); + } + + @Override + public void startMapNode(final IdentifiableItem mapEntryType, final int childSizeHint) + throws IOException { + delegate().startMapNode(mapEntryType, childSizeHint); + } + + @Override + public void startOrderedMapNode(final IdentifiableItem mapEntryType, + final int childSizeHint) throws IOException { + delegate().startOrderedMapNode(mapEntryType, childSizeHint); + } + + @Override + public void startMapEntryNode(final IdentifiableItem keyValues, + final int childSizeHint) throws IOException { + delegate().startMapEntryNode(keyValues, childSizeHint); + } + + @Override + public void startChoiceNode(final Item choice, final int childSizeHint) throws IOException { + delegate().startChoiceNode(choice, childSizeHint); + } + + @Override + public void startCase(final Class caze, final int childSizeHint) throws IOException { + delegate().startCase(caze, childSizeHint); + } + + @Override + public void startAugmentationNode(final Class> 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 index 0000000000..f7a3e5de44 --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/serializer/NormalizedNodeWithAddChildWriter.java @@ -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