Generate bindingToString() and use it in generated implementations
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / InterfaceTemplate.xtend
index 3797ccba0263ff6c8d9d14ffd9c296c7a03b52f1..619d6c2073967362bf3a87d910118bd25448a167 100644 (file)
@@ -7,11 +7,15 @@
  */
 package org.opendaylight.mdsal.binding.java.api.generator
 
-import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
+import static org.opendaylight.mdsal.binding.model.util.Types.STRING;
 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.getGetterMethodForNonnull
 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isGetterMethodName
 import static extension org.opendaylight.mdsal.binding.spec.naming.BindingMapping.isNonnullMethodName
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_TO_STRING_NAME
+import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
 
+import com.google.common.base.MoreObjects
 import java.util.List
 import java.util.Map.Entry
 import java.util.Set
@@ -164,6 +168,8 @@ class InterfaceTemplate extends BaseTemplate {
             «FOR m : methods SEPARATOR "\n"»
                 «IF m.isDefault»
                     «generateDefaultMethod(m)»
+                «ELSEIF m.isStatic»
+                    «generateStaticMethod(m)»
                 «ELSEIF m.parameters.empty && m.name.isGetterMethodName»
                     «generateAccessorMethod(m)»
                 «ELSE»
@@ -183,6 +189,12 @@ class InterfaceTemplate extends BaseTemplate {
         }
     }
 
+    def private generateStaticMethod(MethodSignature method) {
+        switch method.name {
+            case BINDING_TO_STRING_NAME : generateBindingToString
+        }
+    }
+
     def private generateMethod(MethodSignature method) '''
         «method.comment.asJavadoc»
         «method.annotations.generateAnnotations»
@@ -203,6 +215,38 @@ class InterfaceTemplate extends BaseTemplate {
         }
     '''
 
+    def generateBindingToString() '''
+        «val augmentable = analyzeType»
+        /**
+         * Default implementation of {@link «Object.importedName»#toString()} contract for this interface.
+         * Implementations of this interface are encouraged to defer to this method to get consistent string
+         * representations across all implementation.
+         *
+         «IF augmentable»
+         * <p>
+         * @param <T$$> implementation type, which has to also implement «AUGMENTATION_HOLDER.importedName» interface
+         *              contract.
+         «ENDIF»
+         * @param obj Object for which to generate toString() result.
+         * @return {@link «STRING.importedName»} value of data modeled by this interface.
+         * @throws «NPE.importedName» if {@code obj} is null
+         */
+        «IF augmentable»
+            static <T$$ extends «type.fullyQualifiedName» & «AUGMENTATION_HOLDER.importedName»<«type.fullyQualifiedName»>> «STRING.importedName» «BINDING_TO_STRING_NAME»(final @«NONNULL.importedName» T$$ obj) {
+        «ELSE»
+            static «STRING.importedName» «BINDING_TO_STRING_NAME»(final «type.fullyQualifiedName» obj) {
+        «ENDIF»
+            final «MoreObjects.importedName».ToStringHelper helper = «MoreObjects.importedName».toStringHelper("«type.name»");
+            «FOR property : typeAnalysis.value»
+                «CODEHELPERS.importedName».appendValue(helper, "«property.name»", obj.«property.getterName»());
+            «ENDFOR»
+            «IF augmentable»
+                «CODEHELPERS.importedName».appendValue(helper, "«AUGMENTATION_FIELD»", obj.augmentations().values());
+            «ENDIF»
+            return helper.toString();
+        }
+    '''
+
     def private generateNonnullMethod(MethodSignature method) '''
         «val ret = method.returnType»
         «val name = method.name»
@@ -225,9 +269,10 @@ class InterfaceTemplate extends BaseTemplate {
         return !type.getPackageName().isEmpty()
     }
 
-    def analyzeType() {
+    private def boolean analyzeType() {
         if (typeAnalysis === null) {
             typeAnalysis = analyzeTypeHierarchy(type)
         }
+        typeAnalysis.key !== null
     }
 }