blob: 614c260dda24b7efbc999c0f01a72407e3b160c8 [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 saraswalb1170bd2016-07-14 13:26:18 +053019import org.onosproject.yangutils.datamodel.YangAugment;
20import org.onosproject.yangutils.datamodel.YangAugmentableNode;
21import org.onosproject.yangutils.datamodel.YangAugmentedInfo;
janani b23ccc312016-07-14 19:35:22 +053022import org.onosproject.yangutils.datamodel.YangCase;
Bharat saraswalb551aae2016-07-14 15:18:20 +053023import org.onosproject.yangutils.datamodel.YangChoice;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053024import org.onosproject.yangutils.datamodel.YangLeaf;
25import org.onosproject.yangutils.datamodel.YangLeafList;
janani b23ccc312016-07-14 19:35:22 +053026import org.onosproject.yangutils.datamodel.YangLeafRef;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053027import org.onosproject.yangutils.datamodel.YangLeavesHolder;
28import org.onosproject.yangutils.datamodel.YangNode;
janani b23ccc312016-07-14 19:35:22 +053029import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
30import org.onosproject.yangutils.datamodel.utils.YangConstructType;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053031import org.onosproject.yangutils.linker.exceptions.LinkerException;
32
janani b23ccc312016-07-14 19:35:22 +053033import java.util.ArrayList;
34import java.util.List;
35import java.util.regex.Pattern;
36
37import static org.onosproject.yangutils.utils.UtilConstants.COLON;
38import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
39import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
40
Bharat saraswalb1170bd2016-07-14 13:26:18 +053041/**
42 * Represent utilities for YANG linker.
43 */
44public final class YangLinkerUtils {
45
46 private YangLinkerUtils() {
47 }
48
janani b23ccc312016-07-14 19:35:22 +053049 private static final int IDENTIFIER_LENGTH = 64;
50 private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
51 private static final String XML = "xml";
52
Bharat saraswalb1170bd2016-07-14 13:26:18 +053053 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +053054 * 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 +053055 *
56 * @param targetNode target node
57 * @param augment augment node
58 */
59 private static void detectCollision(YangNode targetNode, YangAugment augment) {
60 YangNode targetNodesChild = targetNode.getChild();
61 YangNode augmentsChild = augment.getChild();
62 YangLeavesHolder augmentsLeavesHolder = augment;
Bharat saraswalb551aae2016-07-14 15:18:20 +053063 if (targetNode instanceof YangChoice) {
64 if (augmentsLeavesHolder.getListOfLeaf() != null
65 || augmentsLeavesHolder.getListOfLeafList() != null) {
66 throw new LinkerException("target node " + targetNode.getName()
67 + "is a instance of choice. it can " +
68 "only be augmented with leaf using a case node.");
69 }
70 } else {
71 YangLeavesHolder targetNodesLeavesHolder = (YangLeavesHolder) targetNode;
Bharat saraswalb1170bd2016-07-14 13:26:18 +053072
Bharat saraswalb551aae2016-07-14 15:18:20 +053073 YangNode parent = targetNode;
74 if (targetNode instanceof YangAugment) {
75 parent = targetNode.getParent();
76 } else {
77 while (parent.getParent() != null) {
78 parent = parent.getParent();
Bharat saraswalb1170bd2016-07-14 13:26:18 +053079 }
80 }
Bharat saraswalb551aae2016-07-14 15:18:20 +053081 if (augmentsLeavesHolder.getListOfLeaf() != null && augmentsLeavesHolder.getListOfLeaf().size() != 0
82 && targetNodesLeavesHolder.getListOfLeaf() != null) {
83 for (YangLeaf leaf : augmentsLeavesHolder.getListOfLeaf()) {
84 for (YangLeaf targetLeaf : targetNodesLeavesHolder.getListOfLeaf()) {
85 if (targetLeaf.getName().equals(leaf.getName())) {
86 throw new LinkerException("target node " + targetNode.getName()
87 + " contains augmented leaf " + leaf.getName() + " in module "
88 + parent.getName());
89 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +053090 }
91 }
Bharat saraswalb551aae2016-07-14 15:18:20 +053092 } else if (augmentsLeavesHolder.getListOfLeafList() != null
93 && augmentsLeavesHolder.getListOfLeafList().size() != 0
94 && targetNodesLeavesHolder.getListOfLeafList() != null) {
95 for (YangLeafList leafList : augmentsLeavesHolder.getListOfLeafList()) {
96 for (YangLeafList targetLeafList : targetNodesLeavesHolder.getListOfLeafList()) {
97 if (targetLeafList.getName().equals(leafList.getName())) {
98 throw new LinkerException("target node " + targetNode.getName()
99 + " contains augmented leaf-list" + leafList.getName() + " in module "
100 + parent.getName());
101 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530102 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530103 }
Bharat saraswalb551aae2016-07-14 15:18:20 +0530104 } else {
105 while (augmentsChild != null) {
106 while (targetNodesChild != null) {
107 if (targetNodesChild.getName().equals(augmentsChild.getName())) {
108 throw new LinkerException("target node " + targetNode.getName()
109 + " contains augmented child node" + augmentsChild.getName() + " in module "
110 + parent.getName());
111 }
112 targetNodesChild = targetNodesChild.getNextSibling();
113 }
114 augmentsChild = augmentsChild.getNextSibling();
115 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530116 }
117 }
118 }
119
120 /**
Bharat saraswalb551aae2016-07-14 15:18:20 +0530121 * Detects collision between target nodes and its all leaf/leaf-list or child node with augmented leaf/leaf-list or
122 * child node.
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530123 *
124 * @param targetNode target node
125 * @param augment augment node
126 */
127 public static void detectCollisionForAugmentedNode(YangNode targetNode, YangAugment augment) {
128 // Detect collision for target node and augment node.
129 detectCollision(targetNode, augment);
130 List<YangAugmentedInfo> yangAugmentedInfo = ((YangAugmentableNode) targetNode).getAugmentedInfoList();
131 // Detect collision for target augment node and current augment node.
132 for (YangAugmentedInfo info : yangAugmentedInfo) {
133 detectCollision((YangAugment) info, augment);
134 }
135 }
janani b23ccc312016-07-14 19:35:22 +0530136
137 /**
138 * Returns list of path names that are needed from augment.
139 *
140 * @param augment instance of YANG augment
141 * @param remainingAncestors ancestor count to move in augment path
142 * @return list of path names needed in leafref
143 */
144 public static List<String> getPathWithAugment(YangAugment augment, int remainingAncestors) {
145 String augmentName = augment.getName();
146 List<String> listOfPathName = new ArrayList<>();
147 if (augmentName.contains(SLASH_FOR_STRING)) {
148 String[] augmentNodeNames = augmentName.split(SLASH_FOR_STRING);
149 for (String valueInAugment : augmentNodeNames) {
150 if (valueInAugment != null && valueInAugment != EMPTY_STRING && !valueInAugment.isEmpty()) {
151 listOfPathName.add(valueInAugment);
152 }
153 }
154 }
155 for (int countOfAncestor = 0; countOfAncestor < remainingAncestors; countOfAncestor++) {
156 listOfPathName.remove(listOfPathName.size() - 1);
157 }
158 return listOfPathName;
159 }
160
161 /**
162 * Skips the invalid nodes which cannot have data from YANG.
163 *
164 * @param currentParent current parent node reference
165 * @param leafref instance of YANG leafref
166 * @return parent node which can hold data
167 * @throws LinkerException a violation of linker rules
168 */
169 public static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref) throws LinkerException {
170 while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
171 if (currentParent.getParent() == null) {
172 throw new LinkerException("YANG file error: The target node, in the leafref path " +
173 leafref.getPath() + ", is invalid.");
174 }
175 currentParent = currentParent.getParent();
176 }
177 return currentParent;
178 }
179
180 /**
181 * Checks and return valid node identifier.
182 *
183 * @param nodeIdentifierString string from yang file
184 * @param yangConstruct yang construct for creating error message
185 * @return valid node identifier
186 */
187 public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
188 YangConstructType yangConstruct) {
189 String[] tmpData = nodeIdentifierString.split(Pattern.quote(COLON));
190 if (tmpData.length == 1) {
191 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
192 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct));
193 return nodeIdentifier;
194 } else if (tmpData.length == 2) {
195 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
196 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct));
197 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct));
198 return nodeIdentifier;
199 } else {
200 throw new LinkerException("YANG file error : " +
201 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
202 " is not valid.");
203 }
204 }
205
206 /**
207 * Validates identifier and returns concatenated string if string contains plus symbol.
208 *
209 * @param identifier string from yang file
210 * @param yangConstruct yang construct for creating error message=
211 * @return concatenated string after removing double quotes
212 */
213 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct) {
214
215 if (identifier.length() > IDENTIFIER_LENGTH) {
216 throw new LinkerException("YANG file error : " +
217 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is " +
218 "greater than 64 characters.");
219 } else if (!IDENTIFIER_PATTERN.matcher(identifier).matches()) {
220 throw new LinkerException("YANG file error : " +
221 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifier + " is not " +
222 "valid.");
223 } else if (identifier.toLowerCase().startsWith(XML)) {
224 throw new LinkerException("YANG file error : " +
225 YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifier +
226 " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
227 } else {
228 return identifier;
229 }
230 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530231}