Map system-ordered leaf-lists to Set<T> 97/99697/6
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 11 Feb 2022 16:35:19 +0000 (17:35 +0100)
committerRobert Varga <nite@hq.sk>
Thu, 24 Feb 2022 08:27:40 +0000 (08:27 +0000)
System-ordered leaf-lists can get re-ordered and hence the binding
mapping to java.util.List is not appropriate. Make sure we map them
to java.util.Set.

JIRA: MDSAL-722
Change-Id: I4c82736b3ef25fd1197c446aca2c9d22a59a3d96
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
27 files changed:
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectStreamer.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectStreamerGenerator.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/LeafSetNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/Mdsal668Test.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/NormalizedNodeSerializeDeserializeTest.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/SpecializingLeafrefTest.java
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/LeafListGenerator.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/AugmentedTypeTest.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/DefaultBindingGeneratorTest.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/GeneratedTypesLeafrefTest.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/GeneratedTypesTest.java
binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/UsesTest.java
binding/mdsal-binding-generator/src/test/resources/uses-of-grouping/uses-of-grouping-rpc.yang
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/SpecializingLeafrefTest.java
binding/mdsal-binding-model-ri/src/main/java/org/opendaylight/mdsal/binding/model/ri/Types.java
binding/mdsal-binding-test-model/src/main/yang/test-pattern.yang
binding/mdsal-binding-test-model/src/test/java/org/opendaylight/mdsal/binding/test/model/TestListSquashing.java
binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/CodeHelpers.java
trace/mdsal-trace-impl/src/main/java/org/opendaylight/mdsal/trace/impl/TracingBroker.java
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/LegacyContentBuilder.java
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/MountPointContextFactoryImpl.java
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibraryContentBuilderImpl.java
yanglib/mdsal-yanglib-rfc8525/src/test/java/org/opendaylight/mdsal/yanglib/rfc8525/AbstractYangLibraryTest.java [new file with mode: 0644]
yanglib/mdsal-yanglib-rfc8525/src/test/java/org/opendaylight/mdsal/yanglib/rfc8525/LegacyYangLibraryFormatTest.java
yanglib/mdsal-yanglib-rfc8525/src/test/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupportTest.java

index 94b1a4c44ce298b55f684f1e3d689cce3a4e40a5..1a0793428747de1ef865eb2f2e39168bbe6b73f3 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingStreamEventWriter;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
@@ -99,7 +100,7 @@ public abstract class DataObjectStreamer<T extends DataObject> implements DataOb
     }
 
     protected static final void streamLeafList(final BindingStreamEventWriter writer, final String localName,
-            final List<?> value) throws IOException {
+            final Set<?> value) throws IOException {
         if (value != null) {
             writer.startLeafSet(localName, value.size());
             commonStreamLeafset(writer, value);
@@ -156,7 +157,7 @@ public abstract class DataObjectStreamer<T extends DataObject> implements DataOb
         writer.endNode();
     }
 
-    private static void commonStreamLeafset(final BindingStreamEventWriter writer, final List<?> value)
+    private static void commonStreamLeafset(final BindingStreamEventWriter writer, final Collection<?> value)
             throws IOException {
         for (Object entry : value) {
             writer.leafSetEntryNode(entry);
@@ -186,7 +187,7 @@ public abstract class DataObjectStreamer<T extends DataObject> implements DataOb
         return !(writer instanceof BindingSerializer) || ((BindingSerializer<?, T>) writer).serialize(value) == null;
     }
 
-    private static int nullSize(final List<?> list) {
+    private static int nullSize(final Collection<?> list) {
         return list == null ? 0 : list.size();
     }
 
index 111b8254f7a3721b1944c532766d2b3897c7609d..b007379a0de6762576d23c32899a149cff3c9ad9 100644 (file)
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import net.bytebuddy.ByteBuddy;
 import net.bytebuddy.description.field.FieldDescription;
 import net.bytebuddy.description.method.MethodDescription;
@@ -138,7 +139,7 @@ final class DataObjectStreamerGenerator<T extends DataObjectStreamer<?>> impleme
         "streamLeaf", BindingStreamEventWriter.class, String.class, Object.class);
     private static final StackManipulation STREAM_LEAF_LIST = invokeMethod(DataObjectStreamer.class,
         "streamLeafList",
-        BindingStreamEventWriter.class, String.class, List.class);
+        BindingStreamEventWriter.class, String.class, Set.class);
     private static final StackManipulation STREAM_ORDERED_LEAF_LIST = invokeMethod(DataObjectStreamer.class,
         "streamOrderedLeafList", BindingStreamEventWriter.class, String.class, List.class);
     private static final StackManipulation STREAM_LIST = invokeMethod(DataObjectStreamer.class,
index 8ab953f844831c43cd109183f534862934262a3a..b6477100aa47843e8123eda3f62d4942d8a66da2 100644 (file)
@@ -7,30 +7,34 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
+import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import java.util.Collection;
+import com.google.common.collect.ImmutableSet;
+import java.util.function.IntFunction;
 import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
 final class LeafSetNodeCodecContext extends ValueNodeCodecContext.WithCodec {
+    private final IntFunction<ImmutableCollection.Builder<Object>> builderFactory;
+
     LeafSetNodeCodecContext(final LeafListSchemaNode schema, final IllegalArgumentCodec<Object, Object> codec,
-        final String getterName) {
+            final String getterName) {
         // FIXME: add support for defaults
         super(schema, codec, getterName, null);
+        builderFactory = schema.isUserOrdered() ? ImmutableList::builderWithExpectedSize
+            : ImmutableSet::builderWithExpectedSize;
     }
 
     @Override
-    protected Object deserializeObject(final NormalizedNode normalizedNode) {
+    protected ImmutableCollection<?> deserializeObject(final NormalizedNode normalizedNode) {
         if (normalizedNode instanceof LeafSetNode<?>) {
             @SuppressWarnings("unchecked")
-            final Collection<LeafSetEntryNode<Object>> domValues = ((LeafSetNode<Object>) normalizedNode).body();
-            final IllegalArgumentCodec<Object, Object> codec = getValueCodec();
-            final Builder<Object> builder = ImmutableList.builderWithExpectedSize(domValues.size());
-            for (final LeafSetEntryNode<Object> valueNode : domValues) {
+            final var domValues = ((LeafSetNode<Object>) normalizedNode).body();
+            final var codec = getValueCodec();
+            final var builder = builderFactory.apply(domValues.size());
+            for (var valueNode : domValues) {
                 builder.add(codec.deserialize(valueNode.body()));
             }
             return builder.build();
index 3f7463a1d5d4542c5707e18ce6e89e11e10b02e0..5d8580297eddf6bc57bb8cbee2de9e76cc7d27f0 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import static org.junit.Assert.assertEquals;
 
-import java.util.List;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.mdsal668.norev.Foo;
 import org.opendaylight.yang.gen.v1.mdsal668.norev.FooBuilder;
@@ -40,7 +40,7 @@ public class Mdsal668Test extends AbstractBindingCodecTest {
                     .build())
                 .build())
             .build(), codecContext.toNormalizedNode(FOO_IID,
-                new FooBuilder().setBar(new BarBuilder().setBar(List.of(FOO_IID)).build()).build())
+                new FooBuilder().setBar(new BarBuilder().setBar(Set.of(FOO_IID)).build()).build())
             .getValue());
     }
 }
index 5279a43dbadd156c8521d106d58504d2d25d3eb1..88a3f40e636db9c83b1998e72af63715969667b5 100644 (file)
@@ -22,10 +22,6 @@ import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.ma
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -53,7 +49,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.te
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.top.level.list.NestedListKey;
 import org.opendaylight.yang.gen.v1.urn.test.foo4798.rev160101.Root;
@@ -167,8 +162,8 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
         // Equals on other(lazy, reversed) with no augmentation should be false
         assertNotEquals(entryWithAugments.getValue(), entry.getValue());
 
-        final Top topWithAugments = topWithAugments(Collections.<Class<? extends Augmentation<Top>>, Augmentation<Top>>
-            singletonMap(Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build()));
+        final Top topWithAugments = topWithAugments(
+            Map.of(Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build()));
         // Equals other with same augment should be true
         assertEquals(topWithAugments, entryWithAugments.getValue());
         // Equals other with same augment should be true
@@ -177,8 +172,7 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
         assertEquals(entryWithAugments.getValue(), entryWithAugments.getValue());
 
         final Top topWithAugmentsDiffValue = topWithAugments(
-            Collections.<Class<? extends Augmentation<Top>>, Augmentation<Top>>singletonMap(Top1.class,
-                new Top1Builder().setAugmentedString("differentValue").build()));
+            Map.of(Top1.class, new Top1Builder().setAugmentedString("differentValue").build()));
         assertNotEquals(topWithAugmentsDiffValue, entryWithAugments.getValue());
         assertNotEquals(entryWithAugments.getValue(), topWithAugmentsDiffValue);
     }
@@ -197,18 +191,16 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
 
         final Entry<InstanceIdentifier<?>, DataObject> entryWithAugments = codecContext.fromNormalizedNode(BI_TOP_PATH,
             topNormalizedWithAugments);
-        Map<Class<? extends Augmentation<Top>>, Augmentation<Top>> augments = new HashMap<>();
-        augments.put(Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build());
-        augments.put(Top2.class, new Top2Builder().setAugmentedInt(AUGMENT_INT_VALUE).build());
-        Top topWithAugments = topWithAugments(augments);
+        Top topWithAugments = topWithAugments(Map.of(
+            Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build(),
+            Top2.class, new Top2Builder().setAugmentedInt(AUGMENT_INT_VALUE).build()));
 
         assertEquals(topWithAugments, entryWithAugments.getValue());
         assertEquals(entryWithAugments.getValue(), topWithAugments);
 
-        augments = new HashMap<>();
-        augments.put(Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build());
-        augments.put(Top2.class, new Top2Builder().setAugmentedInt(999).build());
-        topWithAugments = topWithAugments(augments);
+        topWithAugments = topWithAugments(Map.of(
+            Top1.class, new Top1Builder().setAugmentedString(AUGMENT_STRING_VALUE).build(),
+            Top2.class, new Top2Builder().setAugmentedInt(999).build()));
 
         assertNotEquals(topWithAugments, entryWithAugments.getValue());
         assertNotEquals(entryWithAugments.getValue(), topWithAugments);
@@ -261,10 +253,8 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
     public void leafOnlyAugmentationToNormalized() {
         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
             BA_TREE_LEAF_ONLY, new TreeLeafOnlyAugmentBuilder().setSimpleValue("simpleValue").build());
-        final Set<QName> augmentationChildren = new HashSet<>();
-        augmentationChildren.add(SIMPLE_VALUE_QNAME);
         final AugmentationNode augmentationNode = ImmutableAugmentationNodeBuilder.create()
-                .withNodeIdentifier(new AugmentationIdentifier(augmentationChildren))
+                .withNodeIdentifier(new AugmentationIdentifier(Set.of(SIMPLE_VALUE_QNAME)))
                 .withChild(leafNode(SIMPLE_VALUE_QNAME, "simpleValue"))
                 .build();
         assertEquals(augmentationNode, entry.getValue());
@@ -272,23 +262,19 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
 
     @Test
     public void leafOnlyAugmentationFromNormalized() {
-        final Set<QName> augmentationChildren = new HashSet<>();
-        augmentationChildren.add(SIMPLE_VALUE_QNAME);
+        final AugmentationIdentifier augmentationId = new AugmentationIdentifier(Set.of(SIMPLE_VALUE_QNAME));
         final AugmentationNode augmentationNode = ImmutableAugmentationNodeBuilder.create()
-                .withNodeIdentifier(new AugmentationIdentifier(augmentationChildren))
+                .withNodeIdentifier(augmentationId)
                 .withChild(leafNode(SIMPLE_VALUE_QNAME, "simpleValue"))
                 .build();
         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(
-            BI_TOP_LEVEL_LIST_FOO_PATH.node(new AugmentationIdentifier(augmentationChildren)),
-            augmentationNode);
+            BI_TOP_LEVEL_LIST_FOO_PATH.node(augmentationId), augmentationNode);
         assertEquals(new TreeLeafOnlyAugmentBuilder().setSimpleValue("simpleValue").build(), entry.getValue());
     }
 
     @Test
     public void orderedleafListToNormalized() {
-        List<String> topLevelLeafList = new ArrayList<>();
-        topLevelLeafList.add("foo");
-        Top top = new TopBuilder().setTopLevelOrderedLeafList(topLevelLeafList).build();
+        Top top = new TopBuilder().setTopLevelOrderedLeafList(List.of("foo")).build();
 
         Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
             InstanceIdentifier.create(Top.class), top);
@@ -309,9 +295,7 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
 
     @Test
     public void leafListToNormalized() {
-        final List<String> topLevelLeafList = new ArrayList<>();
-        topLevelLeafList.add("foo");
-        final Top top = new TopBuilder().setTopLevelLeafList(topLevelLeafList).build();
+        final Top top = new TopBuilder().setTopLevelLeafList(Set.of("foo")).build();
 
         final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(
             InstanceIdentifier.create(Top.class), top);
@@ -341,9 +325,7 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
                 .build();
         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH,
             topWithLeafList);
-        final List<String> topLevelLeafList = new ArrayList<>();
-        topLevelLeafList.add("foo");
-        final Top top = new TopBuilder().setTopLevelLeafList(topLevelLeafList).build();
+        final Top top = new TopBuilder().setTopLevelLeafList(Set.of("foo")).build();
         assertEquals(top, entry.getValue());
     }
 
@@ -358,9 +340,7 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
                     .build())
                 .build();
         Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(BI_TOP_PATH, topWithLeafList);
-        List<String> topLevelLeafList = new ArrayList<>();
-        topLevelLeafList.add("foo");
-        Top top = new TopBuilder().setTopLevelOrderedLeafList(topLevelLeafList).build();
+        Top top = new TopBuilder().setTopLevelOrderedLeafList(List.of("foo")).build();
         assertEquals(top, entry.getValue());
     }
 
@@ -479,13 +459,13 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
 
     @Test
     public void orderedLisToNormalized() {
-        final InstanceIdentifier<TopLevelList> ii = BA_TOP_LEVEL_LIST;
-        final List<NestedList> nestedLists = new ArrayList<>();
-        nestedLists.add(new NestedListBuilder().withKey(new NestedListKey("foo")).build());
-        nestedLists.add(new NestedListBuilder().withKey(new NestedListKey("bar")).build());
-        final TopLevelList topLevelList = new TopLevelListBuilder().withKey(TOP_LEVEL_LIST_FOO_KEY).setNestedList(
-            nestedLists).build();
-        final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(ii,
+        final TopLevelList topLevelList = new TopLevelListBuilder()
+            .withKey(TOP_LEVEL_LIST_FOO_KEY)
+            .setNestedList(List.of(
+                new NestedListBuilder().withKey(new NestedListKey("foo")).build(),
+                new NestedListBuilder().withKey(new NestedListKey("bar")).build()))
+            .build();
+        final Entry<YangInstanceIdentifier, NormalizedNode> entry = codecContext.toNormalizedNode(BA_TOP_LEVEL_LIST,
             topLevelList);
         final MapEntryNode foo = mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(
                 TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
@@ -508,11 +488,12 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
                     .withChild(mapEntry(NESTED_LIST_QNAME, NESTED_LIST_KEY_QNAME, "bar")).build()).build();
         final Entry<InstanceIdentifier<?>, DataObject> entry = codecContext.fromNormalizedNode(
             BI_TOP_LEVEL_LIST_FOO_PATH, foo);
-        final List<NestedList> nestedLists = new ArrayList<>();
-        nestedLists.add(new NestedListBuilder().withKey(new NestedListKey("foo")).build());
-        nestedLists.add(new NestedListBuilder().withKey(new NestedListKey("bar")).build());
-        final TopLevelList topLevelList = new TopLevelListBuilder().withKey(TOP_LEVEL_LIST_FOO_KEY).setNestedList(
-            nestedLists).build();
+        final TopLevelList topLevelList = new TopLevelListBuilder()
+            .withKey(TOP_LEVEL_LIST_FOO_KEY)
+            .setNestedList(List.of(
+                new NestedListBuilder().withKey(new NestedListKey("foo")).build(),
+                new NestedListBuilder().withKey(new NestedListKey("bar")).build()))
+            .build();
         assertEquals(topLevelList, entry.getValue());
     }
 
@@ -523,8 +504,8 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingCodec
         final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
         final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
 
-        final AugmentationIdentifier aug1Id = new AugmentationIdentifier(Collections.singleton(augmentChoice1QName));
-        final AugmentationIdentifier aug2Id = new AugmentationIdentifier(Collections.singleton(augmentChoice2QName));
+        final AugmentationIdentifier aug1Id = new AugmentationIdentifier(Set.of(augmentChoice1QName));
+        final AugmentationIdentifier aug2Id = new AugmentationIdentifier(Set.of(augmentChoice2QName));
         final NodeIdentifier augmentChoice1Id = new NodeIdentifier(augmentChoice1QName);
         final NodeIdentifier augmentChoice2Id = new NodeIdentifier(augmentChoice2QName);
         final NodeIdentifier containerId = new NodeIdentifier(containerQName);
index 0d3bf463f38cfc24b6fa0923d8b3abe3121ebe7a..f4d9c1e847af4f0ab00c147b24718fc950ee35ab 100644 (file)
@@ -10,9 +10,8 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 import static junit.framework.TestCase.assertTrue;
 import static org.junit.Assert.assertEquals;
 
-import com.google.common.collect.ImmutableList;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.mdsal426.norev.BarCont;
 import org.opendaylight.yang.gen.v1.mdsal426.norev.BarContBuilder;
@@ -57,8 +56,8 @@ public class SpecializingLeafrefTest extends AbstractBindingCodecTest {
 
     @Test
     public void specifiedLeafListTest() {
-        final List<String> testList = ImmutableList.of("test");
-        final BarCont barCont  = new BarContBuilder().setLeafList1(testList).build();
+        final Set<String> testSet = Set.of("test");
+        final BarCont barCont  = new BarContBuilder().setLeafList1(testSet).build();
 
         final Map.Entry<YangInstanceIdentifier, NormalizedNode> res = codecContext
                 .toNormalizedNode(BAR_CONT_II, barCont);
@@ -66,6 +65,6 @@ public class SpecializingLeafrefTest extends AbstractBindingCodecTest {
         final BarCont barContAfterConverting = (BarCont)codecContext
                 .fromNormalizedNode(res.getKey(), res.getValue()).getValue();
 
-        assertEquals(barContAfterConverting.getLeafList1(), testList);
+        assertEquals(barContAfterConverting.getLeafList1(), testSet);
     }
 }
index eb9b36ebf074e7fda50fc9e895060446b030ab31..f20ad882aa49fca638dc9ce408b9cace0ecd1bff 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.mdsal.binding.generator.impl.reactor;
 
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.model.ri.Types;
+import org.opendaylight.yangtools.yang.common.Ordering;
 import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByEffectiveStatement;
 
 /**
  * Generator corresponding to a {@code leaf-list} statement.
@@ -24,6 +26,16 @@ final class LeafListGenerator extends AbstractTypeAwareGenerator<LeafListEffecti
         // If we are a leafref and the reference cannot be resolved, we need to generate a list wildcard, not
         // List<Object>, we will try to narrow the return type in subclasses.
         final Type type = super.methodReturnType(builderFactory);
-        return Types.objectType().equals(type) ? Types.listTypeWildcard() : Types.listTypeFor(type);
+        final boolean isObject = Types.objectType().equals(type);
+        final Ordering ordering = statement().findFirstEffectiveSubstatementArgument(OrderedByEffectiveStatement.class)
+            .orElse(Ordering.SYSTEM);
+        switch (ordering) {
+            case SYSTEM:
+                return isObject ? Types.setTypeWildcard() : Types.setTypeFor(type);
+            case USER:
+                return isObject ? Types.listTypeWildcard() : Types.listTypeFor(type);
+            default:
+                throw new IllegalStateException("Unexpected ordering " + ordering);
+        }
     }
 }
index b9feeb59120c36d910658bf14f57501fcdd93194..b50a57799c8852ed2b2a7979ae9d60203ccc7ce6 100644 (file)
@@ -87,7 +87,7 @@ public class AugmentedTypeTest {
             }
         }
         assertNotNull("getHigherLayerIf method is null", getHigherLayerIfMethod);
-        assertEquals(Types.listTypeFor(Types.STRING), getHigherLayerIfMethod.getReturnType());
+        assertEquals(Types.setTypeFor(Types.STRING), getHigherLayerIfMethod.getReturnType());
 
         // 'InterfaceKey'
         assertNotNull("InterfaceKey is null", gtInterfaceKey);
index 5271db18683776d4e4b651f060e2a0503bd40a07..99417d7016eba689018e8ccbd02fdbcbae801870 100644 (file)
@@ -17,6 +17,7 @@ import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
+import java.util.Set;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -86,7 +87,7 @@ public class DefaultBindingGeneratorTest {
         assertThat(bEnumsType, instanceOf(ParameterizedType.class));
         final var enumsType = (ParameterizedType) bEnumsType;
 
-        assertEquals(Types.typeForClass(List.class), enumsType.getRawType());
+        assertEquals(Types.typeForClass(Set.class), enumsType.getRawType());
         final var enumsTypeArgs = enumsType.getActualTypeArguments();
         assertEquals(1, enumsTypeArgs.length);
         assertEquals(TEST_TYPE_PROVIDER + ".Foo.ListOfEnums", enumsTypeArgs[0].getFullyQualifiedName());
index 47492dabef3fded99a7a3232afc88ed35a519639..f7ad372a3ffed27dde5f5f85e8c23a50ada789de 100644 (file)
@@ -133,7 +133,7 @@ public class GeneratedTypesLeafrefTest {
         Type getHigherLayerIfType = getHigherLayerIf.getReturnType();
         assertNotNull(getHigherLayerIfType);
         assertNotSame("java.lang.Void", getHigherLayerIfType);
-        assertEquals("List", getHigherLayerIfType.getName());
+        assertEquals("Set", getHigherLayerIfType.getName());
 
         // NetworkLink
         final List<MethodSignature> gtNetworkLinkMethods = gtNetworkLink.getMethodDefinitions();
index 9a268e471d35064567bab092212e7a352eec52a7..70de1031fda6ae6e64f06611b7b0bd7af894fbc5 100644 (file)
@@ -166,7 +166,7 @@ public class GeneratedTypesTest {
         }
 
         assertEquals(1, getFooMethodCounter);
-        assertEquals("List", getFooMethodReturnTypeName);
+        assertEquals("Set", getFooMethodReturnTypeName);
 
         assertEquals(1, getBarMethodCounter);
         assertEquals("String", getBarMethodReturnTypeName);
@@ -196,7 +196,7 @@ public class GeneratedTypesTest {
         assertEquals("Uint8", getFooMethodReturnTypeName);
 
         assertEquals(1, getBarMethodCounter);
-        assertEquals("List", getBarMethodReturnTypeName);
+        assertEquals("Set", getBarMethodReturnTypeName);
     }
 
     @Test
index 30596c02eaabae1de0df0014367171b05d804f16..6f17f10a2a981c8d91f215264a22391b7a1dfba9 100644 (file)
@@ -282,8 +282,8 @@ public class UsesTest {
             new NameTypePattern("getContainerGroupingListTest", "ContainerGroupingListTest"),
             new NameTypePattern("getLeafGroupingListTest", "String"),
             new NameTypePattern("requireLeafGroupingListTest", "String"),
-            new NameTypePattern("getLeaffllistGroupingListTest", "List<String>"),
-            new NameTypePattern("requireLeaffllistGroupingListTest", "List<String>"),
+            new NameTypePattern("getLeaffllistGroupingListTest", "Set<String>"),
+            new NameTypePattern("requireLeaffllistGroupingListTest", "Set<String>"),
             new NameTypePattern("getListGroupingListTest", "List<ListGroupingListTest>"));
         containsMethods(listTest.getMethodDefinitions(), new NameTypePattern("getListLeafTest", "String"));
         containsMethods(containerGroupingListTest.getMethodDefinitions(), new NameTypePattern(
@@ -539,8 +539,8 @@ public class UsesTest {
             new NameTypePattern("getLeafNotificationTest",  "String"));
         containsMethods(groupingNotificationTest.getMethodDefinitions(),
             new NameTypePattern("getContainerGroupingNotificationTest", "ContainerGroupingNotificationTest"),
-            new NameTypePattern("getLeaffllistGroupingNotificationTest", "List<String>"),
-            new NameTypePattern("requireLeaffllistGroupingNotificationTest", "List<String>"));
+            new NameTypePattern("getLeaffllistGroupingNotificationTest", "Set<String>"),
+            new NameTypePattern("requireLeaffllistGroupingNotificationTest", "Set<String>"));
         containsMethods(containerGroupingNotificationTest.getMethodDefinitions(),
             new NameTypePattern("getLeafContainerGroupingNotificationTest", "Uint32"),
             new NameTypePattern("requireLeafContainerGroupingNotificationTest", "Uint32"));
index 22b159ef253815bbb19a83e7c1208fd4f17376dd..e13583fdb7480b3386b3dcfe7cc8d09e26622f3d 100644 (file)
@@ -1,15 +1,11 @@
 module grouping_uses_rpc {
-
     namespace "urn:grouping:uses:rpc";
     prefix "sbd";
 
     organization "OPEN DAYLIGHT";
     contact "http://www.opendaylight.org/";
 
-    revision 2013-07-18 {
-    }
-
-
+    revision 2013-07-18;
 
     grouping grouping-rpc-input-test {
         container container-grouping-rpc-input-test {
@@ -19,6 +15,7 @@ module grouping_uses_rpc {
         }
         leaf-list leaflist-grouping-rpc-input-test {
             type uint8;
+            ordered-by user;
         }
     }
 
@@ -28,7 +25,7 @@ module grouping_uses_rpc {
         }
     }
 
-//grouping in RPC
+    // grouping in RPC
     rpc rpc-test {
         input {
             uses grouping-rpc-input-test;
@@ -37,4 +34,4 @@ module grouping_uses_rpc {
             uses grouping-rpc-output-test;
         }
     }
-}
\ No newline at end of file
+}
index f9311a1d0cd0f2cd6b74c21b003fe324e11f0504..9540954ec4053bf70e011bea75c3c4a1d0e3222e 100644 (file)
@@ -251,10 +251,16 @@ class BuilderTemplate extends AbstractBuilderTemplate {
         if (Types.strictTypeEquals(getter.returnType, ownGetterType)) {
             return "this._" + propertyName + " = " + retrieveProperty
         }
-        if (Types.isListType(ownGetterType)) {
-            val itemType = (ownGetterType as ParameterizedType).actualTypeArguments.get(0)
-            return '''
-                this._«propertyName» = Â«CODEHELPERS.importedName».checkListFieldCast(«itemType.importedName».class, "«propertyName»", Â«retrieveProperty»)'''
+        if (ownGetterType instanceof ParameterizedType) {
+            val itemType = ownGetterType.actualTypeArguments.get(0)
+            if (Types.isListType(ownGetterType)) {
+                return '''
+                    this._«propertyName» = Â«CODEHELPERS.importedName».checkListFieldCast(«itemType.importedName».class, "«propertyName»", Â«retrieveProperty»)'''
+            }
+            if (Types.isSetType(ownGetterType)) {
+                return '''
+                this._«propertyName» = Â«CODEHELPERS.importedName».checkSetFieldCast(«itemType.importedName».class, "«propertyName»", Â«retrieveProperty»)'''
+            }
         }
         return '''
             this._«propertyName» = Â«CODEHELPERS.importedName».checkFieldCast(«ownGetter.returnType.importedName».class, "«propertyName»", Â«retrieveProperty»)'''
@@ -317,7 +323,7 @@ class BuilderTemplate extends AbstractBuilderTemplate {
     def private generateSetter(GeneratedProperty field) {
         val returnType = field.returnType
         if (returnType instanceof ParameterizedType) {
-            if (Types.isListType(returnType)) {
+            if (Types.isListType(returnType) || Types.isSetType(returnType)) {
                 val arguments = returnType.actualTypeArguments
                 if (arguments.isEmpty) {
                     return generateListSetter(field, Types.objectType)
index ffafbd51c6e6e2ae924fece8f6d1f74c1e35e6fb..8d3b3b85e979d3a6f553c47eb625e074bf46fd76 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.mdsal.binding.model.api.Enumeration
 import org.opendaylight.mdsal.binding.model.api.GeneratedType
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName
 import org.opendaylight.mdsal.binding.model.api.MethodSignature
+import org.opendaylight.mdsal.binding.model.api.ParameterizedType
 import org.opendaylight.mdsal.binding.model.api.Type
 import org.opendaylight.mdsal.binding.model.ri.Types
 import org.opendaylight.mdsal.binding.model.ri.TypeConstants
@@ -378,8 +379,11 @@ class InterfaceTemplate extends BaseTemplate {
     '''
 
     def private String nullableType(Type type) {
-        if (type.isObject && (Types.isMapType(type) || Types.isListType(type))) {
-            return type.importedNullable
+        if (type.isObject && type instanceof ParameterizedType) {
+            val param = type as ParameterizedType
+            if (Types.isMapType(param) || Types.isListType(param) || Types.isSetType(param)) {
+                return type.importedNullable
+            }
         }
         return type.importedName
     }
index b12f352f15b801432d0d8c91f64bed4d48327c41..0d87cbffc935a76611ee9ba4a15182a739907708 100644 (file)
@@ -32,12 +32,13 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
+import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.model.ri.Types;
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 
 public class SpecializingLeafrefTest extends BaseCompilationTest {
-    private static final Type LIST_STRING_TYPE  = Types.listTypeFor(Types.STRING);
+    private static final ParameterizedType SET_STRING_TYPE  = Types.setTypeFor(Types.STRING);
 
     public static final String BAR_CONT = "BarCont";
     public static final String BOOLEAN_CONT = "BooleanCont";
@@ -55,8 +56,8 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
 
     private static final String GET_LEAF1_TYPE_OBJECT = "    Object getLeaf1();";
     private static final String GET_LEAF1_TYPE_STRING = "    String getLeaf1();";
-    private static final String GET_LEAFLIST1_WILDCARD = "    @Nullable List<?> getLeafList1();";
-    private static final String GET_LEAFLIST1_STRING = "    @Nullable List<String> getLeafList1();";
+    private static final String GET_LEAFLIST1_WILDCARD = "    @Nullable Set<?> getLeafList1();";
+    private static final String GET_LEAFLIST1_STRING = "    @Nullable Set<String> getLeafList1();";
     private static final String GET_LEAFLIST1_DECLARATION = " getLeafList1();";
     private static final String GET_LEAF1_DECLARATION = " getLeaf1();";
 
@@ -100,7 +101,7 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
     @Test
     public void testGroupingWithUnresolvedLeafRefs() throws IOException {
         verifyReturnType(FOO_GRP, GET_LEAF1_NAME, Types.objectType());
-        verifyReturnType(FOO_GRP, GET_LEAFLIST1_NAME, Types.listTypeWildcard());
+        verifyReturnType(FOO_GRP, GET_LEAFLIST1_NAME, Types.setTypeWildcard());
 
         final String content = getFileContent(FOO_GRP);
 
@@ -128,7 +129,7 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
 
     @Test
     public void testLeafListLeafrefPointsLeaf() throws IOException {
-        verifyReturnType(RESOLVED_LEAF_GRP, GET_LEAFLIST1_NAME, LIST_STRING_TYPE);
+        verifyReturnType(RESOLVED_LEAF_GRP, GET_LEAFLIST1_NAME, SET_STRING_TYPE);
 
         final String content = getFileContent(RESOLVED_LEAF_GRP);
 
@@ -137,7 +138,7 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
 
     @Test
     public void testLeafListLeafrefPointsLeafList() throws IOException {
-        verifyReturnType(RESOLVED_LEAFLIST_GRP, GET_LEAFLIST1_NAME, LIST_STRING_TYPE);
+        verifyReturnType(RESOLVED_LEAFLIST_GRP, GET_LEAFLIST1_NAME, SET_STRING_TYPE);
 
         final String content = getFileContent(RESOLVED_LEAFLIST_GRP);
 
@@ -220,7 +221,7 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
                 doubleTab("if (arg instanceof " + FOO_GRP_REF + ") {"),
                 tripleTab("this._leaf1 = CodeHelpers.checkFieldCast(String.class, \"leaf1\", "
                     + ARG_AS_FOO_GRP + ".getLeaf1());"),
-                tripleTab("this._leafList1 = CodeHelpers.checkListFieldCast(String.class, \"leafList1\", "
+                tripleTab("this._leafList1 = CodeHelpers.checkSetFieldCast(String.class, \"leafList1\", "
                     + ARG_AS_FOO_GRP + ".getLeafList1());"),
                 tripleTab("this._leaf2 = " + ARG_AS_FOO_GRP + ".getLeaf2();"),
                 TTAB_SET_IS_VALID_ARG_TRUE,
@@ -239,7 +240,7 @@ public class SpecializingLeafrefTest extends BaseCompilationTest {
                 tab("public BarContBuilder(" + FOO_GRP_REF + " arg) {"),
                 doubleTab("this._leaf1 = CodeHelpers.checkFieldCast(String.class, \"leaf1\", "
                     + "arg.getLeaf1());"),
-                doubleTab("this._leafList1 = CodeHelpers.checkListFieldCast(String.class, \"leafList1\", "
+                doubleTab("this._leafList1 = CodeHelpers.checkSetFieldCast(String.class, \"leafList1\", "
                     + "arg.getLeafList1());"),
                 doubleTab(LEAF2_ASSIGNMENT),
                 TAB_CLOSING_METHOD_BRACE);
index 132de64d03f1ea56f1e9488b436befc5d7bd47ef..b1e53087ca5e6a2c02d86a4a379ecf2725772321 100644 (file)
@@ -65,6 +65,7 @@ public final class Types {
     private static final @NonNull ConcreteType SERIALIZABLE = typeForClass(Serializable.class);
     private static final @NonNull ConcreteType SET_TYPE = typeForClass(Set.class);
     private static final @NonNull ParameterizedType LIST_TYPE_WILDCARD = parameterizedTypeFor(LIST_TYPE);
+    private static final @NonNull ParameterizedType SET_TYPE_WILDCARD = parameterizedTypeFor(SET_TYPE);
 
     /**
      * It is not desirable to create instance of this class.
@@ -194,6 +195,15 @@ public final class Types {
         return parameterizedTypeFor(SET_TYPE, valueType);
     }
 
+    /**
+     * Returns an instance of {@link ParameterizedType} describing the typed {@link Set}&lt;?&gt;.
+     *
+     * @return Description of type instance of Set
+     */
+    public static @NonNull ParameterizedType setTypeWildcard() {
+        return SET_TYPE_WILDCARD;
+    }
+
     /**
      * Returns an instance of {@link ParameterizedType} describing the typed {@link List}&lt;V&gt; with concrete type
      * of value.
@@ -214,6 +224,10 @@ public final class Types {
         return LIST_TYPE_WILDCARD;
     }
 
+    public static boolean isSetType(final ParameterizedType type) {
+        return SET_TYPE.equals(type.getRawType());
+    }
+
     public static boolean isListType(final ParameterizedType type) {
         return LIST_TYPE.equals(type.getRawType());
     }
index 43f7f16aef1a7de6c754479ce7510227f3ff1ecd..ab8d1d0437296090decb92bb2a88a5146cc2ccb8 100644 (file)
@@ -32,6 +32,7 @@ module test-pattern {
             type string {
               pattern '[a-z]*';
             }
+            ordered-by user;
         }
     }
-}
\ No newline at end of file
+}
index 349c4359ccb487eacf13674dab145ab98feaa9d2..9b9a340055cc28ebcd73233c8e68a9ebf8779413 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertNull;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.mdsal442.keydef.norev.Def;
 import org.opendaylight.yang.gen.v1.mdsal442.keydef.norev.DefBuilder;
@@ -31,9 +32,16 @@ import org.opendaylight.yang.gen.v1.urn.test.pattern.rev170101.ContBuilder;
 public class TestListSquashing {
     @Test
     public void testEmptyLeafList() {
-        final Cont obj = new ContBuilder().setTest3(List.of()).build();
+        final Cont obj = new ContBuilder().setTest3(Set.of()).build();
+        // Eventhough return type is Set, it should be retained
+        assertEquals(Set.of(), obj.getTest3());
+    }
+
+    @Test
+    public void testEmptyUserOrderedLeafList() {
+        final Cont obj = new ContBuilder().setTest4(List.of()).build();
         // Eventhough return type is List, it should be retained
-        assertEquals(List.of(), obj.getTest3());
+        assertEquals(List.of(), obj.getTest4());
     }
 
     @Test
index 9f24fe2c45ac719f88d648e007fcf307ddd6fc8c..b378a703ba86e688acb52e01afef817f51d5b333 100644 (file)
@@ -16,10 +16,12 @@ import com.google.common.base.VerifyException;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.Set;
 import java.util.regex.Pattern;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
@@ -386,21 +388,44 @@ public final class CodeHelpers {
      * @param requiredClass Required item class
      * @param fieldName name of the field being filled
      * @param list List, which items should be checked
+     * @return Type-checked List
      * @throws IllegalArgumentException if a list item is not instance of {@code requiredItemClass}
      * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null
      */
     @SuppressWarnings("unchecked")
     public static <T> @Nullable List<T> checkListFieldCast(final @NonNull Class<?> requiredClass,
             final @NonNull String fieldName, final @Nullable List<?> list) {
-        if (list != null) {
+        checkCollectionField(requiredClass, fieldName, list);
+        return (List<T>) list;
+    }
+
+    /**
+     * Utility method for checking whether the items of target list is compatible.
+     *
+     * @param requiredClass Required item class
+     * @param fieldName name of the field being filled
+     * @param set Set, which items should be checked
+     * @return Type-checked Set
+     * @throws IllegalArgumentException if a set item is not instance of {@code requiredItemClass}
+     * @throws NullPointerException if {@code requiredClass} or {@code fieldName} is null
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> @Nullable Set<T> checkSetFieldCast(final @NonNull Class<?> requiredClass,
+            final @NonNull String fieldName, final @Nullable Set<?> set) {
+        checkCollectionField(requiredClass, fieldName, set);
+        return (Set<T>) set;
+    }
+
+    private static void checkCollectionField(final @NonNull Class<?> requiredClass,
+            final @NonNull String fieldName, final @Nullable Collection<?> collection) {
+        if (collection != null) {
             try {
-                list.forEach(item -> requiredClass.cast(requireNonNull(item)));
+                collection.forEach(item -> requiredClass.cast(requireNonNull(item)));
             } catch (ClassCastException | NullPointerException e) {
                 throw new IllegalArgumentException("Invalid input list item for property \"" + requireNonNull(fieldName)
                     + "\"", e);
             }
         }
-        return (List<T>) list;
     }
 
     /**
index aed122ad91bddbed5caa90b72279cdc732034ccc..f3023e9a647518e1abfecd72a55233358c6ab8c0 100644 (file)
@@ -177,7 +177,7 @@ public class TracingBroker implements TracingDOMDataBroker {
 
     private void configure(final Config config) {
         registrationWatches.clear();
-        List<String> paths = config.getRegistrationWatches();
+        Set<String> paths = config.getRegistrationWatches();
         if (paths != null) {
             for (String path : paths) {
                 watchRegistrations(path, null);
index b0020fc17a43b151a596a9e8ffb0fd6c4ca7d88b..ea726bdc64e490c56e405568b44f182d99b93c76 100644 (file)
@@ -12,7 +12,6 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.util.Optional;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
@@ -25,16 +24,16 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.CommonLeafs;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.Module;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.ModuleBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.module.Submodule;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.module.SubmoduleBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.data.api.DatastoreIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
-class LegacyContentBuilder implements YangLibraryContentBuilderWithLegacy {
+final class LegacyContentBuilder implements YangLibraryContentBuilderWithLegacy {
     private static final CommonLeafs.Revision EMPTY_REV = new CommonLeafs.Revision("");
 
     private final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec;
@@ -42,7 +41,7 @@ class LegacyContentBuilder implements YangLibraryContentBuilderWithLegacy {
 
     LegacyContentBuilder(final YangLibraryContentBuilderImpl delegate, final BindingCodecTree codecTree) {
         this.delegate = requireNonNull(delegate);
-        this.legacyCodec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(ModulesState.class)));
+        legacyCodec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(ModulesState.class)));
     }
 
     @Override
@@ -75,24 +74,25 @@ class LegacyContentBuilder implements YangLibraryContentBuilderWithLegacy {
     @VisibleForTesting
     ContainerNode formatModulesState(final EffectiveModelContext context) {
         // Two-step process: we first build the content and then use hashCode() to generate module-set-id
-        final ModulesStateBuilder builder = new ModulesStateBuilder().setModuleSetId("")
-                .setModule(context.getModules().stream()
-                        .map(module -> new ModuleBuilder()
-                                .setName(new YangIdentifier(module.getName()))
-                                .setNamespace(new Uri(module.getNamespace().toString()))
-                                .setRevision(convertRevision(module.getRevision()))
-                                .setSubmodule(module.getSubmodules().stream()
-                                        .map(submodule -> new SubmoduleBuilder()
-                                                .setName(new YangIdentifier(submodule.getName()))
-                                                .setRevision(convertRevision(submodule.getRevision()))
-                                                .build())
-                                        .collect(Collectors.toUnmodifiableMap(Submodule::key, Function.identity())))
-                                .setFeature(module.getFeatures().stream()
-                                        .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
-                                        .collect(Collectors.toUnmodifiableList()))
-                                .setConformanceType(Module.ConformanceType.Implement)
-                                .build())
-                        .collect(Collectors.toUnmodifiableMap(Module::key, Function.identity())));
+        final ModulesStateBuilder builder = new ModulesStateBuilder()
+            .setModuleSetId("")
+            .setModule(context.getModules().stream()
+                .map(module -> new ModuleBuilder()
+                    .setName(new YangIdentifier(module.getName()))
+                    .setNamespace(new Uri(module.getNamespace().toString()))
+                    .setRevision(convertRevision(module.getRevision()))
+                    .setSubmodule(module.getSubmodules().stream()
+                        .map(submodule -> new SubmoduleBuilder()
+                            .setName(new YangIdentifier(submodule.getName()))
+                            .setRevision(convertRevision(submodule.getRevision()))
+                            .build())
+                        .collect(BindingMap.toMap()))
+                    .setFeature(module.getFeatures().stream()
+                        .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
+                        .collect(Collectors.toUnmodifiableSet()))
+                    .setConformanceType(Module.ConformanceType.Implement)
+                    .build())
+                .collect(BindingMap.toMap()));
 
         return (ContainerNode) legacyCodec.serialize(builder.setModuleSetId(String.valueOf(builder.build().hashCode()))
             .build());
index 4064655b46ab9fa4530a2839747eae3d8117e572..d3b039f371eb3f42927b94d9e4f15dba11619201 100644 (file)
@@ -221,7 +221,7 @@ final class MountPointContextFactoryImpl extends AbstractMountPointContextFactor
     }
 
     private static void fillSource(final List<SourceReference> sources, final YangIdentifier sourceName,
-            final Optional<Revision> revision, final List<Uri> uris) {
+            final Optional<Revision> revision, final Set<Uri> uris) {
         final var sourceId = RevisionSourceIdentifier.create(sourceName.getValue(), revision);
         final SourceReference sourceRef;
         if (uris != null && uris.isEmpty()) {
index c15a1e62541d37bc98cb42193e213b25148ebfcb..5f4c79f478b28a1f7410996907be092d4aff7621 100644 (file)
@@ -14,7 +14,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
@@ -27,19 +26,19 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibraryBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.Module;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.ModuleBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.module.Submodule;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.module.SubmoduleBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSet;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSetBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSetKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.data.api.DatastoreIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 
-class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
+final class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
     private static final String MODULE_SET_NAME = "ODL_modules";
 
     private final Map<DatastoreIdentifier, EffectiveModelContext> datastores = new HashMap<>();
@@ -50,7 +49,7 @@ class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
 
     YangLibraryContentBuilderImpl(final BindingCodecTree codecTree) {
         this.codecTree = Objects.requireNonNull(codecTree);
-        this.codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(YangLibrary.class)));
+        codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(YangLibrary.class)));
     }
 
     @Override
@@ -85,10 +84,10 @@ class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
         // Two-step process: we first build the content and then use hashCode() to generate module-set-id
         final YangLibraryBuilder builder = new YangLibraryBuilder().setContentId("");
         final ModuleSetBuilder moduleSetBuilder = new ModuleSetBuilder()
-                .setModule(modelContext.getModules().stream()
-                        .map(this::buildModule)
-                        .collect(Collectors.toUnmodifiableMap(Module::key, Function.identity())))
-                .setName(MODULE_SET_NAME);
+            .setModule(modelContext.getModules().stream()
+                .map(YangLibraryContentBuilderImpl::buildModule)
+                .collect(BindingMap.toMap()))
+            .setName(MODULE_SET_NAME);
         final ModuleSet moduleSet = moduleSetBuilder.build();
 
         builder.setModuleSet(Map.of(new ModuleSetKey(moduleSet.getName()), moduleSet));
@@ -96,21 +95,21 @@ class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
             .build());
     }
 
-    private Module buildModule(final org.opendaylight.yangtools.yang.model.api.Module module) {
+    private static Module buildModule(final org.opendaylight.yangtools.yang.model.api.Module module) {
         return new ModuleBuilder()
-                .setName(new YangIdentifier(module.getName()))
-                .setNamespace(new Uri(module.getQNameModule().getNamespace().toString()))
-                .setRevision(convertRevision(module.getRevision()))
-                .setSubmodule(module.getSubmodules().stream()
-                        .map(submodule -> new SubmoduleBuilder()
-                                .setName(new YangIdentifier(submodule.getName()))
-                                .setRevision(convertRevision(submodule.getRevision()))
-                                .build())
-                        .collect(Collectors.toUnmodifiableMap(Submodule::key, Function.identity())))
-                .setFeature(module.getFeatures().stream()
-                        .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
-                        .collect(Collectors.toUnmodifiableList()))
-                .build();
+            .setName(new YangIdentifier(module.getName()))
+            .setNamespace(new Uri(module.getQNameModule().getNamespace().toString()))
+            .setRevision(convertRevision(module.getRevision()))
+            .setSubmodule(module.getSubmodules().stream()
+                .map(submodule -> new SubmoduleBuilder()
+                    .setName(new YangIdentifier(submodule.getName()))
+                    .setRevision(convertRevision(submodule.getRevision()))
+                    .build())
+                .collect(BindingMap.toMap()))
+            .setFeature(module.getFeatures().stream()
+                .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
+                .collect(Collectors.toUnmodifiableSet()))
+            .build();
     }
 
     private static RevisionIdentifier convertRevision(final Optional<Revision> revision) {
diff --git a/yanglib/mdsal-yanglib-rfc8525/src/test/java/org/opendaylight/mdsal/yanglib/rfc8525/AbstractYangLibraryTest.java b/yanglib/mdsal-yanglib-rfc8525/src/test/java/org/opendaylight/mdsal/yanglib/rfc8525/AbstractYangLibraryTest.java
new file mode 100644 (file)
index 0000000..26c932b
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, 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.yanglib.rfc8525;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
+import org.opendaylight.mdsal.binding.dom.codec.impl.DefaultBindingCodecTreeFactory;
+import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
+import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
+import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator;
+import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
+import org.opendaylight.yangtools.yang.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
+import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
+
+abstract class AbstractYangLibraryTest {
+    private static final BindingRuntimeGenerator BINDING_RUNTIME_GENERATOR = new DefaultBindingRuntimeGenerator();
+    private static final YangParserFactory YANG_PARSER_FACTORY = new DefaultYangParserFactory();
+    private static final BindingCodecTreeFactory CODEC_FACTORY = new DefaultBindingCodecTreeFactory();
+
+    static BindingRuntimeContext runtimeContext;
+    static BindingCodecTree codecTree;
+
+    YangLibrarySupport yangLib;
+
+    @BeforeClass
+    public static void beforeClass() {
+        runtimeContext = BindingRuntimeHelpers.createRuntimeContext();
+        codecTree = CODEC_FACTORY.create(runtimeContext);
+    }
+
+    @Before
+    public void before() throws YangParserException {
+        yangLib = new YangLibrarySupport(YANG_PARSER_FACTORY, BINDING_RUNTIME_GENERATOR, CODEC_FACTORY);
+    }
+}
index cc4201c7cad25dd43a54514dbdb00cc72e2f43ad..1dbff2f5144653f31b8a0cd6ed125f5e9a29d54d 100644 (file)
@@ -10,19 +10,11 @@ package org.opendaylight.mdsal.yanglib.rfc8525;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
-import org.junit.Before;
+import java.util.Set;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
-import org.opendaylight.mdsal.binding.dom.codec.impl.DefaultBindingCodecTreeFactory;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator;
-import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.ModulesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.RevisionIdentifier;
@@ -33,30 +25,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.list.ModuleKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.parser.api.YangParserException;
-import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
-import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
-
-public class LegacyYangLibraryFormatTest {
-
-    private static final BindingRuntimeGenerator BINDING_RUNTIME_GENERATOR = new DefaultBindingRuntimeGenerator();
-
-    private static final YangParserFactory YANG_PARSER_FACTORY = new DefaultYangParserFactory();
-
-    private BindingRuntimeContext runtimeContext;
-    private BindingCodecTree codecTree;
-    private YangLibrarySupport yangLib;
-
-    @Before
-    public void setUp() throws YangParserException {
-        runtimeContext = BindingRuntimeHelpers.createRuntimeContext();
-        final DefaultBindingCodecTreeFactory codecFactory = new DefaultBindingCodecTreeFactory();
-        yangLib = new YangLibrarySupport(YANG_PARSER_FACTORY, BINDING_RUNTIME_GENERATOR,
-                codecFactory);
-        codecTree = codecFactory.create(runtimeContext);
-    }
 
+public class LegacyYangLibraryFormatTest extends AbstractYangLibraryTest {
     @Test
     public void testLegacyFormat() {
         final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec =
@@ -75,21 +47,12 @@ public class LegacyYangLibraryFormatTest {
         assertEquals(createControlModules(), modulesState.getModule());
     }
 
-    private Map<ModuleKey, Module> createControlModules() {
-        final Map<ModuleKey, Module> modules = new HashMap<>();
-        modules.put(new ModuleKey(new YangIdentifier("ietf-yang-library"),
-                        new Revision(new RevisionIdentifier("2019-01-04"))),
-                createModule("ietf-yang-library", "urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-inet-types"),
-                        new Revision(new RevisionIdentifier("2013-07-15"))),
-                createModule("ietf-inet-types", "urn:ietf:params:xml:ns:yang:ietf-inet-types", "2013-07-15"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-datastores"),
-                        new Revision(new RevisionIdentifier("2018-02-14"))),
-                createModule("ietf-datastores", "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-yang-types"),
-                        new Revision(new RevisionIdentifier("2013-07-15"))),
-                createModule("ietf-yang-types", "urn:ietf:params:xml:ns:yang:ietf-yang-types", "2013-07-15"));
-        return modules;
+    private static Map<ModuleKey, Module> createControlModules() {
+        return BindingMap.of(
+            createModule("ietf-yang-library", "urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04"),
+            createModule("ietf-inet-types", "urn:ietf:params:xml:ns:yang:ietf-inet-types", "2013-07-15"),
+            createModule("ietf-datastores", "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"),
+            createModule("ietf-yang-types", "urn:ietf:params:xml:ns:yang:ietf-yang-types", "2013-07-15"));
     }
 
     private static Module createModule(final String name, final String namespace, final String revision) {
@@ -98,7 +61,7 @@ public class LegacyYangLibraryFormatTest {
                 .setNamespace(new Uri(namespace))
                 .setRevision(new Revision(new RevisionIdentifier(revision)))
                 .setConformanceType(ConformanceType.Implement)
-                .setFeature(Collections.emptyList())
+                .setFeature(Set.of())
                 .build();
     }
 }
\ No newline at end of file
index 0e07e8479b7f055853fd9f35831d9ee54765e500..ef43cb7d2ee42ed6098b1b5aad1b6fef83f9c601 100644 (file)
@@ -9,18 +9,10 @@ package org.opendaylight.mdsal.yanglib.rfc8525;
 
 import static org.junit.Assert.assertEquals;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
-import org.junit.Before;
+import java.util.Set;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
-import org.opendaylight.mdsal.binding.dom.codec.impl.DefaultBindingCodecTreeFactory;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeGenerator;
-import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.RevisionIdentifier;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibrary;
@@ -31,28 +23,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.librar
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSetKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
-import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
-
-public class YangLibrarySupportTest {
-
-    private static final BindingRuntimeGenerator BINDING_RUNTIME_GENERATOR = new DefaultBindingRuntimeGenerator();
-
-    private static final YangParserFactory YANG_PARSER_FACTORY = new DefaultYangParserFactory();
-
-    private YangLibrarySupport yangLib;
-    private BindingRuntimeContext runtimeContext;
-    private BindingCodecTree codecTree;
-
-    @Before
-    public void setUp() throws Exception {
-        runtimeContext = BindingRuntimeHelpers.createRuntimeContext();
-        final DefaultBindingCodecTreeFactory codecFactory = new DefaultBindingCodecTreeFactory();
-        yangLib = new YangLibrarySupport(YANG_PARSER_FACTORY, BINDING_RUNTIME_GENERATOR, codecFactory);
-        codecTree = codecFactory.create(runtimeContext);
-    }
 
+public class YangLibrarySupportTest extends AbstractYangLibraryTest {
     @Test
     public void testFormatSchema() {
         final BindingDataObjectCodecTreeNode<YangLibrary> codec =
@@ -68,25 +42,21 @@ public class YangLibrarySupportTest {
         assertEquals(moduleSet.getModule(), createControlModules());
     }
 
-    private Map<ModuleKey, Module> createControlModules() {
-        final Map<ModuleKey, Module> modules = new HashMap<>();
-        modules.put(new ModuleKey(new YangIdentifier("ietf-yang-library")),
-                createModule("ietf-yang-library", "urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-inet-types")),
-                createModule("ietf-inet-types", "urn:ietf:params:xml:ns:yang:ietf-inet-types", "2013-07-15"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-datastores")),
-                createModule("ietf-datastores", "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
-        modules.put(new ModuleKey(new YangIdentifier("ietf-yang-types")),
-                createModule("ietf-yang-types", "urn:ietf:params:xml:ns:yang:ietf-yang-types", "2013-07-15"));
-        return modules;
+    private static Map<ModuleKey, Module> createControlModules() {
+        return BindingMap.of(
+            createModule("ietf-yang-library", "urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04"),
+            createModule("ietf-inet-types", "urn:ietf:params:xml:ns:yang:ietf-inet-types", "2013-07-15"),
+            createModule("ietf-datastores", "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"),
+            createModule("ietf-yang-types", "urn:ietf:params:xml:ns:yang:ietf-yang-types", "2013-07-15"));
     }
 
-    private Module createModule(final String name, final String namespace, final String revision) {
-        return new ModuleBuilder().setName(new YangIdentifier(name))
+    private static Module createModule(final String name, final String namespace, final String revision) {
+        return new ModuleBuilder()
+            .setName(new YangIdentifier(name))
                 .setNamespace(new Uri(namespace))
                 .setRevision(new RevisionIdentifier(revision))
-                .setFeature(Collections.emptyList())
-                .setSubmodule(Collections.emptyMap())
+                .setFeature(Set.of())
+                .setSubmodule(Map.of())
                 .build();
     }
 }
\ No newline at end of file