Move grouping/instantiation lookup code 04/97904/3
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 15 Oct 2021 12:56:29 +0000 (14:56 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 15 Oct 2021 13:58:40 +0000 (15:58 +0200)
DatObjectCodecContext should not be concerned with relationships
between parent and child, certainly not to the point of dealing with
where an original grouping leaf is instantiated.

The natural place for this logic is BindingRuntimeContext or
BindingRuntimeTypes, as those get their indices from
mdsal-binding-generator -- which is the core component understanding
these relationships.

Also ditch use of Optionals for tracking walk through dependencies,
which clears up some ugly casts.

Change-Id: I72bfa499794b55c0c6266462b36df56c2ac085c2
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java

index 8e513b9cee14b6476f89da5d694f1ee562cccbce..ccaddc55dd71f5fd68384471b99a6ce3f24d715f 100644 (file)
@@ -36,7 +36,6 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
 import org.opendaylight.yangtools.yang.binding.OpaqueObject;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -48,9 +47,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -272,62 +269,12 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Dat
     }
 
     private DataContainerCodecPrototype<?> loadChildPrototype(final Class<?> childClass) {
-        final DataSchemaNode origDef = factory().getRuntimeContext().getSchemaDefinition(childClass);
-        // Direct instantiation or use in same module in which grouping
-        // was defined.
-        DataSchemaNode sameName;
-        try {
-            sameName = getSchema().dataChildByName(origDef.getQName());
-        } catch (final IllegalArgumentException e) {
-            LOG.trace("Failed to find schema for {}", origDef, e);
-            sameName = null;
-        }
-        final DataSchemaNode childSchema;
-        if (sameName != null) {
-            // Check if it is:
-            // - exactly same schema node, or
-            // - instantiated node was added via uses statement and is instantiation of same grouping
-            if (origDef.equals(sameName) || origDef.equals(getRootOriginalIfPossible(sameName))) {
-                childSchema = sameName;
-            } else {
-                // Node has same name, but clearly is different
-                childSchema = null;
-            }
-        } else {
-            // We are looking for instantiation via uses in other module
-            final QName instantiedName = origDef.getQName().bindTo(namespace());
-            final DataSchemaNode potential = getSchema().dataChildByName(instantiedName);
-            // We check if it is really instantiated from same definition as class was derived
-            if (potential != null && origDef.equals(getRootOriginalIfPossible(potential))) {
-                childSchema = potential;
-            } else {
-                childSchema = null;
-            }
-        }
-        final DataSchemaNode nonNullChild =
-                childNonNull(childSchema, childClass, "Node %s does not have child named %s", getSchema(), childClass);
+        final DataSchemaNode nonNullChild = childNonNull(
+            factory().getRuntimeContext().findChildSchemaDefinition(getSchema(), namespace(), childClass), childClass,
+            "Node %s does not have child named %s", getSchema(), childClass);
         return DataContainerCodecPrototype.from(createBindingArg(childClass, nonNullChild), nonNullChild, factory());
     }
 
-    private static SchemaNode getRootOriginalIfPossible(final SchemaNode data) {
-        Optional<SchemaNode> previous = Optional.empty();
-        Optional<SchemaNode> next = getOriginalIfPossible(data);
-        while (next.isPresent()) {
-            previous = next;
-            next = getOriginalIfPossible(next.get());
-        }
-        return previous.orElse(null);
-    }
-
-    private static Optional<SchemaNode> getOriginalIfPossible(final SchemaNode node) {
-        if (node instanceof DerivableSchemaNode) {
-            @SuppressWarnings("unchecked")
-            final Optional<SchemaNode> ret  = (Optional<SchemaNode>) ((DerivableSchemaNode) node).getOriginal();
-            return ret;
-        }
-        return Optional.empty();
-    }
-
     @SuppressWarnings("unchecked")
     Item<?> createBindingArg(final Class<?> childClass, final DataSchemaNode childSchema) {
         return Item.of((Class<? extends DataObject>) childClass);
index 80e05a7294973ffd25c90714911fea4d10c630b7..0eb80331245e9a6ea0084c2ea8ff4f6c75f15f3a 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilde
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
@@ -90,6 +91,59 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
         return (DataSchemaNode) getTypes().findSchema(Type.of(cls)).orElse(null);
     }
 
+    @Override
+    public final DataSchemaNode findChildSchemaDefinition(final DataNodeContainer parentSchema,
+            final QNameModule parentNamespace, final Class<?> childClass) {
+        final DataSchemaNode origDef = getSchemaDefinition(childClass);
+        // Direct instantiation or use in same module in which grouping was defined.
+        DataSchemaNode sameName;
+        try {
+            sameName = parentSchema.dataChildByName(origDef.getQName());
+        } catch (final IllegalArgumentException e) {
+            LOG.trace("Failed to find schema for {}", origDef, e);
+            sameName = null;
+        }
+
+        final DataSchemaNode childSchema;
+        if (sameName != null) {
+            // Check if it is:
+            // - exactly same schema node, or
+            // - instantiated node was added via uses statement and is instantiation of same grouping
+            if (origDef.equals(sameName) || origDef.equals(getRootOriginalIfPossible(sameName))) {
+                childSchema = sameName;
+            } else {
+                // Node has same name, but clearly is different
+                childSchema = null;
+            }
+        } else {
+            // We are looking for instantiation via uses in other module
+            final QName instantiedName = origDef.getQName().bindTo(parentNamespace);
+            final DataSchemaNode potential = parentSchema.dataChildByName(instantiedName);
+            // We check if it is really instantiated from same definition as class was derived
+            if (potential != null && origDef.equals(getRootOriginalIfPossible(potential))) {
+                childSchema = potential;
+            } else {
+                childSchema = null;
+            }
+        }
+
+        return childSchema;
+    }
+
+    private static @Nullable SchemaNode getRootOriginalIfPossible(final SchemaNode data) {
+        SchemaNode previous = null;
+        SchemaNode next = getOriginalIfPossible(data);
+        while (next != null) {
+            previous = next;
+            next = getOriginalIfPossible(next);
+        }
+        return previous;
+    }
+
+    private static @Nullable SchemaNode getOriginalIfPossible(final SchemaNode node) {
+        return node instanceof DerivableSchemaNode ? ((DerivableSchemaNode) node).getOriginal().orElse(null) : null;
+    }
+
     @Override
     public final ActionDefinition getActionDefinition(final Class<? extends Action<?, ?, ?>> cls) {
         return (ActionDefinition) getTypes().findSchema(Type.of(cls)).orElse(null);
index 2e2f4543db3b221d5caee940624cea16f818037e..5ee85731b139e4f72acbef10ed263512ab57f4e3 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
@@ -92,6 +93,10 @@ public interface BindingRuntimeContext extends EffectiveModelContextProvider, Im
      */
     @Nullable DataSchemaNode getSchemaDefinition(Class<?> cls);
 
+    // FIXME: document this thing and perhaps move it to BindingRuntimeTypes?
+    @Nullable DataSchemaNode findChildSchemaDefinition(DataNodeContainer parentSchema, QNameModule parentNamespace,
+        Class<?> childClass);
+
     @Nullable ActionDefinition getActionDefinition(Class<? extends Action<?, ?, ?>> cls);
 
     @Nullable Absolute getActionIdentifier(Class<? extends Action<?, ?, ?>> cls);
index 464746eb9c6bd23e542ff7d61f55d0d5acb64e49..d4a0fddbeaf1da1e53b34baad1c231f67b385f8e 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
@@ -52,6 +53,12 @@ public abstract class ForwardingBindingRuntimeContext extends ForwardingObject i
         return delegate().getSchemaDefinition(cls);
     }
 
+    @Override
+    public DataSchemaNode findChildSchemaDefinition(final DataNodeContainer parentSchema,
+            final QNameModule parentNamespace, final Class<?> childClass) {
+        return delegate().findChildSchemaDefinition(parentSchema, parentNamespace, childClass);
+    }
+
     @Override
     public ActionDefinition getActionDefinition(final Class<? extends Action<?, ?, ?>> cls) {
         return delegate().getActionDefinition(cls);