Bug 8903 - binding-data-codec does not work with boolean type using typedef 89/62389/22
authorJie Han <han.jie@zte.com.cn>
Tue, 29 Aug 2017 01:50:00 +0000 (09:50 +0800)
committerRobert Varga <nite@hq.sk>
Mon, 5 Mar 2018 16:48:06 +0000 (16:48 +0000)
Change-Id: Ib47bedea0e6bbebf7c5e3dbbd012b0df3e872a4b
Signed-off-by: Jie Han <han.jie@zte.com.cn>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/gen/impl/DataNodeContainerSerializerSource.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/EncapsulatedValueCodec.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ValueTypeCodec.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/TypedefTest.java [new file with mode: 0644]
binding/mdsal-binding-test-model/src/main/yang/bug8903.yang [new file with mode: 0755]

index 138813dcea14fec84269f18b13b6e0f99224e09e..b56a664ad82e1bc19cbba1ec3dfa06b9e753251f 100644 (file)
@@ -117,7 +117,10 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou
         }
 
         final String prefix;
-        if (type instanceof BooleanTypeDefinition || type instanceof EmptyTypeDefinition) {
+        // Bug 8903: If it is a derived type of boolean or empty, not an inner type, then the return type
+        // of method would be the generated type of typedef not build-in types, so here it should be 'get'.
+        if ((type instanceof BooleanTypeDefinition || type instanceof EmptyTypeDefinition)
+                && (type.getPath().equals(node.getPath()) || type.getBaseType() == null)) {
             prefix = "is";
         } else {
             prefix = "get";
index 1f6be5360cc9e9f093583ffdfbcd2f2e9f1e1c8a..bcf269a80fd1ef2f36c593e34023853e02c921ca 100644 (file)
@@ -50,6 +50,7 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
@@ -225,15 +226,18 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
         final Map<String, DataSchemaNode> getterToLeafSchema = new HashMap<>();
         for (final DataSchemaNode leaf : childSchema.getChildNodes()) {
             if (leaf instanceof TypedDataSchemaNode) {
-                getterToLeafSchema.put(getGetterName(leaf.getQName(), ((TypedDataSchemaNode) leaf).getType()), leaf);
+                getterToLeafSchema.put(getGetterName(leaf, ((TypedDataSchemaNode) leaf).getType()), leaf);
             }
         }
         return getLeafNodesUsingReflection(parentClass, getterToLeafSchema);
     }
 
-    private static String getGetterName(final QName qname, final TypeDefinition<?> typeDef) {
-        final String suffix = BindingMapping.getGetterSuffix(qname);
-        if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
+    private static String getGetterName(final SchemaNode node, final TypeDefinition<?> typeDef) {
+        final String suffix = BindingMapping.getGetterSuffix(node.getQName());
+        // Bug 8903: If it is a derived type of boolean or empty, not an inner type, then the return type
+        // of method would be the generated type of typedef not build-in types, so here it should be 'get'.
+        if ((typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition)
+                && (typeDef.getPath().equals(node.getPath()) || typeDef.getBaseType() == null)) {
             return "is" + suffix;
         }
         return "get" + suffix;
@@ -299,9 +303,9 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
     @SuppressWarnings("checkstyle:illegalCatch")
     private Codec<Object, Object> getCodecForBindingClass(final Class<?> valueType, final TypeDefinition<?> typeDef) {
         if (typeDef instanceof IdentityrefTypeDefinition) {
-            return ValueTypeCodec.encapsulatedValueCodecFor(valueType, identityCodec);
+            return ValueTypeCodec.encapsulatedValueCodecFor(valueType, typeDef, identityCodec);
         } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
-            return ValueTypeCodec.encapsulatedValueCodecFor(valueType, instanceIdentifierCodec);
+            return ValueTypeCodec.encapsulatedValueCodecFor(valueType, typeDef, instanceIdentifierCodec);
         } else if (typeDef instanceof UnionTypeDefinition) {
             final Callable<UnionTypeCodec> loader = UnionTypeCodec.loader(valueType, (UnionTypeDefinition) typeDef,
                 this);
index af147d55a7c10c1eac8fff967b94458357ef0ecb..bc1e4cebaa7dc1fe2dee7975d897331727bb28b7 100644 (file)
@@ -16,6 +16,8 @@ import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 import java.util.concurrent.Callable;
 import org.opendaylight.mdsal.binding.dom.codec.impl.ValueTypeCodec.SchemaUnawareCodec;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
 
 /**
  * Derived YANG types are just immutable value holders for simple value
@@ -36,9 +38,14 @@ final class EncapsulatedValueCodec extends ReflectionBasedCodec implements Schem
         this.valueType = Preconditions.checkNotNull(valueType);
     }
 
-    static Callable<EncapsulatedValueCodec> loader(final Class<?> typeClz) {
+    static Callable<EncapsulatedValueCodec> loader(final Class<?> typeClz, TypeDefinition<?> typeDef) {
         return () -> {
-            final Method m = typeClz.getMethod("getValue");
+            final Method m;
+            if (typeDef instanceof BooleanTypeDefinition) {
+                m = typeClz.getMethod("isValue");
+            } else {
+                m = typeClz.getMethod("getValue");
+            }
             final MethodHandle getter = LOOKUP.unreflect(m).asType(OBJ_METHOD);
             final Class<?> valueType = m.getReturnType();
 
index 17e23debff8d9262c5e95fb79b207fd789fae7e2..5aa18d8c4ce943d72fe06e81922cc0f402748018 100644 (file)
@@ -102,12 +102,14 @@ abstract class ValueTypeCodec implements Codec<Object, Object> {
         } else if (rootType instanceof EmptyTypeDefinition) {
             return EMPTY_LOADER;
         }
-        return EncapsulatedValueCodec.loader(typeClz);
+        return EncapsulatedValueCodec.loader(typeClz, def);
     }
 
     @SuppressWarnings("rawtypes")
-    static ValueTypeCodec encapsulatedValueCodecFor(final Class<?> typeClz, final Codec delegate) {
-        SchemaUnawareCodec extractor = getCachedSchemaUnawareCodec(typeClz, EncapsulatedValueCodec.loader(typeClz));
+    static ValueTypeCodec encapsulatedValueCodecFor(final Class<?> typeClz, final TypeDefinition<?> typeDef,
+             final Codec delegate) {
+        SchemaUnawareCodec extractor = getCachedSchemaUnawareCodec(typeClz,
+            EncapsulatedValueCodec.loader(typeClz, typeDef));
         return new CompositeValueCodec(extractor, delegate);
     }
 
diff --git a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/TypedefTest.java b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/TypedefTest.java
new file mode 100644 (file)
index 0000000..df84389
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 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.dom.codec.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map.Entry;
+import javassist.ClassPool;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yang.gen.v1.bug8903.rev170829.DefaultPolicy;
+import org.opendaylight.yang.gen.v1.bug8903.rev170829.DefaultPolicyBuilder;
+import org.opendaylight.yang.gen.v1.bug8903.rev170829.PolicyLoggingFlag;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+
+public class TypedefTest extends AbstractBindingRuntimeTest {
+
+    private static final InstanceIdentifier<DefaultPolicy> BA_DEFAULT_POLICY =
+            InstanceIdentifier.builder(DefaultPolicy.class).build();
+    private BindingNormalizedNodeCodecRegistry registry;
+
+    @Override
+    public void setup() {
+        super.setup();
+        final JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault());
+        registry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(utils));
+        registry.onBindingRuntimeContextUpdated(getRuntimeContext());
+    }
+
+    @Test
+    public void testTypedef() {
+        DefaultPolicy binding = new DefaultPolicyBuilder()
+                .setAction(true)
+                .setAction2(new PolicyLoggingFlag(false))
+                .setAction3(true)
+                .build();
+        final Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> dom =
+                registry.toNormalizedNode(BA_DEFAULT_POLICY, binding);
+        final Entry<InstanceIdentifier<?>, DataObject> readed =
+                registry.fromNormalizedNode(dom.getKey(),dom.getValue());
+
+        assertEquals(binding,readed.getValue());
+
+    }
+}
diff --git a/binding/mdsal-binding-test-model/src/main/yang/bug8903.yang b/binding/mdsal-binding-test-model/src/main/yang/bug8903.yang
new file mode 100755 (executable)
index 0000000..e088769
--- /dev/null
@@ -0,0 +1,28 @@
+module bug8903 {
+    yang-version 1;
+    namespace "bug8903";
+    prefix "bug8903";
+
+    revision "2017-08-29" {
+    }
+
+    typedef policy-logging-flag {
+        description "false-disable,true-enable";
+        type boolean;
+    }
+
+    container default-policy{
+      leaf action {
+        type boolean;
+      }
+
+      leaf action2 {
+        type policy-logging-flag;
+      }
+
+      leaf action3 {
+        type boolean;
+        default "true";
+      }
+    }
+}