Eliminate CodecItemFactory 53/109753/11
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 12 Jan 2024 01:36:57 +0000 (02:36 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 15 Apr 2024 15:00:49 +0000 (17:00 +0200)
This is a useless indirection, as we can simply pass the required
information down to where the case class is needed.

JIRA: MDSAL-815
Change-Id: I7413f33d0c4a76e29b180ef34623e7a0607c784f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CaseCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CaseCodecPrototype.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecItemFactory.java [deleted file]
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataContainerAnalysis.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecPrototype.java

index 2006df5a5cb2aed0a44502d34781d9f63bc000d5..406c177d6b36d1db69b191065e53a50f5dab8145 100644 (file)
@@ -50,7 +50,7 @@ final class AugmentationCodecContext<A extends Augmentation<?>>
     }
 
     AugmentationCodecContext(final AugmentationCodecPrototype<A> prototype) {
-        this(prototype, new DataContainerAnalysis<>(prototype, CodecItemFactory.of()));
+        this(prototype, new DataContainerAnalysis<>(prototype));
     }
 
     @Override
index fb7836042dbe6dc289b0d8daa1782330bd833709..140ef9ddc5c3607df5aab63a1a84491e1553db52 100644 (file)
@@ -9,15 +9,16 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import java.util.List;
 import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
+import org.opendaylight.yangtools.yang.binding.ChoiceIn;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.DataObjectStep;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
-final class CaseCodecContext<D extends DataObject> extends DataObjectCodecContext<D, CaseRuntimeType> {
-    CaseCodecContext(final CaseCodecPrototype prototype) {
-        super(prototype, CodecItemFactory.of(prototype.javaClass()));
+final class CaseCodecContext<C extends ChoiceIn<?> & DataObject> extends DataObjectCodecContext<C, CaseRuntimeType> {
+    CaseCodecContext(final CaseCodecPrototype<C> prototype) {
+        super(prototype, prototype.javaClass());
     }
 
     @Override
@@ -26,7 +27,7 @@ final class CaseCodecContext<D extends DataObject> extends DataObjectCodecContex
     }
 
     @Override
-    public D deserialize(final NormalizedNode data) {
+    public C deserialize(final NormalizedNode data) {
         return createBindingProxy(checkDataArgument(ChoiceNode.class, data));
     }
 
index 762637e47b17e790b57ab5a225d17631ccd6c8f8..ac91d6141e0fc11ded51038fc9d7cf87ebaf3c40 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
+import org.opendaylight.yangtools.yang.binding.ChoiceIn;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 
-final class CaseCodecPrototype extends DataObjectCodecPrototype<CaseRuntimeType> {
-    CaseCodecPrototype(final Class<?> cls, final CaseRuntimeType type, final CodecContextFactory factory) {
+final class CaseCodecPrototype<C extends ChoiceIn<?> & DataObject> extends DataObjectCodecPrototype<CaseRuntimeType> {
+    CaseCodecPrototype(final Class<C> cls, final CaseRuntimeType type, final CodecContextFactory factory) {
         super(cls, NodeIdentifier.create(type.statement().argument()), type, factory);
     }
 
diff --git a/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecItemFactory.java b/binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/CodecItemFactory.java
deleted file mode 100644 (file)
index bc0eb02..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2023 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 java.util.Objects.requireNonNull;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.binding.DataObjectStep;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-sealed class CodecItemFactory {
-    private static final class Case extends CodecItemFactory {
-        private final Class<?> bindingClass;
-
-        Case(final Class<?> bindingClass) {
-            this.bindingClass = requireNonNull(bindingClass);
-        }
-
-        @Override
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        DataObjectStep<?> createItem(final Class<?> childClass, final EffectiveStatement<?, ?> childSchema) {
-            // FIXME: MDSAL-697: see overridden method for further guidance
-            return childSchema instanceof AddedByUsesAware aware && aware.isAddedByUses()
-                ? InstanceIdentifier.createStep((Class) bindingClass, (Class) childClass)
-                    : super.createItem(childClass, childSchema);
-        }
-    }
-
-    private static final @NonNull CodecItemFactory DEFAULT = new CodecItemFactory();
-
-    private CodecItemFactory() {
-        // Hidden on purpose
-    }
-
-    // FIXME: MDSAL-697: move this method into BindingRuntimeContext
-    //        This method is only called from loadChildPrototype() and exists only to be overridden by
-    //        CaseNodeCodecContext. Since we are providing childClass and our schema to BindingRuntimeContext and
-    //        receiving childSchema from it via findChildSchemaDefinition, we should be able to receive the equivalent
-    //        of Map.Entry<Item, DataSchemaNode>, along with the override we create here. One more input we may need to
-    //        provide is our bindingClass().
-    DataObjectStep<?> createItem(final Class<?> childClass, final EffectiveStatement<?, ?> childSchema) {
-        return InstanceIdentifier.createStep((Class) childClass);
-    }
-
-    static @NonNull CodecItemFactory of() {
-        return DEFAULT;
-    }
-
-    static @NonNull CodecItemFactory of(final Class<?> bindingClass) {
-        return new Case(bindingClass);
-    }
-}
index c799bbbbac0b49285d0a27a09020b66927a3e834..de7aa8063a7c2b950cf19bc9f0bbccda3a5e302f 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Verify.verify;
 import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableMap;
 import java.lang.reflect.Method;
@@ -19,6 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
 import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
@@ -28,9 +30,14 @@ import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
 import org.opendaylight.yangtools.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.binding.ChoiceIn;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataObjectStep;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.OpaqueObject;
 import org.opendaylight.yangtools.yang.binding.contract.Naming;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,12 +59,17 @@ final class DataContainerAnalysis<R extends CompositeRuntimeType> {
     final @NonNull ImmutableMap<Method, ValueNodeCodecContext> leafContexts;
     final @NonNull ImmutableMap<Class<?>, PropertyInfo> daoProperties;
 
-    DataContainerAnalysis(final CommonDataObjectCodecPrototype<R> prototype, final CodecItemFactory itemFactory) {
-        this(prototype.javaClass(), prototype.runtimeType(), prototype.contextFactory(), itemFactory);
+    DataContainerAnalysis(final CommonDataObjectCodecPrototype<R> prototype) {
+        this(prototype.javaClass(), prototype.runtimeType(), prototype.contextFactory(), null);
+    }
+
+    DataContainerAnalysis(final CommonDataObjectCodecPrototype<R> prototype,
+            final Class<? extends DataObject> caseClass) {
+        this(prototype.javaClass(), prototype.runtimeType(), prototype.contextFactory(), requireNonNull(caseClass));
     }
 
     DataContainerAnalysis(final Class<?> bindingClass, final R runtimeType, final CodecContextFactory factory,
-            final CodecItemFactory itemFactory) {
+            final @Nullable Class<? extends DataObject> caseClass) {
         leafContexts = factory.getLeafNodes(bindingClass, runtimeType.statement());
 
         // Reflection-based on the passed class
@@ -90,7 +102,7 @@ final class DataContainerAnalysis<R extends CompositeRuntimeType> {
             // Record getter method
             daoPropertiesBuilder.put(retClass, new PropertyInfo.Getter(method));
 
-            final var childProto = getChildPrototype(runtimeType, factory, itemFactory, retClass);
+            final var childProto = getChildPrototype(runtimeType, factory, caseClass, retClass);
             byStreamClassBuilder.put(childProto.javaClass(), childProto);
             byYangBuilder.put(childProto.yangArg(), childProto);
 
@@ -126,7 +138,7 @@ final class DataContainerAnalysis<R extends CompositeRuntimeType> {
     }
 
     private static @NonNull DataContainerPrototype<?, ?> getChildPrototype(final CompositeRuntimeType type,
-            final CodecContextFactory factory, final CodecItemFactory itemFactory,
+            final CodecContextFactory factory, final @Nullable Class<? extends DataObject> caseClass,
             final Class<? extends DataContainer> childClass) {
         final var child = type.bindingChild(JavaTypeName.create(childClass));
         if (child == null) {
@@ -138,7 +150,7 @@ final class DataContainerAnalysis<R extends CompositeRuntimeType> {
             return new ChoiceCodecPrototype<>(factory, choice, childClass.asSubclass(ChoiceIn.class));
         }
 
-        final var item = itemFactory.createItem(childClass, child.statement());
+        final var item = createItem(caseClass, childClass, child.statement());
         if (child instanceof ContainerLikeRuntimeType containerLike) {
             if (child instanceof ContainerRuntimeType container
                 && container.statement().findFirstEffectiveSubstatement(PresenceEffectiveStatement.class).isEmpty()) {
@@ -153,6 +165,19 @@ final class DataContainerAnalysis<R extends CompositeRuntimeType> {
         }
     }
 
+    // FIXME: MDSAL-697: move this method into BindingRuntimeContext
+    //        This method is only called from loadChildPrototype() and exists only to be overridden by
+    //        CaseNodeCodecContext. Since we are providing childClass and our schema to BindingRuntimeContext and
+    //        receiving childSchema from it via findChildSchemaDefinition, we should be able to receive the equivalent
+    //        of Map.Entry<Item, DataSchemaNode>, along with the override we create here. One more input we may need to
+    //        provide is our bindingClass().
+    private static @NonNull DataObjectStep<?> createItem(final @Nullable Class<? extends DataObject> caseClass,
+            final Class<?> childClass, final EffectiveStatement<?, ?> childSchema) {
+        return caseClass != null && childSchema instanceof AddedByUsesAware aware && aware.isAddedByUses()
+            ? InstanceIdentifier.createStep((Class) caseClass, (Class) childClass)
+                : InstanceIdentifier.createStep((Class) childClass);
+    }
+
     // FIXME: MDSAL-780: these methods perform analytics using java.lang.reflect to acquire the basic shape of the
     //                   class. This is not exactly AOT friendly, as most of the information should be provided by
     //                   CompositeRuntimeType.
index 5341286a7e1461e427dc91e91a09c8b1ee0a51e9..3335246efaa90853f6d7381b9b3fd29a1713dd0e 100644 (file)
@@ -85,15 +85,16 @@ public abstract sealed class DataObjectCodecContext<D extends DataObject, T exte
     private volatile ImmutableMap<Class<?>, CommonDataObjectCodecPrototype<?>> mismatchedAugmented = ImmutableMap.of();
 
     DataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype) {
-        this(prototype, CodecItemFactory.of());
+        this(prototype, new DataContainerAnalysis<>(prototype), null);
     }
 
-    DataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype, final CodecItemFactory itemFactory) {
-        this(prototype, new DataContainerAnalysis<>(prototype, itemFactory), null);
+    DataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype,
+            final Class<? extends DataObject> caseClass) {
+        this(prototype, new DataContainerAnalysis<>(prototype, caseClass), null);
     }
 
     DataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype, final Method keyMethod) {
-        this(prototype, new DataContainerAnalysis<>(prototype, CodecItemFactory.of()), keyMethod);
+        this(prototype, new DataContainerAnalysis<>(prototype), keyMethod);
     }
 
     private DataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype,
index 2137b0f2ac31af831bbe6b4ca42b9d78fd9d958a..b13bde375c4c52fd1dc96ca30877d095442e0972 100644 (file)
@@ -21,11 +21,9 @@ abstract sealed class DataObjectCodecPrototype<T extends CompositeRuntimeType> e
                 NotificationCodecContext.Prototype {
     private final @NonNull NodeIdentifier yangArg;
 
-    // FIXME: this should not be needed
-    @SuppressWarnings("unchecked")
     DataObjectCodecPrototype(final Class<?> cls, final NodeIdentifier yangArg, final T type,
             final CodecContextFactory factory) {
-        this(InstanceIdentifier.createStep((Class<? extends DataObject>) cls), yangArg, type, factory);
+        this(InstanceIdentifier.createStep(cls.asSubclass(DataObject.class)), yangArg, type, factory);
     }
 
     DataObjectCodecPrototype(final DataObjectStep<?> bindingArg, final NodeIdentifier yangArg, final T type,