Separate out mdsal-binding-dom-codec-spi
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / mdsal / binding / dom / codec / impl / DataObjectStreamerGenerator.java
index fa7b0c7443423b7178166d3561fa24b387b4066c..0fc3612463d46ed739515ee3867cb2b41c2f5fe0 100644 (file)
@@ -47,23 +47,23 @@ import net.bytebuddy.jar.asm.MethodVisitor;
 import net.bytebuddy.jar.asm.Opcodes;
 import net.bytebuddy.matcher.ElementMatchers;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingStreamEventWriter;
 import org.opendaylight.mdsal.binding.dom.codec.impl.NodeCodecContext.CodecContextFactory;
 import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader;
 import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader.ClassGenerator;
 import org.opendaylight.mdsal.binding.dom.codec.loader.CodecClassLoader.GeneratorResult;
-import org.opendaylight.mdsal.binding.dom.codec.util.BindingSchemaMapping;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingSchemaMapping;
 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.model.api.MethodSignature;
 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.yangtools.yang.binding.Augmentable;
-import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
@@ -122,6 +122,8 @@ final class DataObjectStreamerGenerator<T extends DataObjectStreamer<?>> impleme
         UNKNOWN_SIZE,
         invokeMethod(BindingStreamEventWriter.class, "startUnkeyedListItem", int.class));
 
+    private static final StackManipulation STREAM_ANYDATA = invokeMethod(DataObjectStreamer.class,
+        "streamAnydata", BindingStreamEventWriter.class, String.class, Object.class);
     private static final StackManipulation STREAM_ANYXML = invokeMethod(DataObjectStreamer.class,
         "streamAnyxml", BindingStreamEventWriter.class, String.class, Object.class);
     private static final StackManipulation STREAM_CHOICE = invokeMethod(DataObjectStreamer.class,
@@ -142,7 +144,7 @@ final class DataObjectStreamerGenerator<T extends DataObjectStreamer<?>> impleme
         BindingStreamEventWriter.class, List.class);
     private static final StackManipulation STREAM_MAP = invokeMethod(DataObjectStreamer.class,
         "streamMap", Class.class, DataObjectStreamer.class, DataObjectSerializerRegistry.class,
-        BindingStreamEventWriter.class, List.class);
+        BindingStreamEventWriter.class, Map.class);
     private static final StackManipulation STREAM_ORDERED_MAP = invokeMethod(DataObjectStreamer.class,
         "streamOrderedMap", Class.class, DataObjectStreamer.class, DataObjectSerializerRegistry.class,
         BindingStreamEventWriter.class, List.class);
@@ -255,19 +257,25 @@ final class DataObjectStreamerGenerator<T extends DataObjectStreamer<?>> impleme
             final String getterName = getter.getName();
             final Type childType = props.get(getterName);
             verify(childType instanceof ParameterizedType, "Unexpected type %s for %s", childType, getterName);
-            final Type valueType = ((ParameterizedType) childType).getActualTypeArguments()[0];
+            final Type[] params = ((ParameterizedType) childType).getActualTypeArguments();
+            final ListSchemaNode listSchema = (ListSchemaNode) childSchema;
             final Class<?> valueClass;
-            try {
-                valueClass = loader.loadClass(valueType.getFullyQualifiedName());
-            } catch (ClassNotFoundException e) {
-                throw new LinkageError("Failed to load " + valueType, e);
+            if (!listSchema.isUserOrdered() && !listSchema.getKeyDefinition().isEmpty()) {
+                loadTypeClass(loader, params[0]);
+                valueClass = loadTypeClass(loader, params[1]);
+            } else {
+                valueClass = loadTypeClass(loader, params[0]);
             }
-            return listChildStream(getter, valueClass.asSubclass(DataObject.class), (ListSchemaNode) childSchema);
+
+            return listChildStream(getter, valueClass.asSubclass(DataObject.class), listSchema);
         }
         if (childSchema instanceof ChoiceSchemaNode) {
             return choiceChildStream(getter);
         }
-        if (childSchema instanceof AnyXmlSchemaNode) {
+        if (childSchema instanceof AnydataSchemaNode) {
+            return qnameChildStream(STREAM_ANYDATA, getter, childSchema);
+        }
+        if (childSchema instanceof AnyxmlSchemaNode) {
             return qnameChildStream(STREAM_ANYXML, getter, childSchema);
         }
         if (childSchema instanceof LeafListSchemaNode) {
@@ -369,6 +377,14 @@ final class DataObjectStreamerGenerator<T extends DataObjectStreamer<?>> impleme
         }
     }
 
+    private static Class<?> loadTypeClass(final CodecClassLoader loader, final Type type) {
+        try {
+            return loader.loadClass(type.getFullyQualifiedName());
+        } catch (ClassNotFoundException e) {
+            throw new LinkageError("Failed to load " + type, e);
+        }
+    }
+
     private static final class SerializeImplementation implements Implementation {
         private final List<ChildStream> children;
         private final StackManipulation startEvent;