--- /dev/null
+/*
+ * 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.context;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecPrototype;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+
+/**
+ * Codec context for serializing and deserializing choice case node and it's
+ * path.
+ *
+ * @param <D>
+ * - type of tree node
+ */
+@Beta
+public final class CaseNodeCodecContext<D extends TreeNode> extends TreeNodeCodecContext<D, ChoiceCaseNode> {
+
+ /**
+ * Prepare context for choice case node from prototype.
+ *
+ * @param prototype
+ * - codec prototype of choice case node
+ */
+ public CaseNodeCodecContext(final DataContainerCodecPrototype<ChoiceCaseNode> prototype) {
+ super(prototype);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected void addYangPathArgument(final TreeArgument arg, final List<PathArgument> builder) {
+ // add your implementation
+ }
+
+ @Nonnull
+ @Override
+ public D deserialize(@Nonnull final NormalizedNode<?, ?> normalizedNode) {
+ Preconditions.checkState(normalizedNode instanceof ChoiceNode);
+ return createBindingProxy((ChoiceNode) normalizedNode);
+ }
+
+ @Override
+ protected Object deserializeObject(final NormalizedNode<?, ?> normalizedNode) {
+ return deserialize(normalizedNode);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public PathArgument serializePathArgument(final TreeArgument arg) {
+ Preconditions.checkArgument(arg == null);
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public TreeArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) {
+ Preconditions.checkArgument(arg == null);
+ return null;
+ }
+}
--- /dev/null
+/*
+ * 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.context;
+
+import com.google.common.annotations.Beta;
+import java.lang.reflect.Method;
+import java.util.List;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecPrototype;
+import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+/**
+ * Codec context for serializing and deserializing keyed list node and it's
+ * path.
+ *
+ * @param <D>
+ * - type of tree node
+ */
+@Beta
+public final class KeyedListNodeCodecContext<D extends TreeNode & Identifiable<?>> extends ListNodeCodecContext<D> {
+
+ private final Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> codec;
+ private final Method keyGetter;
+
+ /**
+ * Prepare context for keyed list node from prototype.
+ *
+ * @param prototype
+ * - codec prototype of keyed list node
+ */
+ KeyedListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
+ super(prototype);
+ this.codec = factory().getPathArgumentCodec(getBindingClass(), getSchema());
+ try {
+ this.keyGetter = getBindingClass().getMethod("getKey");
+ } catch (final NoSuchMethodException e) {
+ throw new IllegalStateException("Required method not available", e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void addYangPathArgument(final TreeArgument arg, final List<PathArgument> builder) {
+ /*
+ * DOM Instance Identifier for list is always represent by two entries
+ * one for map and one for children. This is also true for wildcarded
+ * instance identifiers
+ */
+ if (builder == null) {
+ return;
+ }
+
+ super.addYangPathArgument(arg, builder);
+ if (arg instanceof IdentifiableItem<?, ?>) {
+ builder.add(codec.serialize((IdentifiableItem<?, ?>) arg));
+ } else {
+ // Adding wildcarded
+ super.addYangPathArgument(arg, builder);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Object getBindingChildValue(final Method method, final NormalizedNodeContainer dom) {
+ if (dom instanceof MapEntryNode && keyGetter.equals(method)) {
+ final NodeIdentifierWithPredicates identifier = ((MapEntryNode) dom).getIdentifier();
+ return codec.deserialize(identifier).getKey();
+ } else {
+ return super.getBindingChildValue(method, dom);
+ }
+ }
+
+ @Override
+ protected TreeArgument<?> getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
+ if (domArg instanceof NodeIdentifierWithPredicates) {
+ return codec.deserialize((NodeIdentifierWithPredicates) domArg);
+ }
+ return super.getBindingPathArgument(domArg);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public NodeIdentifierWithPredicates serialize(final IdentifiableItem keyValues) {
+ return codec.serialize(keyValues);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public YangInstanceIdentifier.PathArgument serializePathArgument(final TreeArgument arg) {
+ if (arg instanceof IdentifiableItem) {
+ return codec.serialize((IdentifiableItem<?, ?>) arg);
+ }
+ return super.serializePathArgument(arg);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public TreeArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) {
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ return codec.deserialize((NodeIdentifierWithPredicates) arg);
+ }
+ return super.deserializePathArgument(arg);
+ }
+}
+
--- /dev/null
+/*
+ * 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.context;
+
+import com.google.common.annotations.Beta;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.DataContainerCodecPrototype;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+/**
+ * Codec context for serializing and deserializing list node.
+ *
+ * @param <D>
+ * - type of tree node
+ */
+@Beta
+class ListNodeCodecContext<D extends TreeNode> extends TreeNodeCodecContext<D, ListSchemaNode> {
+
+ /**
+ * Prepare context for list node from prototype.
+ *
+ * @param prototype
+ * - codec prototype of list node
+ */
+ protected ListNodeCodecContext(final DataContainerCodecPrototype<ListSchemaNode> prototype) {
+ super(prototype);
+ }
+
+ @Nonnull
+ @Override
+ public D deserialize(@Nonnull final NormalizedNode<?, ?> node) {
+ if (node instanceof MapEntryNode) {
+ return fromMapEntry((MapEntryNode) node);
+ } else if (node instanceof UnkeyedListEntryNode) {
+ return fromUnkeyedListEntry((UnkeyedListEntryNode) node);
+ } else {
+ throw new IllegalStateException("Unsupported data type " + node.getClass());
+ }
+ }
+
+ @Override
+ protected Object deserializeObject(final NormalizedNode<?, ?> node) {
+ if (node instanceof MapNode) {
+ return fromMap((MapNode) node);
+ } else if (node instanceof MapEntryNode) {
+ return fromMapEntry((MapEntryNode) node);
+ } else if (node instanceof UnkeyedListNode) {
+ return fromUnkeyedList((UnkeyedListNode) node);
+ } else if (node instanceof UnkeyedListEntryNode) {
+ return fromUnkeyedListEntry((UnkeyedListEntryNode) node);
+ } else {
+ throw new IllegalStateException("Unsupported data type " + node.getClass());
+ }
+ }
+
+ private List<D> fromMap(final MapNode nodes) {
+ final List<D> ret = new ArrayList<>(nodes.getValue().size());
+ for (final MapEntryNode node : nodes.getValue()) {
+ ret.add(fromMapEntry(node));
+ }
+ return ret;
+ }
+
+ private D fromMapEntry(final MapEntryNode node) {
+ return createBindingProxy(node);
+ }
+
+ private D fromUnkeyedListEntry(final UnkeyedListEntryNode node) {
+ return createBindingProxy(node);
+ }
+
+ private List<D> fromUnkeyedList(final UnkeyedListNode nodes) {
+ // FIXME: Could be this lazy transformed list?
+ final List<D> ret = new ArrayList<>(nodes.getValue().size());
+ for (final UnkeyedListEntryNode node : nodes.getValue()) {
+ ret.add(fromUnkeyedListEntry(node));
+ }
+ return ret;
+ }
+}
\ No newline at end of file
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
@Beta
-abstract class DataContainerCodecContext<D extends TreeNode, T> extends NodeCodecContext<D> {
+public abstract class DataContainerCodecContext<D extends TreeNode, T> extends NodeCodecContext<D> {
private final DataContainerCodecPrototype<T> prototype;
private volatile TreeNodeSerializer eventStreamSerializer;
throw IncorrectNestingException.create(message, args);
}
- TreeNodeSerializer eventStreamSerializer() {
+ public TreeNodeSerializer eventStreamSerializer() {
if(eventStreamSerializer == null) {
eventStreamSerializer = factory().getEventStreamSerializer(getBindingClass());
}
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
@Beta
-final class DataContainerCodecPrototype<T> implements NodeContextSupplier {
+public final class DataContainerCodecPrototype<T> implements NodeContextSupplier {
private final T schema;
private final QNameModule namespace;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
@Beta
-final class LeafNodeCodecContext<D extends TreeNode> extends NodeCodecContext<D> implements NodeContextSupplier {
+public final class LeafNodeCodecContext<D extends TreeNode> extends NodeCodecContext<D> implements NodeContextSupplier {
private final YangInstanceIdentifier.PathArgument yangIdentifier;
private final Codec<Object, Object> valueCodec;
}
@Override
- protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
+ public YangInstanceIdentifier.PathArgument getDomPathArgument() {
return yangIdentifier;
}
- protected Codec<Object, Object> getValueCodec() {
+ public Codec<Object, Object> getValueCodec() {
return valueCodec;
}
*
*/
@Beta
-abstract class NodeCodecContext<D extends TreeNode> implements BindingTreeNodeCodec<D>{
+public abstract class NodeCodecContext<D extends TreeNode> implements BindingTreeNodeCodec<D> {
/**
* Returns Yang Instance Identifier Path Argument of current node
*
import org.slf4j.LoggerFactory;
@Beta
-abstract class TreeNodeCodecContext<D extends TreeNode, T extends DataNodeContainer>
+public abstract class TreeNodeCodecContext<D extends TreeNode, T extends DataNodeContainer>
extends DataContainerCodecContext<D, T> {
private static final Logger LOG = LoggerFactory.getLogger(TreeNodeCodecContext.class);
"Argument %s is not valid child of %s", arg, getSchema()).get();
}
- protected final LeafNodeCodecContext<?> getLeafChild(final String name) {
+ public final LeafNodeCodecContext<?> getLeafChild(final String name) {
final LeafNodeCodecContext<?> value = leafChild.get(name);
return IncorrectNestingException.checkNonNull(value, "Leaf %s is not valid for %s", name, getBindingClass());
}
}
@SuppressWarnings("rawtypes")
- Object getBindingChildValue(final Method method, final NormalizedNodeContainer domData) {
+ public Object getBindingChildValue(final Method method, final NormalizedNodeContainer domData) {
final NodeCodecContext<?> childContext = byMethod.get(method).get();
@SuppressWarnings("unchecked")
final Optional<NormalizedNode<?, ?>> domChild = domData.getChild(childContext.getDomPathArgument());