Bug 4647: Binding Codec does not provide leaf default value for identityref 67/32867/1
authorIgor Foltin <ifoltin@cisco.com>
Tue, 12 Jan 2016 12:12:29 +0000 (13:12 +0100)
committerRobert Varga <nite@hq.sk>
Sat, 16 Jan 2016 09:55:33 +0000 (09:55 +0000)
Fixed handling of leaf default value for identityref type
even when there is a prefix in the default value.

Also removed obsolete code.

Change-Id: I5a4e1bf67705538f95f001a6eee42926d20c64b4
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
(cherry picked from commit c4b07e397f8a344a3fa638d83c60f1a5bf070794)

binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/LeafDefaultValueTest.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/BindingCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/LeafNodeCodecContext.java
binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test-2.yang [new file with mode: 0644]
binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test.yang

index c6bb24fb3d320779ff2d1beef3c9c3c59daad5c5..d3d127793e2b7e4ff5a2202309562190ad223ca8 100644 (file)
@@ -284,7 +284,7 @@ public class LeafDefaultValueTest extends AbstractDataBrokerTest {
         DecimalContainer decimalCont = decimalContainerNode.get();
         assertEquals(66.66, decimalCont.getDecimalLeaf().getValue().doubleValue(), 0.001);
         assertEquals(66.66, decimalCont.getDecimalLeaf2().getValue().doubleValue(), 0.001);
-        assertEquals(99.9, decimalCont.getDecimalLeaf3().getValue().doubleValue(), 0.01);
+        assertEquals(99.99, decimalCont.getDecimalLeaf3().getValue().doubleValue(), 0.001);
         assertEquals(66.66, decimalCont.getDecimalLeaf4().getValue().doubleValue(), 0.001);
         assertEquals(120.55, decimalCont.getDecimalLeaf5().doubleValue(), 0.001);
         assertEquals(null, decimalCont.getDecimalLeaf6());
@@ -403,5 +403,11 @@ public class LeafDefaultValueTest extends AbstractDataBrokerTest {
 
         IdentityrefContainer idrefCont = identityrefContainerNode.get();
         assertNull(idrefCont.getIdentityrefLeaf());
+        assertEquals("MyDerivedIdentity", idrefCont.getIdentityrefLeaf2().getSimpleName());
+        assertEquals("MyDerivedIdentity", idrefCont.getIdentityrefLeaf3().getSimpleName());
+        assertEquals("MyDerivedIdentity2", idrefCont.getIdentityrefLeaf4().getSimpleName());
+        assertEquals("MyDerivedImportedIdentity", idrefCont.getIdentityrefLeaf5().getSimpleName());
+        assertEquals("MyDerivedIdentity", idrefCont.getIdentityrefLeaf6().getSimpleName());
+        assertNull(idrefCont.getIdentityrefLeaf7());
     }
 }
index 6e05628f42a3688db563df72fb7a21f612f32dd0..be83c9071b6c937394c47fa2bc26557070f8c5c8 100644 (file)
@@ -272,7 +272,8 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
                     continue; // We do not have schema for leaf, so we will ignore it (eg. getClass, getImplementedInterface).
                 }
                 final Codec<Object, Object> codec = getCodec(valueType, schema);
-                final LeafNodeCodecContext<?> leafNode = new LeafNodeCodecContext<>(schema, codec, method);
+                final LeafNodeCodecContext<?> leafNode = new LeafNodeCodecContext<>(schema, codec, method,
+                        context.getSchemaContext());
                 leaves.put(schema.getQName().getLocalName(), leafNode);
             }
         }
index 40c706e354a5b0c5c226dd4cd46dc90f7d329c0e..1b935d1cf28ac270868cdca14a599f661d32ce79 100644 (file)
@@ -10,12 +10,11 @@ package org.opendaylight.yangtools.binding.data.codec.impl;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import javax.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
@@ -23,6 +22,7 @@ import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
@@ -31,9 +31,12 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 
 final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<D> implements NodeContextSupplier {
 
@@ -43,20 +46,25 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
     private final DataSchemaNode schema;
     private final Object defaultObject;
 
-    public LeafNodeCodecContext(final DataSchemaNode schema, final Codec<Object, Object> codec, final Method getter) {
+    public LeafNodeCodecContext(final DataSchemaNode schema, final Codec<Object, Object> codec, final Method getter,
+                                final SchemaContext schemaContext) {
         this.yangIdentifier = new YangInstanceIdentifier.NodeIdentifier(schema.getQName());
         this.valueCodec = Preconditions.checkNotNull(codec);
         this.getter = getter;
         this.schema = Preconditions.checkNotNull(schema);
 
-        this.defaultObject = createDefaultObject(schema, valueCodec);
+        this.defaultObject = createDefaultObject(schema, valueCodec, schemaContext);
     }
 
-    private static Object createDefaultObject(final DataSchemaNode schema, final Codec<Object, Object> codec) {
+    private static Object createDefaultObject(final DataSchemaNode schema, final Codec<Object, Object> codec,
+                                              final SchemaContext schemaContext) {
         if (schema instanceof LeafSchemaNode) {
             Object defaultValue = ((LeafSchemaNode) schema).getDefault();
             TypeDefinition<?> type = ((LeafSchemaNode) schema).getType();
             if (defaultValue != null) {
+                if (type instanceof IdentityrefTypeDefinition) {
+                    return qnameDomValueFromString(codec, schema, (String) defaultValue, schemaContext);
+                }
                 return domValueFromString(codec, type, defaultValue);
             }
             else {
@@ -66,21 +74,8 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
 
                 defaultValue = type.getDefaultValue();
                 if (defaultValue != null) {
-                    if (defaultValue instanceof Boolean) {
-                        return codec.deserialize(defaultValue);
-                    }
-
-                    if (defaultValue instanceof IdentitySchemaNode) {
-                        defaultValue = ((IdentitySchemaNode) defaultValue).getQName();
-                        return codec.deserialize(defaultValue);
-                    }
-
-                    if (defaultValue instanceof ImmutableList) {
-                        return codec.deserialize(ImmutableSet.copyOf((ImmutableList) defaultValue));
-                    }
-
-                    if (defaultValue instanceof List) {
-                        return codec.deserialize(defaultValue);
+                    if (type instanceof IdentityrefTypeDefinition) {
+                        return qnameDomValueFromString(codec, schema, (String) defaultValue, schemaContext);
                     }
                     return domValueFromString(codec, type, defaultValue);
                 }
@@ -89,6 +84,37 @@ final class LeafNodeCodecContext<D extends DataObject> extends NodeCodecContext<
         return null;
     }
 
+    private static Object qnameDomValueFromString(final Codec<Object, Object> codec, final DataSchemaNode schema,
+                                                  final String defaultValue, final SchemaContext schemaContext) {
+        int prefixEndIndex = defaultValue.indexOf(':');
+        QName qname;
+        if (prefixEndIndex != -1) {
+            String defaultValuePrefix = defaultValue.substring(0, prefixEndIndex);
+
+            Module module = schemaContext.findModuleByNamespaceAndRevision(schema.getQName().getNamespace(),
+                    schema.getQName().getRevision());
+
+            if (module.getPrefix().equals(defaultValuePrefix)) {
+                qname = QName.create(module.getQNameModule(), defaultValue.substring(prefixEndIndex + 1));
+                return codec.deserialize(qname);
+            } else {
+                Set<ModuleImport> imports = module.getImports();
+                for (ModuleImport moduleImport : imports) {
+                    if (moduleImport.getPrefix().equals(defaultValuePrefix)) {
+                        Module importedModule = schemaContext.findModuleByName(moduleImport.getModuleName(),
+                                moduleImport.getRevision());
+                        qname = QName.create(importedModule.getQNameModule(), defaultValue.substring(prefixEndIndex + 1));
+                        return codec.deserialize(qname);
+                    }
+                }
+                return null;
+            }
+        }
+
+        qname = QName.create(schema.getQName(), defaultValue);
+        return codec.deserialize(qname);
+    }
+
     private static Object domValueFromString(final Codec<Object, Object> codec, final TypeDefinition<?> type,
     Object defaultValue) {
         TypeDefinitionAwareCodec typeDefAwareCodec = TypeDefinitionAwareCodec.from(type);
diff --git a/binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test-2.yang b/binding/mdsal-binding-test-model/src/main/yang/opendaylight-default-value-test-2.yang
new file mode 100644 (file)
index 0000000..ee60c64
--- /dev/null
@@ -0,0 +1,23 @@
+module opendaylight-default-value-test-2 {
+    namespace "urn:opendaylight:params:xml:ns:default:value:test:2";
+    prefix "def-val-test-2";
+
+    revision 2016-01-11 {
+        description "current revision";
+    }
+
+    identity my-base-identity {
+        description "parent identity for testing purposes";
+    }
+
+    identity my-derived-imported-identity {
+        base my-base-identity;
+        description "child identity for testing purposes";
+    }
+
+    typedef my-imported-identityref {
+        type identityref {
+            base my-base-identity;
+        }
+    }
+}
\ No newline at end of file
index 9a41e0c35ea0d0a3bdcad1fe03d026982cc920d0..ee467480c4c916f31cc29570cb5b75e8c039bf61 100644 (file)
@@ -2,6 +2,11 @@ module opendaylight-default-value-test {
     namespace "urn:opendaylight:params:xml:ns:default:value:test";
     prefix "def-val-test";
 
+    import opendaylight-default-value-test-2 {
+        prefix def-val-test-2;
+        revision-date 2016-01-11;
+    }
+
     typedef tiny-signed-integer {
         type int8 {
             range "-20..-1";
@@ -192,10 +197,10 @@ module opendaylight-default-value-test {
 
     typedef my-derived-decimal2 {
         type my-decimal {
-            fraction-digits 1;
-            range "77.7 .. 111.1";
+            fraction-digits 2;
+            range "77.77 .. 111.11";
         }
-        default "99.9";
+        default "99.99";
     }
 
     typedef my-derived-decimal3 {
@@ -257,7 +262,17 @@ module opendaylight-default-value-test {
     }
 
     identity my-identity {
-        description "identity for testing purposes";
+        description "parent identity for testing purposes";
+    }
+
+    identity my-derived-identity {
+        base my-identity;
+        description "child identity for testing purposes";
+    }
+
+    identity my-derived-identity2 {
+        base my-derived-identity;
+        description "another child identity for testing purposes";
     }
 
     typedef my-identityref {
@@ -266,6 +281,13 @@ module opendaylight-default-value-test {
         }
     }
 
+    typedef my-identityref2 {
+        type identityref {
+            base my-identity;
+        }
+        default "my-derived-identity";
+    }
+
     container tiny-int-container {
         presence "presence container";
 
@@ -622,5 +644,34 @@ module opendaylight-default-value-test {
         leaf identityref-leaf {
             type my-identityref;
         }
+
+        leaf identityref-leaf2 {
+            type my-identityref;
+            default "my-derived-identity";
+        }
+
+        leaf identityref-leaf3 {
+            type my-identityref2;
+        }
+
+        leaf identityref-leaf4 {
+            type my-identityref;
+            default "my-derived-identity2";
+        }
+
+        leaf identityref-leaf5 {
+            type def-val-test-2:my-imported-identityref;
+            default def-val-test-2:my-derived-imported-identity;
+        }
+
+        leaf identityref-leaf6 {
+            type my-identityref;
+            default "def-val-test:my-derived-identity";
+        }
+
+        leaf identityref-leaf7 {
+            type def-val-test-2:my-imported-identityref;
+            default invalid-prefix:my-derived-imported-identity;
+        }
     }
 }
\ No newline at end of file