From 9cf74a4683f1378d5c0e84fde2a88610f08240d6 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Fri, 27 Jan 2017 16:34:30 +0100 Subject: [PATCH] Bug 2332 - Binding Java API Generator -> doesn't handle non-alphabetic signs in names of enum constants, allowed by rfc6020 though - find and convert non Java chars in identifiers of generated transfer objects, initially derived from corresponding YANG - this patch also fixes https://bugs.opendaylight.org/show_bug.cgi?id=2641 Change-Id: Ide01a2b574970397ddedaf7da09e0d28219d0616 Signed-off-by: Jakub Toth --- .../generator/util/AbstractBaseType.java | 26 +- .../javav2/generator/util/JavaIdentifier.java | 28 ++ .../generator/util/NonJavaCharsConverter.java | 280 ++++++++++++++++++ .../type/builder/EnumerationBuilderImpl.java | 91 +++--- .../util/NonJavaCharsConverterTest.java | 115 +++++++ .../builder/EnumerationBuilderImplTest.java | 127 ++++++++ 6 files changed, 607 insertions(+), 60 deletions(-) create mode 100644 binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/JavaIdentifier.java create mode 100644 binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverter.java create mode 100644 binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverterTest.java create mode 100644 binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImplTest.java diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/AbstractBaseType.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/AbstractBaseType.java index 0fe2ec1fdc..296800b1da 100644 --- a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/AbstractBaseType.java +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/AbstractBaseType.java @@ -22,12 +22,12 @@ public abstract class AbstractBaseType implements Type { /** * Name of the package to which this Type belongs. */ - private final String packageName; + protected final String packageName; /** * Name of this Type. */ - private final String name; + protected final String name; /** * Constructs the instance of this class with the concrete package name type @@ -46,7 +46,7 @@ public abstract class AbstractBaseType implements Type { @Override public int hashCode() { - return Objects.hash(name, packageName); + return Objects.hash(this.name, this.packageName); } @Override @@ -60,35 +60,35 @@ public abstract class AbstractBaseType implements Type { if (!(obj instanceof Type)) { return false; } - Type other = (Type) obj; - return Objects.equals(name, other.getName()) && Objects.equals(packageName, other.getPackageName()); + final Type other = (Type) obj; + return Objects.equals(this.name, other.getName()) && Objects.equals(this.packageName, other.getPackageName()); } @Override public String toString() { - if (packageName.isEmpty()) { - return "Type (" + name + ")"; + if (this.packageName.isEmpty()) { + return "Type (" + this.name + ")"; } - return "Type (" + packageName + "." + name + ")"; + return "Type (" + this.packageName + "." + this.name + ")"; } @Override public String getPackageName() { - return packageName; + return this.packageName; } @Override public String getName() { - return name; + return this.name; } @Override public String getFullyQualifiedName() { - if (packageName.isEmpty()) { - return name; + if (this.packageName.isEmpty()) { + return this.name; } else { - return packageName + "." + name; + return this.packageName + "." + this.name; } } } diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/JavaIdentifier.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/JavaIdentifier.java new file mode 100644 index 0000000000..7e76db8d58 --- /dev/null +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/JavaIdentifier.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.javav2.generator.util; + +import com.google.common.annotations.Beta; + +/** + * Types of java identifier: + * + */ +@Beta +public enum JavaIdentifier { + + CLASS, INTERFACE, ENUM, ENUM_VALUE, METHOD, VARIABLE, CONSTANT +} diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverter.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverter.java new file mode 100644 index 0000000000..77573ae59a --- /dev/null +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverter.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.javav2.generator.util; + +import com.google.common.annotations.Beta; +import java.util.List; +import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration; +import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration.Pair; + +/** + * This util class converts every non-java char in identifier to java char by its unicode name + * (JAVA SE + * SPEFICIATIONS - Identifiers). There are special types of mapping non-java chars to original + * identifiers according to specific {@linkplain JavaIdentifier java type}: + * + * + */ +@Beta +public final class NonJavaCharsConverter { + + private final static int FIRST_CHAR = 0; + private final static int FIRST_INDEX = 1; + + private NonJavaCharsConverter() { + throw new UnsupportedOperationException("Util class"); + } + + /** + *

+ * According to YANG RFC 7950, + * all assigned names in an enumeration MUST be unique. Created names are contained in the list + * of {@link Enumeration.Pair}. This method adds actual index with underscore behind name of new + * enum value only if this name already exists in one of the list of {@link Enumeration.Pair}. + * Then, the name will be converted to java chars according to {@link JavaIdentifier#ENUM_VALUE} + * and returned. + *

+ * Example: + * + *
+     * type enumeration {
+     *     enum foo;
+     *     enum Foo;
+     * }
+     * 
+ * + * YANG enum values will be mapped to 'FOO' and 'FOO_1' Java enum values. + * + * @param name + * - name of new enum value + * @param values + * - list of all actual enum values + * @return converted and fixed name of new enum value + */ + public static String convertIdentifierEnumValue(final String name, final List values) { + return convertIdentifierEnumValue(name, name, values, FIRST_INDEX); + } + + private static String convertIdentifierEnumValue(final String name, final String origName, final List values, + final int rank) { + String newName = name; + for (final Pair pair : values) { + if (pair.getName().toLowerCase().equals(name.toLowerCase()) + || pair.getMappedName().toLowerCase().equals(name.toLowerCase())) { + int actualRank = rank; + final StringBuilder actualNameBuilder = new StringBuilder(origName).append('_').append(actualRank); + newName = convertIdentifierEnumValue(actualNameBuilder.toString(), origName, values, + ++actualRank); + } + } + return convertIdentifier(newName, JavaIdentifier.ENUM_VALUE); + } + + /** + * Find and convert non Java chars in identifiers of generated transfer objects, initially + * derived from corresponding YANG. + * + * http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8 + * + * @param identifier + * - name of identifier + * @param javaIdentifier + * - java type of identifier + * @return - java acceptable identifier + */ + public static String convertIdentifier(final String identifier, final JavaIdentifier javaIdentifier) { + final StringBuilder sb = new StringBuilder(); + + // check and convert first char in identifier if there is non-java char + final char firstChar = identifier.charAt(FIRST_CHAR); + if (!Character.isJavaIdentifierStart(firstChar)) { + // converting first char of identifier + sb.append(convertFirst(firstChar, existNext(identifier, FIRST_CHAR))); + } else { + sb.append(firstChar); + } + // check and convert other chars in identifier, if there is non-java char + for (int i = 1; i < identifier.length(); i++) { + final char actualChar = identifier.charAt(i); + if (!Character.isJavaIdentifierPart(actualChar)) { + // prepare actual string of sb for checking if underscore exist on position of the + // last char + final String partialConvertedIdentifier = sb.toString(); + sb.append(convert(actualChar, existNext(identifier, i), + partialConvertedIdentifier.charAt(partialConvertedIdentifier.length() - 1))); + } else { + sb.append(actualChar); + } + } + // apply camel case in appropriate way + return fixCasesByJavaType(sb.toString().replace("__", "_").toLowerCase(), javaIdentifier); + } + + /** + * Fix cases of converted identifiers by Java type + * + * @param string + * - converted identifier + * @param javaIdentifier + * - java type of identifier + * @return converted identifier with right cases according to java type + */ + private static String fixCasesByJavaType(final String convertedIdentifier, final JavaIdentifier javaIdentifier) { + switch (javaIdentifier) { + case CLASS: + case ENUM: + case INTERFACE: + return capitalize(fixCases(convertedIdentifier)); + case ENUM_VALUE: + case CONSTANT: + return convertedIdentifier.toUpperCase(); + case METHOD: + case VARIABLE: + return fixCases(convertedIdentifier); + default: + throw new IllegalArgumentException("Unknown java type of identifier : " + javaIdentifier.toString()); + } + } + + /** + * Delete unnecessary chars in converted identifier and apply camel case in appropriate way. + * + * @param convertedIdentifier + * - original converted identifier + * @return resolved identifier + */ + private static String fixCases(final String convertedIdentifier) { + final StringBuilder sb = new StringBuilder(); + if (convertedIdentifier.contains("_")) { + boolean isFirst = true; + for (final String part : convertedIdentifier.split("_")) { + if (isFirst) { + isFirst = false; + sb.append(part); + } else { + sb.append(capitalize(part)); + } + } + } else { + sb.append(convertedIdentifier); + } + return sb.toString(); + } + + /** + * Check if there exist next char in identifier behind actual char position + * + * @param identifier + * - original identifier + * @param actual + * - actual char position + * @return true if there is another char, false otherwise + */ + private static boolean existNext(final String identifier, final int actual) { + return (identifier.length() - 1) < (actual + 1) ? false : true; + } + + /** + * Converting first char of identifier. This happen only if this char is + * non-java char + * + * @param c + * - first char + * @param existNext + * - existing of next char behind actual char + * @return converted char + */ + private static String convertFirst(final char c, final boolean existNext) { + String name = Character.getName(c); + name = existNext ? (name + "_") : name; + return name.contains(" ") ? name.replaceAll(" ", "_") : name; + } + + /** + * Converting any char in java identifier, This happen only if this char is + * non-java char + * + * @param c + * - actual char + * @param existNext + * - existing of next char behind actual char + * @param partialLastChar + * - last char of partial converted identifier + * @return converted char + */ + private static String convert(final char c, final boolean existNext, final char partialLastChar) { + return partialLastChar == '_' ? convertFirst(c, existNext) : "_" + convertFirst(c, existNext); + } + + /** + * Capitalize input string + * + * @param identifier + * - string to be capitalized + */ + private static String capitalize(final String identifier) { + return identifier.substring(FIRST_CHAR, FIRST_CHAR + 1).toUpperCase() + identifier.substring(1); + } +} diff --git a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImpl.java b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImpl.java index b300dc030e..144dfc2198 100644 --- a/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImpl.java +++ b/binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImpl.java @@ -17,6 +17,8 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.mdsal.binding.javav2.generator.util.AbstractBaseType; +import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier; +import org.opendaylight.mdsal.binding.javav2.generator.util.NonJavaCharsConverter; import org.opendaylight.mdsal.binding.javav2.model.api.AnnotationType; import org.opendaylight.mdsal.binding.javav2.model.api.Constant; import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration; @@ -27,7 +29,6 @@ import org.opendaylight.mdsal.binding.javav2.model.api.MethodSignature; import org.opendaylight.mdsal.binding.javav2.model.api.Type; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.AnnotationTypeBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder; -import org.opendaylight.mdsal.binding.javav2.util.BindingMapping; import org.opendaylight.yangtools.util.LazyCollections; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Status; @@ -37,8 +38,6 @@ import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPai @Beta public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuilder { - private final String packageName; - private final String name; private List values = ImmutableList.of(); private List annotationBuilders = ImmutableList.of(); private String description; @@ -46,10 +45,8 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil private String moduleName; private List schemaPath; - public EnumerationBuilderImpl(String packageName, String name) { - super(packageName, name); - this.packageName = packageName; - this.name = name; + public EnumerationBuilderImpl(final String packageName, final String name) { + super(packageName, NonJavaCharsConverter.convertIdentifier(name, JavaIdentifier.ENUM)); } public void setReference(final String reference) { @@ -65,46 +62,46 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil } @Override - public void setDescription(String description) { + public void setDescription(final String description) { this.description = description; } @Override - public AnnotationTypeBuilder addAnnotation(String packageName, String name) { + public AnnotationTypeBuilder addAnnotation(final String packageName, final String name) { final AnnotationTypeBuilder builder = new AnnotationTypeBuilderImpl(packageName, name); - if (!annotationBuilders.contains(builder)) { - annotationBuilders = LazyCollections.lazyAdd(annotationBuilders, builder); + if (!this.annotationBuilders.contains(builder)) { + this.annotationBuilders = LazyCollections.lazyAdd(this.annotationBuilders, builder); } return builder; } @Override - public void addValue(String name, int value, String description, String reference, Status status) { - final EnumPairImpl p = new EnumPairImpl(name, value, description, reference, status); - values = LazyCollections.lazyAdd(values, p); + public void addValue(final String name, final int value, final String description, final String reference, final Status status) { + final EnumPairImpl p = new EnumPairImpl(name, value, description, reference, status, this.values); + this.values = LazyCollections.lazyAdd(this.values, p); } @Override - public Enumeration toInstance(Type definingType) { - return new EnumerationImpl(definingType, annotationBuilders, packageName, name, values, description, - reference, moduleName, schemaPath); + public Enumeration toInstance(final Type definingType) { + return new EnumerationImpl(definingType, this.annotationBuilders, this.packageName, this.name, this.values, this.description, + this.reference, this.moduleName, this.schemaPath); } @Override public String toString() { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); builder.append("EnumerationBuilderImpl [packageName="); - builder.append(packageName); + builder.append(this.packageName); builder.append(", name="); - builder.append(name); + builder.append(this.name); builder.append(", values="); - builder.append(values); + builder.append(this.values); builder.append(']'); return builder.toString(); } @Override - public void updateEnumPairsFromEnumTypeDef(EnumTypeDefinition enumTypeDef) { + public void updateEnumPairsFromEnumTypeDef(final EnumTypeDefinition enumTypeDef) { final List enums = enumTypeDef.getValues(); if (enums != null) { enums.stream().filter(enumPair -> enumPair != null).forEach(enumPair -> this.addValue(enumPair.getName(), @@ -122,10 +119,10 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil private final Status status; public EnumPairImpl(final String name, final int value, final String description, - final String reference, final Status status) { + final String reference, final Status status, final List values) { this.name = name; - this.mappedName = BindingMapping.getClassName(name); + this.mappedName = NonJavaCharsConverter.convertIdentifierEnumValue(name, values); this.value = value; this.description = description; this.reference = reference; @@ -134,44 +131,44 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil @Override public String getName() { - return name; + return this.name; } @Override public String getMappedName() { - return mappedName; + return this.mappedName; } @Override public int getValue() { - return value; + return this.value; } @Nullable @Override public String getDescription() { - return description; + return this.description; } @Nullable @Override public String getReference() { - return reference; + return this.reference; } @Nonnull @Override public Status getStatus() { - return status; + return this.status; } @Override public int hashCode() { - return Objects.hash(name, value); + return Objects.hash(this.name, this.value); } @Override - public boolean equals(Object obj) { + public boolean equals(final Object obj) { if (this == obj) { return true; } @@ -188,20 +185,20 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil return false; } - EnumPairImpl other = (EnumPairImpl) obj; + final EnumPairImpl other = (EnumPairImpl) obj; - return Objects.equals(name, other.name) && Objects.equals(value, other.value); + return Objects.equals(this.name, other.name) && Objects.equals(this.value, other.value); } @Override public String toString() { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); builder.append("EnumPair [name="); - builder.append(name); + builder.append(this.name); builder.append(", mappedName="); builder.append(getMappedName()); builder.append(", value="); - builder.append(value); + builder.append(this.value); builder.append(']'); return builder.toString(); } @@ -235,27 +232,27 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil @Override public List getAnnotations() { - return annotations; + return this.annotations; } @Override public Type getParentType() { - return definingType; + return this.definingType; } @Override public Optional getDescription() { - return Optional.of(description); + return Optional.of(this.description); } @Override public List getValues() { - return values; + return this.values; } @Override public String toFormattedString() { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); builder.append("public enum"); builder.append(' '); builder.append(getName()); @@ -263,14 +260,14 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil builder.append("\n"); int i = 0; - for (final Enumeration.Pair valPair : values) { + for (final Enumeration.Pair valPair : this.values) { builder.append("\t"); builder.append(' '); builder.append(valPair.getMappedName()); builder.append(" ("); builder.append(valPair.getValue()); - if (i == (values.size() - 1)) { + if (i == (this.values.size() - 1)) { builder.append(" );"); } else { builder.append(" ),"); @@ -283,17 +280,17 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil @Override public Optional getReference() { - return Optional.of(reference); + return Optional.of(this.reference); } @Override public List getSchemaPath() { - return schemaPath; + return this.schemaPath; } @Override public String getModuleName() { - return moduleName; + return this.moduleName; } @Override diff --git a/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverterTest.java b/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverterTest.java new file mode 100644 index 0000000000..de4df85ff7 --- /dev/null +++ b/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverterTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.javav2.generator.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class NonJavaCharsConverterTest { + + @Test + public void acceptableCharsEnumTest() throws Exception { + assertTest("Acceptable", "Acceptable", JavaIdentifier.ENUM); + } + + /** + * Is the same test for class and interface identifiers + */ + @Test + public void nonAcceptableCharsEnumTest() throws Exception { + assertTest("acceptable", "Acceptable", JavaIdentifier.ENUM); + assertTest("acc*", "AccAsterisk", JavaIdentifier.ENUM); + assertTest("Acc*", "AccAsterisk", JavaIdentifier.ENUM); + assertTest("Acc*acc", "AccAsteriskAcc", JavaIdentifier.ENUM); + assertTest("*acc", "AsteriskAcc", JavaIdentifier.ENUM); + assertTest("*Acc", "AsteriskAcc", JavaIdentifier.ENUM); + assertTest("*", "Asterisk", JavaIdentifier.ENUM); + assertTest("\\acc", "ReverseSolidusAcc", JavaIdentifier.ENUM); + assertTest("\\Acc", "ReverseSolidusAcc", JavaIdentifier.ENUM); + assertTest("\\", "ReverseSolidus", JavaIdentifier.ENUM); + assertTest("/acc", "SolidusAcc", JavaIdentifier.ENUM); + assertTest("/Acc", "SolidusAcc", JavaIdentifier.ENUM); + assertTest("/", "Solidus", JavaIdentifier.ENUM); + assertTest("1acc", "DigitOneAcc", JavaIdentifier.ENUM); + assertTest("1Acc", "DigitOneAcc", JavaIdentifier.ENUM); + assertTest("acc1", "Acc1", JavaIdentifier.ENUM); + assertTest("Acc1", "Acc1", JavaIdentifier.ENUM); + assertTest("1", "DigitOne", JavaIdentifier.ENUM); + assertTest("%", "PercentSign", JavaIdentifier.ENUM); + } + + @Test + public void acceptableCharsEnumValueTest() throws Exception { + assertTest("ACCEPTABLE", "ACCEPTABLE", JavaIdentifier.ENUM_VALUE); + } + + @Test + public void nonAcceptableCharsEnumValueTest() throws Exception { + assertTest("acceptable", "ACCEPTABLE", JavaIdentifier.ENUM_VALUE); + assertTest("Acceptable", "ACCEPTABLE", JavaIdentifier.ENUM_VALUE); + assertTest("Acce_ptable", "ACCE_PTABLE", JavaIdentifier.ENUM_VALUE); + assertTest("acc*", "ACC_ASTERISK", JavaIdentifier.ENUM_VALUE); + assertTest("Acc*", "ACC_ASTERISK", JavaIdentifier.ENUM_VALUE); + assertTest("*acc", "ASTERISK_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("*Acc", "ASTERISK_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("*", "ASTERISK", JavaIdentifier.ENUM_VALUE); + assertTest("\\acc", "REVERSE_SOLIDUS_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("\\Acc", "REVERSE_SOLIDUS_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("\\", "REVERSE_SOLIDUS", JavaIdentifier.ENUM_VALUE); + assertTest("/acc", "SOLIDUS_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("/Acc", "SOLIDUS_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("/", "SOLIDUS", JavaIdentifier.ENUM_VALUE); + assertTest("1acc", "DIGIT_ONE_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("1Acc", "DIGIT_ONE_ACC", JavaIdentifier.ENUM_VALUE); + assertTest("acc1", "ACC1", JavaIdentifier.ENUM_VALUE); + assertTest("Acc1", "ACC1", JavaIdentifier.ENUM_VALUE); + assertTest("1", "DIGIT_ONE", JavaIdentifier.ENUM_VALUE); + assertTest("%", "PERCENT_SIGN", JavaIdentifier.ENUM_VALUE); + } + + @Test + public void acceptableCharsMethodTest() throws Exception { + assertTest("acceptable", "acceptable", JavaIdentifier.METHOD); + } + + /** + * Is the same test for variables identifiers + */ + @Test + public void nonAcceptableCharsMethodTest() throws Exception { + assertTest("acc*", "accAsterisk", JavaIdentifier.METHOD); + assertTest("Acc*", "accAsterisk", JavaIdentifier.METHOD); + assertTest("*acc", "asteriskAcc", JavaIdentifier.METHOD); + assertTest("*Acc", "asteriskAcc", JavaIdentifier.METHOD); + assertTest("*", "asterisk", JavaIdentifier.METHOD); + assertTest("\\acc", "reverseSolidusAcc", JavaIdentifier.METHOD); + assertTest("\\Acc", "reverseSolidusAcc", JavaIdentifier.METHOD); + assertTest("\\", "reverseSolidus", JavaIdentifier.METHOD); + assertTest("/acc", "solidusAcc", JavaIdentifier.METHOD); + assertTest("/Acc", "solidusAcc", JavaIdentifier.METHOD); + assertTest("/", "solidus", JavaIdentifier.METHOD); + assertTest("1acc", "digitOneAcc", JavaIdentifier.METHOD); + assertTest("1Acc", "digitOneAcc", JavaIdentifier.METHOD); + assertTest("acc1", "acc1", JavaIdentifier.METHOD); + assertTest("Acc1", "acc1", JavaIdentifier.METHOD); + assertTest("1", "digitOne", JavaIdentifier.METHOD); + assertTest("%", "percentSign", JavaIdentifier.METHOD); + } + + private void assertTest(final String testedIdentifier, final String acceptable, + final JavaIdentifier javaTypeOfIdentifier) { + final String convertedIdentifier = + NonJavaCharsConverter.convertIdentifier(testedIdentifier, javaTypeOfIdentifier); + assertNotNull(convertedIdentifier); + assertTrue(!convertedIdentifier.isEmpty()); + assertEquals(acceptable, convertedIdentifier); + } +} diff --git a/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImplTest.java b/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImplTest.java new file mode 100644 index 0000000000..06dee719fa --- /dev/null +++ b/binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImplTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration; +import org.opendaylight.yangtools.yang.model.api.Status; + +public class EnumerationBuilderImplTest { + + @Test + public void enumTest() { + final EnumerationBuilderImpl enumerationBuilderImpl = + new EnumerationBuilderImpl("package.test", "test**"); + enumerationBuilderImpl.addValue("value", 1, "des", "ref", Status.CURRENT); + final Enumeration enumeration = enumerationBuilderImpl.toInstance(enumerationBuilderImpl); + final String formattedString = enumeration.toFormattedString(); + + assertNotNull(formattedString); + assertTrue(!formattedString.isEmpty()); + assertTrue(formattedString.contains("public enum TestAsteriskAsterisk {")); + assertTrue(formattedString.contains("VALUE")); + } + + @Test + public void enumUniqueTest() { + final EnumerationBuilderImpl enumerationBuilderImpl = new EnumerationBuilderImpl("package.test", "test"); + enumerationBuilderImpl.addValue("foo", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("Foo", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("foo1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("Foo1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("FOO1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("FOO", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("foO1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("foO2", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("foO2", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("Foo*", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("foo*", 1, "des", "ref", Status.CURRENT); + + enumerationBuilderImpl.addValue("f__11", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("f__1_1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("f__1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("F__1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("f_1_1", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("F_1_1", 1, "des", "ref", Status.CURRENT); + + enumerationBuilderImpl.addValue("fo", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("Fo", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("fO", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("FO", 1, "des", "ref", Status.CURRENT); + + final Enumeration enumeration = enumerationBuilderImpl.toInstance(enumerationBuilderImpl); + final String formattedString = enumeration.toFormattedString(); + + assertNotNull(formattedString); + assertTrue(!formattedString.isEmpty()); + assertTrue(formattedString.contains("FOO")); + assertTrue(formattedString.contains("FOO_1")); + assertTrue(formattedString.contains("FOO1")); + assertTrue(formattedString.contains("FOO1_1")); + assertTrue(formattedString.contains("FOO1_2")); + assertTrue(formattedString.contains("FOO_2")); + assertTrue(formattedString.contains("FOO1_3")); + assertTrue(formattedString.contains("FOO2")); + assertTrue(formattedString.contains("FOO2_1")); + assertTrue(formattedString.contains("FOO_ASTERISK")); + assertTrue(formattedString.contains("FOO_ASTERISK_1")); + + assertTrue(formattedString.contains("F_11")); + assertTrue(formattedString.contains("F_1_1")); + assertTrue(formattedString.contains("F_1")); + assertTrue(formattedString.contains("F_1_2")); + assertTrue(formattedString.contains("F_1_1_1")); + assertTrue(formattedString.contains("F_1_1_2")); + + assertTrue(formattedString.contains("FO")); + assertTrue(formattedString.contains("FO_1")); + assertTrue(formattedString.contains("FO_2")); + assertTrue(formattedString.contains("FO_3")); + } + + @Test + public void asteriskInEnumTest() { + final EnumerationBuilderImpl enumerationBuilderImpl = + new EnumerationBuilderImpl("package.test", "test**"); + enumerationBuilderImpl.addValue("val**ue", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("val*ue", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("*value*", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("*", 1, "des", "ref", Status.CURRENT); + final Enumeration enumeration = enumerationBuilderImpl.toInstance(enumerationBuilderImpl); + final String formattedString = enumeration.toFormattedString(); + + assertNotNull(formattedString); + assertTrue(!formattedString.isEmpty()); + assertTrue(formattedString.contains("public enum TestAsteriskAsterisk {")); + assertTrue(formattedString.contains("VAL_ASTERISK_ASTERISK_UE")); + assertTrue(formattedString.contains("VAL_ASTERISK_UE")); + assertTrue(formattedString.contains("ASTERISK_VALUE_ASTERISK")); + assertTrue(formattedString.contains("ASTERISK")); + } + + @Test + public void reverseSolidusInEnumTest() { + final EnumerationBuilderImpl enumerationBuilderImpl = + new EnumerationBuilderImpl("package.test", "test\\\\"); + enumerationBuilderImpl.addValue("val\\\\ue", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("val\\ue", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("\\value\\", 1, "des", "ref", Status.CURRENT); + enumerationBuilderImpl.addValue("\\", 1, "des", "ref", Status.CURRENT); + final Enumeration enumeration = enumerationBuilderImpl.toInstance(enumerationBuilderImpl); + final String formattedString = enumeration.toFormattedString(); + assertNotNull(formattedString); + assertTrue(!formattedString.isEmpty()); + assertTrue(formattedString.contains("public enum TestReverseSolidusReverseSolidus {")); + assertTrue(formattedString.contains("VAL_REVERSE_SOLIDUS_REVERSE_SOLIDUS_UE")); + assertTrue(formattedString.contains("VAL_REVERSE_SOLIDUS_UE")); + assertTrue(formattedString.contains("REVERSE_SOLIDUS_VALUE_REVERSE_SOLIDUS")); + assertTrue(formattedString.contains("REVERSE_SOLIDUS")); + } +} -- 2.36.6