blob: de11f05ea646b2d1915a4db50c5752493b19d35c [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;
37import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
38import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
39import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
40import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
41import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
42import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
43
Vidyashree Rama468f8282016-03-04 19:08:35 +053044/**
Bharat saraswald9822e92016-04-05 15:13:44 +053045 * Represents an utility for listener.
Vidyashree Rama468f8282016-03-04 19:08:35 +053046 */
47public final class ListenerUtil {
Bharat saraswald9822e92016-04-05 15:13:44 +053048
Vidyashree Rama468f8282016-03-04 19:08:35 +053049 private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +053050 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 +053051 private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
Vidyashree Rama1db15562016-05-17 16:16:15 +053052 private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053053 private static final String ONE = "1";
Vidyashree Rama468f8282016-03-04 19:08:35 +053054 private static final int IDENTIFIER_LENGTH = 64;
janani bcc9ac302016-03-24 12:43:48 +053055 private static final String DATE_FORMAT = "yyyy-MM-dd";
Vidyashree Rama468f8282016-03-04 19:08:35 +053056
57 /**
58 * Creates a new listener util.
59 */
60 private ListenerUtil() {
61 }
62
63 /**
64 * Removes doubles quotes and concatenates if string has plus symbol.
65 *
66 * @param yangStringData string from yang file
67 * @return concatenated string after removing double quotes
68 */
69 public static String removeQuotesAndHandleConcat(String yangStringData) {
70
janani bcc9ac302016-03-24 12:43:48 +053071 yangStringData = yangStringData.replace("\"", EMPTY_STRING);
Vidyashree Rama1db15562016-05-17 16:16:15 +053072 String[] tmpData = yangStringData.split(Pattern.quote(ADD));
Vidyashree Rama468f8282016-03-04 19:08:35 +053073 StringBuilder builder = new StringBuilder();
74 for (String yangString : tmpData) {
75 builder.append(yangString);
76 }
77 return builder.toString();
78 }
79
80 /**
81 * Validates identifier and returns concatenated string if string contains plus symbol.
82 *
83 * @param identifier string from yang file
84 * @param yangConstruct yang construct for creating error message
85 * @param ctx yang construct's context to get the line number and character position
86 * @return concatenated string after removing double quotes
87 */
88 public static String getValidIdentifier(String identifier, YangConstructType yangConstruct, ParserRuleContext ctx) {
89
90 String identifierString = removeQuotesAndHandleConcat(identifier);
91 ParserException parserException;
92
93 if (identifierString.length() > IDENTIFIER_LENGTH) {
94 parserException = new ParserException("YANG file error : " +
95 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is " +
96 "greater than 64 characters.");
97 } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
98 parserException = new ParserException("YANG file error : " +
99 YangConstructType.getYangConstructType(yangConstruct) + " name " + identifierString + " is not " +
100 "valid.");
101 } else {
102 return identifierString;
103 }
104
105 parserException.setLine(ctx.getStart().getLine());
106 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
107 throw parserException;
108 }
109
110 /**
111 * Validates the revision date.
112 *
113 * @param dateToValidate input revision date
114 * @return validation result, true for success, false for failure
115 */
116 public static boolean isDateValid(String dateToValidate) {
Vidyashree Ramabe0f6da2016-05-09 11:45:05 +0530117 if (dateToValidate == null || !dateToValidate.matches(DATE_PATTERN)) {
Vidyashree Rama468f8282016-03-04 19:08:35 +0530118 return false;
119 }
120
janani bcc9ac302016-03-24 12:43:48 +0530121 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
Vidyashree Rama468f8282016-03-04 19:08:35 +0530122 sdf.setLenient(false);
123
124 try {
125 //if not valid, it will throw ParseException
126 sdf.parse(dateToValidate);
127 } catch (ParseException e) {
128 return false;
129 }
130
131 return true;
132 }
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530133
134 /**
135 * Validates YANG version.
136 *
137 * @param ctx version context object of the grammar rule
138 * @return valid version
139 */
140 public static byte getValidVersion(GeneratedYangParser.YangVersionStatementContext ctx) {
141
142 String value = removeQuotesAndHandleConcat(ctx.version().getText());
143 if (!value.equals(ONE)) {
144 ParserException parserException = new ParserException("YANG file error: Input version not supported");
145 parserException.setLine(ctx.getStart().getLine());
146 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
147 throw parserException;
148 }
149
150 return Byte.valueOf(value);
151 }
152
153 /**
154 * Validates non negative integer value.
155 *
156 * @param integerValue integer to be validated
157 * @param yangConstruct yang construct for creating error message
158 * @param ctx context object of the grammar rule
159 * @return valid non negative integer value
160 */
161 public static int getValidNonNegativeIntegerValue(String integerValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530162 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530163
164 String value = removeQuotesAndHandleConcat(integerValue);
165 if (!value.matches(NON_NEGATIVE_INTEGER_PATTERN)) {
166 ParserException parserException = new ParserException("YANG file error : " +
167 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
168 "valid.");
169 parserException.setLine(ctx.getStart().getLine());
170 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
171 throw parserException;
172 }
173
174 return Integer.parseInt(value);
175 }
176
177 /**
Vidyashree Rama1db15562016-05-17 16:16:15 +0530178 * Validates integer value.
179 *
180 * @param integerValue integer to be validated
181 * @param yangConstruct yang construct for creating error message
182 * @param ctx context object of the grammar rule
183 * @return valid integer value
184 */
185 public static int getValidIntegerValue(String integerValue, YangConstructType yangConstruct,
186 ParserRuleContext ctx) {
187
188 String value = removeQuotesAndHandleConcat(integerValue);
189 if (!INTEGER_PATTERN.matcher(value).matches()) {
190 ParserException parserException = new ParserException("YANG file error : " +
191 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
192 "valid.");
193 parserException.setLine(ctx.getStart().getLine());
194 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
195 throw parserException;
196 }
197
198 int valueInInteger;
199 try {
200 valueInInteger = Integer.parseInt(value);
201 } catch (NumberFormatException e) {
202 ParserException parserException = new ParserException("YANG file error : " +
203 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
204 "valid.");
205 parserException.setLine(ctx.getStart().getLine());
206 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
207 throw parserException;
208 }
209 return valueInInteger;
210 }
211
212 /**
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530213 * Validates boolean value.
214 *
215 * @param booleanValue value to be validated
216 * @param yangConstruct yang construct for creating error message
217 * @param ctx context object of the grammar rule
218 * @return boolean value either true or false
219 */
220 public static boolean getValidBooleanValue(String booleanValue, YangConstructType yangConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530221 ParserRuleContext ctx) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530222
223 String value = removeQuotesAndHandleConcat(booleanValue);
Vidyashree Rama1db15562016-05-17 16:16:15 +0530224 if (value.equals(TRUE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530225 return true;
Vidyashree Rama1db15562016-05-17 16:16:15 +0530226 } else if (value.equals(FALSE)) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530227 return false;
228 } else {
229 ParserException parserException = new ParserException("YANG file error : " +
230 YangConstructType.getYangConstructType(yangConstruct) + " value " + value + " is not " +
231 "valid.");
232 parserException.setLine(ctx.getStart().getLine());
233 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
234 throw parserException;
235 }
236 }
janani bcc9ac302016-03-24 12:43:48 +0530237
238 /**
239 * Sets current date and makes it in usable format for revision.
240 *
241 * @return usable current date format for revision
242 */
243 public static String setCurrentDateForRevision() {
244
245 Calendar date = Calendar.getInstance();
246 SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530247 String dateForRevision = dateFormat.format(date.getTime()).replaceAll(SLASH, HYPHEN).replaceAll(SPACE,
janani bcc9ac302016-03-24 12:43:48 +0530248 EMPTY_STRING);
249 return dateForRevision;
250 }
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530251
252 /**
253 * Checks and return valid node identifier.
254 *
255 * @param nodeIdentifierString string from yang file
256 * @param yangConstruct yang construct for creating error message
257 * @param ctx yang construct's context to get the line number and character position
258 * @return valid node identifier
259 */
Vinod Kumar Sd4deb062016-04-15 18:08:57 +0530260 public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString,
261 YangConstructType yangConstruct, ParserRuleContext ctx) {
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530262 String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
263 String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
264 if (tmpData.length == 1) {
265 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
266 nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
267 return nodeIdentifier;
268 } else if (tmpData.length == 2) {
269 YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
270 nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
271 nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
272 return nodeIdentifier;
273 } else {
274 ParserException parserException = new ParserException("YANG file error : " +
275 YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
276 " is not valid.");
277 parserException.setLine(ctx.getStart().getLine());
278 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
279 throw parserException;
280 }
281 }
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530282
283 /**
284 * Checks and return valid absolute schema node id.
285 *
286 * @param argumentString string from yang file
287 * @param yangConstructType yang construct for creating error message
288 * @param ctx yang construct's context to get the line number and character position
289 * @return target nodes list of absolute schema node id
290 */
291 public static List<YangNodeIdentifier> getValidAbsoluteSchemaNodeId(String argumentString,
292 YangConstructType yangConstructType, ParserRuleContext ctx) {
293
294 List<YangNodeIdentifier> targetNodes = new LinkedList<>();
295 YangNodeIdentifier yangNodeIdentifier;
296 String tmpSchemaNodeId = removeQuotesAndHandleConcat(argumentString);
297
298 // absolute-schema-nodeid = 1*("/" node-identifier)
299 if (!tmpSchemaNodeId.startsWith(SLASH)) {
300 ParserException parserException = new ParserException("YANG file error : " +
301 YangConstructType.getYangConstructType(yangConstructType) + " name " + argumentString +
302 "is not valid");
303 parserException.setLine(ctx.getStart().getLine());
304 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
305 throw parserException;
306 }
307 String[] tmpData = tmpSchemaNodeId.replaceFirst(CARET + SLASH, EMPTY_STRING).split(SLASH);
308 for (String nodeIdentifiers : tmpData) {
309 yangNodeIdentifier = getValidNodeIdentifier(nodeIdentifiers, yangConstructType, ctx);
310 targetNodes.add(yangNodeIdentifier);
311 }
312 return targetNodes;
313 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530314
315 /**
316 * Throws parser exception for unsupported YANG constructs.
317 *
318 * @param yangConstructType yang construct for creating error message
319 * @param ctx yang construct's context to get the line number and character position
320 * @param errorInfo error information
321 */
322 public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
323 ParserRuleContext ctx, String errorInfo) {
324 ParserException parserException = new ParserException(YANG_FILE_ERROR
325 + QUOTES + YangConstructType.getYangConstructType(yangConstructType) + QUOTES
326 + errorInfo);
327 parserException.setLine(ctx.getStart().getLine());
328 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
329 throw parserException;
330 }
Vidyashree Rama468f8282016-03-04 19:08:35 +0530331}