X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-generator-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fmodel%2Futil%2FBindingGeneratorUtil.java;h=15b733a06345f50f5b8e340bca9b4bd10a66b98b;hb=62d1bb7f2cf0c96ce34ca181462132dc95555daf;hp=f7245e655629176331a2a5f7f45df86e7c974abf;hpb=d1081ff6798c7678eaaa5decb1a389a884389f51;p=mdsal.git diff --git a/binding/mdsal-binding-generator-util/src/main/java/org/opendaylight/mdsal/binding/model/util/BindingGeneratorUtil.java b/binding/mdsal-binding-generator-util/src/main/java/org/opendaylight/mdsal/binding/model/util/BindingGeneratorUtil.java index f7245e6556..15b733a063 100644 --- a/binding/mdsal-binding-generator-util/src/main/java/org/opendaylight/mdsal/binding/model/util/BindingGeneratorUtil.java +++ b/binding/mdsal-binding-generator-util/src/main/java/org/opendaylight/mdsal/binding/model/util/BindingGeneratorUtil.java @@ -8,6 +8,7 @@ package org.opendaylight.mdsal.binding.model.util; import com.google.common.base.CharMatcher; +import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.Iterables; @@ -33,8 +34,6 @@ import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuil import org.opendaylight.mdsal.binding.model.api.type.builder.TypeMemberBuilder; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; @@ -54,16 +53,15 @@ import org.opendaylight.yangtools.yang.model.util.type.DecimalTypeBuilder; public final class BindingGeneratorUtil { /** - * Impossible to instantiate this class. All of the methods or attributes - * are static. + * Impossible to instantiate this class. All of the methods or attributes are static. */ private BindingGeneratorUtil() { + } /** * Pre-compiled replacement pattern. */ - private static final CharMatcher DOT_MATCHER = CharMatcher.is('.'); private static final CharMatcher DASH_COLON_MATCHER = CharMatcher.anyOf("-:"); private static final CharMatcher GT_MATCHER = CharMatcher.is('>'); private static final CharMatcher LT_MATCHER = CharMatcher.is('<'); @@ -92,19 +90,15 @@ public final class BindingGeneratorUtil { }; private static final Comparator> SUID_MEMBER_COMPARATOR = - (o1, o2) -> o1.getName().compareTo(o2.getName()); + Comparator.comparing(TypeMemberBuilder::getName); - private static final Comparator SUID_NAME_COMPARATOR = - (o1, o2) -> o1.getFullyQualifiedName().compareTo(o2.getFullyQualifiedName()); + private static final Comparator SUID_NAME_COMPARATOR = Comparator.comparing(Type::getFullyQualifiedName); /** - * Converts parameterName to valid JAVA parameter name. - * - * If the parameterName is one of the JAVA reserved words then - * it is prefixed with underscore character. + * 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 + * @param parameterName string with the parameter name * @return string with the admissible parameter name */ public static String resolveJavaReservedWordEquivalency(final String parameterName) { @@ -115,44 +109,13 @@ public final class BindingGeneratorUtil { } /** - * Converts module name to valid JAVA package name. - * - * The package name consists of: - *
    - *
  • prefix - org.opendaylight.yang.gen.v
  • - *
  • module YANG version - org.opendaylight.yang.gen.v
  • - *
  • module namespace - invalid characters are replaced with dots
  • - *
  • revision prefix - .rev
  • - *
  • revision - YYYYMMDD (MM and DD aren't spread to the whole length)
  • - *
- * - * @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 - * @deprecated USe {@link BindingMapping#getRootPackageName(QNameModule)} with {@link Module#getQNameModule()}. - */ - @Deprecated - public static String moduleNamespaceToPackageName(final Module module) { - return BindingMapping.getRootPackageName(module.getQNameModule()); - } - - /** - * Creates package name from specified basePackageName (package - * name for module) and schemaPath. + * 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. * - * 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, MUST be normalized, - * otherwise this method may return an invalid string. - * @param schemaPath - * list of names of YANG nodes which are parents of some node + - * name of this node + * @param basePackageName string with package name of the module, MUST be normalized, otherwise this method may + * return an invalid string. + * @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 * @throws NullPointerException if any of the arguments are null */ @@ -166,23 +129,19 @@ public final class BindingGeneratorUtil { } /** - * Creates package name from specified basePackageName (package - * name for module) and schemaPath which crosses an augmentation. - * - * 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. + * Creates package name from specified basePackageName (package name for module) + * and schemaPath which crosses an augmentation. 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, MUST be normalized, - * otherwise this method may return an invalid string. - * @param schemaPath - * list of names of YANG nodes which are parents of some node + - * name of this node + * @param basePackageName string with package name of the module, MUST be normalized, otherwise this method may + * return an invalid string. + * @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 * @throws NullPointerException if any of the arguments are null */ - public static String packageNameForAugmentedGeneratedType(final String basePackageName, final SchemaPath schemaPath) { + public static String packageNameForAugmentedGeneratedType(final String basePackageName, + final SchemaPath schemaPath) { final int size = Iterables.size(schemaPath.getPathTowardsRoot()); if (size == 0) { return basePackageName; @@ -203,223 +162,31 @@ public final class BindingGeneratorUtil { return BindingMapping.normalizePackageName(builder.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 - * @param isUsesAugment - * boolean true if using augment - * @return string with valid JAVA package name - * - * @deprecated Use {@link #packageNameForGeneratedType(String, SchemaPath)} or - * {@link #packageNameForAugmentedGeneratedType(String, SchemaPath)} instead. - */ - @Deprecated - public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath, - final boolean isUsesAugment) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (schemaPath == null) { - throw new IllegalArgumentException("Schema Path cannot be NULL!"); - } - - final Iterable iterable = schemaPath.getPathFromRoot(); - final int size = Iterables.size(iterable); - final int traversalSteps; - if (isUsesAugment) { - traversalSteps = size; - } else { - traversalSteps = size - 1; - } - - if (traversalSteps == 0) { - return BindingMapping.normalizePackageName(basePackageName); - } - - return generateNormalizedPackageName(basePackageName, iterable, traversalSteps); - } - - /** - * 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
  • - *
- * @deprecated This method ignores typeDefinition argument and its result is only - * BindingMapping.normalizePackageName(basePackageName). - * Aside from tests, there is not a single user in OpenDaylight codebase, - * hence it can be considered buggy and defunct. It is scheduled for removal - * in Boron release. - */ - @Deprecated - 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!"); - } - - return BindingMapping.normalizePackageName(basePackageName); - } - - /** - * 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. - * - * @deprecated Use {@link BindingMapping#getClassName(QName)} instead. - */ - @Deprecated - public static String parseToClassName(final String token) { - return parseToCamelCase(token, true); - } - - /** - * 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. - * - * @deprecated Use {@link BindingMapping#getPropertyName(String)} instead. - */ - @Deprecated public static String parseToValidParamName(final String token) { - return resolveJavaReservedWordEquivalency(parseToCamelCase(token, false)); - } - - /** - * - * Converts string token to the cammel case format. - * - * @param token - * string which should be converted to the cammel case format - * @param uppercase - * boolean value which says whether the first character of the - * token should|shuldn't be uppercased - * @return string in the cammel case format - * @throws IllegalArgumentException - *
    - *
  • if token without white spaces is empty
  • - *
  • if token equals null
  • - *
- */ - private static String parseToCamelCase(final String token, final boolean uppercase) { - if (token == null) { - throw new IllegalArgumentException("Name can not be null"); - } - - String correctStr = DOT_MATCHER.removeFrom(token.trim()); - if (correctStr.isEmpty()) { - throw new IllegalArgumentException("Name can not be empty"); - } - - correctStr = replaceWithCamelCase(correctStr, ' '); - correctStr = replaceWithCamelCase(correctStr, '-'); - correctStr = replaceWithCamelCase(correctStr, '_'); - - char firstChar = correctStr.charAt(0); - firstChar = uppercase ? Character.toUpperCase(firstChar) : Character.toLowerCase(firstChar); - - if (firstChar >= '0' && firstChar <= '9') { - return '_' + correctStr; - } else { - return firstChar + correctStr.substring(1); - } - } - - /** - * Replaces all the occurrences 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(final String text, final char removalChar) { - int toBeRemovedPos = text.indexOf(removalChar); - if (toBeRemovedPos == -1) { - return text; - } - - final StringBuilder sb = new StringBuilder(text); - final String toBeRemoved = String.valueOf(removalChar); - do { - 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"); - } - final char replacement = Character.toUpperCase(sb.charAt(toBeRemovedPos)); - sb.setCharAt(toBeRemovedPos, replacement); - toBeRemovedPos = sb.indexOf(toBeRemoved); - } while (toBeRemovedPos != -1); - - return sb.toString(); - } - private static Iterable sortedCollection(final Comparator comparator, final Collection input) { - if (input.size() > 1) { - final List ret = new ArrayList<>(input); - Collections.sort(ret, comparator); - return ret; - } else { + if (input.size() <= 1) { return input; } + + final List ret = new ArrayList<>(input); + ret.sort(comparator); + return ret; } - private static final ThreadLocal SHA1_MD = new ThreadLocal() { - @Override - protected MessageDigest initialValue() { - try { - return MessageDigest.getInstance("SHA"); - } catch (final NoSuchAlgorithmException e) { - throw new IllegalStateException("Failed to get a SHA digest provider", e); - } + private static final ThreadLocal SHA1_MD = ThreadLocal.withInitial(() -> { + try { + return MessageDigest.getInstance("SHA"); + } catch (final NoSuchAlgorithmException e) { + throw new IllegalStateException("Failed to get a SHA digest provider", e); } - }; + }); public static long computeDefaultSUID(final GeneratedTypeBuilderBase to) { final ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (final DataOutputStream dout = new DataOutputStream(bout)) { + try (DataOutputStream dout = new DataOutputStream(bout)) { dout.writeUTF(to.getName()); dout.writeInt(to.isAbstract() ? 3 : 7); - for (final Type ifc : sortedCollection(SUID_NAME_COMPARATOR, to.getImplementsTypes())) { + for (final Type ifc : sortedCollection(SUID_NAME_COMPARATOR, filteredImplementsTypes(to))) { dout.writeUTF(ifc.getFullyQualifiedName()); } @@ -447,6 +214,10 @@ public final class BindingGeneratorUtil { return hash; } + private static Collection filteredImplementsTypes(final GeneratedTypeBuilderBase to) { + return Collections2.filter(to.getImplementsTypes(), item -> !BindingTypes.TYPE_OBJECT.equals(item)); + } + private static > T currentOrEmpty(final T current, final T base) { return current.equals(base) ? (T)Optional.empty() : current; } @@ -597,14 +368,17 @@ public final class BindingGeneratorUtil { public Optional> getRangeConstraint() { return range; } + @Override public List getPatternConstraints() { return pattern; } + @Override public Optional getLengthConstraint() { return length; } + @Override public boolean isEmpty() { return false; @@ -623,7 +397,8 @@ public final class BindingGeneratorUtil { } /** - * Encodes angle brackets in yang statement description + * Encodes angle brackets in yang statement description. + * * @param description description of a yang statement which is used to generate javadoc comments * @return string with encoded angle brackets */ @@ -635,7 +410,28 @@ public final class BindingGeneratorUtil { return description; } - public static String replaceAllIllegalChars(final CharSequence stringBuilder){ + @Deprecated + public static String replaceAllIllegalChars(final CharSequence stringBuilder) { + return defangUnicodeEscapes(stringBuilder); + } + + /** + * Escape potential unicode references so that the resulting string is safe to put into a {@code .java} file. This + * processing is required to ensure this text we want to append does not end up with eligible backslashes. See + * Java Language Specification + * for more information. + * + * @param str Input string + * @return A string with all backslashes made ineligible + */ + public static String replaceAllIllegalChars(final String str) { + final int backslash = str.indexOf('\\'); + return backslash == -1 ? str : defangUnicodeEscapes(str); + } + + private static String defangUnicodeEscapes(final CharSequence stringBuilder) { + // TODO: we should be able to receive the first offset from the non-deprecated method and perform a manual + // check for eligibility and escape -- that would be faster I think. final String ret = UNICODE_CHAR_PATTERN.matcher(stringBuilder).replaceAll("\\\\\\\\u"); return ret.isEmpty() ? "" : ret; }