Runtime Codec cleanup 84/9584/2
authorTony Tkacik <ttkacik@cisco.com>
Fri, 1 Aug 2014 17:15:36 +0000 (19:15 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Sun, 3 Aug 2014 09:55:30 +0000 (11:55 +0200)
- Extracted Augmentation getter to Bidning Reflections
- Fixed retrieval of IdenfierCodec

Change-Id: Ib6b6f45349bd8b5b055dccd036549ec727c0186d
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/LazyGeneratedCodecRegistry.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/BindingMapping.java
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/AugmentationFieldGetter.java [new file with mode: 0644]
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/BindingReflections.java

index ee5d244f9df735f032c48240d860bab1920d2161..b6b3e6d5e99e9cbb6e287a9209cd6d1fa932870e 100644 (file)
@@ -9,18 +9,13 @@ package org.opendaylight.yangtools.sal.binding.generator.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
-
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -35,7 +30,6 @@ import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.yangtools.binding.generator.util.Types;
 import org.opendaylight.yangtools.concepts.Delegator;
@@ -55,6 +49,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.Node;
@@ -133,8 +128,7 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
     private final AbstractTransformerGenerator generator;
     private final SchemaLock lock;
 
-    private static final LoadingCache<Class<?>, AugmentationFieldGetter> AUGMENTATION_GETTERS =
-            CacheBuilder.newBuilder().weakKeys().softValues().build(new AugmentationGetterLoader());
+
 
     // FIXME: how is this protected?
     private SchemaContext currentSchema;
@@ -350,18 +344,36 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
         }
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public IdentifierCodec<?> getIdentifierCodecForIdentifiable(final Class identifiable) {
+
+        Class identifier= ClassLoaderUtils.findFirstGenericArgument(identifiable, org.opendaylight.yangtools.yang.binding.Identifiable.class);
+        IdentifierCodec<?> obj = identifierCodecs.get(identifier);
+        if (obj != null) {
+            return obj;
+        }
+        return createIdentifierCodec(identifier,identifiable);
+    }
+
     @Override
-    public <T extends Identifiable<?>> IdentifierCodec<?> getIdentifierCodecForIdentifiable(final Class<T> type) {
-        IdentifierCodec<?> obj = identifierCodecs.get(type);
+    public <T extends Identifier<?>> IdentifierCodec<T> getCodecForIdentifier(final Class<T> identifier) {
+        @SuppressWarnings("unchecked")
+        IdentifierCodec<T> obj = (IdentifierCodec<T>) identifierCodecs.get(identifier);
         if (obj != null) {
             return obj;
         }
+        Class<? extends Identifiable<T>> identifiable = ClassLoaderUtils.findFirstGenericArgument(identifier, Identifier.class);
+        return createIdentifierCodec(identifier,identifiable);
+    }
+
+    private <T extends Identifier<?>> IdentifierCodec<T> createIdentifierCodec(final Class<T> identifier,final Class<? extends Identifiable<T>> identifiable){
         Class<? extends BindingCodec<Map<QName, Object>, Object>> newCodec = generator
-                .keyTransformerForIdentifiable(type);
+                .keyTransformerForIdentifiable(identifiable);
         BindingCodec<Map<QName, Object>, Object> newInstance;
         newInstance = newInstanceOf(newCodec);
-        IdentifierCodecImpl<?> newWrapper = new IdentifierCodecImpl<>(newInstance);
-        identifierCodecs.put(type, newWrapper);
+        IdentifierCodecImpl<T> newWrapper = new IdentifierCodecImpl<>(newInstance);
+        identifierCodecs.put(identifier, newWrapper);
         return newWrapper;
     }
 
@@ -383,22 +395,6 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
         CodecMapping.setIdentityRefCodec(cls, identityRefCodec);
     }
 
-    @Override
-    public <T extends Identifier<?>> IdentifierCodec<T> getCodecForIdentifier(final Class<T> object) {
-        @SuppressWarnings("unchecked")
-        IdentifierCodec<T> obj = (IdentifierCodec<T>) identifierCodecs.get(object);
-        if (obj != null) {
-            return obj;
-        }
-        Class<? extends BindingCodec<Map<QName, Object>, Object>> newCodec = generator
-                .keyTransformerForIdentifier(object);
-        BindingCodec<Map<QName, Object>, Object> newInstance;
-        newInstance = newInstanceOf(newCodec);
-        IdentifierCodecImpl<T> newWrapper = new IdentifierCodecImpl<>(newInstance);
-        identifierCodecs.put(object, newWrapper);
-        return newWrapper;
-    }
-
     @SuppressWarnings("rawtypes")
     public ChoiceCaseCodecImpl getCaseCodecFor(final Class caseClass) {
         ChoiceCaseCodecImpl<?> potential = caseCodecs.get(caseClass);
@@ -520,50 +516,7 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
         return ret;
     }
 
-    private static final class AugmentationGetterLoader extends CacheLoader<Class<?>, AugmentationFieldGetter> {
-        private static final AugmentationFieldGetter DUMMY = new AugmentationFieldGetter() {
-            @Override
-            Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
-                return Collections.emptyMap();
-            }
-        };
-
-        @Override
-        public AugmentationFieldGetter load(final Class<?> key) throws Exception {
-            Field field;
-            try {
-                field = key.getDeclaredField("augmentation");
-            } catch (NoSuchFieldException | SecurityException e) {
-                LOG.debug("Failed to acquire augmentation field", e);
-                return DUMMY;
-            }
-            field.setAccessible(true);
-
-            return new ReflectionAugmentationFieldGetter(field);
-        }
-    }
-
-    private static abstract class AugmentationFieldGetter {
-        abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input);
-    }
-
-    private static final class ReflectionAugmentationFieldGetter extends AugmentationFieldGetter {
-        private final Field augmentationField;
-
-        ReflectionAugmentationFieldGetter(final Field augmentationField) {
-            this.augmentationField = Preconditions.checkNotNull(augmentationField);
-        }
 
-        @Override
-        @SuppressWarnings("unchecked")
-        Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
-            try {
-                return (Map<Class<? extends Augmentation<?>>, Augmentation<?>>) augmentationField.get(input);
-            } catch (IllegalArgumentException | IllegalAccessException e) {
-                throw new IllegalStateException("Failed to access augmentation field", e);
-            }
-        }
-    }
 
     private static abstract class IntermediateCodec<T> implements DomCodec<T>, Delegator<BindingCodec<Map<QName, Object>, Object>> {
 
@@ -1119,24 +1072,13 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
         public Object serialize(final Object input) {
             Preconditions.checkArgument(augmentableType.isInstance(input), "Object %s is not instance of %s ",input,augmentableType);
             if (input instanceof Augmentable<?>) {
-                Map<Class<? extends Augmentation<?>>, Augmentation<?>> augmentations = getAugmentations(input);
+                Map<Class<? extends Augmentation<?>>, Augmentation<?>> augmentations = BindingReflections.getAugmentations((Augmentable<?>) input);
                 return serializeImpl(augmentations);
             }
             return null;
         }
 
-        /**
-         *
-         * Extracts augmentation from Binding DTO field using reflection
-         *
-         * @param input Instance of DataObject which is augmentable and
-         *      may contain augmentation
-         * @return Map of augmentations if read was successful, otherwise
-         *      empty map.
-         */
-        private Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
-            return AUGMENTATION_GETTERS.getUnchecked(input.getClass()).getAugmentations(input);
-        }
+
 
         /**
          *
@@ -1493,4 +1435,5 @@ class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener
     private static final Type referencedType(final Class<?> augmentableType) {
         return new ReferencedTypeImpl(augmentableType.getPackage().getName(), augmentableType.getSimpleName());
     }
+
 }
index ba8b6812e2c911156ef34db5a7fa9b05fa7093b5..2966fb982fcb7a7cac76965d2e1c01b1e6df53a2 100644 (file)
@@ -9,18 +9,16 @@ package org.opendaylight.yangtools.yang.binding;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
 import java.text.SimpleDateFormat;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-
 public final class BindingMapping {
 
     public static final String VERSION = "0.6";
@@ -37,6 +35,7 @@ public final class BindingMapping {
     public static final String NOTIFICATION_LISTENER_SUFFIX = "Listener";
     public static final String QNAME_STATIC_FIELD_NAME = "QNAME";
     public static final String PACKAGE_PREFIX = "org.opendaylight.yang.gen.v1";
+    public static final String AUGMENTATION_FIELD = "augmentation";
 
     private static final Splitter CAMEL_SPLITTER = Splitter.on(CharMatcher.anyOf(" _.-").precomputed())
             .omitEmptyStrings().trimResults();
diff --git a/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/AugmentationFieldGetter.java b/yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/util/AugmentationFieldGetter.java
new file mode 100644 (file)
index 0000000..8178d8f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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.yangtools.yang.binding.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AugmentationFieldGetter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AugmentationFieldGetter.class);
+
+    private static final AugmentationFieldGetter DUMMY = new AugmentationFieldGetter() {
+        @Override
+        protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
+            return Collections.emptyMap();
+        }
+    };
+
+   /**
+    *
+    * Retrieves augmentations from supplied object
+    *
+    * @param input Input Data object, from which augmentations should be extracted
+    * @return Map of Augmentation class to augmentation
+    */
+   protected abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input);
+
+    private static final LoadingCache<Class<?>, AugmentationFieldGetter> AUGMENTATION_GETTERS =
+            CacheBuilder.newBuilder().weakKeys().softValues().build(new AugmentationGetterLoader());
+
+    public static AugmentationFieldGetter getGetter(final Class<? extends Object> clz) {
+        return AUGMENTATION_GETTERS.getUnchecked(clz);
+    }
+
+    private static final class AugmentationGetterLoader extends CacheLoader<Class<?>, AugmentationFieldGetter> {
+
+        @Override
+        public AugmentationFieldGetter load(final Class<?> key) throws Exception {
+            Field field;
+            try {
+                field = key.getDeclaredField(BindingMapping.AUGMENTATION_FIELD);
+            } catch (NoSuchFieldException | SecurityException e) {
+                LOG.debug("Failed to acquire augmentation field", e);
+                return DUMMY;
+            }
+            field.setAccessible(true);
+
+            return new ReflectionAugmentationFieldGetter(field);
+        }
+    }
+
+    private static final class ReflectionAugmentationFieldGetter extends AugmentationFieldGetter {
+        private final Field augmentationField;
+
+        ReflectionAugmentationFieldGetter(final Field augmentationField) {
+            this.augmentationField = Preconditions.checkNotNull(augmentationField);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
+            try {
+                return (Map<Class<? extends Augmentation<?>>, Augmentation<?>>) augmentationField.get(input);
+            } catch (IllegalArgumentException | IllegalAccessException e) {
+                throw new IllegalStateException("Failed to access augmentation field", e);
+            }
+        }
+    }
+
+
+}
index d6c1d7b75138ab6da9ad5290cc83f4714459b7a3..81ef845de6596ee97417a86b84db5c02cb1cc1ee 100644 (file)
@@ -10,19 +10,25 @@ package org.opendaylight.yangtools.yang.binding.util;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.ServiceLoader;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
@@ -38,13 +44,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-
 public class BindingReflections {
 
     private static final long EXPIRATION_TIME = 60;
@@ -58,6 +57,7 @@ public class BindingReflections {
             .build(new ClassToQNameLoader());
 
 
+
     private BindingReflections() {
         throw new UnsupportedOperationException("Utility class.");
     }
@@ -539,5 +539,18 @@ public class BindingReflections {
                 moduleInfo.getName());
     }
 
+    /**
+    *
+    * Extracts augmentation from Binding DTO field using reflection
+    *
+    * @param input Instance of DataObject which is augmentable and
+    *      may contain augmentation
+    * @return Map of augmentations if read was successful, otherwise
+    *      empty map.
+    */
+   public static Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Augmentable<?> input) {
+       return AugmentationFieldGetter.getGetter(input.getClass()).getAugmentations(input);
+   }
+
 
 }