From 21190939f08b40c46f908fefabf8cc13e7365f2a Mon Sep 17 00:00:00 2001 From: Vidyashree Rama Date: Fri, 17 Aug 2018 12:21:05 +0530 Subject: [PATCH] Implementation for properties node serializer properties node serializer implementation Issue-ID: CCSDK-378 Change-Id: I4eeecb45227e4152d9ff81551fd98efdd1371f84 Signed-off-by: Vidyashree Rama --- restconf-client/provider/pom.xml | 6 + .../yangserializers/pnserializer/InnerNode.java | 133 ++++++++- .../pnserializer/LeafListHolderNode.java | 11 +- .../pnserializer/ListHolderNode.java | 11 +- .../MdsalPropertiesNodeSerializer.java | 84 +++++- .../pnserializer/MdsalPropertiesNodeUtils.java | 297 +++++++++++++++++++++ .../yangserializers/pnserializer/RootNode.java | 129 ++++++++- 7 files changed, 645 insertions(+), 26 deletions(-) create mode 100644 restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeUtils.java diff --git a/restconf-client/provider/pom.xml b/restconf-client/provider/pom.xml index 5a74d8fc..46e00009 100755 --- a/restconf-client/provider/pom.xml +++ b/restconf-client/provider/pom.xml @@ -70,5 +70,11 @@ properties-node-provider 0.3.0-SNAPSHOT + + org.opendaylight.yangtools + yang-data-impl + 2.0.3 + + diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java index 21f0b7c0..063c3d05 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/InnerNode.java @@ -21,10 +21,22 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import java.util.HashMap; import java.util.Map; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment; + /** * Abstraction of an entity that represents an inner node to properties data * tree. @@ -62,8 +74,31 @@ public abstract class InnerNode extends PropertiesNode { public PropertiesNode addChild(String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + PropertiesNode node = ((PropertiesNode) children.get(name)); + if (node != null) { + return node; + } + + // get augment schema, if it is augmented node + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, name); + } + + // create node based on type + if (node == null) { + String uri = getUri(this, name, namespace); + node = createNode(name, namespace, uri, this, appInfo, type); + } + + // If namespace is not same as parent then it is augmented node + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override @@ -71,16 +106,65 @@ public abstract class InnerNode extends PropertiesNode { NodeType type, String value, Namespace valuens, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children.get(name)); + if (node != null) { + return node; + } + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + } + + String uri = getUri(this, name, namespace); + node = new LeafNode(name, namespace, uri, this, + appInfo, type, value); + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localname = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localname)); + + if (node == null) { + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localname); + } + + if (node == null) { + String uri = getUri(this, name, namespace); + node = new ListHolderNode(localname, namespace, uri, + this, appInfo, MULTI_INSTANCE_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localname, ((T) node)); + } + + node = node.addChild(index, localname, namespace, type, appInfo); + } else if (node instanceof ListHolderNode) { + ListHolderChild child = ((ListHolderNode) node).child(index); + node = (child != null ? ((MultiInstanceNode) child) : + node.addChild(index, localname, namespace, type, appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } @Override @@ -88,7 +172,40 @@ public abstract class InnerNode extends PropertiesNode { Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localName = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localName)); + + if (node == null) { + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localName); + } + + if (node == null) { + String uri = getUri(this, name, namespace); + node = new LeafListHolderNode(localName, namespace, uri, this, + appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localName, ((T) node)); + } + + node = node.addChild(index, localName, namespace, type, value, null, appInfo); + } else if (node instanceof LeafListHolderNode) { + LeafNode child = ((LeafNode) ((HolderNode) node).child(index)); + node = (child != null ? child : node.addChild(index, localName, + namespace, type, + value, null, + appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java index aa10e330..94892dca 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/LeafListHolderNode.java @@ -75,7 +75,14 @@ public class LeafListHolderNode extends HolderNode implemen Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children().get(index)); + if (index == null) { + index = String.valueOf(children().size()); + } + String uri = this.uri() + "[" + index + "]"; + node = (node != null) ? node : new LeafNode(name, namespace, uri, + this, appInfo, type, value); + children().put(index, node); + return node; } } diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java index 9d1168b8..ba9da54c 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/ListHolderNode.java @@ -52,8 +52,15 @@ public class ListHolderNode extends HolderNode implements DataN public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + MultiInstanceNode node = ((MultiInstanceNode) children().get(index)); + if (index == null) { + index = String.valueOf(children().size()); + } + String uri = this.uri() + "[" + index + "]"; + node = (node != null) ? node : new MultiInstanceNode(name, namespace, uri, + this, appInfo, type); + children().put(index, node); + return node; } @Override diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java index 05e1ac1e..405e2412 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/MdsalPropertiesNodeSerializer.java @@ -20,13 +20,25 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.slf4j.Logger; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import java.util.Map; -import static org.slf4j.LoggerFactory.getLogger; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getChildSchemaNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getIndex; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getListName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNamespace; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getNodeType; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_LEAF_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.SINGLE_INSTANCE_NODE; /** * Representation of mdsal based properties node serializer implementation. @@ -35,7 +47,6 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer paramMap) { - return null; + public PropertiesNode encode(Map paramMap) throws SvcLogicException { + curSchema = schemaNode(); + String nodeInUri[] = uri().split("\\/"); + String lastNodeName = nodeInUri[nodeInUri.length - 1]; + String rootUri = uri().replaceAll("\\/", "\\."); + node = createRootNode(lastNodeName, rootUri); + + for (Map.Entry entry : paramMap.entrySet()) { + String[] names = entry.getKey().split("\\."); + for (int i = 0; i < names.length; i++) { + if (i < nodeInUri.length) { + if (!(nodeInUri[i].equals(names[i]))) { + break; + } + } else { + createPropertyNode(i, names.length, names[i], + entry.getValue()); + } + } + } + return node; } @Override @@ -58,4 +89,45 @@ public class MdsalPropertiesNodeSerializer extends PropertiesNodeSerializer 1; + } + + /** + * Returns name of the property after pruning namespace and + * index if the property is multi instance. + * + * @param name name of the property + * @return name of the property + */ + public static String resolveName(String name) { + String localName = getListName(name); + final int lastIndexOfColon = localName.lastIndexOf(":"); + if (lastIndexOfColon != -1) { + localName = localName.substring(lastIndexOfColon + 1); + } + return localName; + } + + /** + * Adds current node to parent's augmentation map. + * + * @param augSchema augment schema + * @param parent parent property node + * @param curNode current property node + */ + public static void addToAugmentations(AugmentationSchemaNode augSchema, + PropertiesNode parent, + PropertiesNode curNode) { + Collection childsFromAugmentation = parent + .augmentations().get(augSchema); + if (!childsFromAugmentation.isEmpty()) { + for (PropertiesNode pNode : childsFromAugmentation) { + if (pNode.name().equals(curNode.name())) { + return; + } + } + } + parent.augmentations().put(augSchema, curNode); + } + + + /** + * Returns augmented properties node if it is already + * added in properties tree. + * + * @param augSchema augmented schema node + * @param parent parent properties node + * @param name name of the properties + * @return augmented properties node if it is already added + */ + public static PropertiesNode getAugmentationNode( + AugmentationSchemaNode augSchema, + PropertiesNode parent, String name) { + if (augSchema != null) { + Collection childsFromAugmentation = parent + .augmentations().get(augSchema); + if (!childsFromAugmentation.isEmpty()) { + for (PropertiesNode pNode : childsFromAugmentation) { + if (pNode.name().equals(name)) { + return pNode; + } + } + } + } + return null; + } + + /** + * Creates uri with specified name and namespace. + * + * @param parent parent properties node + * @param name name of the node + * @param ns namespace of the node + * @return uri with specified name and namespace + */ + public static String getUri(PropertiesNode parent, String name, + Namespace ns) { + String uri = name; + if (!(parent.namespace().moduleNs().equals(ns.moduleNs()))) { + uri = ns.moduleName() + ":" + name; + } + return parent.uri() + "." + uri; + } + + /** + * Creates new properties with specified parameters. + * + * @param name name of the properties node + * @param namespace namespace of the properties node + * @param uri uri of the properties node + * @param parent parent node + * @param appInfo application info + * @param type node type + * @return new properties node + */ + public static PropertiesNode createNode(String name, Namespace namespace, + String uri, PropertiesNode parent, + Object appInfo, NodeType type) { + switch (type) { + case SINGLE_INSTANCE_NODE: + return new SingleInstanceNode(name, namespace, uri, parent, appInfo, type); + case MULTI_INSTANCE_HOLDER_NODE: + return new ListHolderNode(name, namespace, uri, parent, appInfo, type); + case MULTI_INSTANCE_LEAF_HOLDER_NODE: + return new LeafListHolderNode(name, namespace, uri, parent, appInfo, type); + default: + throw new RuntimeException("Invalid node type"); + } + } + + /** + * Returns true if namespace is same as parent's namespace. + * + * @param parent parent property node + * @param curNode current property node + * @return true if namespace is same as parent namespace + */ + public static boolean isNamespaceAsParent(PropertiesNode parent, + PropertiesNode curNode) { + return parent.namespace().moduleNs().equals(curNode.namespace().moduleNs()); + } + + /** + * Returns namespace. + * + * @param childName name of the property + * @param ctx schema context + * @param parent parent property node + * @return namespace + */ + public static Namespace getNamespace(String childName, + SchemaContext ctx, + PropertiesNode parent) { + int lastIndexOfColon = childName.lastIndexOf(":"); + if (lastIndexOfColon != -1) { + String moduleName = childName.substring(0, lastIndexOfColon); + Iterator it = ctx.findModules(moduleName).iterator(); + if (!it.hasNext()) { + // module is not present in context + return null; + } + Module m = it.next(); + return new Namespace(moduleName, m.getQNameModule().getNamespace(), + getRevision(m.getRevision())); + } + Namespace parentNs = parent.namespace(); + return new Namespace(parentNs.moduleName(), parentNs.moduleNs(), + parentNs.revision()); + } + + /** + * Returns child schema node. + * + * @param curSchema current schema node + * @param name name of the property + * @param namespace namespace of the property + * @return child schema node + */ + public static SchemaNode getChildSchemaNode(SchemaNode curSchema, + String name, + Namespace namespace) { + if (namespace == null) { + return null; + } + + QName qname = QName.create(namespace.moduleNs(), + Revision.of(namespace.revision()), name); + + // YANG RPC will not be instance of DataSchemaNode + if (curSchema instanceof DataSchemaNode) { + Deque schemaNodeDeque = ParserStreamUtils. + findSchemaNodeByNameAndNamespace(((DataSchemaNode) + curSchema), name, namespace.moduleNs()); + if (schemaNodeDeque.isEmpty()) { + // could not find schema node + return null; + } + + DataSchemaNode schemaNode = schemaNodeDeque.pop(); + if (schemaNodeDeque.isEmpty()){ + // Simple node + return schemaNode; + } + + // node is child of Choice/case + return SchemaUtils.findSchemaForChild(((ChoiceSchemaNode) schemaNode), + qname); + } else { + return SchemaUtils.findDataChildSchemaByQName(curSchema, qname); + } + } + + /** + * Returns the property node type. + * + * @param index current index + * @param length length of the properties + * @param name name of the property + * @return the property node type + */ + public static NodeType getNodeType(int index, int length, String name) { + if (index == length-1) { + return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE : + NodeType.SINGLE_INSTANCE_LEAF_NODE); + } else { + return (isListEntry(name) ? NodeType.MULTI_INSTANCE_NODE : + NodeType.SINGLE_INSTANCE_NODE); + } + } + + /** + * Returns revision in string. + * + * @param r YANG revision + * @return revision in string + */ + public static String getRevision(Optional r) { + return (r.isPresent()) ? r.get().toString() : null; + } +} diff --git a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java index 5cb8e4c9..0159683a 100644 --- a/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java +++ b/restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/yangserializers/pnserializer/RootNode.java @@ -21,10 +21,22 @@ package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer; import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import java.util.HashMap; import java.util.Map; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.addToAugmentations; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.createNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getAugmentationNode; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getUri; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.isNamespaceAsParent; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.resolveName; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_HOLDER_NODE; +import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.NodeType.MULTI_INSTANCE_LEAF_HOLDER_NODE; +import static org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils.findCorrespondingAugment; + /** * Abstraction of node representing properties data tree. */ @@ -59,8 +71,32 @@ public class RootNode extends PropertiesNode { public PropertiesNode addChild(String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + PropertiesNode node = ((PropertiesNode) children.get(name)); + if (node != null) { + return node; + } + + // get augment schema, if it is augmented node + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, name); + } + + // create node based on type, this api will be invoked only for these three types + if (node == null) { + String uri = getUri(this, name, namespace); + node = createNode(name, namespace, uri, this, appInfo, type); + } + + // If namespace is not same as parent then it is augmented node + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override @@ -68,16 +104,63 @@ public class RootNode extends PropertiesNode { NodeType type, String value, Namespace valuens, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + LeafNode node = ((LeafNode) children.get(name)); + if (node != null) { + return node; + } + + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + } + + String uri = getUri(this, name, namespace); + node = new LeafNode(name, namespace, uri, this, + appInfo, type, value); + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(name, ((T) node)); + } + return node; } @Override public PropertiesNode addChild(String index, String name, Namespace namespace, NodeType type, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localname = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localname)); + if (node == null) { + String uri = getUri(this, name, namespace); + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localname); + } + + if (node == null) { + node = new ListHolderNode(localname, namespace, uri, + this, appInfo, MULTI_INSTANCE_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localname, ((T) node)); + } + node = node.addChild(index, localname, namespace, type, appInfo); + } else if (node instanceof ListHolderNode) { + ListHolderChild child = ((ListHolderNode) node).child(index); + node = (child != null ? ((MultiInstanceNode) child) : + node.addChild(index, localname, namespace, type, appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } @Override @@ -85,7 +168,37 @@ public class RootNode extends PropertiesNode { Namespace namespace, NodeType type, String value, Namespace valueNs, Object appInfo) throws SvcLogicException { - // TODO : to be implemented - return null; + String localName = resolveName(name); + PropertiesNode node = ((PropertiesNode) children.get(localName)); + if (node == null) { + String uri = getUri(this, name, namespace); + AugmentationSchemaNode augSchema = null; + if (((DataSchemaNode) appInfo).isAugmenting()) { + augSchema = findCorrespondingAugment(((DataSchemaNode) this.appInfo()), + ((DataSchemaNode) appInfo)); + node = getAugmentationNode(augSchema, this, localName); + } + + if (node == null) { + node = new LeafListHolderNode(localName, namespace, uri, this, + appInfo, MULTI_INSTANCE_LEAF_HOLDER_NODE); + } + + if (augSchema != null && !isNamespaceAsParent(this, node)) { + addToAugmentations(augSchema, this, node); + } else { + children.put(localName, ((T) node)); + } + node = node.addChild(index, localName, namespace, type, value, null, appInfo); + } else if (node instanceof LeafListHolderNode) { + LeafNode child = ((LeafNode) ((HolderNode) node).child(index)); + node = (child != null ? child : node.addChild(index, localName, + namespace, type, + value, null, + appInfo)); + } else { + throw new SvcLogicException("Duplicate node exist with same node"); + } + return node; } } -- 2.16.6