blob: 7f4e86b755a61a63d736f988ab7801e95614d886 [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;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053028import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
Vidyashree Rama468f8282016-03-04 19:08:35 +053029import org.onosproject.yangutils.parser.exceptions.ParserException;
Bharat saraswald9822e92016-04-05 15:13:44 +053030import org.onosproject.yangutils.utils.YangConstructType;
Vidyashree Rama468f8282016-03-04 19:08:35 +053031
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 Rama8a6b1282016-03-15 10:18:25 +053057 private static final String ONE = "1";
Vidyashree Rama468f8282016-03-04 19:08:35 +053058 private static final int IDENTIFIER_LENGTH = 64;
janani bcc9ac302016-03-24 12:43:48 +053059 private static final String DATE_FORMAT = "yyyy-MM-dd";
Vidyashree Rama468f8282016-03-04 19:08:35 +053060
61 /**
62 * Creates a new listener util.
63 */
64 private ListenerUtil() {
65 }
66
67 /**
68 * Removes doubles quotes and concatenates if string has plus symbol.
69 *
70 * @param yangStringData string from yang file
71 * @return concatenated string after removing double quotes
72 */
73 public static String removeQuotesAndHandleConcat(String yangStringData) {
74
janani bcc9ac302016-03-24 12:43:48 +053075 yangStringData = yangStringData.replace("\"", EMPTY_STRING);
Vidyashree Rama1db15562016-05-17 16:16:15 +053076 String[] tmpData = yangStringData.split(Pattern.quote(ADD));
Vidyashree Rama468f8282016-03-04 19:08:35 +053077 StringBuilder builder = new StringBuilder();
78 for (String yangString : tmpData) {
79 builder.append(yangString);
80 }
81 return builder.toString();
82 }
83
84 /**
85 * Validates identifier and returns concatenated string if string contains plus symbol.
86 *
87 * @param identifier string from yang file
88 * @param yangConstruct yang construct for creating error message
89 * @param ctx yang construct's context to get the line number and character position
90 * @return concatenated string after removing double quotes
91 */
92 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
93
94 String identifierString = removeQuotesAndHandleConcat(identifier);
95 ParserException parserException;
96
97 if (identifierString.length() > IDENTIFIER_LENGTH) {
98 parserException = new ParserException("YANG file error : " +
99 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is " +
100 "greater than 64 characters.");
101 } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
102 parserException = new ParserException("YANG file error : " +
103 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is not " +
104 "valid.");
105 } else {
106 return identifierString;
107 }
108
109 parserException.setLine(ctx.getStart().getLine());
110 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
111 throw parserException;
112 }
113
114 /**
115 * Validates the revision date.
116 *
117 * @param dateToValidate input revision date
118 * @return validation result, true for success, false for failure
119 */
120 public static boolean isDateValid(String dateToValidate) {
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +0530121 if (dateToValidate == null || !dateToValidate.matches(DATE_PATTERN)) {
Vidyashree Rama468f8282016-03-04 19:08:35 +0530122 return false;
123 }
124
janani bcc9ac302016-03-24 12:43:48 +0530125 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Vidyashree Rama468f8282016-03-04 19:08:35 +0530126 sdf.setLenient(false);
127
128 try {
129 //if not valid, it will throw ParseException
130 sdf.parse(dateToValidate);
131 } catch (ParseException e) {
132 return false;
133 }
134
135 return true;
136 }
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530137
138 /**
139 * Validates YANG version.
140 *
141 * @param ctx version context object of the grammar rule
142 * @return valid version
143 */
144 public static byte getValidVersion(GeneratedYangParser.YangVersionStatementContext ctx) {
145
146 String value = removeQuotesAndHandleConcat(ctx.version().getText());
147 if (!value.equals(ONE)) {
148 ParserException parserException = new ParserException("YANG file error: Input version not supported");
149 parserException.setLine(ctx.getStart().getLine());
150 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
151 throw parserException;
152 }
153
154 return Byte.valueOf(value);
155 }
156
157 /**
158 * Validates non negative integer value.
159 *
160 * @param integerValue integer to be validated
161 * @param yangConstruct yang construct for creating error message
162 * @param ctx context object of the grammar rule
163 * @return valid non negative integer value
164 */
165 public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530166 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530167
168 String value = removeQuotesAndHandleConcat(integerValue);
169 if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
170 ParserException parserException = new ParserException("YANG file error : " +
171 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
172 "valid.");
173 parserException.setLine(ctx.getStart().getLine());
174 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
175 throw parserException;
176 }
177
178 return Integer.parseInt(value);
179 }
180
181 /**
Vidyashree Rama1db15562016-05-17 16:16:15 +0530182 * Validates integer value.
183 *
184 * @param integerValue integer to be validated
185 * @param yangConstruct yang construct for creating error message
186 * @param ctx context object of the grammar rule
187 * @return valid integer value
188 */
189 public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
190 ParserRuleContext ctx) {
191
192 String value = removeQuotesAndHandleConcat(integerValue);
193 if (!INTEGER_PATTERN.matcher(value).matches()) {
194 ParserException parserException = new ParserException("YANG file error : " +
195 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
196 "valid.");
197 parserException.setLine(ctx.getStart().getLine());
198 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
199 throw parserException;
200 }
201
202 int valueInInteger;
203 try {
204 valueInInteger = Integer.parseInt(value);
205 } catch (NumberFormatException e) {
206 ParserException parserException = new ParserException("YANG file error : " +
207 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
208 "valid.");
209 parserException.setLine(ctx.getStart().getLine());
210 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
211 throw parserException;
212 }
213 return valueInInteger;
214 }
215
216 /**
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530217 * Validates boolean value.
218 *
219 * @param booleanValue value to be validated
220 * @param yangConstruct yang construct for creating error message
221 * @param ctx context object of the grammar rule
222 * @return boolean value either true or false
223 */
224 public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530225 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530226
227 String value = removeQuotesAndHandleConcat(booleanValue);
Vidyashree Rama1db15562016-05-17 16:16:15 +0530228 if (value.equals(TRUE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530229 return true;
Vidyashree Rama1db15562016-05-17 16:16:15 +0530230 } else if (value.equals(FALSE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530231 return false;
232 } else {
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 }
janani bcc9ac302016-03-24 12:43:48 +0530241
242 /**
243 * Sets current date and makes it in usable format for revision.
244 *
245 * @return usable current date format for revision
246 */
247 public static String setCurrentDateForRevision() {
248
249 Calendar date = Calendar.getInstance();
250 SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530251 String dateForRevision = dateFormat.format(date.getTime()).replaceAll(SLASH, HYPHEN).replaceAll(SPACE,
janani bcc9ac302016-03-24 12:43:48 +0530252 EMPTY_STRING);
253 return dateForRevision;
254 }
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530255
256 /**
257 * Checks and return valid node identifier.
258 *
259 * @param nodeIdentifierString string from yang file
260 * @param yangConstruct yang construct for creating error message
261 * @param ctx yang construct's context to get the line number and character position
262 * @return valid node identifier
263 */
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530264 public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
265 YangConstructType yangConstruct, ParserRuleContext ctx) {
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530266 String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
267 String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
268 if (tmpData.length == 1) {
269 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
janani b6240d292016-05-17 18:20:33 +0530270 checkForUnsupportedTypes(tmpData[0], yangConstruct, ctx);
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530271 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
272 return nodeIdentifier;
273 } else if (tmpData.length == 2) {
274 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
275 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
276 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
277 return nodeIdentifier;
278 } else {
279 ParserException parserException = new ParserException("YANG file error : " +
280 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
281 " is not valid.");
282 parserException.setLine(ctx.getStart().getLine());
283 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
284 throw parserException;
285 }
286 }
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530287
288 /**
janani b6240d292016-05-17 18:20:33 +0530289 * Checks whether the type is an unsupported type.
290 *
291 * @param typeName name of the type
292 * @param yangConstruct yang construct to check if it is type
293 * @param ctx yang construct's context to get the line number and character position
294 */
295 private static void checkForUnsupportedTypes(String typeName,
296 YangConstructType yangConstruct, ParserRuleContext ctx) {
297
298 if (yangConstruct == YangConstructType.TYPE_DATA) {
299 if (typeName.equalsIgnoreCase(LEAFREF)) {
300 handleUnsupportedYangConstruct(YangConstructType.LEAFREF_DATA,
301 ctx, CURRENTLY_UNSUPPORTED);
302 } else if (typeName.equalsIgnoreCase(IDENTITYREF)) {
303 handleUnsupportedYangConstruct(YangConstructType.IDENTITYREF_DATA,
304 ctx, CURRENTLY_UNSUPPORTED);
305 } else if (typeName.equalsIgnoreCase(INSTANCE_IDENTIFIER)) {
306 handleUnsupportedYangConstruct(YangConstructType.INSTANCE_IDENTIFIER_DATA,
307 ctx, CURRENTLY_UNSUPPORTED);
308 }
309 }
310 }
311
312 /**
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530313 * Checks and return valid absolute schema node id.
314 *
315 * @param argumentString string from yang file
316 * @param yangConstructType yang construct for creating error message
317 * @param ctx yang construct's context to get the line number and character position
318 * @return target nodes list of absolute schema node id
319 */
320 public static List<YangNodeIdentifier> getValidAbsoluteSchemaNodeId(String argumentString,
321 YangConstructType yangConstructType, ParserRuleContext ctx) {
322
323 List<YangNodeIdentifier> targetNodes = new LinkedList<>();
324 YangNodeIdentifier yangNodeIdentifier;
325 String tmpSchemaNodeId = removeQuotesAndHandleConcat(argumentString);
326
327 // absolute-schema-nodeid = 1*("/" node-identifier)
328 if (!tmpSchemaNodeId.startsWith(SLASH)) {
329 ParserException parserException = new ParserException("YANG file error : " +
330 YangConstructType.getYangConstructType(yangConstructType) + " name " + argumentString +
331 "is not valid");
332 parserException.setLine(ctx.getStart().getLine());
333 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
334 throw parserException;
335 }
336 String[] tmpData = tmpSchemaNodeId.replaceFirst(CARET + SLASH, EMPTY_STRING).split(SLASH);
337 for (String nodeIdentifiers : tmpData) {
338 yangNodeIdentifier = getValidNodeIdentifier(nodeIdentifiers, yangConstructType, ctx);
339 targetNodes.add(yangNodeIdentifier);
340 }
341 return targetNodes;
342 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530343
344 /**
345 * Throws parser exception for unsupported YANG constructs.
346 *
347 * @param yangConstructType yang construct for creating error message
348 * @param ctx yang construct's context to get the line number and character position
349 * @param errorInfo error information
350 */
351 public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
352 ParserRuleContext ctx, String errorInfo) {
353 ParserException parserException = new ParserException(YANG_FILE_ERROR
354 + QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
355 + errorInfo);
356 parserException.setLine(ctx.getStart().getLine());
357 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
358 throw parserException;
359 }
Vidyashree Rama468f8282016-03-04 19:08:35 +0530360}