Move BindingReflections.getChildrenClass* 40/103340/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Nov 2022 10:23:21 +0000 (11:23 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Nov 2022 11:47:34 +0000 (12:47 +0100)
These methods are only used by mdsal-binding-dom-codec, move them to
their sole users.

JIRA: MDSAL-781
Change-Id: I074a8c91f1729194f47310424dd93a9e703ca629
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ChoiceNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataContainerCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/DataObjectCodecContext.java
binding/mdsal-binding-spec-util/src/main/java/org/opendaylight/mdsal/binding/spec/reflect/BindingReflections.java

index f720b6825f7b3c204a42a6cc6701a7520c50221a..7fda3cd1b45c330ac6ead51188c2d2d7155f7c6e 100644 (file)
@@ -19,10 +19,12 @@ import com.google.common.collect.MultimapBuilder.SetMultimapBuilder;
 import com.google.common.collect.Multimaps;
 import com.google.common.collect.SetMultimap;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -34,7 +36,9 @@ import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -125,7 +129,7 @@ final class ChoiceNodeCodecContext<D extends DataObject> extends DataContainerCo
             // Updates collection of case children
             @SuppressWarnings("unchecked")
             final Class<? extends DataObject> cazeCls = (Class<? extends DataObject>) cazeDef.getBindingClass();
-            for (final Class<? extends DataObject> cazeChild : BindingReflections.getChildrenClasses(cazeCls)) {
+            for (final Class<? extends DataObject> cazeChild : getChildrenClasses(cazeCls)) {
                 childToCase.put(cazeChild, cazeDef);
             }
             // Updates collection of YANG instance identifier to case
@@ -308,4 +312,27 @@ final class ChoiceNodeCodecContext<D extends DataObject> extends DataContainerCo
 
         return childNonNull(result, type, "Class %s is not child of any cases for %s", type, bindingArg()).get();
     }
+
+    /**
+     * Scans supplied class and returns an iterable of all data children classes.
+     *
+     * @param type
+     *            YANG Modeled Entity derived from DataContainer
+     * @return Iterable of all data children, which have YANG modeled entity
+     */
+    // FIXME: MDSAL-780: replace use of this method
+    @SuppressWarnings("unchecked")
+    private static Iterable<Class<? extends DataObject>> getChildrenClasses(final Class<? extends DataContainer> type) {
+        checkArgument(type != null, "Target type must not be null");
+        checkArgument(DataContainer.class.isAssignableFrom(type), "Supplied type must be derived from DataContainer");
+        List<Class<? extends DataObject>> ret = new LinkedList<>();
+        for (Method method : type.getMethods()) {
+            Optional<Class<? extends DataContainer>> entity = getYangModeledReturnType(method,
+                BindingMapping.GETTER_PREFIX);
+            if (entity.isPresent()) {
+                ret.add((Class<? extends DataObject>) entity.get());
+            }
+        }
+        return ret;
+    }
 }
index df089fd1fc7fd3f51f3eda606ec300affe7b46ff..c14693f0d6ac3ae143aaaa3d385b99b9af103c9d 100644 (file)
@@ -15,7 +15,10 @@ import com.google.common.collect.ImmutableSet;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
@@ -31,8 +34,10 @@ import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.RuntimeTypeContainer;
+import org.opendaylight.yangtools.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BindingObject;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -43,9 +48,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.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 abstract class DataContainerCodecContext<D extends DataObject, T extends RuntimeTypeContainer> extends NodeCodecContext
         implements BindingDataObjectCodecTreeNode<D>  {
+    private static final Logger LOG = LoggerFactory.getLogger(DataContainerCodecContext.class);
     private static final VarHandle EVENT_STREAM_SERIALIZER;
 
     static {
@@ -268,4 +276,62 @@ abstract class DataContainerCodecContext<D extends DataObject, T extends Runtime
             throw new IllegalArgumentException("Expected " + expectedType.getSimpleName(), e);
         }
     }
+
+    // FIXME: MDSAL-780 replace this method with BindingRuntimeTypes-driven logic
+    static final Optional<Class<? extends DataContainer>> getYangModeledReturnType(final Method method,
+            final String prefix) {
+        final String methodName = method.getName();
+        if ("getClass".equals(methodName) || !methodName.startsWith(prefix) || method.getParameterCount() > 0) {
+            return Optional.empty();
+        }
+
+        final Class<?> returnType = method.getReturnType();
+        if (DataContainer.class.isAssignableFrom(returnType)) {
+            return optionalDataContainer(returnType);
+        } else if (List.class.isAssignableFrom(returnType)) {
+            return getYangModeledReturnType(method, 0);
+        } else if (Map.class.isAssignableFrom(returnType)) {
+            return getYangModeledReturnType(method, 1);
+        }
+        return Optional.empty();
+    }
+
+    @SuppressWarnings("checkstyle:illegalCatch")
+    private static Optional<Class<? extends DataContainer>> getYangModeledReturnType(final Method method,
+            final int parameterOffset) {
+        try {
+            return ClassLoaderUtils.callWithClassLoader(method.getDeclaringClass().getClassLoader(),
+                () -> genericParameter(method.getGenericReturnType(), parameterOffset)
+                    .flatMap(result -> result instanceof Class ? optionalCast((Class<?>) result) : Optional.empty()));
+        } catch (Exception e) {
+            /*
+             * It is safe to log this this exception on debug, since this
+             * method should not fail. Only failures are possible if the
+             * runtime / backing.
+             */
+            LOG.debug("Unable to find YANG modeled return type for {}", method, e);
+        }
+        return Optional.empty();
+    }
+
+    private static Optional<java.lang.reflect.Type> genericParameter(final java.lang.reflect.Type type,
+            final int offset) {
+        if (type instanceof ParameterizedType parameterized) {
+            final var parameters = parameterized.getActualTypeArguments();
+            if (parameters.length > offset) {
+                return Optional.of(parameters[offset]);
+            }
+        }
+        return Optional.empty();
+    }
+
+    private static Optional<Class<? extends DataContainer>> optionalCast(final Class<?> type) {
+        return DataContainer.class.isAssignableFrom(type) ? optionalDataContainer(type) : Optional.empty();
+    }
+
+
+    // FIXME: MDSAL-780: remove this method
+    static final Optional<Class<? extends DataContainer>> optionalDataContainer(final Class<?> type) {
+        return Optional.of(type.asSubclass(DataContainer.class));
+    }
 }
index 224ca141735be3c92e3e88fdd8870ecb86caffad..6ca2ebfb48c0d94e74fe3eb6102ba51483d02c6a 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.mdsal.binding.runtime.api.AugmentableRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
@@ -107,8 +108,7 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Com
 
         final ImmutableMap<Method, ValueNodeCodecContext> tmpLeaves = factory().getLeafNodes(bindingClass,
             getType().statement());
-        final Map<Class<? extends DataContainer>, Method> clsToMethod =
-            BindingReflections.getChildrenClassToMethod(bindingClass);
+        final Map<Class<? extends DataContainer>, Method> clsToMethod = getChildrenClassToMethod(bindingClass);
 
         final Map<YangInstanceIdentifier.PathArgument, NodeContextSupplier> byYangBuilder = new HashMap<>();
         final Map<Class<?>, DataContainerCodecPrototype<?>> byStreamClassBuilder = new HashMap<>();
@@ -152,7 +152,7 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Com
         }
 
         // Find all non-default nonnullFoo() methods and update the corresponding property info
-        for (var entry : BindingReflections.getChildrenClassToNonnullMethod(bindingClass).entrySet()) {
+        for (var entry : getChildrenClassToNonnullMethod(bindingClass).entrySet()) {
             final var method = entry.getValue();
             if (!method.isDefault()) {
                 daoProperties.compute(entry.getKey(), (key, value) -> new PropertyInfo.GetterAndNonnull(
@@ -482,4 +482,33 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Com
         checkArgument(bindingArg().equals(arg));
         return getDomPathArgument();
     }
+
+    /**
+     * Scans supplied class and returns an iterable of all data children classes.
+     *
+     * @param type YANG Modeled Entity derived from DataContainer
+     * @return Iterable of all data children, which have YANG modeled entity
+     */
+    // FIXME: MDSAL-780: replace use of this method
+    private static Map<Class<? extends DataContainer>, Method> getChildrenClassToMethod(final Class<?> type) {
+        return getChildClassToMethod(type, BindingMapping.GETTER_PREFIX);
+    }
+
+    // FIXME: MDSAL-780: replace use of this method
+    private static Map<Class<? extends DataContainer>, Method> getChildrenClassToNonnullMethod(final Class<?> type) {
+        return getChildClassToMethod(type, BindingMapping.NONNULL_PREFIX);
+    }
+
+    // FIXME: MDSAL-780: replace use of this method
+    private static Map<Class<? extends DataContainer>, Method> getChildClassToMethod(final Class<?> type,
+            final String prefix) {
+        checkArgument(type != null, "Target type must not be null");
+        checkArgument(DataContainer.class.isAssignableFrom(type), "Supplied type %s must be derived from DataContainer",
+            type);
+        final var ret = new HashMap<Class<? extends DataContainer>, Method>();
+        for (Method method : type.getMethods()) {
+            getYangModeledReturnType(method, prefix).ifPresent(entity -> ret.put(entity, method));
+        }
+        return ret;
+    }
 }
index fb4635efdb440256e7606205d7329bbe21c9d099..0e10689fc6f267c770b4897580f3b19f56221036 100644 (file)
@@ -21,14 +21,9 @@ import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.Set;
@@ -376,116 +371,6 @@ public final class BindingReflections {
                 && (targetType.getName().endsWith("Input") || targetType.getName().endsWith("Output"));
     }
 
-    /**
-     * Scans supplied class and returns an iterable of all data children classes.
-     *
-     * @param type YANG Modeled Entity derived from DataContainer
-     * @return Iterable of all data children, which have YANG modeled entity
-     * @deprecated This method is only used in mdsal-binding-dom-codec and is schedule for removal.
-     */
-    @Deprecated(since = "10.0.4", forRemoval = true)
-    @SuppressWarnings("unchecked")
-    public static Iterable<Class<? extends DataObject>> getChildrenClasses(final Class<? extends DataContainer> type) {
-        checkArgument(type != null, "Target type must not be null");
-        checkArgument(DataContainer.class.isAssignableFrom(type), "Supplied type must be derived from DataContainer");
-        List<Class<? extends DataObject>> ret = new LinkedList<>();
-        for (Method method : type.getMethods()) {
-            Optional<Class<? extends DataContainer>> entity = getYangModeledReturnType(method,
-                BindingMapping.GETTER_PREFIX);
-            if (entity.isPresent()) {
-                ret.add((Class<? extends DataObject>) entity.get());
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Scans supplied class and returns an iterable of all data children classes.
-     *
-     * @param type YANG Modeled Entity derived from DataContainer
-     * @return Iterable of all data children, which have YANG modeled entity
-     * @deprecated This method is only used in mdsal-binding-dom-codec and is schedule for removal.
-     */
-    @Deprecated(since = "10.0.4", forRemoval = true)
-    public static Map<Class<? extends DataContainer>, Method> getChildrenClassToMethod(final Class<?> type) {
-        return getChildClassToMethod(type, BindingMapping.GETTER_PREFIX);
-    }
-
-    @Beta
-    @Deprecated(since = "10.0.4", forRemoval = true)
-    public static Map<Class<? extends DataContainer>, Method> getChildrenClassToNonnullMethod(final Class<?> type) {
-        return getChildClassToMethod(type, BindingMapping.NONNULL_PREFIX);
-    }
-
-    private static Map<Class<? extends DataContainer>, Method> getChildClassToMethod(final Class<?> type,
-            final String prefix) {
-        checkArgument(type != null, "Target type must not be null");
-        checkArgument(DataContainer.class.isAssignableFrom(type), "Supplied type %s must be derived from DataContainer",
-            type);
-        Map<Class<? extends DataContainer>, Method> ret = new HashMap<>();
-        for (Method method : type.getMethods()) {
-            Optional<Class<? extends DataContainer>> entity = getYangModeledReturnType(method, prefix);
-            if (entity.isPresent()) {
-                ret.put(entity.get(), method);
-            }
-        }
-        return ret;
-    }
-
-    private static Optional<Class<? extends DataContainer>> getYangModeledReturnType(final Method method,
-            final String prefix) {
-        final String methodName = method.getName();
-        if ("getClass".equals(methodName) || !methodName.startsWith(prefix) || method.getParameterCount() > 0) {
-            return Optional.empty();
-        }
-
-        final Class<?> returnType = method.getReturnType();
-        if (DataContainer.class.isAssignableFrom(returnType)) {
-            return optionalDataContainer(returnType);
-        } else if (List.class.isAssignableFrom(returnType)) {
-            return getYangModeledReturnType(method, 0);
-        } else if (Map.class.isAssignableFrom(returnType)) {
-            return getYangModeledReturnType(method, 1);
-        }
-        return Optional.empty();
-    }
-
-    @SuppressWarnings("checkstyle:illegalCatch")
-    private static Optional<Class<? extends DataContainer>> getYangModeledReturnType(final Method method,
-            final int parameterOffset) {
-        try {
-            return ClassLoaderUtils.callWithClassLoader(method.getDeclaringClass().getClassLoader(),
-                () -> genericParameter(method.getGenericReturnType(), parameterOffset)
-                    .flatMap(result -> result instanceof Class ? optionalCast((Class<?>) result) : Optional.empty()));
-        } catch (Exception e) {
-            /*
-             * It is safe to log this this exception on debug, since this
-             * method should not fail. Only failures are possible if the
-             * runtime / backing.
-             */
-            LOG.debug("Unable to find YANG modeled return type for {}", method, e);
-        }
-        return Optional.empty();
-    }
-
-    private static Optional<Class<? extends DataContainer>> optionalCast(final Class<?> type) {
-        return DataContainer.class.isAssignableFrom(type) ? optionalDataContainer(type) : Optional.empty();
-    }
-
-    private static Optional<Class<? extends DataContainer>> optionalDataContainer(final Class<?> type) {
-        return Optional.of(type.asSubclass(DataContainer.class));
-    }
-
-    private static Optional<Type> genericParameter(final Type type, final int offset) {
-        if (type instanceof ParameterizedType parameterized) {
-            final Type[] parameters = parameterized.getActualTypeArguments();
-            if (parameters.length > offset) {
-                return Optional.of(parameters[offset]);
-            }
-        }
-        return Optional.empty();
-    }
-
     private static class ClassToQNameLoader extends CacheLoader<Class<?>, Optional<QName>> {
 
         @Override