Propagate notification status to generated listener methods
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / BaseTemplate.xtend
index a17d9c7ca33927238d94ba3549b815928d4c52f6..24ea00a0191f132dac0c1568ba06e06802bc5be0 100644 (file)
@@ -7,19 +7,21 @@
  */
 package org.opendaylight.mdsal.binding.java.api.generator
 
-import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.encodeAngleBrackets
-import static org.opendaylight.mdsal.binding.model.util.Types.STRING;
+import static extension org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.encodeAngleBrackets
+import static extension org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.replaceAllIllegalChars
 
 import com.google.common.base.CharMatcher
-import com.google.common.base.MoreObjects
 import com.google.common.base.Splitter
+import com.google.common.collect.ImmutableMap
 import com.google.common.collect.Iterables
+import java.math.BigInteger
 import java.util.Collection
 import java.util.List
 import java.util.Locale
 import java.util.Map.Entry
 import java.util.StringTokenizer
 import java.util.regex.Pattern
+import org.eclipse.jdt.annotation.NonNull;
 import org.gaul.modernizer_maven_annotations.SuppressModernizer
 import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.ConcreteType
@@ -30,14 +32,17 @@ import org.opendaylight.mdsal.binding.model.api.JavaTypeName
 import org.opendaylight.mdsal.binding.model.api.MethodSignature
 import org.opendaylight.mdsal.binding.model.api.Restrictions
 import org.opendaylight.mdsal.binding.model.api.Type
-import org.opendaylight.mdsal.binding.model.api.TypeMember
+import org.opendaylight.mdsal.binding.model.api.TypeMemberComment
 import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition.Single
 import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition.Multiple
-import org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil
 import org.opendaylight.mdsal.binding.model.util.TypeConstants
 import org.opendaylight.mdsal.binding.model.util.Types
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
 import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.Uint8
+import org.opendaylight.yangtools.yang.common.Uint16
+import org.opendaylight.yangtools.yang.common.Uint32
+import org.opendaylight.yangtools.yang.common.Uint64
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
@@ -65,6 +70,13 @@ abstract class BaseTemplate extends JavaFileTemplate {
         .addIgnoredStatement(YangStmtMapping.ORGANIZATION)
         .build();
 
+    protected static val UINT_TYPES = ImmutableMap.of(
+        Types.typeForClass(Uint8), Types.typeForClass(Short),
+        Types.typeForClass(Uint16), Types.typeForClass(Integer),
+        Types.typeForClass(Uint32), Types.typeForClass(Long),
+        Types.typeForClass(Uint64), Types.typeForClass(BigInteger)
+    );
+
     new(GeneratedType type) {
         super(type)
     }
@@ -90,7 +102,7 @@ abstract class BaseTemplate extends JavaFileTemplate {
         "_" + property.name
     }
 
-    final protected def propertyNameFromGetter(MethodSignature getter) {
+    final protected static def propertyNameFromGetter(MethodSignature getter) {
         var String prefix;
         if (getter.name.startsWith(BindingMapping.BOOLEAN_GETTER_PREFIX)) {
             prefix = BindingMapping.BOOLEAN_GETTER_PREFIX
@@ -111,18 +123,16 @@ abstract class BaseTemplate extends JavaFileTemplate {
      * generated property with data about field which is generated as the getter method
      * @return string with the getter method source code in JAVA format
      */
-    protected def getterMethod(GeneratedProperty field) {
-        '''
-            public «field.returnType.importedName» «field.getterMethodName»() {
-                «val fieldName = field.fieldName»
-                «IF field.returnType.name.endsWith("[]")»
-                return «fieldName» == null ? null : «fieldName».clone();
-                «ELSE»
-                return «fieldName»;
-                «ENDIF»
-            }
-        '''
-    }
+    protected def getterMethod(GeneratedProperty field) '''
+        public «field.returnType.importedName» «field.getterMethodName»() {
+            «val fieldName = field.fieldName»
+            «IF field.returnType.name.endsWith("[]")»
+            return «fieldName» == null ? null : «fieldName».clone();
+            «ELSE»
+            return «fieldName»;
+            «ENDIF»
+        }
+    '''
 
     final protected def getterMethodName(GeneratedProperty field) {
         val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get"
@@ -154,6 +164,17 @@ abstract class BaseTemplate extends JavaFileTemplate {
     def final protected asArgumentsDeclaration(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
         returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»'''
 
+    /**
+     * Template method which generates method parameters with their types from <code>parameters</code>, annotating them
+     * with {@link NonNull}.
+     *
+     * @param parameters group of generated property instances which are transformed to the method parameters
+     * @return string with the list of the method parameters with their types in JAVA format
+     */
+    def final protected asNonNullArgumentsDeclaration(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»
+        «FOR parameter : parameters SEPARATOR ", "»«parameter.returnType.importedNonNull» «parameter
+        .fieldName»«ENDFOR»«ENDIF»'''
+
     /**
      * Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
      *
@@ -170,13 +191,17 @@ abstract class BaseTemplate extends JavaFileTemplate {
      * @param comment string with the comment for whole JAVA class
      * @return string with comment in JAVA format
      */
-    def protected CharSequence asJavadoc(String comment) {
+    def final protected asJavadoc(TypeMemberComment comment) {
         if (comment === null) {
             return ''
         }
-        return '''
-            «wrapToDocumentation(formatToParagraph(comment.trim))»
-        '''
+        return wrapToDocumentation('''
+           «comment.contractDescription»
+
+           «comment.referenceDescription.formatReference»
+
+           «comment.typeSignature»
+        ''')
     }
 
     def static String wrapToDocumentation(String text) {
@@ -259,7 +284,7 @@ abstract class BaseTemplate extends JavaFileTemplate {
                 if (node instanceof SchemaNode) {
                     sb.append("The schema path to identify an instance is\n")
                     .append("<i>")
-                    .append(formatSchemaPath(def.module.argument, node.path.pathFromRoot))
+                    .append(formatSchemaPath(def.module.argument.localName, node.path.pathFromRoot))
                     .append("</i>\n")
 
                     if (hasBuilderClass(node)) {
@@ -290,7 +315,7 @@ abstract class BaseTemplate extends JavaFileTemplate {
     def private static void appendYangSnippet(StringBuilder sb, ModuleEffectiveStatement module,
             DeclaredStatement<?> stmt) {
         for (String str : YANG_FORMATTER.toYangTextSnippet(module, stmt)) {
-            sb.append(BindingGeneratorUtil.replaceAllIllegalChars(encodeAngleBrackets(encodeJavadocSymbols(str))))
+            sb.append(str.encodeJavadocSymbols.encodeAngleBrackets.replaceAllIllegalChars)
         }
     }
 
@@ -315,24 +340,16 @@ abstract class BaseTemplate extends JavaFileTemplate {
         return sb.toString();
     }
 
-    def protected static String formatDataForJavaDoc(TypeMember type, String additionalComment) {
-        val StringBuilder typeDescriptionBuilder = new StringBuilder();
-        if (!type.comment.nullOrEmpty) {
-            typeDescriptionBuilder.append(formatToParagraph(type.comment))
-            typeDescriptionBuilder.append(NEW_LINE)
-            typeDescriptionBuilder.append(NEW_LINE)
-            typeDescriptionBuilder.append(NEW_LINE)
-        }
-        typeDescriptionBuilder.append(additionalComment)
-        var typeDescription = wrapToDocumentation(typeDescriptionBuilder.toString)
-        return '''
-            «typeDescription»
-        '''.toString
-    }
+    def static formatReference(String reference) '''
+        «IF reference !== null»
+            <pre>
+                <code>
+                    «reference.encodeAngleBrackets.formatToParagraph»
+                </code>
+            </pre>
 
-    def asCode(String text) {
-        return "<code>" + text + "</code>"
-    }
+        «ENDIF»
+    '''
 
     def asLink(String text) {
         val StringBuilder sb = new StringBuilder()
@@ -357,21 +374,15 @@ abstract class BaseTemplate extends JavaFileTemplate {
         return sb.toString
     }
 
-    protected static def formatToParagraph(String text) {
-        if(text === null || text.isEmpty)
-            return text
-
-        var formattedText = text
+    protected static def formatToParagraph(String inputText) {
         val StringBuilder sb = new StringBuilder();
         var StringBuilder lineBuilder = new StringBuilder();
         var boolean isFirstElementOnNewLineEmptyChar = false;
 
-        formattedText = encodeJavadocSymbols(formattedText)
-        formattedText = WS_MATCHER.replaceFrom(formattedText, SPACE)
+        var formattedText = WS_MATCHER.replaceFrom(inputText.encodeJavadocSymbols, SPACE)
         formattedText = SPACES_PATTERN.matcher(formattedText).replaceAll(" ")
 
-        val StringTokenizer tokenizer = new StringTokenizer(formattedText, " ", true);
-
+        val StringTokenizer tokenizer = new StringTokenizer(formattedText, " ", true)
         while (tokenizer.hasMoreTokens) {
             val nextElement = tokenizer.nextToken
 
@@ -390,7 +401,6 @@ abstract class BaseTemplate extends JavaFileTemplate {
                     isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
                 }
             }
-
             if (isFirstElementOnNewLineEmptyChar) {
                 isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar
             } else {
@@ -401,19 +411,6 @@ abstract class BaseTemplate extends JavaFileTemplate {
         return sb.append(lineBuilder).append(NEW_LINE).toString
     }
 
-    def protected generateToString(Collection<? extends GeneratedProperty> properties) '''
-        «IF !properties.empty»
-            @«OVERRIDE.importedName»
-            public «STRING.importedName» toString() {
-                final «MoreObjects.importedName».ToStringHelper helper = «MoreObjects.importedName».toStringHelper(«type.importedName».class);
-                «FOR property : properties»
-                    «CODEHELPERS.importedName».appendValue(helper, "«property.fieldName»", «property.fieldName»);
-                «ENDFOR»
-                return helper.toString();
-            }
-        «ENDIF»
-    '''
-
     /**
      * Template method which generates method parameters with their types from <code>parameters</code>.
      *