Added tests for yang.model.util
[yangtools.git] / code-generator / binding-java-api-generator / src / main / java / org / opendaylight / yangtools / sal / java / api / generator / BuilderTemplate.xtend
index 7645504e6c7584a1f1c3d2857e0bc6197383caa2..286b5f06b17017a6c01fe9ad678db612a65af16b 100644 (file)
@@ -7,7 +7,14 @@
  */
 package org.opendaylight.yangtools.sal.java.api.generator
 
-import java.util.Arrays;
+import com.google.common.collect.ImmutableSortedSet
+import com.google.common.collect.Range
+import java.util.ArrayList
+import java.util.Arrays
+import java.util.Collection
+import java.util.Collections
+import java.util.HashMap
+import java.util.HashSet
 import java.util.LinkedHashSet
 import java.util.List
 import java.util.Map
@@ -15,23 +22,15 @@ import java.util.Set
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
 import org.opendaylight.yangtools.binding.generator.util.Types
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl
+import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
 import org.opendaylight.yangtools.sal.binding.model.api.Type
 import org.opendaylight.yangtools.yang.binding.Augmentable
-import static org.opendaylight.yangtools.binding.generator.util.Types.*
-import java.util.HashMap
-import java.util.Collections
 import org.opendaylight.yangtools.yang.binding.DataObject
-import java.util.ArrayList
-import java.util.HashSet
-import java.util.Collection
 import org.opendaylight.yangtools.yang.binding.Identifiable
-import com.google.common.collect.Range
-import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType
-import com.google.common.collect.ImmutableList
 
 /**
  * Template for generating JAVA builder classes. 
@@ -64,6 +63,8 @@ class BuilderTemplate extends BaseTemplate {
      */
     val Set<GeneratedProperty> properties
 
+    private static val METHOD_COMPARATOR = new AlphabeticallyTypeMemberComparator<MethodSignature>();
+
     /**
      * Constructs new instance of this class.
      * @throws IllegalArgumentException if <code>genType</code> equals <code>null</code>
@@ -80,15 +81,17 @@ class BuilderTemplate extends BaseTemplate {
      * @returns set of method signature instances
      */
     def private Set<MethodSignature> createMethods() {
-        val Set<MethodSignature> methods = new LinkedHashSet
+        val Set<MethodSignature> methods = new LinkedHashSet();
         methods.addAll(type.methodDefinitions)
         collectImplementedMethods(methods, type.implements)
-        return methods
+        val Set<MethodSignature> sortedMethods = ImmutableSortedSet.orderedBy(METHOD_COMPARATOR).addAll(methods).build()
+
+        return sortedMethods
     }
 
     /**
      * Adds to the <code>methods</code> set all the methods of the <code>implementedIfcs</code> 
-     * and recursivelly their implemented interfaces.
+     * and recursively their implemented interfaces.
      * 
      * @param methods set of method signatures
      * @param implementedIfcs list of implemented interfaces
@@ -188,7 +191,7 @@ class BuilderTemplate extends BaseTemplate {
             throw new IllegalArgumentException("Method, method name, method return type reference cannot be NULL or empty!")
         }
         var prefix = "get";
-        if(BOOLEAN.equals(method.returnType)) {
+        if(Types.BOOLEAN.equals(method.returnType)) {
             prefix = "is";
         } 
         if (method.name.startsWith(prefix)) {
@@ -537,31 +540,27 @@ class BuilderTemplate extends BaseTemplate {
                 }
             «ENDIF»
             «FOR field : allProps»
-                «IF List.canonicalName.equals(field.returnType.fullyQualifiedName)»
-                    if (base.«field.getterMethodName»() == null || base.«field.getterMethodName»().isEmpty()) {
-                        this.«field.fieldName» = «Collections.importedName».emptyList();
-                    } else {
-                        this.«field.fieldName» = «ImmutableList.importedName».copyOf(base.«field.getterMethodName»());
-                    }
-                «ELSE»
-                    this.«field.fieldName» = base.«field.getterMethodName»();
-                «ENDIF»
+                this.«field.fieldName» = base.«field.getterMethodName»();
             «ENDFOR»
             «IF augmentField != null»
                 «IF !impl»if (base instanceof «type.name»«IMPL») {«ENDIF»
                     «IF !impl»«type.name»«IMPL» _impl = («type.name»«IMPL») base;«ENDIF»
                     «val prop = if (impl) "base" else "_impl"»
-                    switch («prop».«augmentField.name».size()) {
-                    case 0:
-                        this.«augmentField.name» = «Collections.importedName».emptyMap();
-                        break;
-                    case 1:
-                        final «Map.importedName».Entry<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> e = «prop».«augmentField.name».entrySet().iterator().next();
-                        this.«augmentField.name» = «Collections.importedName».<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»>singletonMap(e.getKey(), e.getValue());
-                        break;
-                    default :
+                    «IF impl»
+                        switch («prop».«augmentField.name».size()) {
+                        case 0:
+                            this.«augmentField.name» = «Collections.importedName».emptyMap();
+                            break;
+                            case 1:
+                                final «Map.importedName».Entry<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> e = «prop».«augmentField.name».entrySet().iterator().next();
+                                this.«augmentField.name» = «Collections.importedName».<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»>singletonMap(e.getKey(), e.getValue());       
+                            break;
+                        default :
+                            this.«augmentField.name» = new «HashMap.importedName»<>(«prop».«augmentField.name»);
+                        }
+                    «ELSE»
                         this.«augmentField.name» = new «HashMap.importedName»<>(«prop».«augmentField.name»);
-                    }
+                    «ENDIF»
                 «IF !impl»}«ENDIF»
             «ENDIF»
         }
@@ -660,35 +659,50 @@ class BuilderTemplate extends BaseTemplate {
                 if (this == obj) {
                     return true;
                 }
-                if (obj == null) {
+                if (!(obj instanceof «DataObject.importedName»)) {
                     return false;
                 }
-                if (getClass() != obj.getClass()) {
+                if (!«type.importedName».class.equals(((«DataObject.importedName»)obj).getImplementedInterface())) {
                     return false;
                 }
-                «type.name»«IMPL» other = («type.name»«IMPL») obj;
+                «type.importedName» other = («type.importedName»)obj;
                 «FOR property : properties»
                     «val fieldName = property.fieldName»
                     if («fieldName» == null) {
-                        if (other.«fieldName» != null) {
+                        if (other.«property.getterMethodName»() != null) {
                             return false;
                         }
                     «IF property.returnType.name.contains("[")»
-                    } else if(!«Arrays.importedName».equals(«fieldName», other.«fieldName»)) {
+                    } else if(!«Arrays.importedName».equals(«fieldName», other.«property.getterMethodName»())) {
                     «ELSE»
-                    } else if(!«fieldName».equals(other.«fieldName»)) {
+                    } else if(!«fieldName».equals(other.«property.getterMethodName»())) {
                     «ENDIF»
                         return false;
                     }
                 «ENDFOR»
                 «IF augmentField != null»
-                    «val fieldName = augmentField.name»
-                    if («fieldName» == null) {
-                        if (other.«fieldName» != null) {
+                    if (getClass() == obj.getClass()) {
+                        // Simple case: we are comparing against self
+                        «type.name»«IMPL» otherImpl = («type.name»«IMPL») obj;
+                        «val fieldName = augmentField.name»
+                        if («fieldName» == null) {
+                            if (otherImpl.«fieldName» != null) {
+                                return false;
+                            }
+                        } else if(!«fieldName».equals(otherImpl.«fieldName»)) {
+                            return false;
+                        }
+                    } else {
+                        // Hard case: compare our augments with presence there...
+                        for («Map.importedName».Entry<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> e : «augmentField.name».entrySet()) {
+                            if (!e.getValue().equals(other.getAugmentation(e.getKey()))) {
+                                return false;
+                            }
+                        }
+                        // .. and give the other one the chance to do the same
+                        if (!obj.equals(this)) {
                             return false;
                         }
-                    } else if(!«fieldName».equals(other.«fieldName»)) {
-                        return false;
                     }
                 «ENDIF»
                 return true;
@@ -741,5 +755,23 @@ class BuilderTemplate extends BaseTemplate {
         return «type.importedName».class;
     }
     '''
+    
+    private def createDescription(GeneratedType type) {
+        return '''
+        Class that builds {@link «type.importedName»} instances.
+        
+        @see «type.importedName»
+    '''
+    }
+    
+    override def protected String formatDataForJavaDoc(GeneratedType type) {
+        val typeDescription = createDescription(type)
 
+        return '''
+            «IF !typeDescription.nullOrEmpty»
+            «typeDescription»
+            «ENDIF»
+        '''.toString
+    }
 }
+