Check unions for identityref types 50/90250/4
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Jun 2020 11:06:06 +0000 (13:06 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Jun 2020 12:21:38 +0000 (14:21 +0200)
If an identityref type is encountered within a union, we end up
going to TypeDefinitionAwareCodec, which is not equiped to handle
the complexities of XML-encoding identityrefs. Make sure we do
perform a check to side-step this problem.

JIRA: YANGTOOLS-1108
Change-Id: I8dcf70385aceabc5f3e33a508ddd00f926047774
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/XMLStreamWriterUtils.java

index 62766f4e4f148bd18a5dc6db81b772f7c05a5c95..ac3119ff40f89c3544d8816f6ecc153b6b94866a 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,11 +73,25 @@ abstract class XMLStreamWriterUtils {
             return encode(writer, (IdentityrefTypeDefinition) type, value, parent);
         } else if (type instanceof InstanceIdentifierTypeDefinition) {
             return encode(writer, (InstanceIdentifierTypeDefinition) type, value);
+        } else if (value instanceof QName && isIdentityrefUnion(type)) {
+            // Ugly special-case form unions with identityrefs
+            return encode(writer, (QName) value, parent);
         } else {
             return serialize(type, value);
         }
     }
 
+    private static boolean isIdentityrefUnion(final TypeDefinition<?> type) {
+        if (type instanceof UnionTypeDefinition) {
+            for (TypeDefinition<?> subtype : ((UnionTypeDefinition) type).getTypes()) {
+                if (subtype instanceof IdentityrefTypeDefinition || isIdentityrefUnion(subtype)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private static String serialize(final @NonNull TypeDefinition<?> type, final @NonNull Object value) {
         final TypeDefinitionAwareCodec<Object, ?> codec = TypeDefinitionAwareCodec.from(type);
         if (codec == null) {