Merge "Change target to ${project.build.target} in a bunch of pom file. Add some...
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / dom / serializer / impl / InstanceIdentifierCodecImpl.xtend
index 270660980643cfa6e58a1bcc5fc7aeff856fc584..d9103727b2debc5e066a34380b7caef2d9f2e8a4 100644 (file)
@@ -22,14 +22,18 @@ import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 import org.opendaylight.yangtools.yang.data.api.Node
 import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.Augmentable
+import com.google.common.collect.ImmutableList
+import org.opendaylight.yangtools.yang.binding.Augmentation
+import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections
 
 class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
     
     private static val LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl);
     val CodecRegistry codecRegistry;
     
-    val Map<Class<?>,QName> classToQName = new WeakHashMap;
-    
+    val Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = new WeakHashMap;
     
     public new(CodecRegistry registry) {
         codecRegistry = registry;
@@ -44,10 +48,18 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         for(biArg : biArgs) {
             scannedPath.add(biArg.nodeType);
             val baArg = deserializePathArgument(biArg,scannedPath)
-            baArgs.add(baArg)
             baType = baArg?.type
+            val injectAugment = classToPreviousAugment.get(baType);
+            if(injectAugment != null) {
+                val augment = injectAugment.get(scannedPath) as Class<? extends DataObject>;
+                if(augment != null) {
+                    baArgs.add(new Item(augment));
+                }
+            }
+            baArgs.add(baArg)
         }
         val ret = new InstanceIdentifier(baArgs,baType as Class<? extends DataObject>);
+        LOG.debug("DOM Instance Identifier {} deserialized to {}",input,ret);
         return ret;
     }
     
@@ -74,21 +86,46 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
     }
     
     override serialize(InstanceIdentifier input) {
+        var Class<?> previousAugmentation = null
         val pathArgs = input.path as List<org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument>
         var QName previousQName = null;
         val components = new ArrayList<PathArgument>(pathArgs.size);
+        val qnamePath = new ArrayList<QName>(pathArgs.size);
         for(baArg : pathArgs) { 
-            codecRegistry.bindingClassEncountered(baArg.type);
-            val biArg = serializePathArgument(baArg,previousQName);
-            previousQName = biArg.nodeType;
-            components.add(biArg);
+            
+            if(!Augmentation.isAssignableFrom(baArg.type)) {
+                
+                val biArg = serializePathArgument(baArg,previousQName);
+                previousQName = biArg.nodeType;
+                components.add(biArg);
+                qnamePath.add(biArg.nodeType);
+                val immutableList = ImmutableList.copyOf(qnamePath);
+                codecRegistry.putPathToClass(immutableList,baArg.type);
+                if(previousAugmentation !== null) {
+                    updateAugmentationInjection(baArg.type,immutableList,previousAugmentation)
+                }
+                
+                previousAugmentation = null;
+            } else {
+                previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class);
+                previousAugmentation = baArg.type;
+            }
+        }
+        val ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+        LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}",input,ret);
+        return ret;
+    }
+    
+    def updateAugmentationInjection(Class<? extends DataObject> class1, ImmutableList<QName> list, Class<?> augmentation) {
+        if(classToPreviousAugment.get(class1) == null) {
+            classToPreviousAugment.put(class1,new ConcurrentHashMap());
         }
-        return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+        classToPreviousAugment.get(class1).put(list,augmentation);
     }
     
     private def dispatch PathArgument serializePathArgument(Item argument, QName previousQname) {
         val type = argument.type;
-        val qname = resolveQname(type);
+        val qname = BindingReflections.findQName(type);
         if(previousQname == null) {
             return new NodeIdentifier(qname);
         }
@@ -100,7 +137,7 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         val Map<QName,Object> predicates = new HashMap();
         val type = argument.type;
         val keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
-        val qname = resolveQname(type);
+        val qname = BindingReflections.findQName(type);
         val combinedInput =  new ValueWithQName(previousQname,argument.key)
         val compositeOutput = keyCodec.serialize(combinedInput as ValueWithQName);
         for(outputValue :compositeOutput.value) {
@@ -111,15 +148,4 @@ class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
         }
         return new NodeIdentifierWithPredicates(QName.create(previousQname,qname.localName),predicates);
     }
-    
-    def resolveQname(Class<?> class1) {
-        val qname = classToQName.get(class1);
-        if(qname !== null) {
-            return qname;
-        }
-        val qnameField = class1.getField("QNAME");
-        val qnameValue = qnameField.get(null) as QName;
-        classToQName.put(class1,qnameValue);
-        return qnameValue;
-    }
 }
\ No newline at end of file