Bug 2332 - Binding Java API Generator -> doesn't handle 32/51132/27
authorJakub Toth <jatoth@cisco.com>
Fri, 27 Jan 2017 15:34:30 +0000 (16:34 +0100)
committerJakub Toth <jatoth@cisco.com>
Fri, 17 Feb 2017 08:16:01 +0000 (08:16 +0000)
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 <jatoth@cisco.com>
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/AbstractBaseType.java
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/JavaIdentifier.java [new file with mode: 0644]
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverter.java [new file with mode: 0644]
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImpl.java
binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/NonJavaCharsConverterTest.java [new file with mode: 0644]
binding2/mdsal-binding2-generator-util/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/util/generated/type/builder/EnumerationBuilderImplTest.java [new file with mode: 0644]

index 0fe2ec1fdcc0e0683ba6802c9b087688ebc45df2..296800b1da49d273735ce99c845cfbe712843a5c 100644 (file)
@@ -22,12 +22,12 @@ public abstract class AbstractBaseType implements Type {
     /**
      * Name of the package to which this <code>Type</code> belongs.
      */
-    private final String packageName;
+    protected final String packageName;
 
     /**
      * Name of this <code>Type</code>.
      */
-    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 (file)
index 0000000..7e76db8
--- /dev/null
@@ -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:
+ * <ul>
+ * <li>class</li>
+ * <li>interface</li>
+ * <li>enum</li>
+ * <li>enum value</li>
+ * <li>method</li>
+ * <li>variable</li>
+ * <li>constant</li>
+ * </ul>
+ */
+@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 (file)
index 0000000..77573ae
--- /dev/null
@@ -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
+ * (<a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8">JAVA SE
+ * SPEFICIATIONS - Identifiers</a>). There are special types of mapping non-java chars to original
+ * identifiers according to specific {@linkplain JavaIdentifier java type}:
+ * <ul>
+ * <li>class, enum, interface</li>
+ * <li>
+ * <ul>
+ * <li>without special separator</li>
+ * <li>the first character of identifier, any other first character of identifier part mapped by
+ * non-Java char name from unicode and char in identifier behind non-java char name are converting
+ * to upper case</li>
+ * <li>examples:</li>
+ * <li>
+ * <ul>
+ * <li>example* - ExampleAsterisk</li>
+ * <li>example*example - ExampleAserisksExample</li>
+ * <li>\example - ReverseSolidusExample</li>
+ * <li>1example - DigitOneExample</li>
+ * <li>example1 - Example1</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </li>
+ * <li>enum value, constant</li>
+ * <li>
+ * <ul>
+ * <li>used underscore as special separator</li>
+ * <li>converted identifier to upper case</li>
+ * <li>examples:</li>
+ * <li>
+ * <ul>
+ * <li>example* - EXAMPLE_ASTERISK</li>
+ * <li>example*example - EXAMPLE_ASTERISK_EXAMPLE</li>
+ * <li>\example - REVERSE_SOLIDUS_EXAMPLE</li>
+ * <li>1example - DIGIT_ONE_EXAMPLE</li>
+ * <li>example1 - EXAMPLE1</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </li>
+ * <li>method, variable
+ * <li>
+ * <li>
+ * <ul>
+ * <li>without special separator</li>
+ * <li>the first character of identifier is converting to lower case</li>
+ * <li>any other first character of identifier part mapped by non-Java char name from unicode and
+ * char in identifier behind non-java char name are converting to upper case
+ * <li>examples:</li>
+ * <li>
+ * <ul>
+ * <li>example* - exampleAsterisk</li>
+ * <li>example*example - exampleAserisksExample</li>
+ * <li>\example - reverseSolidusExample</li>
+ * <li>1example - digitOneExample</li>
+ * <li>example1 - example1</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ */
+@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");
+    }
+
+    /**
+     * <p>
+     * According to <a href="https://tools.ietf.org/html/rfc7950#section-9.6.4">YANG RFC 7950</a>,
+     * 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.
+     * </p>
+     * Example:
+     *
+     * <pre>
+     * type enumeration {
+     *     enum foo;
+     *     enum Foo;
+     * }
+     * </pre>
+     *
+     * 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<Pair> values) {
+        return convertIdentifierEnumValue(name, name, values, FIRST_INDEX);
+    }
+
+    private static String convertIdentifierEnumValue(final String name, final String origName, final List<Pair> 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.
+     *
+     * <a>http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8</a>
+     *
+     * @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);
+    }
+}
index b300dc030e58de9a9d2b1fc3df4ec94a10fa1d84..144dfc219858e7722c9dcc1ac7dfab0dd2afa9ae 100644 (file)
@@ -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<Pair> values = ImmutableList.of();
     private List<AnnotationTypeBuilder> annotationBuilders = ImmutableList.of();
     private String description;
@@ -46,10 +45,8 @@ public class EnumerationBuilderImpl extends AbstractBaseType implements EnumBuil
     private String moduleName;
     private List<QName> 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<EnumPair> 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<Pair> 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<AnnotationType> getAnnotations() {
-            return annotations;
+            return this.annotations;
         }
 
         @Override
         public Type getParentType() {
-            return definingType;
+            return this.definingType;
         }
 
         @Override
         public Optional<String> getDescription() {
-            return Optional.of(description);
+            return Optional.of(this.description);
         }
 
         @Override
         public List<Pair> 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<String> getReference() {
-            return Optional.of(reference);
+            return Optional.of(this.reference);
         }
 
         @Override
         public List<QName> 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 (file)
index 0000000..de4df85
--- /dev/null
@@ -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 (file)
index 0000000..06dee71
--- /dev/null
@@ -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"));
+    }
+}