Vinod Kumar S
Committed by Gerrit Code Review

YANG uses Intra file linking

Change-Id: I45936bee910ba4c81805f59daf2702bea5e60d08
......@@ -16,6 +16,8 @@
package org.onosproject.yangutils.datamodel;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
/**
* Abstraction of YANG resolvable information. Abstracted to obtain the
* information required for linking resolution.
......@@ -44,6 +46,9 @@ public interface Resolvable {
/**
* Resolves the linking.
*
* @throws DataModelException data model error
*/
void resolve();
void resolve()
throws DataModelException;
}
......
......@@ -16,11 +16,17 @@
package org.onosproject.yangutils.datamodel;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.translator.tojava.TraversalType;
import static org.onosproject.yangutils.translator.tojava.TraversalType.CHILD;
import static org.onosproject.yangutils.translator.tojava.TraversalType.PARENT;
import static org.onosproject.yangutils.translator.tojava.TraversalType.SIBILING;
/**
* Represents base class of a node in data model tree.
*/
public abstract class YangNode {
public abstract class YangNode
implements Cloneable {
/**
* Type of node.
......@@ -146,7 +152,7 @@ public abstract class YangNode {
*
* @param sibling YANG node
*/
public void setNextSibling(YangNode sibling) {
private void setNextSibling(YangNode sibling) {
nextSibling = sibling;
}
......@@ -164,7 +170,7 @@ public abstract class YangNode {
*
* @param previousSibling points to predecessor sibling
*/
public void setPreviousSibling(YangNode previousSibling) {
private void setPreviousSibling(YangNode previousSibling) {
this.previousSibling = previousSibling;
}
......@@ -175,7 +181,8 @@ public abstract class YangNode {
* @param newChild refers to a child to be added
* @throws DataModelException due to violation in data model rules
*/
public void addChild(YangNode newChild) throws DataModelException {
public void addChild(YangNode newChild)
throws DataModelException {
if (newChild.getNodeType() == null) {
throw new DataModelException("Abstract node cannot be inserted into a tree");
}
......@@ -207,24 +214,10 @@ public abstract class YangNode {
YangNode curNode;
curNode = getChild();
/*-
* If the new node needs to be the first child
if (newChild.getNodeType().ordinal() < curNode.getNodeType().ordinal()) {
newChild.setNextSibling(curNode);
curNode.setPreviousSibling(newChild);
setChild(newChild);
return;
}
*/
/*
* Get the predecessor child of new child
*/
while (curNode.getNextSibling() != null
/*
* && newChild.getNodeType().ordinal() >=
* curNode.getNextSibling().getNodeType().ordinal()
*/) {
while (curNode.getNextSibling() != null) {
curNode = curNode.getNextSibling();
}
......@@ -233,16 +226,143 @@ public abstract class YangNode {
if (curNode.getNextSibling() == null) {
curNode.setNextSibling(newChild);
newChild.setPreviousSibling(curNode);
}
}
/**
* Clone the current node contents and create a new node.
*
* @return cloned node
* @throws CloneNotSupportedException clone is not supported by the referred node
*/
public YangNode clone()
throws CloneNotSupportedException {
YangNode clonedNode = (YangNode) super.clone();
clonedNode.setParent(null);
clonedNode.setChild(null);
clonedNode.setNextSibling(null);
clonedNode.setPreviousSibling(null);
return clonedNode;
}
/**
* Clone the subtree from the specified source node to the mentioned target node.
* The source and target root node cloning is carried out by the caller.
*
* @param srcRootNode source node for sub tree cloning
* @param dstRootNode destination node where the sub tree needs to be cloned
* @throws DataModelException data model error
*/
public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode)
throws DataModelException {
YangNode nextNodeToClone = srcRootNode;
TraversalType curTraversal;
YangNode clonedTreeCurNode = dstRootNode;
YangNode newNode = null;
nextNodeToClone = nextNodeToClone.getChild();
if (nextNodeToClone == null) {
return;
} else {
/**
* Root level cloning is taken care in the caller.
*/
curTraversal = CHILD;
}
/*-
* Insert the new node in child node list sorted by type
newChild.setNextSibling(curNode.getNextSibling());
newChild.setPreviousSibling(curNode);
curNode.getNextSibling().setPreviousSibling(newChild);
curNode.setNextSibling(newChild);
return;
/**
* Caller ensures the cloning of the root nodes
*/
try {
while (nextNodeToClone != srcRootNode) {
if (nextNodeToClone == null) {
throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
}
if (curTraversal == CHILD) {
newNode = nextNodeToClone.clone();
/**
* add the new node to the cloned tree.
*/
clonedTreeCurNode.addChild(newNode);
/**
* update the cloned tree's travesal current node as the new node.
*/
clonedTreeCurNode = newNode;
} else if (curTraversal == SIBILING) {
newNode = nextNodeToClone.clone();
clonedTreeCurNode.addNextSibling(newNode);
clonedTreeCurNode = newNode;
} else if (curTraversal == PARENT) {
clonedTreeCurNode = clonedTreeCurNode.getParent();
}
if (curTraversal != PARENT && nextNodeToClone.getChild() != null) {
curTraversal = CHILD;
/**
* update the traversal's current node.
*/
nextNodeToClone = nextNodeToClone.getChild();
} else if (nextNodeToClone.getNextSibling() != null) {
curTraversal = SIBILING;
nextNodeToClone = nextNodeToClone.getNextSibling();
} else {
curTraversal = PARENT;
nextNodeToClone = nextNodeToClone.getParent();
}
}
} catch (CloneNotSupportedException e) {
throw new DataModelException("Failed to clone the tree");
}
}
/**
* Add a new next sibling.
*
* @param newSibling new sibling to be added
* @throws DataModelException data model error
*/
private void addNextSibling(YangNode newSibling)
throws DataModelException {
if (newSibling.getNodeType() == null) {
throw new DataModelException("Cloned abstract node cannot be inserted into a tree");
}
if (newSibling.getParent() == null) {
/**
* Since the siblings needs to have a common parent, set the parent as the current node's parent
*/
newSibling.setParent(this.getParent());
} else {
throw new DataModelException("Node is already part of a tree, and cannot be added as a sibling");
}
if (newSibling.getPreviousSibling() == null) {
newSibling.setPreviousSibling(this);
setNextSibling(newSibling);
} else {
throw new DataModelException("New sibling to be added is not atomic, it already has a previous sibling");
}
if (newSibling.getChild() != null) {
throw new DataModelException("Sibling to be added is not atomic, it already has a child");
}
if (newSibling.getNextSibling() != null) {
throw new DataModelException("Sibling to be added is not atomic, it already has a next sibling");
}
}
}
......
......@@ -190,7 +190,8 @@ public class YangResolutionInfo<T> {
/**
* Resolve the current entity in the stack.
*/
private void resolveTopOfStack() {
private void resolveTopOfStack()
throws DataModelException {
((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus()
......
......@@ -19,6 +19,8 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getParentNodeInGenCode;
/*-
* Reference RFC 6020.
*
......@@ -255,8 +257,33 @@ public class YangUses
}
@Override
public void resolve() {
//TODO: implement the method.
public void resolve()
throws DataModelException {
YangGrouping referredGrouping = getRefGroup();
if (referredGrouping == null) {
throw new DataModelException("YANG uses linker error, cannot resolve uses");
}
YangNode usesParentNode = getParentNodeInGenCode(this);
if (!(usesParentNode instanceof YangLeavesHolder)) {
throw new DataModelException("YANG uses holder construct is wrong");
}
YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
if (referredGrouping.getListOfLeaf() != null) {
for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
usesParentLeavesHolder.addLeaf(leaf);
}
}
if (referredGrouping.getListOfLeafList() != null) {
for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
usesParentLeavesHolder.addLeafList(leafList);
}
}
YangNode.cloneSubTree(getRefGroup(), usesParentNode);
}
@Override
......
......@@ -19,6 +19,7 @@ package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
......@@ -37,8 +38,10 @@ import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.get
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
.constructExtendedListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
......@@ -134,7 +137,8 @@ public final class ContainerListener {
|| curData instanceof YangList || curData instanceof YangCase
|| curData instanceof YangNotification
|| curData instanceof YangInput || curData instanceof YangOutput
|| curData instanceof YangAugment) {
|| curData instanceof YangAugment
|| curData instanceof YangGrouping) {
YangNode curNode = (YangNode) curData;
try {
curNode.addChild(container);
......@@ -190,6 +194,6 @@ public final class ContainerListener {
ctx.identifier().getText());
validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, CONTAINER_DATA, ctx.identifier().getText());
validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, CONTAINER_DATA, ctx.identifier().getText());
// TODO when, grouping, typedef.
// TODO validate 'when' cardinality
}
}
......