Check unions for identityref types 85/90285/1
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 15:20:34 +0000 (17:20 +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>
(cherry picked from commit ded2b6279af65315840a43a2d507cd715bdad851)

yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/XMLStreamWriterUtils.java

index cb9e2ec9129713e3915ca04e839831a6e1e2ba53..903710c24fd0d3ccd0eacdd2f92466d9dd5e9665 100644 (file)
@@ -19,6 +19,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;
 
@@ -66,11 +67,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) {