<!-- 
RSS generated by JIRA (8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d) at Wed Feb 07 20:10:06 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>OpenDaylight JIRA</title>
    <link>https://jira.opendaylight.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>8.20.10</version>
        <build-number>820010</build-number>
        <build-date>22-06-2022</build-date>
    </build-info>


<item>
            <title>[MDSAL-553] Add BindingMap to help with interfacing with keyed lists (Maps)</title>
                <link>https://jira.opendaylight.org/browse/MDSAL-553</link>
                <project id="10137" key="MDSAL">mdsal</project>
                    <description>&lt;p&gt;Current Builders allow setting properties only as an entire field. This is ends up being clunky, as we really want them to be built in a fluent way.&lt;/p&gt;

&lt;p&gt;This is especially problematic with Map-based properties, as populating the map requires the product to be present to extract the key:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
Map&amp;lt;Bar&amp;gt; bars = ...;
Bar tmp = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;one&quot;&lt;/span&gt;).build();
bars.put(tmp.key(), tmp);
tmp = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;two&quot;&lt;/span&gt;).build();
bars.put(tmp.key(), tmp);
Foo foo = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; FooBuilder().setBar(bars).build();
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;with the empty/null equivalence, we can improve this to something like:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
Foo foo = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; FooBuilder()
    .addBar(&lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;one&quot;&lt;/span&gt;).build())
    .addBar(&lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;two&quot;&lt;/span&gt;).build())
    .build();
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Since these methods are shifting backing structure maintenance to the builder, we also need to ensure proper encapsulation of copy mechanics.&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;</description>
                <environment></environment>
        <key id="32649">MDSAL-553</key>
            <summary>Add BindingMap to help with interfacing with keyed lists (Maps)</summary>
                <type id="10100" iconUrl="https://jira.opendaylight.org/secure/viewavatar?size=xsmall&amp;avatarId=10310&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.opendaylight.org/images/icons/priorities/major.svg">Medium</priority>
                        <status id="5" iconUrl="https://jira.opendaylight.org/images/icons/statuses/resolved.png" description="A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.">Resolved</status>
                    <statusCategory id="3" key="done" colorName="green"/>
                                    <resolution id="10000">Done</resolution>
                                        <assignee username="ilyaigushev">Ilya Igushev</assignee>
                                    <reporter username="rovarga">Robert Varga</reporter>
                        <labels>
                    </labels>
                <created>Mon, 11 May 2020 08:28:58 +0000</created>
                <updated>Wed, 30 Sep 2020 00:10:03 +0000</updated>
                            <resolved>Wed, 30 Sep 2020 00:10:03 +0000</resolved>
                                                    <fixVersion>7.0.0</fixVersion>
                    <fixVersion>6.0.6</fixVersion>
                                    <component>Binding Spec</component>
                        <due></due>
                            <votes>0</votes>
                                    <watches>1</watches>
                                                                                                                <comments>
                            <comment id="68644" author="rovarga" created="Thu, 24 Sep 2020 19:53:50 +0000"  >&lt;p&gt;Adding these methods will lead to significant increase of class size, as we will be creating these all over the place. The convenience used by people is that they construct a List and add them as they are built &#8211; and that is what we are essentially migrating from.&lt;/p&gt;

&lt;p&gt;The key problem we are facing is that extant Map-based utilities are not opinionated enough about their content. In our case, the Map is always in the form:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
Map&amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;i.e. we can mechanically derive the key from the entry, so each of our maps could have:&#160;&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
&lt;span class=&quot;code-keyword&quot;&gt;default&lt;/span&gt; void add(V value) {
    put(value.key(), value);
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Based on these observations, I think we would be best served with a custom Map factory/builder in vein of:&#160;&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
&lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;class &lt;/span&gt;BindingMap {
    &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt; Map&amp;lt;K, V&amp;gt; of(V v1) {
        &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; Map.of(v1.key(), v1);
    }

    &lt;span class=&quot;code-comment&quot;&gt;// ... plus all specializations to map to Map.of(), and then:
&lt;/span&gt;
    &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt; Map&amp;lt;K, V&amp;gt; of(V... values) {
        &lt;span class=&quot;code-comment&quot;&gt;// This, or something with Map.ofEntries()
&lt;/span&gt;        &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; Maps.uniqueIndex(Arrays.asList(values), Identifiable::key);
    }

    &lt;span class=&quot;code-comment&quot;&gt;// and then a builder bridge
&lt;/span&gt;    &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt; BindingMap.Builder&amp;lt;K, V&amp;gt; builder();

    &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt; BindingMap.Builder&amp;lt;K, V&amp;gt; builder(&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt; expectedSize);

    &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;class &lt;/span&gt;Builder&amp;lt;K &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifier&amp;lt;V&amp;gt;, V &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; Identifiable&amp;lt;K&amp;gt;&amp;gt; &lt;span class=&quot;code-keyword&quot;&gt;implements&lt;/span&gt; org.opendaylight.yangtools.concepts.Builder&amp;lt;Map&amp;lt;K, V&amp;gt;&amp;gt; {
        &lt;span class=&quot;code-comment&quot;&gt;// ... and overall design of ImmutableMap.builder(), except we take advantage of Map.entryOf()/Map.ofEntries()
&lt;/span&gt;
        &lt;span class=&quot;code-comment&quot;&gt;// ... and instead of put()/putAll() we have ImmutableList.Builder-like:
&lt;/span&gt;
        &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; Builder&amp;lt;K, V&amp;gt; add(V value);

        &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; Builder&amp;lt;K, V&amp;gt; addAll(V.. values);

        &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; Builder&amp;lt;K, V&amp;gt; addAll(Collection&amp;lt;V&amp;gt; values);

    }
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With that we&apos;ll have a very convenient way of building Maps, hence we do not need add/remove and can just flow like this:&#160;&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
Foo foo = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; FooBuilder()
    .setBar(BindingMap.of(
        &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;one&quot;&lt;/span&gt;).build(),
        &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;two&quot;&lt;/span&gt;).build()))
    .build();
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;or builder-based:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
Foo foo = &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; FooBuilder()
    .setBar(BindingMap.&amp;lt;BarKey, Bar&amp;gt;buider()
        .add(&lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;one&quot;&lt;/span&gt;).build())
        .add(&lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; BarBuilder().setName(&lt;span class=&quot;code-quote&quot;&gt;&quot;two&quot;&lt;/span&gt;).build())
        .build())
    .build(); 
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;now ... the question is where to place such a class. It definitely needs to be in yang-binding.jar. Let&apos;s prototype it there first and see where it leads us.&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                            <customfield id="customfield_11400" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10000" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|i03sef:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                </customfields>
    </item>
</channel>
</rss>