blob: aa38b87ffc97a667101ebd875c3f2bf24a4fda08 [file] [log] [blame]
Vidyashree Rama468f8282016-03-04 19:08:35 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Vidyashree Rama468f8282016-03-04 19:08:35 +05303 *
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.parser.impl.parserutils;
18
janani b23ccc312016-07-14 19:35:22 +053019import org.antlr.v4.runtime.ParserRuleContext;
20import org.onosproject.yangutils.datamodel.YangAtomicPath;
21import org.onosproject.yangutils.datamodel.YangImport;
22import org.onosproject.yangutils.datamodel.YangLeaf;
23import org.onosproject.yangutils.datamodel.YangLeafRef;
24import org.onosproject.yangutils.datamodel.YangLeavesHolder;
25import org.onosproject.yangutils.datamodel.YangList;
26import org.onosproject.yangutils.datamodel.YangModule;
27import org.onosproject.yangutils.datamodel.YangNode;
28import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
29import org.onosproject.yangutils.datamodel.YangPathPredicate;
30import org.onosproject.yangutils.datamodel.YangReferenceResolver;
31import org.onosproject.yangutils.datamodel.YangRelativePath;
32import org.onosproject.yangutils.datamodel.YangSubModule;
33import org.onosproject.yangutils.datamodel.utils.YangConstructType;
34import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
35import org.onosproject.yangutils.parser.exceptions.ParserException;
36
Vidyashree Rama468f8282016-03-04 19:08:35 +053037import java.text.ParseException;
38import java.text.SimpleDateFormat;
janani be18b5342016-07-13 21:06:41 +053039import java.util.ArrayList;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053040import java.util.Date;
janani b23ccc312016-07-14 19:35:22 +053041import java.util.HashMap;
janani be18b5342016-07-13 21:06:41 +053042import java.util.Iterator;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053043import java.util.LinkedList;
44import java.util.List;
Vidyashree Rama468f8282016-03-04 19:08:35 +053045import java.util.regex.Pattern;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053046
janani be18b5342016-07-13 21:06:41 +053047import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
48import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
49import static org.onosproject.yangutils.datamodel.YangPathOperator.EQUALTO;
Vidyashree Rama1db15562016-05-17 16:16:15 +053050import static org.onosproject.yangutils.utils.UtilConstants.ADD;
janani be18b5342016-07-13 21:06:41 +053051import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR;
52import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR_IN_PATH;
Vidyashree Rama1db15562016-05-17 16:16:15 +053053import static org.onosproject.yangutils.utils.UtilConstants.CARET;
janani be18b5342016-07-13 21:06:41 +053054import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_CLOSE_SQUARE_BRACKET;
55import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_OPEN_SQUARE_BRACKET;
56import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_SLASH;
57import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_PARENTHESIS;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053058import static org.onosproject.yangutils.utils.UtilConstants.COLON;
janani be18b5342016-07-13 21:06:41 +053059import static org.onosproject.yangutils.utils.UtilConstants.CURRENT;
Vidyashree Rama1db15562016-05-17 16:16:15 +053060import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
Vidyashree Rama1db15562016-05-17 16:16:15 +053061import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
janani be18b5342016-07-13 21:06:41 +053062import static org.onosproject.yangutils.utils.UtilConstants.OPEN_SQUARE_BRACKET;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053063import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
64import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
janani be18b5342016-07-13 21:06:41 +053065import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
Vidyashree Ramadeac28b2016-06-20 15:12:43 +053066import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
67import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
Vidyashree Rama1db15562016-05-17 16:16:15 +053068
Vidyashree Rama468f8282016-03-04 19:08:35 +053069/**
Bharat saraswald9822e92016-04-05 15:13:44 +053070 * Represents an utility for listener.
Vidyashree Rama468f8282016-03-04 19:08:35 +053071 */
72public final class ListenerUtil {
Bharat saraswald9822e92016-04-05 15:13:44 +053073
Vidyashree Rama468f8282016-03-04 19:08:35 +053074 private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +053075 private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053076 private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
Vidyashree Rama1db15562016-05-17 16:16:15 +053077 private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
janani be18b5342016-07-13 21:06:41 +053078 private static final Pattern PATH_PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
Vidyashree Rama210c01d2016-05-20 16:29:25 +053079 private static final String XML = "xml";
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053080 private static final String ONE = "1";
Vidyashree Rama468f8282016-03-04 19:08:35 +053081 private static final int IDENTIFIER_LENGTH = 64;
janani bcc9ac302016-03-24 12:43:48 +053082 private static final String DATE_FORMAT = "yyyy-MM-dd";
Vidyashree Rama468f8282016-03-04 19:08:35 +053083
84 /**
85 * Creates a new listener util.
86 */
87 private ListenerUtil() {
88 }
89
90 /**
91 * Removes doubles quotes and concatenates if string has plus symbol.
92 *
93 * @param yangStringData string from yang file
94 * @return concatenated string after removing double quotes
95 */
96 public static String removeQuotesAndHandleConcat(String yangStringData) {
97
janani bcc9ac302016-03-24 12:43:48 +053098 yangStringData = yangStringData.replace("\"", EMPTY_STRING);
Vidyashree Rama1db15562016-05-17 16:16:15 +053099 String[] tmpData = yangStringData.split(Pattern.quote(ADD));
Vidyashree Rama468f8282016-03-04 19:08:35 +0530100 StringBuilder builder = new StringBuilder();
101 for (String yangString : tmpData) {
102 builder.append(yangString);
103 }
104 return builder.toString();
105 }
106
107 /**
108 * Validates identifier and returns concatenated string if string contains plus symbol.
109 *
janani b23ccc312016-07-14 19:35:22 +0530110 * @param identifier string from yang file
Vidyashree Rama468f8282016-03-04 19:08:35 +0530111 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530112 * @param ctx yang construct's context to get the line number and character position
Vidyashree Rama468f8282016-03-04 19:08:35 +0530113 * @return concatenated string after removing double quotes
114 */
115 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
116
117 String identifierString = removeQuotesAndHandleConcat(identifier);
118 ParserException parserException;
119
120 if (identifierString.length() > IDENTIFIER_LENGTH) {
121 parserException = new ParserException("YANG file error : " +
122 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is " +
123 "greater than 64 characters.");
124 } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
125 parserException = new ParserException("YANG file error : " +
126 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is not " +
127 "valid.");
Vidyashree Rama210c01d2016-05-20 16:29:25 +0530128 } else if (identifierString.toLowerCase().startsWith(XML)) {
129 parserException = new ParserException("YANG file error : " +
130 YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifierString +
131 " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
Vidyashree Rama468f8282016-03-04 19:08:35 +0530132 } else {
133 return identifierString;
134 }
135
136 parserException.setLine(ctx.getStart().getLine());
137 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
138 throw parserException;
139 }
140
141 /**
janani be18b5342016-07-13 21:06:41 +0530142 * Validates identifier and returns concatenated string if string contains plus symbol.
143 *
janani b23ccc312016-07-14 19:35:22 +0530144 * @param identifier string from yang file
janani be18b5342016-07-13 21:06:41 +0530145 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530146 * @param ctx yang construct's context to get the line number and character position
147 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530148 * @return concatenated string after removing double quotes
149 */
150 public static String getValidIdentifierForLeafref(String identifier, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530151 ParserRuleContext ctx, YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530152
153 String identifierString = removeQuotesAndHandleConcat(identifier);
154 ParserException parserException;
155
156 if (identifierString.length() > IDENTIFIER_LENGTH) {
157 parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
158 YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is " +
159 "greater than 64 characters.");
160 } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
161 parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
162 YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is not " +
163 "valid.");
164 } else if (identifierString.toLowerCase().startsWith(XML)) {
165 parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
166 YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
167 " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
168 } else {
169 return identifierString;
170 }
171
172 parserException.setLine(ctx.getStart().getLine());
173 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
174 throw parserException;
175 }
176
177 /**
Vidyashree Rama468f8282016-03-04 19:08:35 +0530178 * Validates the revision date.
179 *
180 * @param dateToValidate input revision date
181 * @return validation result, true for success, false for failure
182 */
183 public static boolean isDateValid(String dateToValidate) {
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +0530184 if (dateToValidate == null || !dateToValidate.matches(DATE_PATTERN)) {
Vidyashree Rama468f8282016-03-04 19:08:35 +0530185 return false;
186 }
187
janani bcc9ac302016-03-24 12:43:48 +0530188 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Vidyashree Rama468f8282016-03-04 19:08:35 +0530189 sdf.setLenient(false);
190
191 try {
192 //if not valid, it will throw ParseException
193 sdf.parse(dateToValidate);
194 } catch (ParseException e) {
195 return false;
196 }
197
198 return true;
199 }
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530200
201 /**
202 * Validates YANG version.
203 *
204 * @param ctx version context object of the grammar rule
205 * @return valid version
206 */
207 public static byte getValidVersion(GeneratedYangParser.YangVersionStatementContext ctx) {
208
209 String value = removeQuotesAndHandleConcat(ctx.version().getText());
210 if (!value.equals(ONE)) {
211 ParserException parserException = new ParserException("YANG file error: Input version not supported");
212 parserException.setLine(ctx.getStart().getLine());
213 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
214 throw parserException;
215 }
216
217 return Byte.valueOf(value);
218 }
219
220 /**
221 * Validates non negative integer value.
222 *
janani b23ccc312016-07-14 19:35:22 +0530223 * @param integerValue integer to be validated
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530224 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530225 * @param ctx context object of the grammar rule
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530226 * @return valid non negative integer value
227 */
228 public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530229 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530230
231 String value = removeQuotesAndHandleConcat(integerValue);
232 if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
233 ParserException parserException = new ParserException("YANG file error : " +
234 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
235 "valid.");
236 parserException.setLine(ctx.getStart().getLine());
237 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
238 throw parserException;
239 }
240
Vidyashree Rama210c01d2016-05-20 16:29:25 +0530241 int valueInInteger;
242 try {
243 valueInInteger = Integer.parseInt(value);
244 } catch (NumberFormatException e) {
245 ParserException parserException = new ParserException("YANG file error : " +
246 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
247 "valid.");
248 parserException.setLine(ctx.getStart().getLine());
249 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
250 throw parserException;
251 }
252 return valueInInteger;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530253 }
254
255 /**
Vidyashree Rama1db15562016-05-17 16:16:15 +0530256 * Validates integer value.
257 *
janani b23ccc312016-07-14 19:35:22 +0530258 * @param integerValue integer to be validated
Vidyashree Rama1db15562016-05-17 16:16:15 +0530259 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530260 * @param ctx context object of the grammar rule
Vidyashree Rama1db15562016-05-17 16:16:15 +0530261 * @return valid integer value
262 */
263 public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530264 ParserRuleContext ctx) {
Vidyashree Rama1db15562016-05-17 16:16:15 +0530265
266 String value = removeQuotesAndHandleConcat(integerValue);
267 if (!INTEGER_PATTERN.matcher(value).matches()) {
268 ParserException parserException = new ParserException("YANG file error : " +
269 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
270 "valid.");
271 parserException.setLine(ctx.getStart().getLine());
272 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
273 throw parserException;
274 }
275
276 int valueInInteger;
277 try {
278 valueInInteger = Integer.parseInt(value);
279 } catch (NumberFormatException e) {
280 ParserException parserException = new ParserException("YANG file error : " +
281 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
282 "valid.");
283 parserException.setLine(ctx.getStart().getLine());
284 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
285 throw parserException;
286 }
287 return valueInInteger;
288 }
289
290 /**
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530291 * Validates boolean value.
292 *
janani b23ccc312016-07-14 19:35:22 +0530293 * @param booleanValue value to be validated
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530294 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530295 * @param ctx context object of the grammar rule
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530296 * @return boolean value either true or false
297 */
298 public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530299 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530300
301 String value = removeQuotesAndHandleConcat(booleanValue);
Vidyashree Rama1db15562016-05-17 16:16:15 +0530302 if (value.equals(TRUE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530303 return true;
Vidyashree Rama1db15562016-05-17 16:16:15 +0530304 } else if (value.equals(FALSE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530305 return false;
306 } else {
307 ParserException parserException = new ParserException("YANG file error : " +
308 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
309 "valid.");
310 parserException.setLine(ctx.getStart().getLine());
311 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
312 throw parserException;
313 }
314 }
janani bcc9ac302016-03-24 12:43:48 +0530315
316 /**
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530317 * Returns current date and makes it in usable format for revision.
janani bcc9ac302016-03-24 12:43:48 +0530318 *
319 * @return usable current date format for revision
320 */
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530321 public static Date getCurrentDateForRevision() {
janani bcc9ac302016-03-24 12:43:48 +0530322
janani bcc9ac302016-03-24 12:43:48 +0530323 SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530324
325 Date date = new Date();
326 String dateInString = dateFormat.format(date);
327 try {
328 //if not valid, it will throw ParseException
329 Date now = dateFormat.parse(dateInString);
330 return date;
331 } catch (ParseException e) {
332 ParserException parserException = new ParserException("YANG file error: Input date is not correct");
333 throw parserException;
334 }
janani bcc9ac302016-03-24 12:43:48 +0530335 }
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530336
337 /**
338 * Checks and return valid node identifier.
339 *
340 * @param nodeIdentifierString string from yang file
janani b23ccc312016-07-14 19:35:22 +0530341 * @param yangConstruct yang construct for creating error message
342 * @param ctx yang construct's context to get the line number and character position
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530343 * @return valid node identifier
344 */
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530345 public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
janani b23ccc312016-07-14 19:35:22 +0530346 YangConstructType yangConstruct, ParserRuleContext ctx) {
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530347 String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
348 String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
349 if (tmpData.length == 1) {
350 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
351 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
352 return nodeIdentifier;
353 } else if (tmpData.length == 2) {
354 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
355 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
356 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
357 return nodeIdentifier;
358 } else {
359 ParserException parserException = new ParserException("YANG file error : " +
360 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
361 " is not valid.");
362 parserException.setLine(ctx.getStart().getLine());
363 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
364 throw parserException;
365 }
366 }
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530367
368 /**
janani be18b5342016-07-13 21:06:41 +0530369 * Checks and return valid node identifier specific to nodes in leafref path.
370 *
371 * @param nodeIdentifierString string from yang file
janani b23ccc312016-07-14 19:35:22 +0530372 * @param yangConstruct yang construct for creating error message
373 * @param ctx yang construct's context to get the line number and character position
374 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530375 * @return valid node identifier
376 */
377 public static YangNodeIdentifier getValidNodeIdentifierForLeafref(String nodeIdentifierString,
janani b23ccc312016-07-14 19:35:22 +0530378 YangConstructType yangConstruct,
379 ParserRuleContext ctx, YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530380
381 String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
382 String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
383 if (tmpData.length == 1) {
384 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
janani be18b5342016-07-13 21:06:41 +0530385 nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
386 return nodeIdentifier;
387 } else if (tmpData.length == 2) {
388 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
389 nodeIdentifier.setPrefix(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
390 nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[1], yangConstruct, ctx, yangLeafRef));
391 return nodeIdentifier;
392 } else {
393 ParserException parserException = new ParserException("YANG file error : " +
394 YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
395 " is not valid.");
396 parserException.setLine(ctx.getStart().getLine());
397 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
398 throw parserException;
399 }
400 }
401
402 /**
403 * Validates the path argument. It can be either absolute or relative path.
404 *
janani b23ccc312016-07-14 19:35:22 +0530405 * @param pathString the path string from the path type
janani be18b5342016-07-13 21:06:41 +0530406 * @param yangConstruct yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530407 * @param ctx yang construct's context to get the line number and character position
408 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530409 */
410 public static void validatePathArgument(String pathString, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530411 ParserRuleContext ctx, YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530412
413 String completePathString = removeQuotesAndHandleConcat(pathString);
414 yangLeafRef.setPath(completePathString);
415 if (completePathString.startsWith(SLASH)) {
416 yangLeafRef.setPathType(ABSOLUTE_PATH);
417 List<YangAtomicPath> yangAtomicPathListList = validateAbsolutePath(completePathString, yangConstruct, ctx,
418 yangLeafRef);
janani b23ccc312016-07-14 19:35:22 +0530419 validatePrefixAndYangNode(yangAtomicPathListList, yangLeafRef);
janani be18b5342016-07-13 21:06:41 +0530420 yangLeafRef.setAtomicPath(yangAtomicPathListList);
421 } else if (completePathString.startsWith(ANCESTOR_ACCESSOR)) {
422 yangLeafRef.setPathType(RELATIVE_PATH);
423 validateRelativePath(completePathString, yangConstruct, ctx, yangLeafRef);
424 } else {
425 ParserException parserException = new ParserException("YANG file error : " +
426 YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
427 " does not follow valid path syntax");
428 parserException.setLine(ctx.getStart().getLine());
429 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
430 throw parserException;
431 }
432 }
433
434 /**
janani b23ccc312016-07-14 19:35:22 +0530435 * Validates the prefixes in the leafref and assigns them to the respective imported name in map.
436 *
437 * @param yangAtomicPathList list of atomic poth
438 * @param yangLeafRef instance YANG leafref
439 */
440 private static void validatePrefixAndYangNode(List<YangAtomicPath> yangAtomicPathList, YangLeafRef yangLeafRef) {
441 Iterator<YangAtomicPath> yangAtomicPathIterator = yangAtomicPathList.listIterator();
442 while (yangAtomicPathIterator.hasNext()) {
443 YangAtomicPath atomicPath = yangAtomicPathIterator.next();
444 String prefix = atomicPath.getNodeIdentifier().getPrefix();
445 YangNode parentNodeOfLeafref = yangLeafRef.getParentNodeOfLeafref();
446 YangNode moduleOrSubModule = getModuleOrSubmoduleInFileOfTheCurrentNode(parentNodeOfLeafref);
447 YangModule moduleNode = null;
448 if (moduleOrSubModule instanceof YangModule) {
449 moduleNode = (YangModule) moduleOrSubModule;
450 }
451 if (moduleNode != null) {
452 updatePrefixWithTheImportedList(moduleNode, prefix, yangLeafRef);
453 }
454 }
455 }
456
457 /**
458 * Updates the prefix with the imported list in the module.
459 *
460 * @param moduleNode root node of the leafref
461 * @param prefixInPath prefix in the path
462 * @param yangLeafRef instance YANG leafref
463 */
464 private static void updatePrefixWithTheImportedList(YangModule moduleNode, String prefixInPath, YangLeafRef
465 yangLeafRef) {
466 if (prefixInPath != null && prefixInPath != EMPTY_STRING && !prefixInPath.equals(moduleNode.getPrefix())) {
467 List<YangImport> moduleImportList = moduleNode.getImportList();
468 if (moduleImportList != null && !moduleImportList.isEmpty()) {
469 Iterator<YangImport> yangImportIterator = moduleImportList.listIterator();
470 while (yangImportIterator.hasNext()) {
471 YangImport yangImport = yangImportIterator.next();
472 if (yangImport.getPrefixId().equals(prefixInPath)) {
473 HashMap prefixMap = new HashMap();
474 prefixMap.put(prefixInPath, yangImport.getModuleName());
475 yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
476 }
477 }
478 }
479 } else {
480 HashMap prefixMap = new HashMap();
481 prefixMap.put(prefixInPath, moduleNode.getName());
482 yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
483 }
484 }
485
486 /**
487 * Returns module or submodule node from the current node.
488 *
489 * @param node current node
490 * @return root node
491 */
492 private static YangNode getModuleOrSubmoduleInFileOfTheCurrentNode(YangNode node) {
493 while (!(node instanceof YangModule) && !(node instanceof YangSubModule)) {
494 if (node == null) {
495 throw new ParserException("Internal datamodel error: Datamodel tree is not correct");
496 }
497 node = node.getParent();
498 }
499 return node;
500 }
501
502 /**
503 * Validates the unique syntax from the reference path.
504 *
505 * @param uniquePath path of unique
506 * @param prefixOfFile current file's prefix
507 * @param ctx yang construct's context to get the line number and character position
508 * @return list of absolute path
509 */
510 private static List<YangAtomicPath> validateUniqueValues(String uniquePath, String prefixOfFile,
511 ParserRuleContext ctx) {
512 List<YangAtomicPath> atomicPath = new LinkedList<>();
513 String[] pathInUnique = uniquePath.split(SLASH_FOR_STRING);
514 for (String uniqueValue : pathInUnique) {
515 YangAtomicPath yangAtomicPathPath = new YangAtomicPath();
516 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(uniqueValue, YangConstructType.UNIQUE_DATA, ctx);
517 yangAtomicPathPath.setNodeIdentifier(nodeIdentifier);
518 atomicPath.add(yangAtomicPathPath);
519 if (nodeIdentifier.getPrefix() != null && nodeIdentifier.getPrefix() != prefixOfFile) {
520 ParserException parserException = new ParserException("YANG file error : A leaf reference, in unique," +
521 " must refer to a leaf in the list");
522 parserException.setLine(ctx.getStart().getLine());
523 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
524 throw parserException;
525 }
526 }
527 return atomicPath;
528 }
529
530 /**
531 * Validates unique field from the list.
532 *
533 * @param yangList instance of YANG list
534 * @param ctx yang construct's context to get the line number and character position
535 */
536 public static void validateUniqueInList(YangList yangList, ParserRuleContext ctx) {
537 YangLeaf leaf;
538 // Returns the prefix for the file where unique is present.
539 String prefixOfTheFile = getPrefixInFileOfTheCurrentNode(yangList);
540 List<String> uniques = yangList.getUniqueList();
541 if (uniques != null && !uniques.isEmpty()) {
542 Iterator<String> uniqueList = uniques.listIterator();
543 while (uniqueList.hasNext()) {
544 String pathInUnique = uniqueList.next();
545 List<YangAtomicPath> atomicPathInUnique = validateUniqueValues(pathInUnique, prefixOfTheFile, ctx);
546 YangAtomicPath leafInPath = atomicPathInUnique.get(atomicPathInUnique.size() - 1);
547 if (atomicPathInUnique.size() == 1) {
548 leaf = getReferenceLeafFromUnique(yangList, leafInPath);
549 } else {
550 atomicPathInUnique.remove(atomicPathInUnique.size() - 1);
551 YangNode holderOfLeaf = getNodeUnderListFromPath(atomicPathInUnique, yangList, ctx);
552 leaf = getReferenceLeafFromUnique(holderOfLeaf, leafInPath);
553 }
554 if (leaf == null) {
555 ParserException parserException = new ParserException("YANG file error : A leaf reference, in " +
556 "unique," +
557 " must refer to a leaf under the list");
558 parserException.setLine(ctx.getStart().getLine());
559 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
560 throw parserException;
561 }
562 }
563 }
564 }
565
566 /**
567 * Returns the last node under the unique path.
568 *
569 * @param uniquePath atomic path list
570 * @param node root node from where it starts searching
571 * @param ctx yang construct's context to get the line number and character position
572 * @return last node in the list
573 */
574 private static YangNode getNodeUnderListFromPath(List<YangAtomicPath> uniquePath, YangNode node,
575 ParserRuleContext ctx) {
576 Iterator<YangAtomicPath> nodesInReference = uniquePath.listIterator();
577 YangNode potentialReferredNode = node.getChild();
578 while (nodesInReference.hasNext()) {
579 YangAtomicPath nodeInUnique = nodesInReference.next();
580 YangNode referredNode = getReferredNodeFromTheUniqueNodes(nodeInUnique.getNodeIdentifier(),
581 potentialReferredNode);
582 if (referredNode == null) {
583 ParserException parserException = new ParserException("YANG file error : The target node in unique " +
584 "reference path is invalid");
585 parserException.setLine(ctx.getStart().getLine());
586 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
587 throw parserException;
588 } else {
589 potentialReferredNode = referredNode.getChild();
590 }
591 }
592 return potentialReferredNode;
593 }
594
595 /**
596 * Returns the node that matches with the name of the node in path.
597 *
598 * @param nodeInUnique node name in path
599 * @param potentialReferredNode node under which it has to match
600 * @return referred node
601 */
602 private static YangNode getReferredNodeFromTheUniqueNodes(YangNodeIdentifier nodeInUnique, YangNode
603 potentialReferredNode) {
604 while (potentialReferredNode != null) {
605 // Check if the potential referred node is the actual referred node
606 if (potentialReferredNode.getName().equals(nodeInUnique.getName())) {
607 return potentialReferredNode;
608 }
609 potentialReferredNode = potentialReferredNode.getNextSibling();
610 }
611 return null;
612 }
613
614 /**
615 * Returns the leaf which unique refers.
616 *
617 * @param nodeForLeaf last node where leaf is referred
618 * @param leafInUnique leaf in unique path
619 * @return YANG leaf
620 */
621 private static YangLeaf getReferenceLeafFromUnique(YangNode nodeForLeaf, YangAtomicPath leafInUnique) {
622 YangLeavesHolder leavesHolder = (YangLeavesHolder) nodeForLeaf;
623 List<YangLeaf> leaves = leavesHolder.getListOfLeaf();
624 if (leaves != null && !leaves.isEmpty()) {
625 for (YangLeaf leaf : leaves) {
626 if (leafInUnique.getNodeIdentifier().getName().equals(leaf.getName())) {
627 return leaf;
628 }
629 }
630 }
631 return null;
632 }
633
634 /**
635 * Returns the prefix of the current file.
636 *
637 * @param node node where it needs to find the root node
638 * @return prefix of root node
639 */
640 public static String getPrefixInFileOfTheCurrentNode(YangNode node) {
641 String prefixInFile;
642 while (!(node instanceof YangReferenceResolver)) {
643 node = node.getParent();
644 if (node == null) {
645 throw new ParserException("Internal datamodel error: Datamodel tree is not correct");
646 }
647 }
648 if (node instanceof YangModule) {
649 YangModule yangModule = (YangModule) node;
650 prefixInFile = yangModule.getPrefix();
651 } else {
652 YangSubModule yangSubModule = (YangSubModule) node;
653 prefixInFile = yangSubModule.getPrefix();
654 }
655 return prefixInFile;
656 }
657
658 /**
janani be18b5342016-07-13 21:06:41 +0530659 * Validates the relative path.
660 *
661 * @param completePathString the path string of relative path
janani b23ccc312016-07-14 19:35:22 +0530662 * @param yangConstruct yang construct for creating error message
663 * @param ctx yang construct's context to get the line number and character position
664 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530665 */
666 private static void validateRelativePath(String completePathString, YangConstructType yangConstruct,
janani b23ccc312016-07-14 19:35:22 +0530667 ParserRuleContext ctx, YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530668
669 YangRelativePath relativePath = new YangRelativePath();
670 int numberOfAncestors = 0;
671 while (completePathString.startsWith(ANCESTOR_ACCESSOR_IN_PATH)) {
672 completePathString = completePathString.replaceFirst(ANCESTOR_ACCESSOR_IN_PATH, EMPTY_STRING);
673 numberOfAncestors = numberOfAncestors + 1;
674 }
675 if (completePathString == null || completePathString.length() == 0) {
676 ParserException parserException = new ParserException("YANG file error : "
677 + YangConstructType.getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
678 " does not follow valid path syntax");
679 parserException.setLine(ctx.getStart().getLine());
680 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
681 throw parserException;
682 }
683 relativePath.setAncestorNodeCount(numberOfAncestors);
684 List<YangAtomicPath> atomicPath = validateAbsolutePath(SLASH_FOR_STRING + completePathString,
685 yangConstruct,
686 ctx, yangLeafRef);
janani b23ccc312016-07-14 19:35:22 +0530687 validatePrefixAndYangNode(atomicPath, yangLeafRef);
janani be18b5342016-07-13 21:06:41 +0530688 relativePath.setAtomicPathList(atomicPath);
689 yangLeafRef.setRelativePath(relativePath);
690 }
691
692 /**
693 * Validates the absolute path.
694 *
695 * @param completePathString the path string of absolute path
janani b23ccc312016-07-14 19:35:22 +0530696 * @param yangConstruct yang construct for creating error message
697 * @param ctx yang construct's context to get the line number and character position
698 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530699 * @return list of object of node in absolute path
700 */
701 private static List<YangAtomicPath> validateAbsolutePath(String completePathString,
janani b23ccc312016-07-14 19:35:22 +0530702 YangConstructType yangConstruct, ParserRuleContext
703 ctx, YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530704
705 List<YangAtomicPath> absolutePathList = new LinkedList<>();
706 YangPathPredicate yangPathPredicate = new YangPathPredicate();
707 YangNodeIdentifier yangNodeIdentifier;
708
709 while (completePathString != null) {
710 String path = completePathString.replaceFirst(SLASH_FOR_STRING, EMPTY_STRING);
711 if (path == null || path.length() == 0) {
712 ParserException parserException = new ParserException("YANG file error : "
713 + YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
714 " does not follow valid path syntax");
715 parserException.setLine(ctx.getStart().getLine());
716 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
717 throw parserException;
718 }
719 String matchedPathPredicate;
720 String nodeIdentifier;
721 String[] differentiate = new String[2];
722 int forNodeIdentifier = path.indexOf(CHAR_OF_SLASH);
723 int forPathPredicate = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
724
725 // Checks if path predicate is present for the node.
726 if ((forPathPredicate < forNodeIdentifier) && (forPathPredicate != -1)) {
727 List<String> pathPredicate = new ArrayList<>();
728 matchedPathPredicate = matchForPathPredicate(path);
729
730 if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
731 ParserException parserException = new ParserException("YANG file error : "
732 + YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
733 " does not follow valid path syntax");
734 parserException.setLine(ctx.getStart().getLine());
735 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
736 throw parserException;
737 }
738 int indexOfMatchedFirstOpenBrace = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
739 differentiate[0] = path.substring(0, indexOfMatchedFirstOpenBrace);
740 differentiate[1] = path.substring(indexOfMatchedFirstOpenBrace);
741 pathPredicate.add(matchedPathPredicate);
742 nodeIdentifier = differentiate[0];
743 // Starts adding all path predicates of a node into the list.
744 if (!differentiate[1].isEmpty()) {
745 while (differentiate[1].startsWith(OPEN_SQUARE_BRACKET)) {
746 matchedPathPredicate = matchForPathPredicate(differentiate[1]);
747 if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
748 ParserException parserException = new ParserException(
749 "YANG file error : " + YangConstructType.getYangConstructType(yangConstruct) + " "
750 + yangLeafRef.getPath() +
751 " does not follow valid path syntax");
752 parserException.setLine(ctx.getStart().getLine());
753 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
754 throw parserException;
755 }
756 pathPredicate.add(matchedPathPredicate);
757 differentiate[1] = differentiate[1].substring(matchedPathPredicate.length());
758 }
759 }
760
761 List<YangPathPredicate> pathPredicateList = validatePathPredicate(pathPredicate, yangConstruct, ctx,
762 yangPathPredicate, yangLeafRef);
763 YangAtomicPath atomicPath = new YangAtomicPath();
764 yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
765 atomicPath.setNodeIdentifier(yangNodeIdentifier);
766 atomicPath.setPathPredicatesList(pathPredicateList);
767 absolutePathList.add(atomicPath);
768 } else {
769 if (path.contains(SLASH_FOR_STRING)) {
770 nodeIdentifier = path.substring(0, path.indexOf(CHAR_OF_SLASH));
771 differentiate[1] = path.substring(path.indexOf(CHAR_OF_SLASH));
772 } else {
773 nodeIdentifier = path;
774 differentiate[1] = null;
775 }
776 yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
777
778 YangAtomicPath atomicPath = new YangAtomicPath();
779 atomicPath.setNodeIdentifier(yangNodeIdentifier);
780 atomicPath.setPathPredicatesList(null);
781 absolutePathList.add(atomicPath);
782 }
783 if (differentiate[1] == null || differentiate[1].length() == 0) {
784 completePathString = null;
785 } else {
786 completePathString = differentiate[1];
787 }
788 }
789 return absolutePathList;
790 }
791
792 /**
793 * Validates path predicate in the absolute path's node.
794 *
janani b23ccc312016-07-14 19:35:22 +0530795 * @param pathPredicate list of path predicates in the node of absolute path
796 * @param yangConstruct yang construct for creating error message
797 * @param ctx yang construct's context to get the line number and character position
janani be18b5342016-07-13 21:06:41 +0530798 * @param yangPathPredicate instance of path predicate where it has to be set
janani b23ccc312016-07-14 19:35:22 +0530799 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530800 * @return list of object of path predicates in absolute path's node
801 */
802 private static List<YangPathPredicate> validatePathPredicate(List<String> pathPredicate,
janani b23ccc312016-07-14 19:35:22 +0530803 YangConstructType yangConstruct, ParserRuleContext
804 ctx, YangPathPredicate yangPathPredicate,
805 YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530806
807 Iterator<String> pathPredicateString = pathPredicate.iterator();
808 List<String> pathEqualityExpression = new ArrayList<>();
809
810 while (pathPredicateString.hasNext()) {
811 String pathPredicateForNode = pathPredicateString.next();
812 pathPredicateForNode = (pathPredicateForNode.substring(1)).trim();
813 pathPredicateForNode = pathPredicateForNode.substring(0,
814 pathPredicateForNode.indexOf(CHAR_OF_CLOSE_SQUARE_BRACKET));
815 pathEqualityExpression.add(pathPredicateForNode);
816 }
817 List<YangPathPredicate> validatedPathPredicateList = validatePathEqualityExpression(pathEqualityExpression,
818 yangConstruct, ctx, yangPathPredicate, yangLeafRef);
819 return validatedPathPredicateList;
820 }
821
822 /**
823 * Validates the path equality expression.
824 *
825 * @param pathEqualityExpression list of path equality expression in the path predicates of the node
janani b23ccc312016-07-14 19:35:22 +0530826 * @param yangConstruct yang construct for creating error message
827 * @param ctx yang construct's context to get the line number and character position
828 * @param yangPathPredicate instance of path predicate where it has to be set
829 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530830 * @return list of object of path predicates in absolute path's node
831 */
832 private static List<YangPathPredicate> validatePathEqualityExpression(List<String> pathEqualityExpression,
janani b23ccc312016-07-14 19:35:22 +0530833 YangConstructType yangConstruct,
834 ParserRuleContext ctx, YangPathPredicate
835 yangPathPredicate,
836 YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530837
838 Iterator<String> pathEqualityExpressionString = pathEqualityExpression.iterator();
839 List<YangPathPredicate> yangPathPredicateList = new ArrayList<>();
840
841 while (pathEqualityExpressionString.hasNext()) {
842 String pathEqualityExpressionForNode = pathEqualityExpressionString.next();
843 String[] pathEqualityExpressionArray = pathEqualityExpressionForNode.split("[=]");
844
845 YangNodeIdentifier yangNodeIdentifierForPredicate;
846 YangRelativePath yangRelativePath;
847 yangNodeIdentifierForPredicate = getValidNodeIdentifierForLeafref(pathEqualityExpressionArray[0].trim(),
848 yangConstruct, ctx, yangLeafRef);
849 yangRelativePath = validatePathKeyExpression(pathEqualityExpressionArray[1].trim(), yangConstruct, ctx,
850 yangLeafRef);
851 yangPathPredicate.setNodeIdentifier(yangNodeIdentifierForPredicate);
852 yangPathPredicate.setPathOperator(EQUALTO);
853 yangPathPredicate.setRightRelativePath(yangRelativePath);
854 yangPathPredicateList.add(yangPathPredicate);
855 }
856 return yangPathPredicateList;
857 }
858
859 /**
860 * Validate the path key expression.
861 *
862 * @param rightRelativePath relative path in the path predicate
janani b23ccc312016-07-14 19:35:22 +0530863 * @param yangConstruct yang construct for creating error message
864 * @param ctx yang construct's context to get the line number and character position
865 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530866 * @return object of right relative path in path predicate
867 */
868 private static YangRelativePath validatePathKeyExpression(String rightRelativePath,
janani b23ccc312016-07-14 19:35:22 +0530869 YangConstructType yangConstruct, ParserRuleContext ctx,
870 YangLeafRef yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530871
872 YangRelativePath yangRelativePath = new YangRelativePath();
873 String[] relativePath = rightRelativePath.split(SLASH_FOR_STRING);
874 List<String> rightAbsolutePath = new ArrayList<>();
875 int accessAncestor = 0;
876 for (String path : relativePath) {
877 if (path.trim().equals(ANCESTOR_ACCESSOR)) {
878 accessAncestor = accessAncestor + 1;
879 } else {
880 rightAbsolutePath.add(path);
881 }
882 }
883 List<YangAtomicPath> atomicPathInRelativePath = validateRelativePathKeyExpression(rightAbsolutePath,
884 yangConstruct, ctx, yangLeafRef);
885 yangRelativePath.setAtomicPathList(atomicPathInRelativePath);
886 yangRelativePath.setAncestorNodeCount(accessAncestor);
887 return yangRelativePath;
888 }
889
890 /**
891 * Validates the relative path key expression.
892 *
893 * @param rightAbsolutePath absolute path nodes present in the relative path
janani b23ccc312016-07-14 19:35:22 +0530894 * @param yangConstruct yang construct for creating error message
895 * @param ctx yang construct's context to get the line number and character position
896 * @param yangLeafRef instance of leafref where the path argument has to be set
janani be18b5342016-07-13 21:06:41 +0530897 * @return list of object of absolute path nodes present in the relative path
898 */
899 private static List<YangAtomicPath> validateRelativePathKeyExpression(List<String> rightAbsolutePath,
janani b23ccc312016-07-14 19:35:22 +0530900 YangConstructType yangConstruct,
901 ParserRuleContext ctx, YangLeafRef
902 yangLeafRef) {
janani be18b5342016-07-13 21:06:41 +0530903
904 List<YangAtomicPath> atomicPathList = new ArrayList<>();
905 YangNodeIdentifier yangNodeIdentifier;
906
907 Iterator<String> nodes = rightAbsolutePath.iterator();
908 String currentInvocationFunction = nodes.next();
909 currentInvocationFunction = currentInvocationFunction.trim();
910 String[] currentFunction = currentInvocationFunction.split("[(]");
911
912 if (!(currentFunction[0].trim().equals(CURRENT)) || !(currentFunction[1].trim().equals(CLOSE_PARENTHESIS))) {
913 ParserException parserException = new ParserException("YANG file error : "
914 + YangConstructType.getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
915 " does not follow valid path syntax");
916 parserException.setLine(ctx.getStart().getLine());
917 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
918 throw parserException;
919 }
920
921 while (nodes.hasNext()) {
922 YangAtomicPath atomicPath = new YangAtomicPath();
923 String node = nodes.next();
924 yangNodeIdentifier = getValidNodeIdentifierForLeafref(node.trim(), yangConstruct, ctx, yangLeafRef);
925 atomicPath.setNodeIdentifier(yangNodeIdentifier);
926 atomicPathList.add(atomicPath);
927 }
928 return atomicPathList;
929 }
930
931 /**
932 * Validates the match for first path predicate in a given string.
933 *
934 * @param matchRequiredString string for which match has to be done
935 * @return the matched string
936 */
937 private static String matchForPathPredicate(String matchRequiredString) {
938
939 String matchedString = null;
940 java.util.regex.Matcher matcher = PATH_PREDICATE_PATTERN.matcher(matchRequiredString);
941 if (matcher.find()) {
942 matchedString = matcher.group(0);
943 }
944 return matchedString;
945 }
946
947 /**
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530948 * Checks and return valid absolute schema node id.
949 *
janani b23ccc312016-07-14 19:35:22 +0530950 * @param argumentString string from yang file
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530951 * @param yangConstructType yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530952 * @param ctx yang construct's context to get the line number and character position
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530953 * @return target nodes list of absolute schema node id
954 */
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530955 public static List<YangAtomicPath> getValidAbsoluteSchemaNodeId(String argumentString,
janani b23ccc312016-07-14 19:35:22 +0530956 YangConstructType yangConstructType,
957 ParserRuleContext ctx) {
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530958
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530959 List<YangAtomicPath> targetNodes = new ArrayList<>();
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530960 YangNodeIdentifier yangNodeIdentifier;
961 String tmpSchemaNodeId = removeQuotesAndHandleConcat(argumentString);
962
963 // absolute-schema-nodeid = 1*("/" node-identifier)
964 if (!tmpSchemaNodeId.startsWith(SLASH)) {
965 ParserException parserException = new ParserException("YANG file error : " +
966 YangConstructType.getYangConstructType(yangConstructType) + " name " + argumentString +
967 "is not valid");
968 parserException.setLine(ctx.getStart().getLine());
969 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
970 throw parserException;
971 }
972 String[] tmpData = tmpSchemaNodeId.replaceFirst(CARET + SLASH, EMPTY_STRING).split(SLASH);
973 for (String nodeIdentifiers : tmpData) {
974 yangNodeIdentifier = getValidNodeIdentifier(nodeIdentifiers, yangConstructType, ctx);
Bharat saraswalb1170bd2016-07-14 13:26:18 +0530975 YangAtomicPath yangAbsPath = new YangAtomicPath();
976 yangAbsPath.setNodeIdentifier(yangNodeIdentifier);
977 targetNodes.add(yangAbsPath);
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530978 }
979 return targetNodes;
980 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530981
982 /**
983 * Throws parser exception for unsupported YANG constructs.
984 *
985 * @param yangConstructType yang construct for creating error message
janani b23ccc312016-07-14 19:35:22 +0530986 * @param ctx yang construct's context to get the line number and character position
987 * @param errorInfo error information
Vidyashree Rama1db15562016-05-17 16:16:15 +0530988 */
989 public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
janani b23ccc312016-07-14 19:35:22 +0530990 ParserRuleContext ctx, String errorInfo) {
Vidyashree Rama1db15562016-05-17 16:16:15 +0530991 ParserException parserException = new ParserException(YANG_FILE_ERROR
992 + QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
993 + errorInfo);
994 parserException.setLine(ctx.getStart().getLine());
995 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
996 throw parserException;
997 }
Vidyashree Ramadeac28b2016-06-20 15:12:43 +0530998
999 /**
1000 * Returns date and makes it in usable format for revision.
1001 *
1002 * @param dateInString date argument string from yang file
1003 * @param ctx yang construct's context to get the line number and character position
1004 * @return date format for revision
1005 */
1006 public static Date getValidDateFromString(String dateInString, ParserRuleContext ctx) {
1007 String dateArgument = removeQuotesAndHandleConcat(dateInString);
1008 if (dateArgument == null || !dateArgument.matches(DATE_PATTERN)) {
1009 ParserException parserException = new ParserException("YANG file error: Input date is not correct");
1010 parserException.setLine(ctx.getStart().getLine());
1011 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
1012 throw parserException;
1013 }
1014
1015 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
1016 sdf.setLenient(false);
1017
1018 try {
1019 //if not valid, it will throw ParseException
1020 Date date = sdf.parse(dateArgument);
1021 return date;
1022 } catch (ParseException e) {
1023 ParserException parserException = new ParserException("YANG file error: Input date is not correct");
1024 parserException.setLine(ctx.getStart().getLine());
1025 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
1026 throw parserException;
1027 }
1028 }
Bharat saraswalb1170bd2016-07-14 13:26:18 +05301029}