[ONOS-4842] Leafref implementation for augment and uses
Change-Id: I919553a64d683aff65a8f16e2de783702dd5a45f
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
index 571873b..c4091a9 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/Resolvable.java
@@ -22,8 +22,10 @@
/**
* Abstraction of YANG resolvable information. Abstracted to obtain the
* information required for linking resolution.
+ *
+ * @param <T> YANG resolvable info
*/
-public interface Resolvable {
+public interface Resolvable<T> {
/**
* Returns the status of resolution. If completely resolved returns enum
@@ -48,8 +50,9 @@
/**
* Resolves the linking.
*
+ * @return list of entities to be added for resolution
* @throws DataModelException data model exception
*/
- void resolve()
+ T resolve()
throws DataModelException;
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
index 6d475cb..21c7bd3 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangAugment.java
@@ -442,8 +442,9 @@
}
@Override
- public void resolve() throws DataModelException {
+ public Object resolve() throws DataModelException {
// Resolving of target node is being done in XPathLinker.
+ return null;
}
/**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
index 40c2293..8d118d2 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBase.java
@@ -109,6 +109,7 @@
}
@Override
- public void resolve() throws DataModelException {
+ public Object resolve() throws DataModelException {
+ return null;
}
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
index b7bdf08..7aa0d5d 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java
new file mode 100644
index 0000000..8fe6b22
--- /dev/null
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangEntityToResolveInfoImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.yangutils.datamodel;
+
+import java.io.Serializable;
+
+/**
+ * Represents implementation of information about entity being resolved.
+ *
+ * @param <T> type of entity being resolved, uses / grouping
+ */
+public class YangEntityToResolveInfoImpl<T> implements YangEntityToResolveInfo<T>, Serializable, LocationInfo {
+
+ private static final long serialVersionUID = 806201659L;
+
+ /**
+ * Parsable node for which resolution is to be performed.
+ */
+ private T entityToResolve;
+
+ /**
+ * Holder of the YANG construct for which resolution has to be carried out.
+ */
+ private YangNode holderOfEntityToResolve;
+
+ /**
+ * Error line number.
+ */
+ private transient int lineNumber;
+
+ /**
+ * Error character position in number.
+ */
+ private transient int charPositionInLine;
+
+ @Override
+ public T getEntityToResolve() {
+ return entityToResolve;
+ }
+
+ @Override
+ public void setEntityToResolve(T entityToResolve) {
+ this.entityToResolve = entityToResolve;
+ }
+
+ @Override
+ public YangNode getHolderOfEntityToResolve() {
+ return holderOfEntityToResolve;
+ }
+
+ @Override
+ public void setHolderOfEntityToResolve(YangNode holderOfEntityToResolve) {
+ this.holderOfEntityToResolve = holderOfEntityToResolve;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public int getCharPosition() {
+ return charPositionInLine;
+ }
+
+ @Override
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ @Override
+ public void setCharPosition(int charPositionInLine) {
+ this.charPositionInLine = charPositionInLine;
+ }
+}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
index d03fcf4..2019339 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIdentityRef.java
@@ -80,7 +80,7 @@
}
@Override
- public void resolve() throws DataModelException {
+ public Object resolve() throws DataModelException {
// Check if the derived info is present.
YangIdentity identity = getReferredIdentity();
@@ -92,10 +92,11 @@
while (identity.getBaseNode() != null) {
if (identity.getBaseNode().getResolvableStatus() != ResolvableStatus.RESOLVED) {
setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
- return;
+ return null;
}
identity = identity.getBaseNode().getReferredIdentity();
}
+ return null;
}
/**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
index a44fbdc..c2c8709 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangIfFeature.java
@@ -170,7 +170,7 @@
}
@Override
- public void resolve() throws DataModelException {
+ public Object resolve() throws DataModelException {
YangFeature feature = getReferredFeature();
// check whether feature has if-feature
@@ -181,9 +181,10 @@
YangIfFeature ifFeature = ifFeatureIterator.next();
if (ifFeature.getResolvableStatus() != ResolvableStatus.RESOLVED) {
setResolvableStatus(ResolvableStatus.INTRA_FILE_RESOLVED);
- return;
+ return null;
}
}
}
+ return null;
}
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
index 4973303..104d701 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
@@ -16,17 +16,18 @@
package org.onosproject.yangutils.datamodel;
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.YangErrMsgConstants.DATA_MISSING_ERROR_TAG;
@@ -47,7 +48,7 @@
* @param <T> YANG leafref info
*/
public class YangLeafRef<T> implements Parsable, Resolvable, Serializable, YangIfFeatureHolder,
- YangXPathResolver, YangAppErrorHolder {
+ YangXPathResolver, YangAppErrorHolder, LocationInfo {
private static final long serialVersionUID = 286201644L;
@@ -100,6 +101,61 @@
private List<YangIfFeature> ifFeatureList;
/**
+ * Parent node of the leafref's leaf.
+ */
+ private YangNode parentNodeOfLeafref;
+
+ /**
+ * Error line number.
+ */
+ private transient int lineNumber;
+
+ /**
+ * Error character position in number.
+ */
+ private transient int charPositionInLine;
+
+ /**
+ * Prefix in the nodes of the leafref path and its imported node name.
+ */
+ private Map<String, String> prefixAndItsImportedModule;
+
+ /**
+ * Returns the prefix in the leafref path and its imported node name.
+ *
+ * @return the list of leafref prefix and imported node name
+ */
+ public Map<String, String> getPrefixAndItsImportedModule() {
+ return prefixAndItsImportedModule;
+ }
+
+ /**
+ * Sets the prefix in the leafref path and its imported node name.
+ *
+ * @param prefixAndItsImportedModule the list of leafref prefix and imported node name
+ */
+ public void setPrefixAndItsImportedModule(Map<String, String> prefixAndItsImportedModule) {
+ this.prefixAndItsImportedModule = prefixAndItsImportedModule;
+ }
+
+ /**
+ * Returns the parent node from the leafref's leaf.
+ *
+ * @return parent node of the leafref
+ */
+ public YangNode getParentNodeOfLeafref() {
+ return parentNodeOfLeafref;
+ }
+
+ /**
+ * Sets the parent node from the leafref's leaf.
+ *
+ * @param parentNodeOfLeafref parent node of the leafref
+ */
+ public void setParentNodeOfLeafref(YangNode parentNodeOfLeafref) {
+ this.parentNodeOfLeafref = parentNodeOfLeafref;
+ }
+ /**
* YANG application error information.
*/
private YangAppErrorInfo yangAppErrorInfo;
@@ -294,7 +350,7 @@
}
@Override
- public void resolve() throws DataModelException {
+ public Object resolve() throws DataModelException {
if (getReferredLeafOrLeafList() == null) {
throw new DataModelException("Linker Error: The leafref does not refer to any leaf/leaf-list.");
@@ -306,6 +362,7 @@
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
+ return null;
}
/**
@@ -443,4 +500,24 @@
throw new DataModelException("Linker Error: The leafref must refer only to leaf/leaf-list.");
}
}
+
+ @Override
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ @Override
+ public int getCharPosition() {
+ return charPositionInLine;
+ }
+
+ @Override
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ @Override
+ public void setCharPosition(int charPositionInLine) {
+ this.charPositionInLine = charPositionInLine;
+ }
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
index d5eafb1..2b2426a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
@@ -16,15 +16,15 @@
package org.onosproject.yangutils.datamodel;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.Parsable;
import org.onosproject.yangutils.datamodel.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
/*
@@ -119,6 +119,26 @@
private List<String> keyList;
/**
+ * Reference RFC 6020.
+ *
+ * The "unique" statement is used to put constraints on valid list
+ * entries. It takes as an argument a string that contains a space-
+ * separated list of schema node identifiers, which MUST be given in the
+ * descendant form. Each such schema node identifier MUST refer to a leaf.
+ *
+ * If one of the referenced leafs represents configuration data, then
+ * all of the referenced leafs MUST represent configuration data.
+ *
+ * The "unique" constraint specifies that the combined values of all the
+ * leaf instances specified in the argument string, including leafs with
+ * default values, MUST be unique within all list entry instances in
+ * which all referenced leafs exist.
+ *
+ * List of unique leaf/leaf-list names
+ */
+ private List<String> uniqueList;
+
+ /**
* List of leaves.
*/
private List<YangLeaf> listOfLeaf;
@@ -271,6 +291,24 @@
}
/**
+ * Returns the list of unique field names.
+ *
+ * @return the list of unique field names
+ */
+ public List<String> getUniqueList() {
+ return uniqueList;
+ }
+
+ /**
+ * Sets the list of unique field names.
+ *
+ * @param uniqueList the list of unique field names
+ */
+ private void setUniqueList(List<String> uniqueList) {
+ this.uniqueList = uniqueList;
+ }
+
+ /**
* Returns the list of key field names.
*
* @return the list of key field names
@@ -309,6 +347,24 @@
}
/**
+ * Adds a unique field name.
+ *
+ * @param unique unique field name.
+ * @throws DataModelException a violation of data model rules
+ */
+ public void addUnique(String unique)
+ throws DataModelException {
+ if (getUniqueList() == null) {
+ setUniqueList(new LinkedList<>());
+ }
+ if (getUniqueList().contains(unique)) {
+ throw new DataModelException("A leaf identifier must not appear more than once in the\n" +
+ " unique");
+ }
+ getUniqueList().add(unique);
+ }
+
+ /**
* Returns the list of leaves.
*
* @return the list of leaves
@@ -489,11 +545,11 @@
validateConfig(leaves, leafLists);
/* A list must have atleast one key leaf if config is true */
- if (isConfig && (keys == null || leaves == null && leafLists == null) && !isUsesPresentInList()
+ if (isConfig && (keys == null || leaves == null) && !isUsesPresentInList()
&& !isListPresentInGrouping()) {
throw new DataModelException("A list must have atleast one key leaf if config is true;");
} else if (keys != null) {
- validateKey(leaves, leafLists, keys);
+ validateKey(leaves, keys);
}
}
@@ -501,7 +557,7 @@
* Sets the config's value to all leaf if leaf's config statement is not
* specified.
*
- * @param leaves list of leaf attributes of YANG list
+ * @param leaves list of leaf attributes of YANG list
* @param leafLists list of leaf-list attributes of YANG list
*/
private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
@@ -534,7 +590,7 @@
/**
* Validates config statement of YANG list.
*
- * @param leaves list of leaf attributes of YANG list
+ * @param leaves list of leaf attributes of YANG list
* @param leafLists list of leaf-list attributes of YANG list
* @throws DataModelException a violation of data model rules
*/
@@ -567,16 +623,15 @@
/**
* Validates key statement of list.
*
- * @param leaves list of leaf attributes of list
+ * @param leaves list of leaf attributes of list
* @param leafLists list of leaf-list attributes of list
- * @param keys list of key attributes of list
+ * @param keys list of key attributes of list
* @throws DataModelException a violation of data model rules
*/
- private void validateKey(List<YangLeaf> leaves, List<YangLeafList> leafLists, List<String> keys)
+ private void validateKey(List<YangLeaf> leaves, List<String> keys)
throws DataModelException {
boolean leafFound = false;
List<YangLeaf> keyLeaves = new LinkedList<>();
- List<YangLeafList> keyLeafLists = new LinkedList<>();
/*
* 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
@@ -597,20 +652,6 @@
}
}
- if (leafLists != null && !leafLists.isEmpty()) {
- for (YangLeafList leafList : leafLists) {
- if (key.equals(leafList.getName())) {
- if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
- throw new DataModelException(" A leaf-list that is part of the key" +
- " must not be the built-in type \"empty\".");
- }
- leafFound = true;
- keyLeafLists.add(leafList);
- break;
- }
- }
- }
-
if (!leafFound && !isUsesPresentInList() && !isListPresentInGrouping()) {
throw new DataModelException("An identifier, in key, must refer to a child leaf of the list");
}
@@ -627,17 +668,6 @@
" \"config\" as the list itself.");
}
}
-
- /*
- * All key leafs in a list MUST have the same value for their "config"
- * as the list itself.
- */
- for (YangLeafList keyLeafList : keyLeafLists) {
- if (isConfig() != keyLeafList.isConfig()) {
- throw new DataModelException("All key leaf-lists in a list must have the same value for their" +
- " \"config\" as the list itself.");
- }
- }
}
@Override
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
index be90e76..381a39a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -272,12 +272,12 @@
* @throws CloneNotSupportedException clone is not supported by the referred
* node
*/
- public YangNode clone()
+ public YangNode clone(YangUses yangUses)
throws CloneNotSupportedException {
YangNode clonedNode = (YangNode) super.clone();
if (clonedNode instanceof YangLeavesHolder) {
try {
- cloneLeaves((YangLeavesHolder) clonedNode);
+ cloneLeaves((YangLeavesHolder) clonedNode, yangUses);
} catch (DataModelException e) {
throw new CloneNotSupportedException(e.getMessage());
}
@@ -299,7 +299,7 @@
* @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)
+ public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode, YangUses yangUses)
throws DataModelException {
YangNode nextNodeToClone = srcRootNode;
@@ -327,7 +327,7 @@
throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
}
if (curTraversal != PARENT) {
- newNode = nextNodeToClone.clone();
+ newNode = nextNodeToClone.clone(yangUses);
detectCollisionWhileCloning(clonedTreeCurNode, newNode, curTraversal);
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
index c0ac20d..d49241e 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
@@ -239,7 +239,7 @@
}
@Override
- public void resolve()
+ public Object resolve()
throws DataModelException {
/*
* Check whether the data type is derived.
@@ -260,6 +260,7 @@
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
+ return null;
}
/**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
index 51cd310..5cd1e7a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangUses.java
@@ -26,6 +26,8 @@
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.getParentNodeInGenCode;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.updateClonedLeavesUnionEnumRef;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeaf;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.resolveLeafrefUnderGroupingForLeafList;
/*-
* Reference RFC 6020.
@@ -126,6 +128,16 @@
private List<List<YangLeafList>> resolvedGroupingLeafLists;
/**
+ * Effective list of leaf lists of grouping that needs to replicated at YANG uses.
+ */
+ private List<YangEntityToResolveInfoImpl> entityToResolveInfoList;
+
+ /**
+ * Current grouping depth for uses.
+ */
+ private int currentGroupingDepth;
+
+ /**
* Creates an YANG uses node.
*/
public YangUses() {
@@ -138,6 +150,38 @@
}
/**
+ * Returns the list of entity to resolve.
+ *
+ * @return the list of entity to resolve
+ */
+ public List<YangEntityToResolveInfoImpl> getEntityToResolveInfoList() {
+ return entityToResolveInfoList;
+ }
+
+ /**
+ * Sets the list of entity to resolve.
+ *
+ * @param entityToResolveInfoList the list of entity to resolve
+ */
+ public void setEntityToResolveInfoList(List<YangEntityToResolveInfoImpl> entityToResolveInfoList) {
+ this.entityToResolveInfoList = entityToResolveInfoList;
+ }
+
+ /**
+ * Adds an entity to resolve in list.
+ *
+ * @param entityToResolve entity to resolved
+ * @throws DataModelException a violation of data model rules
+ */
+ public void addEntityToResolve(YangEntityToResolveInfoImpl entityToResolve)
+ throws DataModelException {
+ if (getEntityToResolveInfoList() == null) {
+ setEntityToResolveInfoList(new LinkedList<YangEntityToResolveInfoImpl>());
+ }
+ getEntityToResolveInfoList().add(entityToResolve);
+ }
+
+ /**
* Returns the referred group.
*
* @return the referred group
@@ -314,7 +358,7 @@
}
@Override
- public void resolve()
+ public Object resolve()
throws DataModelException {
YangGrouping referredGrouping = getRefGroup();
@@ -337,7 +381,13 @@
((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leaf.getName(),
YangConstructType.LEAF_DATA);
clonedLeaf = leaf.clone();
-
+ if (getCurrentGroupingDepth() == 0) {
+ YangEntityToResolveInfoImpl resolveInfo = resolveLeafrefUnderGroupingForLeaf(clonedLeaf,
+ usesParentLeavesHolder, this);
+ if (resolveInfo != null) {
+ addEntityToResolve(resolveInfo);
+ }
+ }
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
@@ -353,7 +403,13 @@
((CollisionDetector) usesParentLeavesHolder).detectCollidingChild(leafList.getName(),
YangConstructType.LEAF_LIST_DATA);
clonedLeafList = leafList.clone();
-
+ if (getCurrentGroupingDepth() == 0) {
+ YangEntityToResolveInfoImpl resolveInfo =
+ resolveLeafrefUnderGroupingForLeafList(clonedLeafList, usesParentLeavesHolder);
+ if (resolveInfo != null) {
+ addEntityToResolve(resolveInfo);
+ }
+ }
} catch (CloneNotSupportedException | DataModelException e) {
throw new DataModelException(e.getMessage());
}
@@ -364,11 +420,12 @@
}
try {
- YangNode.cloneSubTree(referredGrouping, usesParentNode);
+ YangNode.cloneSubTree(referredGrouping, usesParentNode, this);
} catch (DataModelException e) {
throw new DataModelException(e.getMessage());
}
updateClonedLeavesUnionEnumRef(usesParentLeavesHolder);
+ return getEntityToResolveInfoList();
}
/**
@@ -378,7 +435,7 @@
* @param usesHolder holder of uses
*/
private void addResolvedUsesInfoOfGrouping(YangUses usesInGrouping,
- YangLeavesHolder usesHolder) throws DataModelException {
+ YangLeavesHolder usesHolder) throws DataModelException {
for (YangNode usesResolvedNode : usesInGrouping.getUsesResolvedNodeList()) {
addNodeOfGrouping(usesResolvedNode);
}
@@ -402,7 +459,7 @@
* @throws DataModelException a violation in data model rule
*/
private List<YangLeaf> cloneLeavesList(List<YangLeaf> listOfLeaves,
- YangLeavesHolder usesParentNode) throws DataModelException {
+ YangLeavesHolder usesParentNode) throws DataModelException {
if (listOfLeaves == null || listOfLeaves.size() == 0) {
throw new DataModelException("No leaves to clone");
}
@@ -433,7 +490,7 @@
* @return cloned list of leaf list
*/
private List<YangLeafList> cloneListOfLeafList(List<YangLeafList> listOfLeafList,
- YangLeavesHolder usesParentNode) throws DataModelException {
+ YangLeavesHolder usesParentNode) throws DataModelException {
if (listOfLeafList == null || listOfLeafList.size() == 0) {
throw new DataModelException("No leaf lists to clone");
}
@@ -556,4 +613,13 @@
public void setIfFeatureList(List<YangIfFeature> ifFeatureList) {
this.ifFeatureList = ifFeatureList;
}
+
+ public void setCurrentGroupingDepth(int currentGroupingDepth) {
+ this.currentGroupingDepth = currentGroupingDepth;
+ }
+
+ public int getCurrentGroupingDepth() {
+ return currentGroupingDepth;
+ }
+
}
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 64f2c78..503bebe 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -16,25 +16,21 @@
package org.onosproject.yangutils.datamodel.utils;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
import org.onosproject.yangutils.datamodel.CollisionDetector;
import org.onosproject.yangutils.datamodel.ResolvableType;
-import org.onosproject.yangutils.datamodel.YangIfFeature;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangBase;
+import org.onosproject.yangutils.datamodel.YangEntityToResolveInfoImpl;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.datamodel.YangIdentityRef;
+import org.onosproject.yangutils.datamodel.YangIfFeature;
+import org.onosproject.yangutils.datamodel.YangImport;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeafRef;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangReferenceResolver;
import org.onosproject.yangutils.datamodel.YangResolutionInfo;
@@ -45,6 +41,16 @@
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* Represents utilities for data model tree.
*/
@@ -206,7 +212,7 @@
* @throws DataModelException a violation of data model rules
*/
public static void resolveLinkingForResolutionList(List<YangResolutionInfo> resolutionList,
- YangReferenceResolver dataModelRootNode)
+ YangReferenceResolver dataModelRootNode)
throws DataModelException {
for (YangResolutionInfo resolutionInfo : resolutionList) {
@@ -222,7 +228,7 @@
* @throws DataModelException a violation of data model rules
*/
public static void linkInterFileReferences(List<YangResolutionInfo> resolutionList,
- YangReferenceResolver dataModelRootNode)
+ YangReferenceResolver dataModelRootNode)
throws DataModelException {
/*
* Run through the resolution list, find type/uses referring to inter
@@ -316,16 +322,24 @@
* Clones the list of leaves and list of leaf list in the leaves holder.
*
* @param leavesHolder YANG node potentially containing leaves or leaf lists
+ * @param yangUses instance of YANG uses
* @throws CloneNotSupportedException clone is not supported
* @throws DataModelException data model error
*/
- public static void cloneLeaves(YangLeavesHolder leavesHolder)
+ public static void cloneLeaves(YangLeavesHolder leavesHolder, YangUses yangUses)
throws CloneNotSupportedException, DataModelException {
List<YangLeaf> currentListOfLeaves = leavesHolder.getListOfLeaf();
if (currentListOfLeaves != null) {
List<YangLeaf> clonedLeavesList = new LinkedList<YangLeaf>();
for (YangLeaf leaf : currentListOfLeaves) {
YangLeaf clonedLeaf = leaf.clone();
+ if (yangUses.getCurrentGroupingDepth() == 0) {
+ YangEntityToResolveInfoImpl resolveInfo =
+ resolveLeafrefUnderGroupingForLeaf(clonedLeaf, leavesHolder, yangUses);
+ if (resolveInfo != null) {
+ yangUses.addEntityToResolve(resolveInfo);
+ }
+ }
clonedLeaf.setContainedIn(leavesHolder);
clonedLeavesList.add(clonedLeaf);
}
@@ -337,6 +351,13 @@
List<YangLeafList> clonedListOfLeafList = new LinkedList<YangLeafList>();
for (YangLeafList leafList : currentListOfLeafList) {
YangLeafList clonedLeafList = leafList.clone();
+ if (yangUses.getCurrentGroupingDepth() == 0) {
+ YangEntityToResolveInfoImpl resolveInfo =
+ resolveLeafrefUnderGroupingForLeafList(clonedLeafList, leavesHolder);
+ if (resolveInfo != null) {
+ yangUses.addEntityToResolve(resolveInfo);
+ }
+ }
clonedLeafList.setContainedIn(leavesHolder);
clonedListOfLeafList.add(clonedLeafList);
}
@@ -345,6 +366,112 @@
}
/**
+ * Resolves leafref in leaf, which are under grouping by adding it to the resolution list.
+ *
+ * @param clonedLeaf cloned leaf in uses from grouping
+ * @param leafParentHolder holder of the leaf from uses
+ * @return entity of leafref which has to be resolved
+ * @throws DataModelException data model error
+ */
+ public static YangEntityToResolveInfoImpl resolveLeafrefUnderGroupingForLeaf(YangLeaf clonedLeaf,
+ YangLeavesHolder leafParentHolder,
+ YangUses yangUses) throws
+ DataModelException {
+ if (clonedLeaf.getDataType().getDataTypeExtendedInfo() instanceof YangLeafRef) {
+ YangLeafRef leafrefForCloning = (YangLeafRef) clonedLeaf.getDataType().getDataTypeExtendedInfo();
+ // Conversion of prefixes in absolute path while cloning them.
+ convertThePrefixesDuringChange(leafrefForCloning, yangUses);
+ leafrefForCloning.setParentNodeOfLeafref((YangNode) leafParentHolder);
+ YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+ yangEntityToResolveInfo.setEntityToResolve(leafrefForCloning);
+ yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafParentHolder);
+ yangEntityToResolveInfo.setLineNumber(leafrefForCloning.getLineNumber());
+ yangEntityToResolveInfo.setCharPosition(leafrefForCloning.getCharPosition());
+ return yangEntityToResolveInfo;
+ }
+ return null;
+ }
+
+ /**
+ * Converts the prefixes in all the nodes of the leafref with respect to the uses node.
+ *
+ * @param leafrefForCloning leafref that is to be cloned
+ * @param yangUses instance of YANG uses where cloning is done
+ * @throws DataModelException data model error
+ */
+ private static void convertThePrefixesDuringChange(YangLeafRef leafrefForCloning, YangUses yangUses) throws
+ DataModelException {
+ List<YangAtomicPath> atomicPathList = leafrefForCloning.getAtomicPath();
+ if (atomicPathList != null && !atomicPathList.isEmpty()) {
+ Iterator<YangAtomicPath> atomicPathIterator = atomicPathList.listIterator();
+ while (atomicPathIterator.hasNext()) {
+ YangAtomicPath atomicPath = atomicPathIterator.next();
+ Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndItsImportedModule();
+ if (!prefixesAndItsImportNameNode.isEmpty() || prefixesAndItsImportNameNode != null) {
+ String prefixInPath = atomicPath.getNodeIdentifier().getPrefix();
+ String importedNodeName = prefixesAndItsImportNameNode.get(prefixInPath);
+ assignCurrentLeafrefWithNewPrefixes(importedNodeName, atomicPath, yangUses);
+ }
+ }
+ }
+ }
+
+ /**
+ * Assigns leafref with new prefixes while cloning.
+ *
+ * @param importedNodeName imported node name from grouping
+ * @param atomicPath atomic path in leafref
+ * @param node instance of YANG uses where cloning is done
+ * @throws DataModelException data model error
+ */
+ private static void assignCurrentLeafrefWithNewPrefixes(String importedNodeName, YangAtomicPath atomicPath,
+ YangNode node) throws DataModelException {
+ while (!(node instanceof YangReferenceResolver)) {
+ node = node.getParent();
+ if (node == null) {
+ throw new DataModelException("Internal datamodel error: Datamodel tree is not correct");
+ }
+ }
+ if (node instanceof YangModule) {
+ List<YangImport> importInUsesList = ((YangModule) node).getImportList();
+ if (importInUsesList != null && !importInUsesList.isEmpty()) {
+ Iterator<YangImport> importInUsesListIterator = importInUsesList.listIterator();
+ while (importInUsesListIterator.hasNext()) {
+ YangImport importInUsesNode = importInUsesListIterator.next();
+ if (importInUsesNode.getModuleName().equals(importedNodeName)) {
+ atomicPath.getNodeIdentifier().setPrefix(importInUsesNode.getPrefixId());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolves leafref in leaf-list, which are under grouping by adding it to the resolution list.
+ *
+ * @param clonedLeafList cloned leaf-list in uses from grouping
+ * @param leafListParentHolder holder of the leaf-list from uses
+ * @return entity of leafref which has to be resolved
+ * @throws DataModelException data model error
+ */
+ public static YangEntityToResolveInfoImpl resolveLeafrefUnderGroupingForLeafList(YangLeafList clonedLeafList,
+ YangLeavesHolder
+ leafListParentHolder)
+ throws DataModelException {
+ if (clonedLeafList.getDataType().getDataTypeExtendedInfo() instanceof YangLeafRef) {
+ YangLeafRef leafrefForCloning = (YangLeafRef) clonedLeafList.getDataType().getDataTypeExtendedInfo();
+ leafrefForCloning.setParentNodeOfLeafref((YangNode) leafListParentHolder);
+ YangEntityToResolveInfoImpl yangEntityToResolveInfo = new YangEntityToResolveInfoImpl();
+ yangEntityToResolveInfo.setEntityToResolve(leafrefForCloning);
+ yangEntityToResolveInfo.setHolderOfEntityToResolve((YangNode) leafListParentHolder);
+ yangEntityToResolveInfo.setLineNumber(leafrefForCloning.getLineNumber());
+ yangEntityToResolveInfo.setCharPosition(leafrefForCloning.getCharPosition());
+ return yangEntityToResolveInfo;
+ }
+ return null;
+ }
+
+ /**
* Clones the union or enum leaves. If there is any cloned leaves whose type is union/enum then the corresponding
* type info needs to be updated to the cloned new type node.
*