Do not retain java.lang.reflect.Method in ValueNodeCodecContext 29/81829/2
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 30 Apr 2019 15:39:28 +0000 (17:39 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 1 May 2019 11:38:42 +0000 (11:38 +0000)
We only require method references during DataObjectCodecContext,
after which all we need is their name -- hence we index the map
by Method, as we can get the name from there and we can derive
the former string from the underlying schema, just as we did
before.

Change-Id: Icfb6bc3b89ce313ae054e773bd566c03c16d8a31
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.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/LeafNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/LeafSetNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/NodeCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/OpaqueNodeCodecContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ValueContext.java
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ValueNodeCodecContext.java

index daa0b9239f82839af91cf2fc4379722aa8498da5..488892be817f570edcb1d3678923e80e0fc202a5 100644 (file)
@@ -297,7 +297,7 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
     }
 
     @Override
-    public ImmutableMap<String, ValueNodeCodecContext> getLeafNodes(final Class<?> parentClass,
+    public ImmutableMap<Method, ValueNodeCodecContext> getLeafNodes(final Class<?> parentClass,
             final DataNodeContainer childSchema) {
         final Map<String, DataSchemaNode> getterToLeafSchema = new HashMap<>();
         for (final DataSchemaNode leaf : childSchema.getChildNodes()) {
@@ -309,9 +309,9 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
         return getLeafNodesUsingReflection(parentClass, getterToLeafSchema);
     }
 
-    private ImmutableMap<String, ValueNodeCodecContext> getLeafNodesUsingReflection(final Class<?> parentClass,
-            final Map<String, DataSchemaNode> getterToLeafSchema) {
-        final Map<String, ValueNodeCodecContext> leaves = new HashMap<>();
+    private ImmutableMap<Method, ValueNodeCodecContext> getLeafNodesUsingReflection(
+            final Class<?> parentClass, final Map<String, DataSchemaNode> getterToLeafSchema) {
+        final Map<Method, ValueNodeCodecContext> leaves = new HashMap<>();
         for (final Method method : parentClass.getMethods()) {
             if (method.getParameterCount() == 0) {
                 final DataSchemaNode schema = getterToLeafSchema.get(method.getName());
@@ -322,7 +322,7 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
 
                     final Class<?> valueType = method.getReturnType();
                     final Codec<Object, Object> codec = getCodec(valueType, leafSchema.getType());
-                    valueNode = LeafNodeCodecContext.of(leafSchema, codec, method, valueType,
+                    valueNode = LeafNodeCodecContext.of(leafSchema, codec, method.getName(), valueType,
                         context.getSchemaContext());
                 } else if (schema instanceof LeafListSchemaNode) {
                     final Optional<Type> optType = ClassLoaderUtils.getFirstGenericParameter(
@@ -341,11 +341,11 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
 
                     final LeafListSchemaNode leafListSchema = (LeafListSchemaNode) schema;
                     final Codec<Object, Object> codec = getCodec(valueType, leafListSchema.getType());
-                    valueNode = new LeafSetNodeCodecContext(leafListSchema, codec, method);
+                    valueNode = new LeafSetNodeCodecContext(leafListSchema, codec, method.getName());
                 } else if (schema instanceof AnyXmlSchemaNode) {
                     final Class<?> valueType = method.getReturnType();
                     verify(OpaqueObject.class.isAssignableFrom(valueType), "Illegal value type %s", valueType);
-                    valueNode = new OpaqueNodeCodecContext.AnyXml<>((AnyXmlSchemaNode) schema, method,
+                    valueNode = new OpaqueNodeCodecContext.AnyXml<>((AnyXmlSchemaNode) schema, method.getName(),
                             valueType.asSubclass(OpaqueObject.class), loader);
                 } else {
                     verify(schema == null, "Unhandled schema %s for method %s", schema, method);
@@ -353,7 +353,7 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
                     continue;
                 }
 
-                leaves.put(schema.getQName().getLocalName(), valueNode);
+                leaves.put(method, valueNode);
             }
         }
         return ImmutableMap.copyOf(leaves);
index 92f76510c003af53c66a631720d809d1b2319f47..55e13f1c52f2dcfc9ff6c08817a832759c5efebe 100644 (file)
@@ -111,8 +111,8 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Dat
         super(prototype);
 
         final Class<D> bindingClass = getBindingClass();
-        this.leafChild = factory().getLeafNodes(bindingClass, getSchema());
 
+        final Map<Method, ValueNodeCodecContext> tmpLeaves = factory().getLeafNodes(bindingClass, getSchema());
         final Map<Class<?>, Method> clsToMethod = BindingReflections.getChildrenClassToMethod(bindingClass);
 
         final Map<YangInstanceIdentifier.PathArgument, NodeContextSupplier> byYangBuilder = new HashMap<>();
@@ -121,10 +121,15 @@ public abstract class DataObjectCodecContext<D extends DataObject, T extends Dat
         final Map<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClassBuilder = new HashMap<>();
 
         // Adds leaves to mapping
-        for (final ValueNodeCodecContext leaf : leafChild.values()) {
-            tmpMethodToSupplier.put(leaf.getGetter(), leaf);
+        final Builder<String, ValueNodeCodecContext> leafChildBuilder =
+                ImmutableMap.builderWithExpectedSize(tmpLeaves.size());
+        for (final Entry<Method, ValueNodeCodecContext> entry : tmpLeaves.entrySet()) {
+            final ValueNodeCodecContext leaf = entry.getValue();
+            tmpMethodToSupplier.put(entry.getKey(), leaf);
+            leafChildBuilder.put(leaf.getSchema().getQName().getLocalName(), leaf);
             byYangBuilder.put(leaf.getDomPathArgument(), leaf);
         }
+        this.leafChild = leafChildBuilder.build();
 
         for (final Entry<Class<?>, Method> childDataObj : clsToMethod.entrySet()) {
             final Method method = childDataObj.getValue();
index e628568644d9ba6c3381afba0055315814681528..3b1890819c2a86a8858996adc0e6c4da5dab6d7c 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import static java.util.Objects.requireNonNull;
 
-import java.lang.reflect.Method;
 import java.util.Optional;
 import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
@@ -33,9 +32,9 @@ class LeafNodeCodecContext extends ValueNodeCodecContext.WithCodec {
             implements BindingTypeObjectCodecTreeNode<T> {
         private final @NonNull Class<T> bindingClass;
 
-        OfTypeObject(final LeafSchemaNode schema, final Codec<Object, Object> codec, final Method getter,
+        OfTypeObject(final LeafSchemaNode schema, final Codec<Object, Object> codec, final String getterName,
                 final SchemaContext schemaContext, final Class<T> bindingClass) {
-            super(schema, codec, getter, schemaContext);
+            super(schema, codec, getterName, schemaContext);
             this.bindingClass = requireNonNull(bindingClass);
         }
 
@@ -56,15 +55,15 @@ class LeafNodeCodecContext extends ValueNodeCodecContext.WithCodec {
     }
 
     LeafNodeCodecContext(final LeafSchemaNode schema, final Codec<Object, Object> codec,
-            final Method getter, final SchemaContext schemaContext) {
-        super(schema, codec, getter, createDefaultObject(schema, codec, schemaContext));
+            final String getterName, final SchemaContext schemaContext) {
+        super(schema, codec, getterName, createDefaultObject(schema, codec, schemaContext));
     }
 
     static LeafNodeCodecContext of(final LeafSchemaNode schema, final Codec<Object, Object> codec,
-            final Method getter, final Class<?> valueType, final SchemaContext schemaContext) {
+            final String getterName, final Class<?> valueType, final SchemaContext schemaContext) {
         return TypeObject.class.isAssignableFrom(valueType)
-                ? new OfTypeObject<>(schema, codec, getter, schemaContext, valueType.asSubclass(TypeObject.class))
-                        : new LeafNodeCodecContext(schema, codec, getter, schemaContext);
+                ? new OfTypeObject<>(schema, codec, getterName, schemaContext, valueType.asSubclass(TypeObject.class))
+                        : new LeafNodeCodecContext(schema, codec, getterName, schemaContext);
     }
 
     @Override
index 4d92685ddad8e31001e0a935b19c9e9fc4144278..ea6947d3dbac9d3ce143108a6458783fca5765d7 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -19,9 +18,9 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
 final class LeafSetNodeCodecContext extends ValueNodeCodecContext.WithCodec {
     LeafSetNodeCodecContext(final LeafListSchemaNode schema, final Codec<Object, Object> codec,
-        final Method getter) {
+        final String getterName) {
         // FIXME: add support for defaults
-        super(schema, codec, getter, null);
+        super(schema, codec, getterName, null);
     }
 
     @Override
index 95f308fe61854ed31ba64166e7a4e545e99c9c18..0b02e4bc3623ffa8a8f74a914b39b73f43b6b254 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import com.google.common.collect.ImmutableMap;
+import java.lang.reflect.Method;
 import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
@@ -65,7 +66,7 @@ abstract class NodeCodecContext implements BindingCodecTreeNode {
          * @param schema  Instantiated schema of binding type.
          * @return Map of local name to leaf node context.
          */
-        ImmutableMap<String, ValueNodeCodecContext> getLeafNodes(Class<?> type, DataNodeContainer schema);
+        ImmutableMap<Method, ValueNodeCodecContext> getLeafNodes(Class<?> type, DataNodeContainer schema);
 
         /**
          * Returns Path argument codec for list item.
index 313e300ee8f00b1d019d3450753b6cb3267f83c4..77acf086e4e79953434ad38c8e43a8939db9cdd0 100644 (file)
@@ -16,7 +16,6 @@ import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
 import javax.xml.transform.dom.DOMSource;
 import net.bytebuddy.ByteBuddy;
 import net.bytebuddy.dynamic.DynamicType.Builder;
@@ -38,9 +37,9 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 abstract class OpaqueNodeCodecContext<T extends OpaqueObject<T>> extends ValueNodeCodecContext
         implements BindingOpaqueObjectCodecTreeNode<T> {
     static final class AnyXml<T extends OpaqueObject<T>> extends OpaqueNodeCodecContext<T> {
-        AnyXml(final AnyXmlSchemaNode schema, final Method getter, final Class<T> bindingClass,
+        AnyXml(final AnyXmlSchemaNode schema, final String getterName, final Class<T> bindingClass,
                 final CodecClassLoader loader) {
-            super(schema, getter, bindingClass, loader);
+            super(schema, getterName, bindingClass, loader);
         }
 
         @Override
@@ -79,9 +78,9 @@ abstract class OpaqueNodeCodecContext<T extends OpaqueObject<T>> extends ValueNo
     private final MethodHandle proxyConstructor;
     private final @NonNull Class<T> bindingClass;
 
-    OpaqueNodeCodecContext(final DataSchemaNode schema, final Method getter, final Class<T> bindingClass,
+    OpaqueNodeCodecContext(final DataSchemaNode schema, final String getterName, final Class<T> bindingClass,
             final CodecClassLoader loader) {
-        super(schema, getter, null);
+        super(schema, getterName, null);
         this.bindingClass = requireNonNull(bindingClass);
         proxyConstructor = createImpl(loader, bindingClass);
     }
index f18133e4837d74b727a0ca27c3a4057ca4190464..1ee46c73d340864dea6a589e0487f7f439ee5871 100644 (file)
@@ -22,7 +22,7 @@ final class ValueContext {
     private final String getterName;
 
     ValueContext(final Class<?> identifier, final ValueNodeCodecContext leaf) {
-        getterName = leaf.getGetter().getName();
+        getterName = leaf.getGetterName();
         try {
             getter = MethodHandles.publicLookup().unreflect(identifier.getMethod(getterName)).asType(OBJECT_METHOD);
         } catch (IllegalAccessException | NoSuchMethodException | SecurityException e) {
index d6baafe129fde507ffcd001623e044be8ced37d3..e51172df43734b5bd6ab4196649008577c4525a6 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import static java.util.Objects.requireNonNull;
 
-import java.lang.reflect.Method;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -23,9 +22,9 @@ abstract class ValueNodeCodecContext extends NodeCodecContext implements NodeCon
     abstract static class WithCodec extends ValueNodeCodecContext {
         private final @NonNull Codec<Object, Object> valueCodec;
 
-        WithCodec(final DataSchemaNode schema, final Codec<Object, Object> codec, final Method getter,
+        WithCodec(final DataSchemaNode schema, final Codec<Object, Object> codec, final String getterName,
                 final Object defaultObject) {
-            super(schema, getter, defaultObject);
+            super(schema, getterName, defaultObject);
             this.valueCodec = requireNonNull(codec);
         }
 
@@ -36,13 +35,13 @@ abstract class ValueNodeCodecContext extends NodeCodecContext implements NodeCon
     }
 
     private final @NonNull NodeIdentifier yangIdentifier;
-    private final @NonNull Method getter;
+    private final @NonNull String getterName;
     private final @NonNull DataSchemaNode schema;
     private final Object defaultObject;
 
-    ValueNodeCodecContext(final DataSchemaNode schema, final Method getter, final Object defaultObject) {
+    ValueNodeCodecContext(final DataSchemaNode schema, final String getterName, final Object defaultObject) {
         this.yangIdentifier = NodeIdentifier.create(schema.getQName());
-        this.getter = requireNonNull(getter);
+        this.getterName = requireNonNull(getterName);
         this.schema = requireNonNull(schema);
         this.defaultObject = defaultObject;
     }
@@ -57,8 +56,8 @@ abstract class ValueNodeCodecContext extends NodeCodecContext implements NodeCon
         return this;
     }
 
-    final Method getGetter() {
-        return getter;
+    final String getGetterName() {
+        return getterName;
     }
 
     abstract Codec<Object, Object> getValueCodec();