Move BindingReflections to mdsal-binding-spec-util
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / LazyDataObject.java
index 998f461583ddf223509b2d061aadeed5d57d2ede..18dcc018818f67e0031dd1c598b7c4836e0d8562 100644 (file)
@@ -21,10 +21,11 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import org.opendaylight.mdsal.binding.dom.codec.util.AugmentationReader;
+import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
@@ -37,7 +38,6 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
     private static final String GET_IMPLEMENTED_INTERFACE = "getImplementedInterface";
     private static final String TO_STRING = "toString";
     private static final String EQUALS = "equals";
-    private static final String GET_AUGMENTATION = "getAugmentation";
     private static final String HASHCODE = "hashCode";
     private static final String AUGMENTATIONS = "augmentations";
     private static final Object NULL_VALUE = new Object();
@@ -69,7 +69,7 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
                 return getAugmentationsImpl();
             }
             return getBindingData(method);
-        } else if (GET_AUGMENTATION.equals(method.getName())) {
+        } else if (BindingMapping.AUGMENTABLE_AUGMENTATION_NAME.equals(method.getName())) {
             return getAugmentationImpl((Class<?>) args[0]);
         } else if (EQUALS.equals(method.getName())) {
             return bindingEquals(args[0]);
@@ -96,7 +96,7 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
                     if (!Arrays.equals((byte[]) thisValue, (byte[]) otherValue)) {
                         return false;
                     }
-                } else if (!Objects.equals(thisValue, otherValue)){
+                } else if (!Objects.equals(thisValue, otherValue)) {
                     return false;
                 }
             }
@@ -116,7 +116,7 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
     private static Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentations(final Object dataObject) {
         if (dataObject instanceof AugmentationReader) {
             return ((AugmentationReader) dataObject).getAugmentations(dataObject);
-        } else if (dataObject instanceof Augmentable<?>){
+        } else if (dataObject instanceof Augmentable<?>) {
             return BindingReflections.getAugmentations((Augmentable<?>) dataObject);
         }
 
@@ -181,18 +181,27 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
     }
 
     private Object getAugmentationImpl(final Class<?> cls) {
+        Preconditions.checkNotNull(cls, "Supplied augmentation must not be null.");
+
         final ImmutableMap<Class<? extends Augmentation<?>>, Augmentation<?>> aug = cachedAugmentations;
         if (aug != null) {
             return aug.get(cls);
         }
-        Preconditions.checkNotNull(cls,"Supplied augmentation must not be null.");
 
         @SuppressWarnings({"unchecked","rawtypes"})
-        final Optional<DataContainerCodecContext<?,?>> augCtx= context.possibleStreamChild((Class) cls);
-        if(augCtx.isPresent()) {
-            final Optional<NormalizedNode<?, ?>> augData = data.getChild(augCtx.get().getDomPathArgument());
-            if (augData.isPresent()) {
-                return augCtx.get().deserialize(augData.get());
+        final Optional<DataContainerCodecContext<?, ?>> optAugCtx = context.possibleStreamChild((Class) cls);
+        if (optAugCtx.isPresent()) {
+            final DataContainerCodecContext<?, ?> augCtx = optAugCtx.get();
+            // Due to binding specification not representing grouping instantiations we can end up having the same
+            // augmentation applied to a grouping multiple times. While these augmentations have the same shape, they
+            // are still represented by distinct binding classes and therefore we need to make sure the result matches
+            // the augmentation the user is requesting -- otherwise a strict receiver would end up with a cryptic
+            // ClassCastException.
+            if (cls.isAssignableFrom(augCtx.getBindingClass())) {
+                final java.util.Optional<NormalizedNode<?, ?>> augData = data.getChild(augCtx.getDomPathArgument());
+                if (augData.isPresent()) {
+                    return augCtx.deserialize(augData.get());
+                }
             }
         }
         return null;
@@ -201,7 +210,7 @@ class LazyDataObject<D extends DataObject> implements InvocationHandler, Augment
     public String bindingToString() {
         final ToStringHelper helper = MoreObjects.toStringHelper(context.getBindingClass()).omitNullValues();
 
-        for (final Method m :context.getHashCodeAndEqualsMethods()) {
+        for (final Method m : context.getHashCodeAndEqualsMethods()) {
             helper.add(m.getName(), getBindingData(m));
         }
         if (Augmentable.class.isAssignableFrom(context.getBindingClass())) {