Bug 4969: NPE in JSONCodecFactory by attempt to find codec for a leafref
[yangtools.git] / yang / yang-data-codec-gson / src / main / java / org / opendaylight / yangtools / yang / data / codec / gson / JSONCodecFactory.java
index ebbd99af322032d5ff2a513a3e241aea3b5adbe5..1d6ffc827724a1670da028bdc5a34cc9810ccc43 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
@@ -20,6 +21,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
 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;
@@ -79,7 +81,7 @@ public final class JSONCodecFactory {
 
     private JSONCodecFactory(final SchemaContext context) {
         this.schemaContext = Preconditions.checkNotNull(context);
-        iidCodec = new JSONStringInstanceIdentifierCodec(context);
+        iidCodec = new JSONStringInstanceIdentifierCodec(context, this);
     }
 
     /**
@@ -94,15 +96,15 @@ public final class JSONCodecFactory {
 
     @SuppressWarnings("unchecked")
     private JSONCodec<Object> createCodec(final DataSchemaNode key, final TypeDefinition<?> type) {
-        final TypeDefinition<?> baseType = DerivedType.from(type);
-        if (baseType instanceof LeafrefTypeDefinition) {
-            return createReferencedTypeCodec(key, (LeafrefTypeDefinition) baseType);
-        } else if (baseType instanceof IdentityrefTypeDefinition) {
-            final JSONCodec<?> jsonStringIdentityrefCodec = new JSONStringIdentityrefCodec(schemaContext,
-                    key.getQName().getModule());
+        final TypeDefinition<?> normalizedType = DerivedType.from(type);
+        if (normalizedType instanceof LeafrefTypeDefinition) {
+            return createReferencedTypeCodec(key, (LeafrefTypeDefinition) normalizedType);
+        } else if (normalizedType instanceof IdentityrefTypeDefinition) {
+            final JSONCodec<?> jsonStringIdentityrefCodec =
+                    new JSONStringIdentityrefCodec(schemaContext, key.getQName().getModule());
             return (JSONCodec<Object>) jsonStringIdentityrefCodec;
         }
-        return createFromSimpleType(type);
+        return createFromSimpleType(normalizedType);
     }
 
     private JSONCodec<Object> createReferencedTypeCodec(final DataSchemaNode schema,
@@ -110,6 +112,7 @@ public final class JSONCodecFactory {
         // FIXME: Verify if this does indeed support leafref of leafref
         final TypeDefinition<?> referencedType =
                 SchemaContextUtil.getBaseTypeForLeafRef(type, getSchemaContext(), schema);
+        Verify.verifyNotNull(referencedType, "Unable to find base type for leafref node '%s'.", schema.getPath());
         return createCodec(schema, referencedType);
     }
 
@@ -118,6 +121,9 @@ public final class JSONCodecFactory {
         if (type instanceof InstanceIdentifierTypeDefinition) {
             return (JSONCodec<Object>) iidCodec;
         }
+        if (type instanceof EmptyTypeDefinition) {
+            return JSONEmptyCodec.INSTANCE;
+        }
 
         final TypeDefinitionAwareCodec<Object, ?> codec = TypeDefinitionAwareCodec.from(type);
         if (codec == null) {