blob: d05c8d0644833feddcd9a8b45bb828dd13ec642f [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
Vidyashree Rama468f8282016-03-04 19:08:35 +053019import java.text.ParseException;
20import java.text.SimpleDateFormat;
janani bcc9ac302016-03-24 12:43:48 +053021import java.util.Calendar;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053022import java.util.LinkedList;
23import java.util.List;
Vidyashree Rama468f8282016-03-04 19:08:35 +053024import java.util.regex.Pattern;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053025
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053026import org.antlr.v4.runtime.ParserRuleContext;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053027import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Bharat saraswal96dfef02016-06-16 00:29:12 +053028import org.onosproject.yangutils.datamodel.utils.YangConstructType;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053029import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
Vidyashree Rama468f8282016-03-04 19:08:35 +053030import org.onosproject.yangutils.parser.exceptions.ParserException;
31
Vidyashree Rama1db15562016-05-17 16:16:15 +053032import static org.onosproject.yangutils.utils.UtilConstants.ADD;
33import static org.onosproject.yangutils.utils.UtilConstants.SPACE;
34import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
35import static org.onosproject.yangutils.utils.UtilConstants.COLON;
36import static org.onosproject.yangutils.utils.UtilConstants.CARET;
janani b6240d292016-05-17 18:20:33 +053037import static org.onosproject.yangutils.utils.UtilConstants.CURRENTLY_UNSUPPORTED;
Vidyashree Rama1db15562016-05-17 16:16:15 +053038import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
39import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
40import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
41import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
42import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
43import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
janani b6240d292016-05-17 18:20:33 +053044import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF;
45import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF;
46import static org.onosproject.yangutils.utils.UtilConstants.INSTANCE_IDENTIFIER;
Vidyashree Rama1db15562016-05-17 16:16:15 +053047
Vidyashree Rama468f8282016-03-04 19:08:35 +053048/**
Bharat saraswald9822e92016-04-05 15:13:44 +053049 * Represents an utility for listener.
Vidyashree Rama468f8282016-03-04 19:08:35 +053050 */
51public final class ListenerUtil {
Bharat saraswald9822e92016-04-05 15:13:44 +053052
Vidyashree Rama468f8282016-03-04 19:08:35 +053053 private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +053054 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 +053055 private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
Vidyashree Rama1db15562016-05-17 16:16:15 +053056 private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
Vidyashree Rama210c01d2016-05-20 16:29:25 +053057 private static final String XML = "xml";
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053058 private static final String ONE = "1";
Vidyashree Rama468f8282016-03-04 19:08:35 +053059 private static final int IDENTIFIER_LENGTH = 64;
janani bcc9ac302016-03-24 12:43:48 +053060 private static final String DATE_FORMAT = "yyyy-MM-dd";
Vidyashree Rama468f8282016-03-04 19:08:35 +053061
62 /**
63 * Creates a new listener util.
64 */
65 private ListenerUtil() {
66 }
67
68 /**
69 * Removes doubles quotes and concatenates if string has plus symbol.
70 *
71 * @param yangStringData string from yang file
72 * @return concatenated string after removing double quotes
73 */
74 public static String removeQuotesAndHandleConcat(String yangStringData) {
75
janani bcc9ac302016-03-24 12:43:48 +053076 yangStringData = yangStringData.replace("\"", EMPTY_STRING);
Vidyashree Rama1db15562016-05-17 16:16:15 +053077 String[] tmpData = yangStringData.split(Pattern.quote(ADD));
Vidyashree Rama468f8282016-03-04 19:08:35 +053078 StringBuilder builder = new StringBuilder();
79 for (String yangString : tmpData) {
80 builder.append(yangString);
81 }
82 return builder.toString();
83 }
84
85 /**
86 * Validates identifier and returns concatenated string if string contains plus symbol.
87 *
88 * @param identifier string from yang file
89 * @param yangConstruct yang construct for creating error message
90 * @param ctx yang construct's context to get the line number and character position
91 * @return concatenated string after removing double quotes
92 */
93 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
94
95 String identifierString = removeQuotesAndHandleConcat(identifier);
96 ParserException parserException;
97
98 if (identifierString.length() > IDENTIFIER_LENGTH) {
99 parserException = new ParserException("YANG file error : " +
100 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is " +
101 "greater than 64 characters.");
102 } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
103 parserException = new ParserException("YANG file error : " +
104 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is not " +
105 "valid.");
Vidyashree Rama210c01d2016-05-20 16:29:25 +0530106 } else if (identifierString.toLowerCase().startsWith(XML)) {
107 parserException = new ParserException("YANG file error : " +
108 YangConstructType.getYangConstructType(yangConstruct) + " identifier " + identifierString +
109 " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
Vidyashree Rama468f8282016-03-04 19:08:35 +0530110 } else {
111 return identifierString;
112 }
113
114 parserException.setLine(ctx.getStart().getLine());
115 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
116 throw parserException;
117 }
118
119 /**
120 * Validates the revision date.
121 *
122 * @param dateToValidate input revision date
123 * @return validation result, true for success, false for failure
124 */
125 public static boolean isDateValid(String dateToValidate) {
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +0530126 if (dateToValidate == null || !dateToValidate.matches(DATE_PATTERN)) {
Vidyashree Rama468f8282016-03-04 19:08:35 +0530127 return false;
128 }
129
janani bcc9ac302016-03-24 12:43:48 +0530130 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Vidyashree Rama468f8282016-03-04 19:08:35 +0530131 sdf.setLenient(false);
132
133 try {
134 //if not valid, it will throw ParseException
135 sdf.parse(dateToValidate);
136 } catch (ParseException e) {
137 return false;
138 }
139
140 return true;
141 }
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530142
143 /**
144 * Validates YANG version.
145 *
146 * @param ctx version context object of the grammar rule
147 * @return valid version
148 */
149 public static byte getValidVersion(GeneratedYangParser.YangVersionStatementContext ctx) {
150
151 String value = removeQuotesAndHandleConcat(ctx.version().getText());
152 if (!value.equals(ONE)) {
153 ParserException parserException = new ParserException("YANG file error: Input version not supported");
154 parserException.setLine(ctx.getStart().getLine());
155 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
156 throw parserException;
157 }
158
159 return Byte.valueOf(value);
160 }
161
162 /**
163 * Validates non negative integer value.
164 *
165 * @param integerValue integer to be validated
166 * @param yangConstruct yang construct for creating error message
167 * @param ctx context object of the grammar rule
168 * @return valid non negative integer value
169 */
170 public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530171 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530172
173 String value = removeQuotesAndHandleConcat(integerValue);
174 if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
175 ParserException parserException = new ParserException("YANG file error : " +
176 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
177 "valid.");
178 parserException.setLine(ctx.getStart().getLine());
179 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
180 throw parserException;
181 }
182
Vidyashree Rama210c01d2016-05-20 16:29:25 +0530183 int valueInInteger;
184 try {
185 valueInInteger = Integer.parseInt(value);
186 } catch (NumberFormatException e) {
187 ParserException parserException = new ParserException("YANG file error : " +
188 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
189 "valid.");
190 parserException.setLine(ctx.getStart().getLine());
191 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
192 throw parserException;
193 }
194 return valueInInteger;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530195 }
196
197 /**
Vidyashree Rama1db15562016-05-17 16:16:15 +0530198 * Validates integer value.
199 *
200 * @param integerValue integer to be validated
201 * @param yangConstruct yang construct for creating error message
202 * @param ctx context object of the grammar rule
203 * @return valid integer value
204 */
205 public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
206 ParserRuleContext ctx) {
207
208 String value = removeQuotesAndHandleConcat(integerValue);
209 if (!INTEGER_PATTERN.matcher(value).matches()) {
210 ParserException parserException = new ParserException("YANG file error : " +
211 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
212 "valid.");
213 parserException.setLine(ctx.getStart().getLine());
214 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
215 throw parserException;
216 }
217
218 int valueInInteger;
219 try {
220 valueInInteger = Integer.parseInt(value);
221 } catch (NumberFormatException e) {
222 ParserException parserException = new ParserException("YANG file error : " +
223 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
224 "valid.");
225 parserException.setLine(ctx.getStart().getLine());
226 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
227 throw parserException;
228 }
229 return valueInInteger;
230 }
231
232 /**
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530233 * Validates boolean value.
234 *
235 * @param booleanValue value to be validated
236 * @param yangConstruct yang construct for creating error message
237 * @param ctx context object of the grammar rule
238 * @return boolean value either true or false
239 */
240 public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530241 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530242
243 String value = removeQuotesAndHandleConcat(booleanValue);
Vidyashree Rama1db15562016-05-17 16:16:15 +0530244 if (value.equals(TRUE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530245 return true;
Vidyashree Rama1db15562016-05-17 16:16:15 +0530246 } else if (value.equals(FALSE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530247 return false;
248 } else {
249 ParserException parserException = new ParserException("YANG file error : " +
250 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
251 "valid.");
252 parserException.setLine(ctx.getStart().getLine());
253 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
254 throw parserException;
255 }
256 }
janani bcc9ac302016-03-24 12:43:48 +0530257
258 /**
259 * Sets current date and makes it in usable format for revision.
260 *
261 * @return usable current date format for revision
262 */
263 public static String setCurrentDateForRevision() {
264
265 Calendar date = Calendar.getInstance();
266 SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530267 String dateForRevision = dateFormat.format(date.getTime()).replaceAll(SLASH, HYPHEN).replaceAll(SPACE,
janani bcc9ac302016-03-24 12:43:48 +0530268 EMPTY_STRING);
269 return dateForRevision;
270 }
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530271
272 /**
273 * Checks and return valid node identifier.
274 *
275 * @param nodeIdentifierString string from yang file
276 * @param yangConstruct yang construct for creating error message
277 * @param ctx yang construct's context to get the line number and character position
278 * @return valid node identifier
279 */
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530280 public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
281 YangConstructType yangConstruct, ParserRuleContext ctx) {
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530282 String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
283 String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
284 if (tmpData.length == 1) {
285 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
janani b6240d292016-05-17 18:20:33 +0530286 checkForUnsupportedTypes(tmpData[0], yangConstruct, ctx);
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530287 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
288 return nodeIdentifier;
289 } else if (tmpData.length == 2) {
290 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
291 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
292 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
293 return nodeIdentifier;
294 } else {
295 ParserException parserException = new ParserException("YANG file error : " +
296 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
297 " is not valid.");
298 parserException.setLine(ctx.getStart().getLine());
299 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
300 throw parserException;
301 }
302 }
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530303
304 /**
janani b6240d292016-05-17 18:20:33 +0530305 * Checks whether the type is an unsupported type.
306 *
307 * @param typeName name of the type
308 * @param yangConstruct yang construct to check if it is type
309 * @param ctx yang construct's context to get the line number and character position
310 */
311 private static void checkForUnsupportedTypes(String typeName,
312 YangConstructType yangConstruct, ParserRuleContext ctx) {
313
314 if (yangConstruct == YangConstructType.TYPE_DATA) {
315 if (typeName.equalsIgnoreCase(LEAFREF)) {
316 handleUnsupportedYangConstruct(YangConstructType.LEAFREF_DATA,
317 ctx, CURRENTLY_UNSUPPORTED);
318 } else if (typeName.equalsIgnoreCase(IDENTITYREF)) {
319 handleUnsupportedYangConstruct(YangConstructType.IDENTITYREF_DATA,
320 ctx, CURRENTLY_UNSUPPORTED);
321 } else if (typeName.equalsIgnoreCase(INSTANCE_IDENTIFIER)) {
322 handleUnsupportedYangConstruct(YangConstructType.INSTANCE_IDENTIFIER_DATA,
323 ctx, CURRENTLY_UNSUPPORTED);
324 }
325 }
326 }
327
328 /**
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530329 * Checks and return valid absolute schema node id.
330 *
331 * @param argumentString string from yang file
332 * @param yangConstructType yang construct for creating error message
333 * @param ctx yang construct's context to get the line number and character position
334 * @return target nodes list of absolute schema node id
335 */
336 public static List<YangNodeIdentifier> getValidAbsoluteSchemaNodeId(String argumentString,
337 YangConstructType yangConstructType, ParserRuleContext ctx) {
338
339 List<YangNodeIdentifier> targetNodes = new LinkedList<>();
340 YangNodeIdentifier yangNodeIdentifier;
341 String tmpSchemaNodeId = removeQuotesAndHandleConcat(argumentString);
342
343 // absolute-schema-nodeid = 1*("/" node-identifier)
344 if (!tmpSchemaNodeId.startsWith(SLASH)) {
345 ParserException parserException = new ParserException("YANG file error : " +
346 YangConstructType.getYangConstructType(yangConstructType) + " name " + argumentString +
347 "is not valid");
348 parserException.setLine(ctx.getStart().getLine());
349 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
350 throw parserException;
351 }
352 String[] tmpData = tmpSchemaNodeId.replaceFirst(CARET + SLASH, EMPTY_STRING).split(SLASH);
353 for (String nodeIdentifiers : tmpData) {
354 yangNodeIdentifier = getValidNodeIdentifier(nodeIdentifiers, yangConstructType, ctx);
355 targetNodes.add(yangNodeIdentifier);
356 }
357 return targetNodes;
358 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530359
360 /**
361 * Throws parser exception for unsupported YANG constructs.
362 *
363 * @param yangConstructType yang construct for creating error message
364 * @param ctx yang construct's context to get the line number and character position
365 * @param errorInfo error information
366 */
367 public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
368 ParserRuleContext ctx, String errorInfo) {
369 ParserException parserException = new ParserException(YANG_FILE_ERROR
370 + QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
371 + errorInfo);
372 parserException.setLine(ctx.getStart().getLine());
373 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
374 throw parserException;
375 }
Vidyashree Rama468f8282016-03-04 19:08:35 +0530376}