Treat wildcards as objects 46/96546/7
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 16 Jun 2021 09:11:59 +0000 (11:11 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 16 Jun 2021 11:51:22 +0000 (13:51 +0200)
The effort to properly specialize leafref values has created
opportunities for WildcardType to be reported as the return. Handle
these as Objects for now, but also issue FIXMEs for a follow-up proper
fix.

JIRA: MDSAL-668
JIRA: MDSAL-670
Change-Id: I4e8a6ff3aa23a3e94c1ec4a52726e9caf9e9c4ff
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/Mdsal668Test.java [new file with mode: 0644]
binding/mdsal-binding-test-model/src/main/yang/mdsal668.yang [new file with mode: 0644]

index 225cdabe5a76ef2b8ec99b785a4f19189d85c0b2..08fd323144440f4db14ed64f1b5c4da559935098 100644 (file)
@@ -23,6 +23,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
 import java.time.Instant;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
@@ -367,6 +368,8 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri
                 if (schema instanceof LeafSchemaNode) {
                     final LeafSchemaNode leafSchema = (LeafSchemaNode) schema;
 
+                    // FIXME: MDSAL-670: this is not right as we need to find a concrete type, but this may return
+                    //                   Object.class
                     final Class<?> valueType = method.getReturnType();
                     final IllegalArgumentCodec<Object, Object> codec = getCodec(valueType, leafSchema.getType());
                     valueNode = LeafNodeCodecContext.of(leafSchema, codec, method.getName(), valueType,
@@ -382,6 +385,9 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri
                         valueType = (Class<?>) genericType;
                     } else if (genericType instanceof ParameterizedType) {
                         valueType = (Class<?>) ((ParameterizedType) genericType).getRawType();
+                    } else if (genericType instanceof WildcardType) {
+                        // FIXME: MDSAL-670: this is not right as we need to find a concrete type
+                        valueType = Object.class;
                     } else {
                         throw new IllegalStateException("Unexpected return type " + genericType);
                     }
@@ -420,6 +426,8 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri
         } else if (BindingReflections.isBindingClass(valueType)) {
             return getCodecForBindingClass(valueType, instantiatedType);
         }
+        // FIXME: MDSAL-670: this is right for most situations, but we must never return NOOP_CODEC for
+        //                   valueType=Object.class
         return ValueTypeCodec.NOOP_CODEC;
     }
 
diff --git a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/Mdsal668Test.java b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/Mdsal668Test.java
new file mode 100644 (file)
index 0000000..3f7463a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 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.binding.dom.codec.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.mdsal668.norev.Foo;
+import org.opendaylight.yang.gen.v1.mdsal668.norev.FooBuilder;
+import org.opendaylight.yang.gen.v1.mdsal668.norev.bar.Bar;
+import org.opendaylight.yang.gen.v1.mdsal668.norev.bar.BarBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+
+public class Mdsal668Test extends AbstractBindingCodecTest {
+    private static final NodeIdentifier FOO = new NodeIdentifier(Foo.QNAME);
+    private static final InstanceIdentifier<Foo> FOO_IID = InstanceIdentifier.create(Foo.class);
+
+    @Test
+    public void testLeaflistLeafref() {
+        assertEquals(Builders.containerBuilder()
+            .withNodeIdentifier(FOO)
+            .withChild(Builders.containerBuilder()
+                .withNodeIdentifier(new NodeIdentifier(Bar.QNAME))
+                .withChild(Builders.leafSetBuilder()
+                    .withNodeIdentifier(new NodeIdentifier(Bar.QNAME))
+                    .withChild(Builders.leafSetEntryBuilder()
+                        // FIXME: MDSAL-670: these should get translated to YangInstanceIdentifier.create(FOO)
+                        .withNodeIdentifier(new NodeWithValue<>(Bar.QNAME, FOO_IID))
+                        .withValue(FOO_IID)
+                        .build())
+                    .build())
+                .build())
+            .build(), codecContext.toNormalizedNode(FOO_IID,
+                new FooBuilder().setBar(new BarBuilder().setBar(List.of(FOO_IID)).build()).build())
+            .getValue());
+    }
+}
diff --git a/binding/mdsal-binding-test-model/src/main/yang/mdsal668.yang b/binding/mdsal-binding-test-model/src/main/yang/mdsal668.yang
new file mode 100644 (file)
index 0000000..cdddbd1
--- /dev/null
@@ -0,0 +1,22 @@
+module mdsal668 {
+  namespace mdsal668;
+  prefix mdsal668;
+
+  grouping bar {
+    container bar {
+      leaf-list bar {
+        type leafref {
+          path ../../foo;
+        }
+      }
+    }
+  }
+
+  container foo {
+    leaf foo {
+      type instance-identifier;
+    }
+
+    uses bar;
+  }
+}