package org.opendaylight.yangtools.binding.generator.util; import java.util.Arrays; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; /** * Contains the methods for converting strings to valid JAVA language strings * (package names, class names, attribute names). * * */ public final class BindingGeneratorUtil { /** * Array of strings values which represents JAVA reserved words. */ private static final String[] SET_VALUES = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" }; /** * Impossible to instantiate this class. All of the methods or attributes * are static. */ private BindingGeneratorUtil() { } /** * Hash set of words which are reserved in JAVA language. */ private static final Set JAVA_RESERVED_WORDS = new HashSet(Arrays.asList(SET_VALUES)); /** * Converts string packageName to valid JAVA package name. * * If some words of package name are digits of JAVA reserved words they are * prefixed with underscore character. * * @param packageName * string which contains words separated by point. * @return package name which contains words separated by point. */ private static String validateJavaPackage(final String packageName) { if (packageName != null) { final String[] packNameParts = packageName.split("\\."); if (packNameParts != null) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < packNameParts.length; ++i) { final String packNamePart = packNameParts[i]; if (Character.isDigit(packNamePart.charAt(0))) { packNameParts[i] = "_" + packNamePart; } else if (JAVA_RESERVED_WORDS.contains(packNamePart)) { packNameParts[i] = "_" + packNamePart; } if (i > 0) { builder.append("."); } builder.append(packNameParts[i]); } return builder.toString(); } } return packageName; } /** * Converts parameterName to valid JAVA parameter name. * * If the parameterName is one of the JAVA reserved words then * it is prefixed with underscore character. * * @param parameterName * string with the parameter name * @return string with the admissible parameter name */ public static String validateParameterName(final String parameterName) { if (parameterName != null) { if (JAVA_RESERVED_WORDS.contains(parameterName)) { return "_" + parameterName; } } return parameterName; } /** * Creates generated TO builder from packageName and * transObjectName. * * @param packageName * string with name of package to which the returned object * belongs * @param transObjectName * string with name which the returned object has * @return generated TO builder or null value if * packageName or transObjectName equal * null */ public static GeneratedTOBuilder schemaNodeToTransferObjectBuilder(final String packageName, final String transObjectName) { if (packageName != null && transObjectName != null) { final String genTOName = BindingGeneratorUtil.parseToClassName(transObjectName); final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName); return newType; } return null; } /** * Converts module name to valid JAVA package name. * * The package name consists of: * * * @param module * module which contains data about namespace and revision date * @return string with the valid JAVA package name * @throws IllegalArgumentException * if the revision date of the module equals * null */ public static String moduleNamespaceToPackageName(final Module module) { final StringBuilder packageNameBuilder = new StringBuilder(); final Calendar calendar = Calendar.getInstance(); if (module.getRevision() == null) { throw new IllegalArgumentException("Module " + module.getName() + " does not specify revision date!"); } packageNameBuilder.append("org.opendaylight.yang.gen.v"); packageNameBuilder.append(module.getYangVersion()); packageNameBuilder.append("."); String namespace = module.getNamespace().toString(); namespace = namespace.replace("://", "."); namespace = namespace.replace("/", "."); namespace = namespace.replace(":", "."); namespace = namespace.replace("-", "."); namespace = namespace.replace("@", "."); namespace = namespace.replace("$", "."); namespace = namespace.replace("#", "."); namespace = namespace.replace("'", "."); namespace = namespace.replace("*", "."); namespace = namespace.replace("+", "."); namespace = namespace.replace(",", "."); namespace = namespace.replace(";", "."); namespace = namespace.replace("=", "."); packageNameBuilder.append(namespace); calendar.setTime(module.getRevision()); packageNameBuilder.append(".rev"); packageNameBuilder.append(calendar.get(Calendar.YEAR)); packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1)); packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH)); return validateJavaPackage(packageNameBuilder.toString()); } /** * Creates package name from specified basePackageName (package * name for module) and schemaPath. * * Resulting package name is concatenation of basePackageName * and all local names of YANG nodes which are parents of some node for * which schemaPath is specified. * * @param basePackageName * string with package name of the module * @param schemaPath * list of names of YANG nodes which are parents of some node + * name of this node * @return string with valid JAVA package name */ public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) { if (basePackageName == null) { throw new IllegalArgumentException("Base Package Name cannot be NULL!"); } if (schemaPath == null) { throw new IllegalArgumentException("Schema Path cannot be NULL!"); } final StringBuilder builder = new StringBuilder(); builder.append(basePackageName); final List pathToNode = schemaPath.getPath(); final int traversalSteps = (pathToNode.size() - 1); for (int i = 0; i < traversalSteps; ++i) { builder.append("."); String nodeLocalName = pathToNode.get(i).getLocalName(); nodeLocalName = nodeLocalName.replace(":", "."); nodeLocalName = nodeLocalName.replace("-", "."); builder.append(nodeLocalName); } return validateJavaPackage(builder.toString()); } /** * Generates the package name for type definition from * typeDefinition and basePackageName. * * @param basePackageName * string with the package name of the module * @param typeDefinition * type definition for which the package name will be generated * * @return string with valid JAVA package name * @throws IllegalArgumentException *
    *
  • if basePackageName equals null
  • *
  • if typeDefinition equals null
  • *
*/ public static String packageNameForTypeDefinition(final String basePackageName, final TypeDefinition typeDefinition) { if (basePackageName == null) { throw new IllegalArgumentException("Base Package Name cannot be NULL!"); } if (typeDefinition == null) { throw new IllegalArgumentException("Type Definition reference cannot be NULL!"); } final StringBuilder builder = new StringBuilder(); builder.append(basePackageName); return validateJavaPackage(builder.toString()); } /** * Converts token to string which is in accordance with best * practices for JAVA class names. * * @param token * string which contains characters which should be converted to * JAVA class name * @return string which is in accordance with best practices for JAVA class * name. */ public static String parseToClassName(String token) { token = token.replace(".", ""); String correctStr = parseToCamelCase(token); // make first char upper-case char first = Character.toUpperCase(correctStr.charAt(0)); if(first >= '0' && first <= '9') { correctStr = "_" + correctStr; } else { correctStr = first + correctStr.substring(1); } return correctStr; } /** * Converts token to string which is in accordance with best * practices for JAVA parameter names. * * @param token * string which contains characters which should be converted to * JAVA parameter name * @return string which is in accordance with best practices for JAVA * parameter name. */ public static String parseToValidParamName(final String token) { final String validToken = token.replace(".", ""); String correctStr = parseToCamelCase(validToken); // make first char lower-case char first = Character.toLowerCase(correctStr.charAt(0)); correctStr = first + correctStr.substring(1); return validateParameterName(correctStr); } /** * Converts token to capital letters and removes invalid * characters. * * @param token * string with characters which should be conversed to capital * @return string with capital letters */ public static String convertToCapitalLetters(final String token) { String convertedStr = token.replace(" ", "_"); convertedStr = convertedStr.replace(".", "_"); convertedStr = convertedStr.toUpperCase(); return convertedStr; } /** * * Converts string token to the cammel case format. * * @param token * string which should be converted to the cammel case format * @return string in the cammel case format * @throws NullPointerException * - if token equals null * @throws IllegalArgumentException * - if token without white spaces is empty */ private static String parseToCamelCase(String token) { if (token == null) { throw new NullPointerException("Name can not be null"); } String correctStr = token.trim(); if (correctStr.isEmpty()) { throw new IllegalArgumentException("Name can not be emty"); } correctStr = replaceWithCamelCase(correctStr, ' '); correctStr = replaceWithCamelCase(correctStr, '-'); correctStr = replaceWithCamelCase(correctStr, '_'); return correctStr; } /** * Replaces all the occurances of the removalChar in the * text with empty string and converts following character to * upper case. * * @param text * string with source text which should be converted * @param removalChar * character which is sought in the text * @return string which doesn't contain removalChar and has * following characters converted to upper case * @throws IllegalArgumentException * if the length of the returning string has length 0 */ private static String replaceWithCamelCase(String text, char removalChar) { StringBuilder sb = new StringBuilder(text); String toBeRemoved = String.valueOf(removalChar); int toBeRemovedPos = sb.indexOf(toBeRemoved); while (toBeRemovedPos != -1) { sb.replace(toBeRemovedPos, toBeRemovedPos + 1, ""); // check if 'toBeRemoved' character is not the only character in // 'text' if (sb.length() == 0) { throw new IllegalArgumentException("The resulting string can not be empty"); } String replacement = String.valueOf(sb.charAt(toBeRemovedPos)).toUpperCase(); sb.setCharAt(toBeRemovedPos, replacement.charAt(0)); toBeRemovedPos = sb.indexOf(toBeRemoved); } return sb.toString(); } }