final Map<Class<?>, DataContainerCodecPrototype<?>> byClassBuilder = new HashMap<>();
final Map<Class<?>, DataContainerCodecPrototype<?>> byCaseChildClassBuilder = new HashMap<>();
final Set<Class<?>> potentialSubstitutions = new HashSet<>();
+
+ //TODO: Collect all choice/cases' descendant data children including augmented data nodes.
// Walks all cases for supplied choice in current runtime context
for (final Class<?> caze : factory().getRuntimeContext().getCases(getBindingClass())) {
// We try to load case using exact match thus name
return Optional.empty();
}
- Iterable<Class<?>> getCaseChildrenClasses() {
- return byCaseChildClass.keySet();
+
+ /**
+ * Gets the map of case class and prototype for {@link
+ * org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext}
+ * to catch choice/cases' data child by class.
+ *
+ * @return the map of case class and prototype
+ */
+ public Map<Class<?>, DataContainerCodecPrototype<?>> getClassCaseChildren() {
+ return byCaseChildClass;
+ }
+
+
+ /**
+ * Gets the map of case path argument and prototype for {@link
+ * org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext}
+ * to catch choice/cases' data child by class.
+ *
+ * @return the the map of case path and prototype
+ */
+ public Map<YangInstanceIdentifier.PathArgument, DataContainerCodecPrototype<?>> getYangCaseChildren() {
+ return byYangCaseChild;
+ }
+
+ public DataContainerCodecContext<?, ?> getCaseByChildClass(final @Nonnull Class<? extends TreeNode> type) {
+ final DataContainerCodecPrototype<?> protoCtx =
+ childNonNull(byCaseChildClass.get(type), type, "Class %s is not child of any cases for %s", type,
+ bindingArg());
+ return protoCtx.get();
}
private DataContainerCodecPrototype<CaseSchemaNode> loadCase(final Class<?> childClass) {
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.ChoiceNodeCodecContext;
import org.opendaylight.mdsal.binding.javav2.generator.api.ClassLoadingStrategy;
import org.opendaylight.mdsal.binding.javav2.model.api.Type;
import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
byMethodBuilder.put(childDataObj.getValue(), childProto);
byStreamClassBuilder.put(childProto.getBindingClass(), childProto);
byYangBuilder.put(childProto.getYangArg(), childProto);
- //TODO: get cases in consideration - finish in patches to come
- //if (childProto.isChoice()) {
+
+ if (childProto.isChoice()) {
+ final ChoiceNodeCodecContext<?> choice = (ChoiceNodeCodecContext<?>) childProto.get();
+ choice.getClassCaseChildren().entrySet().forEach(entry ->
+ byBindingArgClassBuilder.put(entry.getKey(), childProto));
+
+ choice.getYangCaseChildren().entrySet().forEach(entry ->
+ byYangBuilder.put(entry.getKey(), childProto));
+ }
}
+
this.byMethod = ImmutableSortedMap.copyOfSorted(byMethodBuilder);
this.byYang = ImmutableMap.copyOf(byYangBuilder);
this.byStreamClass = ImmutableMap.copyOf(byStreamClassBuilder);
}
final DataContainerCodecContext<?, ?> context =
childNonNull(ctxProto, argType, "Class %s is not valid child of %s", argType, getBindingClass()).get();
- //TODO: get cases in consideration - finish in patches to come
-// if (context instanceof ChoiceNodeCodecContext) {
+
+ if (context instanceof ChoiceNodeCodecContext) {
+ final ChoiceNodeCodecContext<?> choice = (ChoiceNodeCodecContext<?>) context;
+ final DataContainerCodecContext<?, ?> caze = choice.getCaseByChildClass(argType);
+ // FIXME: Instance identifier should not reference choice or case as they're
+ // not data tree nodes.
+ return caze.bindingPathArgumentChild(arg, builder);
+ }
+
context.addYangPathArgument(arg, builder);
return context;
}
childSupplier = byYang.get(arg);
}
+ // FIXME: Since instance identifier does not reference choice or case,
+ // we should search in data children of choice/case
+ if (childSupplier instanceof DataContainerCodecPrototype) {
+ final DataContainerCodecContext<?,T> context = ((DataContainerCodecPrototype) childSupplier).get();
+ if (context instanceof ChoiceNodeCodecContext) {
+ return (NodeCodecContext<D>) childNonNull(((ChoiceNodeCodecContext) context).yangPathArgumentChild(arg),
+ arg, "Argument %s is not valid child of %s", arg, getSchema());
+ }
+ }
+
return (NodeCodecContext<D>) childNonNull(childSupplier, arg,
"Argument %s is not valid child of %s", arg, getSchema()).get();
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Cisco Systems, Inc. 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;
+
+import static org.junit.Assert.assertEquals;
+
+import javassist.ClassPool;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.javav2.runtime.javassist.JavassistUtils;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.ChoiceContainer;
+import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.choice_container.identifier.simple.SimpleId;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class InstanceIdentifierSerializeDeserializeTest extends AbstractBindingRuntimeTest {
+ private static final InstanceIdentifier<SimpleId> BA_SIMPLE_ID = InstanceIdentifier
+ .builder(ChoiceContainer.class).child(SimpleId.class).build();
+
+ private static final QName CHOICE_CONTAINER_QNAME = ChoiceContainer.QNAME;
+ private static final QName SIMPLE_ID_QNAME = SimpleId.QNAME;
+
+
+ private static final YangInstanceIdentifier BI_SIMPLE_ID_PATH = YangInstanceIdentifier
+ .of(CHOICE_CONTAINER_QNAME).node(SIMPLE_ID_QNAME);
+
+ private BindingNormalizedNodeCodecRegistry registry;
+
+ @Override
+ @Before
+ public void setup() {
+ super.setup();
+ final JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault());
+ registry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(utils));
+ registry.onBindingRuntimeContextUpdated(getRuntimeContext());
+ }
+
+ @Test
+ public void testYangIIToBindingAwareII() {
+ final InstanceIdentifier<?> instanceIdentifier = registry.fromYangInstanceIdentifier(BI_SIMPLE_ID_PATH);
+ assertEquals(BA_SIMPLE_ID, instanceIdentifier);
+ }
+
+ @Test
+ public void testBindingAwareIIToYangIContainer() {
+ final YangInstanceIdentifier yangInstanceIdentifier = registry.toYangInstanceIdentifier(BA_SIMPLE_ID);
+ assertEquals(BI_SIMPLE_ID_PATH, yangInstanceIdentifier);
+ }
+}
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.data.TreeLeafOnlyUsesAugment;
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.dto.TreeLeafOnlyUsesAugmentBuilder;
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.grp.LeafFromGrouping;
+import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.ChoiceContainer;
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.Top;
+import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.choice_container.identifier.simple.SimpleId;
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.top.TopLevelList;
import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.dto.TopBuilder;
+import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.dto.choice_container.identifier.simple.SimpleIdBuilder;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
private static final QName AUGMENTED_INT_QNAME = QName.create(TopLevelList.QNAME, "augmented-int");
private static final QName SIMPLE_VALUE_QNAME = QName.create(LeafFromGrouping.QNAME, "simple-value");
private static final QName SIMPLE_TYPE_QNAME = QName.create(LeafFromGrouping.QNAME, "simple-type");
+ private static final QName CHOICE_CONTAINER_QNAME = ChoiceContainer.QNAME;
+ private static final QName SIMPLE_ID_QNAME = SimpleId.QNAME;
+ private static final QName SIMPLE_LEAF_ID_QNAME = QName.create(SimpleId.QNAME, "id");
+
+ private static final InstanceIdentifier<SimpleId> BA_SIMPLE_ID = InstanceIdentifier
+ .builder(ChoiceContainer.class).child(SimpleId.class).build();
+ private static final YangInstanceIdentifier BI_SIMPLE_ID_PATH = YangInstanceIdentifier
+ .of(CHOICE_CONTAINER_QNAME).node(SIMPLE_ID_QNAME);
@Before
public void setup() {
assertEquals(topBindingData(), entry.getValue());
}
+ private static SimpleId simpleIdBindingData() {
+ return new SimpleIdBuilder().setId(10).build();
+ }
+
+ private static ContainerNode simpleIdNormailziedData() {
+ return ImmutableContainerNodeBuilder.create()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(SIMPLE_ID_QNAME))
+ .withChild(leafNode(SIMPLE_LEAF_ID_QNAME, 10))
+ .build();
+ }
+
+ @Test
+ public void testChoiceDataToNormalizedNode() {
+ final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry =
+ registry.toNormalizedNode(BA_SIMPLE_ID, simpleIdBindingData());
+ assertEquals(simpleIdNormailziedData(), entry.getValue());
+ }
+
+ @Test
+ public void testChoiceDataFromNormalizedNode() {
+ final Entry<InstanceIdentifier<?>, TreeNode> entry =
+ registry.fromNormalizedNode(BI_SIMPLE_ID_PATH, simpleIdNormailziedData());
+ assertEquals(simpleIdBindingData(), entry.getValue());
+ }
+
}
\ No newline at end of file