From: Jan Hajnar Date: Tue, 24 Mar 2015 16:52:01 +0000 (+0100) Subject: Bug 2894 - Yang Data Codec Gson: null pointer exception when trying to X-Git-Tag: release/lithium~183^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=08c9d84f927740567791ffb0b9dfba6176cee321;p=yangtools.git Bug 2894 - Yang Data Codec Gson: null pointer exception when trying to deserialize leafref value * added function to serch for module where type was originaly defined, so correct DataSchemaNode can be found when resolving leafref. Change-Id: I00fd8fbdfe6f548f465e7e50eed9845e443b1f43 Signed-off-by: Jan Hajnar --- diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java index 10abb048d5..20fe4ceb3a 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java @@ -20,6 +20,7 @@ import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -221,7 +222,7 @@ public final class SchemaContextUtil { final QName qname = Iterables.getFirst(schemaNode.getPath().getPathTowardsRoot(), null); Preconditions.checkState(qname != null, "Schema Path contains invalid state of path parts. " + - "The Schema Path MUST contain at least ONE QName which defines namespace and Local name of path."); + "The Schema Path MUST contain at least ONE QName which defines namespace and Local name of path."); return context.findModuleByNamespaceAndRevision(qname.getNamespace(), qname.getRevision()); } @@ -626,7 +627,7 @@ public final class SchemaContextUtil { RevisionAwareXPath pathStatement = typeDefinition.getPathStatement(); pathStatement = new RevisionAwareXPathImpl(stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute()); - final Module parentModule = SchemaContextUtil.findParentModule(schemaContext, schema); + Module parentModule = findParentModuleByType(schemaContext, schema); final DataSchemaNode dataSchemaNode; if(pathStatement.isAbsolute()) { @@ -651,6 +652,50 @@ public final class SchemaContextUtil { } } + /** + * Returns parent Yang Module for specified Schema Context in which Schema + * Node is declared. If Schema Node is of type 'ExtendedType' it tries to find parent module + * in which the type was originally declared (needed for correct leafref path resolution).
+ * If the Schema Node is not present in Schema Context the + * operation will return null.
+ * If Schema Context or Schema Node contains null references + * the method will throw IllegalArgumentException + * + * @throws IllegalArgumentException + * + * @param schemaContext + * Schema Context + * @param schemaNode + * Schema Node + * @return Yang Module for specified Schema Context and Schema Node, if + * Schema Node is NOT present, the method will returns + * null + */ + public static Module findParentModuleByType(final SchemaContext schemaContext, final SchemaNode schemaNode) { + Preconditions.checkArgument(schemaContext != null, "Schema Context reference cannot be NULL!"); + Preconditions.checkArgument(schemaNode != null, "Schema Node cannot be NULL!"); + TypeDefinition nodeType = null; + + if (schemaNode instanceof LeafSchemaNode) { + nodeType = ((LeafSchemaNode) schemaNode).getType(); + } else if (schemaNode instanceof LeafListSchemaNode) { + nodeType = ((LeafListSchemaNode) schemaNode).getType(); + } + + if (nodeType != null && nodeType instanceof ExtendedType) { + while (nodeType.getBaseType() instanceof ExtendedType) { + nodeType = nodeType.getBaseType(); + } + + QNameModule typeDefModuleQname = nodeType.getQName().getModule(); + + return schemaContext.findModuleByNamespaceAndRevision(typeDefModuleQname.getNamespace(), + typeDefModuleQname.getRevision()); + } + + return SchemaContextUtil.findParentModule(schemaContext, schemaNode); + } + /** * Returns base type for {@code typeDefinition} which belongs to module specified via {@code qName}. This handle case * when leafref type isn't specified as type substatement of leaf or leaf-list but is defined in other module as typedef