From b5e4a31d61c4b0cfc6fbeacb01d8c5d23bfe1db8 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 15 Oct 2021 14:56:29 +0200 Subject: [PATCH] Move grouping/instantiation lookup code 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 --- .../codec/impl/DataObjectCodecContext.java | 59 +------------------ .../api/AbstractBindingRuntimeContext.java | 54 +++++++++++++++++ .../runtime/api/BindingRuntimeContext.java | 5 ++ .../spi/ForwardingBindingRuntimeContext.java | 7 +++ 4 files changed, 69 insertions(+), 56 deletions(-) diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java index 8e513b9cee..ccaddc55dd 100644 --- a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java +++ b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java @@ -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 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 previous = Optional.empty(); - Optional next = getOriginalIfPossible(data); - while (next.isPresent()) { - previous = next; - next = getOriginalIfPossible(next.get()); - } - return previous.orElse(null); - } - - private static Optional getOriginalIfPossible(final SchemaNode node) { - if (node instanceof DerivableSchemaNode) { - @SuppressWarnings("unchecked") - final Optional ret = (Optional) ((DerivableSchemaNode) node).getOriginal(); - return ret; - } - return Optional.empty(); - } - @SuppressWarnings("unchecked") Item createBindingArg(final Class childClass, final DataSchemaNode childSchema) { return Item.of((Class) childClass); diff --git a/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java b/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java index 80e05a7294..0eb8033124 100644 --- a/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java +++ b/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java @@ -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> cls) { return (ActionDefinition) getTypes().findSchema(Type.of(cls)).orElse(null); diff --git a/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java b/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java index 2e2f4543db..5ee85731b1 100644 --- a/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java +++ b/binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeContext.java @@ -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> cls); @Nullable Absolute getActionIdentifier(Class> cls); diff --git a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java index 464746eb9c..d4a0fddbea 100644 --- a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java +++ b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ForwardingBindingRuntimeContext.java @@ -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> cls) { return delegate().getActionDefinition(cls); -- 2.36.6