blob: 27b9e8031c547fef246bca9e30627fe6d375257c [file] [log] [blame]
Bharat saraswal870c56f2016-02-20 21:57:16 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Bharat saraswal870c56f2016-02-20 21:57:16 +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.translator.tojava.utils;
18
19import java.util.ArrayList;
janani bde4ffab2016-04-15 16:18:30 +053020import java.util.List;
Bharat saraswal870c56f2016-02-20 21:57:16 +053021
Vinod Kumar S38046502016-03-23 15:30:27 +053022import org.onosproject.yangutils.datamodel.YangNode;
b.janani1fef2732016-03-04 12:29:05 +053023import org.onosproject.yangutils.translator.exception.TranslatorException;
Vinod Kumar S38046502016-03-23 15:30:27 +053024import org.onosproject.yangutils.translator.tojava.HasJavaFileInfo;
25import org.onosproject.yangutils.translator.tojava.JavaFileInfo;
Bharat saraswale2d51d62016-03-23 19:40:35 +053026
27import static org.onosproject.yangutils.utils.UtilConstants.COLAN;
28import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT_BASE_PKG;
29import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
30import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
31import static org.onosproject.yangutils.utils.UtilConstants.JAVA_KEY_WORDS;
32import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
33import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
janani bde4ffab2016-04-15 16:18:30 +053034import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_DIGITS_WITH_SINGLE_LETTER;
Bharat saraswale2d51d62016-03-23 19:40:35 +053035import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_FIRST_DIGIT;
janani bde4ffab2016-04-15 16:18:30 +053036import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_HYPHEN;
37import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_IDENTIFIER_SPECIAL_CHAR;
38import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_PERIOD;
39import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_SINGLE_LETTER;
40import static org.onosproject.yangutils.utils.UtilConstants.REGEX_FOR_UNDERSCORE;
41import static org.onosproject.yangutils.utils.UtilConstants.REGEX_WITH_ALL_SPECIAL_CHAR;
Bharat saraswal2f11f652016-03-25 18:19:46 +053042import static org.onosproject.yangutils.utils.UtilConstants.REVISION_PREFIX;
Bharat saraswale2d51d62016-03-23 19:40:35 +053043import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
44import static org.onosproject.yangutils.utils.UtilConstants.UNDER_SCORE;
Bharat saraswal2f11f652016-03-25 18:19:46 +053045import static org.onosproject.yangutils.utils.UtilConstants.VERSION_PREFIX;
janani bde4ffab2016-04-15 16:18:30 +053046import static org.onosproject.yangutils.utils.UtilConstants.YANG_AUTO_PREFIX;
Bharat saraswal870c56f2016-02-20 21:57:16 +053047
48/**
Bharat saraswald9822e92016-04-05 15:13:44 +053049 * Represents an utility Class for translating the name from YANG to java convention.
Bharat saraswal870c56f2016-02-20 21:57:16 +053050 */
51public final class JavaIdentifierSyntax {
52
b.janani1fef2732016-03-04 12:29:05 +053053 private static final int MAX_MONTHS = 12;
54 private static final int MAX_DAYS = 31;
55 private static final int INDEX_ZERO = 0;
56 private static final int INDEX_ONE = 1;
57 private static final int INDEX_TWO = 2;
Bharat saraswal6ef0b762016-04-05 12:45:45 +053058 private static final int VALUE_CHECK = 10;
59 private static final String ZERO = "0";
b.janani1fef2732016-03-04 12:29:05 +053060
Bharat saraswal870c56f2016-02-20 21:57:16 +053061 /**
Bharat saraswald9822e92016-04-05 15:13:44 +053062 * Create instance of java identifier syntax.
Bharat saraswal870c56f2016-02-20 21:57:16 +053063 */
64 private JavaIdentifierSyntax() {
65 }
66
67 /**
Bharat saraswald9822e92016-04-05 15:13:44 +053068 * Returns the root package string.
Bharat saraswal870c56f2016-02-20 21:57:16 +053069 *
Vinod Kumar Sc4216002016-03-03 19:55:30 +053070 * @param version YANG version
71 * @param nameSpace name space of the module
Bharat saraswal870c56f2016-02-20 21:57:16 +053072 * @param revision revision of the module defined
Vinod Kumar Sc4216002016-03-03 19:55:30 +053073 * @return returns the root package string
Bharat saraswal870c56f2016-02-20 21:57:16 +053074 */
75 public static String getRootPackage(byte version, String nameSpace, String revision) {
76
77 String pkg;
Bharat saraswale2d51d62016-03-23 19:40:35 +053078 pkg = DEFAULT_BASE_PKG;
79 pkg = pkg + PERIOD;
Bharat saraswal870c56f2016-02-20 21:57:16 +053080 pkg = pkg + getYangVersion(version);
Bharat saraswale2d51d62016-03-23 19:40:35 +053081 pkg = pkg + PERIOD;
Bharat saraswal870c56f2016-02-20 21:57:16 +053082 pkg = pkg + getPkgFromNameSpace(nameSpace);
Bharat saraswale2d51d62016-03-23 19:40:35 +053083 pkg = pkg + PERIOD;
Bharat saraswal870c56f2016-02-20 21:57:16 +053084 pkg = pkg + getYangRevisionStr(revision);
85
Bharat saraswal4bf8b152016-02-25 02:26:43 +053086 return pkg.toLowerCase();
Bharat saraswal870c56f2016-02-20 21:57:16 +053087 }
88
89 /**
Bharat saraswald9822e92016-04-05 15:13:44 +053090 * Returns the contained data model parent node.
Vinod Kumar S38046502016-03-23 15:30:27 +053091 *
92 * @param currentNode current node which parent contained node is required
93 * @return parent node in which the current node is an attribute
94 */
95 public static YangNode getParentNodeInGenCode(YangNode currentNode) {
96
97 /*
98 * TODO: recursive parent lookup to support choice/augment/uses. TODO:
99 * need to check if this needs to be updated for
100 * choice/case/augment/grouping
101 */
102 return currentNode.getParent();
103 }
104
105 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530106 * Returns the node package string.
Vinod Kumar S38046502016-03-23 15:30:27 +0530107 *
108 * @param curNode current java node whose package string needs to be set
109 * @return returns the root package string
110 */
111 public static String getCurNodePackage(YangNode curNode) {
112
113 String pkg;
114 if (!(curNode instanceof HasJavaFileInfo)
115 || curNode.getParent() == null) {
Bharat saraswal6ef0b762016-04-05 12:45:45 +0530116 throw new TranslatorException("missing parent node to get current node's package");
Vinod Kumar S38046502016-03-23 15:30:27 +0530117 }
118
119 YangNode parentNode = getParentNodeInGenCode(curNode);
120 if (!(parentNode instanceof HasJavaFileInfo)) {
Bharat saraswal6ef0b762016-04-05 12:45:45 +0530121 throw new TranslatorException("missing parent java node to get current node's package");
Vinod Kumar S38046502016-03-23 15:30:27 +0530122 }
123 JavaFileInfo parentJavaFileHandle = ((HasJavaFileInfo) parentNode).getJavaFileInfo();
Bharat saraswale2d51d62016-03-23 19:40:35 +0530124 pkg = parentJavaFileHandle.getPackage() + PERIOD + parentJavaFileHandle.getJavaName();
Vinod Kumar S38046502016-03-23 15:30:27 +0530125 return pkg.toLowerCase();
126 }
127
128 /**
Bharat saraswal870c56f2016-02-20 21:57:16 +0530129 * Returns version.
130 *
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530131 * @param ver YANG version
Bharat saraswal870c56f2016-02-20 21:57:16 +0530132 * @return version
133 */
134 private static String getYangVersion(byte ver) {
Bharat saraswal2f11f652016-03-25 18:19:46 +0530135 return VERSION_PREFIX + ver;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530136 }
137
138 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530139 * Returns package name from name space.
Bharat saraswal870c56f2016-02-20 21:57:16 +0530140 *
141 * @param nameSpace name space of YANG module
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530142 * @return java package name as per java rules
Bharat saraswal870c56f2016-02-20 21:57:16 +0530143 */
Bharat saraswald9822e92016-04-05 15:13:44 +0530144 private static String getPkgFromNameSpace(String nameSpace) {
Vinod Kumar S38046502016-03-23 15:30:27 +0530145
Bharat saraswal870c56f2016-02-20 21:57:16 +0530146 ArrayList<String> pkgArr = new ArrayList<String>();
Bharat saraswale2d51d62016-03-23 19:40:35 +0530147 nameSpace = nameSpace.replace(QUOTES, EMPTY_STRING);
janani bde4ffab2016-04-15 16:18:30 +0530148 String properNameSpace = nameSpace.replaceAll(REGEX_WITH_ALL_SPECIAL_CHAR, COLAN);
Bharat saraswale2d51d62016-03-23 19:40:35 +0530149 String[] nameSpaceArr = properNameSpace.split(COLAN);
Bharat saraswal870c56f2016-02-20 21:57:16 +0530150
151 for (String nameSpaceString : nameSpaceArr) {
152 pkgArr.add(nameSpaceString);
153 }
154 return getPkgFrmArr(pkgArr);
155 }
156
157 /**
158 * Returns revision string array.
159 *
160 * @param date YANG module revision
161 * @return revision string
b.janani1fef2732016-03-04 12:29:05 +0530162 * @throws TranslatorException when date is invalid.
Bharat saraswal870c56f2016-02-20 21:57:16 +0530163 */
Bharat saraswald9822e92016-04-05 15:13:44 +0530164 private static String getYangRevisionStr(String date) throws TranslatorException {
Vinod Kumar S38046502016-03-23 15:30:27 +0530165
Bharat saraswale2d51d62016-03-23 19:40:35 +0530166 String[] revisionArr = date.split(HYPHEN);
Bharat saraswal870c56f2016-02-20 21:57:16 +0530167
Bharat saraswal2f11f652016-03-25 18:19:46 +0530168 String rev = REVISION_PREFIX;
Bharat saraswal2f00b4b2016-03-04 20:08:09 +0530169 rev = rev + revisionArr[INDEX_ZERO];
b.janani1fef2732016-03-04 12:29:05 +0530170
Vinod Kumar S38046502016-03-23 15:30:27 +0530171 if (Integer.parseInt(revisionArr[INDEX_ONE]) <= MAX_MONTHS
b.janani1fef2732016-03-04 12:29:05 +0530172 && Integer.parseInt(revisionArr[INDEX_TWO]) <= MAX_DAYS) {
173 for (int i = INDEX_ONE; i < revisionArr.length; i++) {
174
175 Integer val = Integer.parseInt(revisionArr[i]);
Bharat saraswal6ef0b762016-04-05 12:45:45 +0530176 if (val < VALUE_CHECK) {
177 rev = rev + ZERO;
b.janani1fef2732016-03-04 12:29:05 +0530178 }
179 rev = rev + val;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530180 }
b.janani1fef2732016-03-04 12:29:05 +0530181
182 return rev;
183 } else {
184 throw new TranslatorException("Date in revision is not proper: " + date);
Bharat saraswal870c56f2016-02-20 21:57:16 +0530185 }
Bharat saraswal870c56f2016-02-20 21:57:16 +0530186 }
187
188 /**
189 * Returns the package string.
190 *
191 * @param pkgArr package array
192 * @return package string
193 */
Bharat saraswald9822e92016-04-05 15:13:44 +0530194 private static String getPkgFrmArr(ArrayList<String> pkgArr) {
Bharat saraswal870c56f2016-02-20 21:57:16 +0530195
Bharat saraswale2d51d62016-03-23 19:40:35 +0530196 String pkg = EMPTY_STRING;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530197 int size = pkgArr.size();
198 int i = 0;
199 for (String member : pkgArr) {
Bharat saraswale2d51d62016-03-23 19:40:35 +0530200 boolean presenceOfKeyword = JAVA_KEY_WORDS.contains(member);
201 if (presenceOfKeyword || member.matches(REGEX_FOR_FIRST_DIGIT)) {
janani bde4ffab2016-04-15 16:18:30 +0530202 member = YANG_AUTO_PREFIX + member;
b.janani1fef2732016-03-04 12:29:05 +0530203 }
Bharat saraswal870c56f2016-02-20 21:57:16 +0530204 pkg = pkg + member;
205 if (i != size - 1) {
Bharat saraswale2d51d62016-03-23 19:40:35 +0530206 pkg = pkg + PERIOD;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530207 }
208 i++;
209 }
210 return pkg;
211 }
212
213 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530214 * Returns package sub name from YANG identifier name.
Bharat saraswal870c56f2016-02-20 21:57:16 +0530215 *
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530216 * @param name YANG identifier name
217 * @return java package sub name as per java rules
Bharat saraswal870c56f2016-02-20 21:57:16 +0530218 */
219 public static String getSubPkgFromName(String name) {
Vinod Kumar S38046502016-03-23 15:30:27 +0530220
Bharat saraswal870c56f2016-02-20 21:57:16 +0530221 ArrayList<String> pkgArr = new ArrayList<String>();
Bharat saraswale2d51d62016-03-23 19:40:35 +0530222 String[] nameArr = name.split(COLAN);
Bharat saraswal870c56f2016-02-20 21:57:16 +0530223
224 for (String nameString : nameArr) {
225 pkgArr.add(nameString);
226 }
227 return getPkgFrmArr(pkgArr);
228 }
229
230 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530231 * Returns the YANG identifier name as java identifier.
Bharat saraswal870c56f2016-02-20 21:57:16 +0530232 *
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530233 * @param yangIdentifier identifier in YANG file
janani bde4ffab2016-04-15 16:18:30 +0530234 * @param conflictResolver object of YANG to java naming confilct util
Bharat saraswal870c56f2016-02-20 21:57:16 +0530235 * @return corresponding java identifier
236 */
janani bde4ffab2016-04-15 16:18:30 +0530237 public static String getCamelCase(String yangIdentifier, YangToJavaNamingConflictUtil conflictResolver) {
Vinod Kumar S38046502016-03-23 15:30:27 +0530238
janani bde4ffab2016-04-15 16:18:30 +0530239 if (conflictResolver != null) {
240 String replacementForHyphen = conflictResolver.getReplacementForHyphen();
241 String replacementForPeriod = conflictResolver.getReplacementForPeriod();
242 String replacementForUnderscore = conflictResolver.getReplacementForUnderscore();
243 if (replacementForPeriod != null) {
244 yangIdentifier = yangIdentifier.replaceAll(REGEX_FOR_PERIOD,
245 PERIOD + replacementForPeriod.toLowerCase() + PERIOD);
246 }
247 if (replacementForUnderscore != null) {
248 yangIdentifier = yangIdentifier.replaceAll(REGEX_FOR_UNDERSCORE,
249 UNDER_SCORE + replacementForUnderscore.toLowerCase() + UNDER_SCORE);
250 }
251 if (replacementForHyphen != null) {
252 yangIdentifier = yangIdentifier.replaceAll(REGEX_FOR_HYPHEN,
253 HYPHEN + replacementForHyphen.toLowerCase() + HYPHEN);
254 }
Bharat saraswal870c56f2016-02-20 21:57:16 +0530255 }
janani bde4ffab2016-04-15 16:18:30 +0530256 yangIdentifier = yangIdentifier.replaceAll(REGEX_FOR_IDENTIFIER_SPECIAL_CHAR, COLAN);
257 String[] strArray = yangIdentifier.split(COLAN);
258 if (strArray[0].isEmpty()) {
259 List<String> stringArrangement = new ArrayList<String>();
260 for (int i = 1; i < strArray.length; i++) {
261 stringArrangement.add(strArray[i]);
262 }
263 strArray = stringArrangement.toArray(new String[stringArrangement.size()]);
264 }
265 return applyCamelCaseRule(strArray);
266 }
267
268 /**
269 * Applies the rule that a string does not end with a capitalized letter and capitalizes
270 * the letter next to a number in an array.
271 *
272 * @param stringArray containing strings for camel case separation
273 * @return camel cased string
274 */
275 public static String applyCamelCaseRule(String[] stringArray) {
276
277 String ruleChecker = stringArray[0];
278 int i;
279 if (ruleChecker.matches(REGEX_FOR_FIRST_DIGIT)) {
280 i = 0;
281 ruleChecker = EMPTY_STRING;
282 } else {
283 i = 1;
284 }
285 for (; i < stringArray.length; i++) {
286 if ((i + 1) == stringArray.length) {
287 if (stringArray[i].matches(REGEX_FOR_SINGLE_LETTER)
288 || stringArray[i].matches(REGEX_FOR_DIGITS_WITH_SINGLE_LETTER)) {
289 ruleChecker = ruleChecker + stringArray[i];
290 break;
291 }
292 }
293 if (stringArray[i].matches(REGEX_FOR_FIRST_DIGIT)) {
294 for (int j = 0; j < stringArray[i].length(); j++) {
295 char letterCheck = stringArray[i].charAt(j);
296 if (Character.isLetter(letterCheck)) {
297 stringArray[i] = stringArray[i].substring(0, j)
298 + stringArray[i].substring(j, j + 1).toUpperCase() + stringArray[i].substring(j + 1);
299 break;
300 }
301 }
302 ruleChecker = ruleChecker + stringArray[i];
303 } else {
304 ruleChecker = ruleChecker + stringArray[i].substring(0, 1).toUpperCase() + stringArray[i].substring(1);
305 }
306 }
307 String ruleCheckerWithPrefix = addPrefix(ruleChecker);
308 return restrictConsecutiveCapitalCase(ruleCheckerWithPrefix);
309 }
310
311 /**
312 * Adds prefix YANG auto prefix if the string begins with digit or is a java key word.
313 *
314 * @param camelCasePrefixer string for adding prefix
315 * @return prefixed camel case string
316 */
317 public static String addPrefix(String camelCasePrefixer) {
318
319 if (camelCasePrefixer.matches(REGEX_FOR_FIRST_DIGIT)) {
320 camelCasePrefixer = YANG_AUTO_PREFIX + camelCasePrefixer;
321 }
322 if (JAVA_KEY_WORDS.contains(camelCasePrefixer)) {
323 camelCasePrefixer = YANG_AUTO_PREFIX + camelCasePrefixer.substring(0, 1).toUpperCase()
324 + camelCasePrefixer.substring(1);
325 }
326 return camelCasePrefixer;
327 }
328
329 /**
330 * Restricts consecutive capital cased string as a rule in camel case.
331 *
332 * @param consecCapitalCaseRemover which requires the restriction of consecutive capital case
333 * @return string without consecutive capital case
334 */
335 public static String restrictConsecutiveCapitalCase(String consecCapitalCaseRemover) {
336
337 for (int k = 0; k < consecCapitalCaseRemover.length(); k++) {
338 if (k + 1 < consecCapitalCaseRemover.length()) {
339 if (Character.isUpperCase(consecCapitalCaseRemover.charAt(k))) {
340 if (Character.isUpperCase(consecCapitalCaseRemover.charAt(k + 1))) {
341 consecCapitalCaseRemover = consecCapitalCaseRemover.substring(0, k + 1)
342 + consecCapitalCaseRemover.substring(k + 1, k + 2).toLowerCase()
343 + consecCapitalCaseRemover.substring(k + 2);
344 }
345 }
346 }
347 }
348 return consecCapitalCaseRemover;
Bharat saraswal870c56f2016-02-20 21:57:16 +0530349 }
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530350
351 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530352 * Returns the YANG identifier name as java identifier with first letter
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530353 * in caps.
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530354 *
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530355 * @param yangIdentifier identifier in YANG file
Bharat saraswal594bc6d2016-02-22 22:15:21 +0530356 * @return corresponding java identifier
357 */
358 public static String getCaptialCase(String yangIdentifier) {
359 return yangIdentifier.substring(0, 1).toUpperCase() + yangIdentifier.substring(1);
360 }
b.janani1fef2732016-03-04 12:29:05 +0530361
362 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530363 * Returns the YANG identifier name as java identifier with first letter
Vinod Kumar S38046502016-03-23 15:30:27 +0530364 * in small.
b.janani1fef2732016-03-04 12:29:05 +0530365 *
366 * @param yangIdentifier identifier in YANG file.
367 * @return corresponding java identifier
368 */
Bharat saraswal2f11f652016-03-25 18:19:46 +0530369 public static String getSmallCase(String yangIdentifier) {
b.janani1fef2732016-03-04 12:29:05 +0530370 return yangIdentifier.substring(0, 1).toLowerCase() + yangIdentifier.substring(1);
371 }
Vinod Kumar S38046502016-03-23 15:30:27 +0530372
373 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530374 * Returns the java Package from package path.
Vinod Kumar S38046502016-03-23 15:30:27 +0530375 *
376 * @param packagePath package path
377 * @return java package
378 */
379 public static String getJavaPackageFromPackagePath(String packagePath) {
Bharat saraswale2d51d62016-03-23 19:40:35 +0530380 return packagePath.replace(SLASH, PERIOD);
Vinod Kumar S38046502016-03-23 15:30:27 +0530381 }
382
383 /**
Bharat saraswald72411a2016-04-19 01:00:16 +0530384 * Returns enum's java name.
385 *
386 * @param name enum's name
387 * @return enum's java name
388 */
389 public static String getEnumJavaAttribute(String name) {
390
391 String[] strArray = name.split(HYPHEN);
392 String output = EMPTY_STRING;
393 for (int i = 0; i < strArray.length; i++) {
394 output = output + strArray[i];
395 if (i > 0 && i < strArray.length - 1) {
396 output = output + UNDER_SCORE;
397 }
398 }
399 return output;
400 }
401
402 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530403 * Returns the directory path corresponding to java package.
Vinod Kumar S38046502016-03-23 15:30:27 +0530404 *
405 * @param packagePath package path
406 * @return java package
407 */
408 public static String getPackageDirPathFromJavaJPackage(String packagePath) {
Bharat saraswale2d51d62016-03-23 19:40:35 +0530409 return packagePath.replace(PERIOD, SLASH);
Vinod Kumar S38046502016-03-23 15:30:27 +0530410 }
Bharat saraswal870c56f2016-02-20 21:57:16 +0530411}