BUG-8004: handle implicit RPC input
[mdsal.git] / binding / mdsal-binding-dom-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / BindingCodecContext.java
index 0452a7dabb40207a821fb64b7552423858e0210e..1f8f9eb79d542b0d12d75aab3095ac4b071e0f8f 100644 (file)
@@ -52,6 +52,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
@@ -200,7 +201,7 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
         }
 
         if (currentList != null) {
-            if(bindingArguments != null) {
+            if (bindingArguments != null) {
                 bindingArguments.add(currentList.getBindingPathArgument(null));
             }
             return currentList;
@@ -212,7 +213,7 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
         return root.getNotification(notification);
     }
 
-    ContainerNodeCodecContext<?> getRpcDataContext(final SchemaPath path) {
+    RpcInputCodec<?> getRpcInputCodec(final SchemaPath path) {
         return root.getRpc(path);
     }
 
@@ -221,26 +222,15 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
             final DataNodeContainer childSchema) {
         final Map<String, DataSchemaNode> getterToLeafSchema = new HashMap<>();
         for (final DataSchemaNode leaf : childSchema.getChildNodes()) {
-            final TypeDefinition<?> typeDef;
-            if (leaf instanceof LeafSchemaNode) {
-                typeDef = ((LeafSchemaNode) leaf).getType();
-            } else if (leaf instanceof LeafListSchemaNode) {
-                typeDef = ((LeafListSchemaNode) leaf).getType();
-            } else {
-                continue;
+            if (leaf instanceof TypedSchemaNode) {
+                getterToLeafSchema.put(getGetterName(leaf.getQName(), ((TypedSchemaNode) leaf).getType()), leaf);
             }
-
-            final String getterName = getGetterName(leaf.getQName(), typeDef);
-            getterToLeafSchema.put(getterName, leaf);
         }
         return getLeafNodesUsingReflection(parentClass, getterToLeafSchema);
     }
 
-    private static String getGetterName(final QName qName, TypeDefinition<?> typeDef) {
+    private static String getGetterName(final QName qName, final TypeDefinition<?> typeDef) {
         final String suffix = BindingMapping.getGetterSuffix(qName);
-        while (typeDef.getBaseType() != null) {
-            typeDef = typeDef.getBaseType();
-        }
         if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
             return "is" + suffix;
         }
@@ -279,14 +269,12 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
     }
 
     private Codec<Object, Object> getCodec(final Class<?> valueType, final DataSchemaNode schema) {
-        final TypeDefinition<?> instantiatedType;
-        if (schema instanceof LeafSchemaNode) {
-            instantiatedType = ((LeafSchemaNode) schema).getType();
-        } else if (schema instanceof LeafListSchemaNode) {
-            instantiatedType = ((LeafListSchemaNode) schema).getType();
-        } else {
-            throw new IllegalArgumentException("Unsupported leaf node type " + schema.getClass());
-        }
+        Preconditions.checkArgument(schema instanceof TypedSchemaNode, "Unsupported leaf node type %s", schema);
+
+        return getCodec(valueType, ((TypedSchemaNode)schema).getType());
+    }
+
+    Codec<Object, Object> getCodec(final Class<?> valueType, final TypeDefinition<?> instantiatedType) {
         if (Class.class.equals(valueType)) {
             @SuppressWarnings({ "unchecked", "rawtypes" })
             final Codec<Object, Object> casted = (Codec) identityCodec;
@@ -296,39 +284,34 @@ final class BindingCodecContext implements CodecContextFactory, BindingCodecTree
             final Codec<Object, Object> casted = (Codec) instanceIdentifierCodec;
             return casted;
         } else if (Boolean.class.equals(valueType)) {
-            if(instantiatedType instanceof EmptyTypeDefinition) {
+            if (instantiatedType instanceof EmptyTypeDefinition) {
                 return ValueTypeCodec.EMPTY_CODEC;
             }
         } else if (BindingReflections.isBindingClass(valueType)) {
-                            return getCodec(valueType, instantiatedType);
+            return getCodecForBindingClass(valueType, instantiatedType);
         }
         return ValueTypeCodec.NOOP_CODEC;
     }
 
-    private Codec<Object, Object> getCodec(final Class<?> valueType, final TypeDefinition<?> instantiatedType) {
-        @SuppressWarnings("rawtypes")
-        TypeDefinition rootType = instantiatedType;
-        while (rootType.getBaseType() != null) {
-            rootType = rootType.getBaseType();
-        }
-        if (rootType instanceof IdentityrefTypeDefinition) {
+    private Codec<Object, Object> getCodecForBindingClass(final Class<?> valueType, final TypeDefinition<?> typeDef) {
+        if (typeDef instanceof IdentityrefTypeDefinition) {
             return ValueTypeCodec.encapsulatedValueCodecFor(valueType, identityCodec);
-        } else if (rootType instanceof InstanceIdentifierTypeDefinition) {
+        } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
             return ValueTypeCodec.encapsulatedValueCodecFor(valueType, instanceIdentifierCodec);
-        } else if (rootType instanceof UnionTypeDefinition) {
-            final Callable<UnionTypeCodec> loader = UnionTypeCodec.loader(valueType, (UnionTypeDefinition) rootType);
+        } else if (typeDef instanceof UnionTypeDefinition) {
+            final Callable<UnionTypeCodec> loader = UnionTypeCodec.loader(valueType, (UnionTypeDefinition) typeDef, this);
             try {
                 return loader.call();
             } catch (final Exception e) {
                 throw new IllegalStateException("Unable to load codec for " + valueType, e);
             }
-        } else if(rootType instanceof LeafrefTypeDefinition) {
+        } else if (typeDef instanceof LeafrefTypeDefinition) {
             final Entry<GeneratedType, Object> typeWithSchema = context.getTypeWithSchema(valueType);
             final Object schema = typeWithSchema.getValue();
             Preconditions.checkState(schema instanceof TypeDefinition<?>);
             return getCodec(valueType, (TypeDefinition<?>) schema);
         }
-        return ValueTypeCodec.getCodecFor(valueType, instantiatedType);
+        return ValueTypeCodec.getCodecFor(valueType, typeDef);
     }
 
     @Override