blob: c9fedd84dc0a6c366b67053b42b0852d6406f908 [file] [log] [blame]
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.linker.impl;
18
Bharat saraswald50c6382016-07-14 21:57:13 +053019import java.util.ArrayList;
20import java.util.Iterator;
21import java.util.List;
22import java.util.Set;
23import java.util.regex.Pattern;
24
Bharat saraswal2d90b0c2016-08-04 02:00:03 +053025import org.onosproject.yangutils.datamodel.YangAtomicPath;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053026import org.onosproject.yangutils.datamodel.YangAugment;
27import org.onosproject.yangutils.datamodel.YangAugmentableNode;
28import org.onosproject.yangutils.datamodel.YangAugmentedInfo;
janani b23ccc312016-07-14 19:35:22 +053029import org.onosproject.yangutils.datamodel.YangCase;
Bharat saraswalb551aae2016-07-14 15:18:20 +053030import org.onosproject.yangutils.datamodel.YangChoice;
Bharat saraswald50c6382016-07-14 21:57:13 +053031import org.onosproject.yangutils.datamodel.YangImport;
32import org.onosproject.yangutils.datamodel.YangInclude;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053033import org.onosproject.yangutils.datamodel.YangLeaf;
34import org.onosproject.yangutils.datamodel.YangLeafList;
janani b23ccc312016-07-14 19:35:22 +053035import org.onosproject.yangutils.datamodel.YangLeafRef;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053036import org.onosproject.yangutils.datamodel.YangLeavesHolder;
37import org.onosproject.yangutils.datamodel.YangNode;
janani b23ccc312016-07-14 19:35:22 +053038import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Bharat saraswald50c6382016-07-14 21:57:13 +053039import org.onosproject.yangutils.datamodel.YangReferenceResolver;
janani b23ccc312016-07-14 19:35:22 +053040import org.onosproject.yangutils.datamodel.utils.YangConstructType;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053041import org.onosproject.yangutils.linker.exceptions.LinkerException;
42
janani b23ccc312016-07-14 19:35:22 +053043import static org.onosproject.yangutils.utils.UtilConstants.COLON;
44import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
janani b23ccc312016-07-14 19:35:22 +053045
Bharat saraswalb1170bd2016-07-14 13:26:18 +053046/**
47 * Represent utilities for YANG linker.
48 */
49public final class YangLinkerUtils {
50
janani b23ccc312016-07-14 19:35:22 +053051 private static final int IDENTIFIER_LENGTH = 64;
52 private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
53 private static final String XML = "xml";
54
Bharat saraswald50c6382016-07-14 21:57:13 +053055 private YangLinkerUtils() {
56 }
57
Bharat saraswalb1170bd2016-07-14 13:26:18 +053058 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +053059 * Detects collision between target nodes leaf/leaf-list or child node with augmented leaf/leaf-list or child node.
Bharat saraswalb1170bd2016-07-14 13:26:18 +053060 *
61 * @param targetNode target node
62 * @param augment augment node
63 */
64 private static void detectCollision(YangNode targetNode, YangAugment augment) {
65 YangNode targetNodesChild = targetNode.getChild();
66 YangNode augmentsChild = augment.getChild();
Bharat saraswald50c6382016-07-14 21:57:13 +053067 YangNode parent = targetNode;
68 if (targetNode instanceof YangAugment) {
69 parent = targetNode.getParent();
Bharat saraswalb551aae2016-07-14 15:18:20 +053070 } else {
Bharat saraswald50c6382016-07-14 21:57:13 +053071 while (parent.getParent() != null) {
72 parent = parent.getParent();
73 }
74 }
75 if (targetNode instanceof YangChoice) {
Bharat saraswal2d90b0c2016-08-04 02:00:03 +053076 //Do nothing
Bharat saraswald50c6382016-07-14 21:57:13 +053077 } else {
78 detectCollisionInLeaveHolders(targetNode, augment);
79 while (augmentsChild != null) {
80 detectCollisionInChildNodes(targetNodesChild, augmentsChild, targetNode.getName(), parent.getName());
81 augmentsChild = augmentsChild.getNextSibling();
82 }
83 }
84 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +053085
Bharat saraswal2d90b0c2016-08-04 02:00:03 +053086 /*Detects collision between leaves/leaf-lists*/
Bharat saraswald50c6382016-07-14 21:57:13 +053087 private static void detectCollisionInLeaveHolders(YangNode targetNode, YangAugment augment) {
88 YangLeavesHolder targetNodesLeavesHolder = (YangLeavesHolder) targetNode;
89 YangNode parent = targetNode;
90 if (targetNode instanceof YangAugment) {
91 parent = targetNode.getParent();
92 } else {
93 while (parent.getParent() != null) {
94 parent = parent.getParent();
95 }
96 }
97 if (augment.getListOfLeaf() != null && augment.getListOfLeaf().size() != 0
98 && targetNodesLeavesHolder.getListOfLeaf() != null) {
99 for (YangLeaf leaf : augment.getListOfLeaf()) {
100 for (YangLeaf targetLeaf : targetNodesLeavesHolder.getListOfLeaf()) {
101 if (targetLeaf.getName().equals(leaf.getName())) {
102 throw new LinkerException("target node " + targetNode.getName()
103 + " contains augmented leaf " + leaf.getName() + " in module "
104 + parent.getName());
105 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530106 }
107 }
Bharat saraswald50c6382016-07-14 21:57:13 +0530108 } else if (augment.getListOfLeafList() != null
109 && augment.getListOfLeafList().size() != 0
110 && augment.getListOfLeafList() != null) {
111 for (YangLeafList leafList : augment.getListOfLeafList()) {
112 for (YangLeafList targetLeafList : targetNodesLeavesHolder.getListOfLeafList()) {
113 if (targetLeafList.getName().equals(leafList.getName())) {
114 throw new LinkerException("target node " + targetNode.getName()
115 + " contains augmented leaf-list" + leafList.getName() + " in module "
116 + parent.getName());
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530117 }
118 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530119 }
120 }
121 }
122
Bharat saraswald50c6382016-07-14 21:57:13 +0530123 /*Detects collision for child nodes.*/
124 private static void detectCollisionInChildNodes(YangNode targetNodesChild, YangNode augmentsChild, String
125 targetName, String parentName) {
126 while (augmentsChild != null) {
127 while (targetNodesChild != null) {
128 if (targetNodesChild.getName().equals(augmentsChild.getName())) {
129 throw new LinkerException("target node " + targetName
130 + " contains augmented child node" + augmentsChild.getName() + " in module "
131 + parentName);
132 }
133 targetNodesChild = targetNodesChild.getNextSibling();
134 }
135 augmentsChild = augmentsChild.getNextSibling();
136 }
137 }
138
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530139 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +0530140 * Detects collision between target nodes and its all leaf/leaf-list or child node with augmented leaf/leaf-list or
141 * child node.
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530142 *
143 * @param targetNode target node
144 * @param augment augment node
145 */
Bharat saraswald50c6382016-07-14 21:57:13 +0530146 static void detectCollisionForAugmentedNode(YangNode targetNode, YangAugment augment) {
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530147 // Detect collision for target node and augment node.
148 detectCollision(targetNode, augment);
149 List<YangAugmentedInfo> yangAugmentedInfo = ((YangAugmentableNode) targetNode).getAugmentedInfoList();
150 // Detect collision for target augment node and current augment node.
151 for (YangAugmentedInfo info : yangAugmentedInfo) {
152 detectCollision((YangAugment) info, augment);
153 }
154 }
janani b23ccc312016-07-14 19:35:22 +0530155
156 /**
157 * Returns list of path names that are needed from augment.
158 *
159 * @param augment instance of YANG augment
160 * @param remainingAncestors ancestor count to move in augment path
161 * @return list of path names needed in leafref
162 */
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530163 static List<String> getPathWithAugment(YangAugment augment, int remainingAncestors) {
janani b23ccc312016-07-14 19:35:22 +0530164 List<String> listOfPathName = new ArrayList<>();
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530165 for (YangAtomicPath atomicPath : augment.getTargetNode()) {
166 if (atomicPath.getNodeIdentifier().getPrefix() != null && !atomicPath.getNodeIdentifier().getPrefix()
167 .equals(EMPTY_STRING)) {
168 listOfPathName.add(atomicPath.getNodeIdentifier().getPrefix() + ":" +
169 atomicPath.getNodeIdentifier().getName());
170 } else {
171 listOfPathName.add(atomicPath.getNodeIdentifier().getName());
janani b23ccc312016-07-14 19:35:22 +0530172 }
173 }
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530174
175
janani b23ccc312016-07-14 19:35:22 +0530176 for (int countOfAncestor = 0; countOfAncestor < remainingAncestors; countOfAncestor++) {
177 listOfPathName.remove(listOfPathName.size() - 1);
178 }
179 return listOfPathName;
180 }
181
182 /**
183 * Skips the invalid nodes which cannot have data from YANG.
184 *
185 * @param currentParent current parent node reference
186 * @param leafref instance of YANG leafref
187 * @return parent node which can hold data
188 * @throws LinkerException a violation of linker rules
189 */
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530190 static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref) throws LinkerException {
janani b23ccc312016-07-14 19:35:22 +0530191 while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
192 if (currentParent.getParent() == null) {
193 throw new LinkerException("YANG file error: The target node, in the leafref path " +
194 leafref.getPath() + ", is invalid.");
195 }
196 currentParent = currentParent.getParent();
197 }
198 return currentParent;
199 }
200
201 /**
202 * Checks and return valid node identifier.
203 *
204 * @param nodeIdentifierString string from yang file
205 * @param yangConstruct yang construct for creating error message
206 * @return valid node identifier
207 */
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530208 static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
209 YangConstructType yangConstruct) {
janani b23ccc312016-07-14 19:35:22 +0530210 String[] tmpData = nodeIdentifierString.split(Pattern.quote(COLON));
211 if (tmpData.length == 1) {
212 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
213 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct));
214 return nodeIdentifier;
215 } else if (tmpData.length == 2) {
216 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
217 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct));
218 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct));
219 return nodeIdentifier;
220 } else {
221 throw new LinkerException("YANG file error : " +
222 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
223 " is not valid.");
224 }
225 }
226
227 /**
228 * Validates identifier and returns concatenated string if string contains plus symbol.
229 *
230 * @param identifier string from yang file
231 * @param yangConstruct yang construct for creating error message=
232 * @return concatenated string after removing double quotes
233 */
234 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct) {
235
236 if (identifier.length() > IDENTIFIER_LENGTH) {
237 throw new LinkerException("YANG file error : " +
238 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is " +
239 "greater than 64 characters.");
240 } else if (!IDENTIFIER_PATTERN.matcher(identifier).matches()) {
241 throw new LinkerException("YANG file error : " +
242 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is not " +
243 "valid.");
244 } else if (identifier.toLowerCase().startsWith(XML)) {
245 throw new LinkerException("YANG file error : " +
246 YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifier +
247 " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
248 } else {
249 return identifier;
250 }
251 }
Bharat saraswald50c6382016-07-14 21:57:13 +0530252
253 /**
254 * Updates the priority for all the input files.
255 *
256 * @param yangNodeSet set of YANG files info
257 */
258 public static void updateFilePriority(Set<YangNode> yangNodeSet) {
259 for (YangNode yangNode : yangNodeSet) {
260 updateFilePriorityOfNode(yangNode);
261 }
262 }
263
264 /**
265 * Updates priority of the node.
266 *
267 * @param yangNode YANG node information
268 */
Bharat saraswal2d90b0c2016-08-04 02:00:03 +0530269 private static void updateFilePriorityOfNode(YangNode yangNode) {
Bharat saraswald50c6382016-07-14 21:57:13 +0530270 int curNodePriority = yangNode.getPriority();
271 if (yangNode instanceof YangReferenceResolver) {
272 List<YangImport> yangImportList = ((YangReferenceResolver) yangNode).getImportList();
273 Iterator<YangImport> importInfoIterator = yangImportList.iterator();
274 // Run through the imported list to update priority.
275 while (importInfoIterator.hasNext()) {
276 YangImport yangImport = importInfoIterator.next();
277 YangNode importedNode = yangImport.getImportedNode();
278 if (curNodePriority >= importedNode.getPriority()) {
279 importedNode.setPriority(curNodePriority + 1);
280 updateFilePriorityOfNode(importedNode);
281 }
282 }
283
284 List<YangInclude> yangIncludeList = ((YangReferenceResolver) yangNode).getIncludeList();
285 Iterator<YangInclude> includeInfoIterator = yangIncludeList.iterator();
286 // Run through the imported list to update priority.
287 while (includeInfoIterator.hasNext()) {
288 YangInclude yangInclude = includeInfoIterator.next();
289 YangNode includedNode = yangInclude.getIncludedNode();
290 if (curNodePriority >= includedNode.getPriority()) {
291 includedNode.setPriority(curNodePriority + 1);
292 updateFilePriorityOfNode(includedNode);
293 }
294 }
295 }
296 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530297}