Specialize relative leafref types during instantiation
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / AbstractBuilderTemplate.xtend
index 198f02cf8ad2b8381a6bde11075ec30df6c12634..5dcce2a4c9b28f7b979bb4f80360c65d41222aa9 100644 (file)
@@ -7,25 +7,21 @@
  */
 package org.opendaylight.mdsal.binding.java.api.generator
 
-import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTABLE_AUGMENTATION_NAME
 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
 
-import com.google.common.base.MoreObjects
 import java.util.ArrayList
 import java.util.Collection
 import java.util.Collections
 import java.util.Comparator
 import java.util.List
-import java.util.Map
 import java.util.Set
+import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject
 import org.opendaylight.mdsal.binding.model.api.GeneratedType
 import org.opendaylight.mdsal.binding.model.api.Type
-import org.opendaylight.mdsal.binding.model.util.Types
+import org.opendaylight.mdsal.binding.model.util.BindingTypes
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
-import org.opendaylight.yangtools.yang.binding.CodeHelpers
-import org.opendaylight.yangtools.yang.binding.Identifiable
 
 abstract class AbstractBuilderTemplate extends BaseTemplate {
     static val Comparator<GeneratedProperty> KEY_PROPS_COMPARATOR = [ p1, p2 | return p1.name.compareTo(p2.name) ]
@@ -38,7 +34,7 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
     /**
      * Set of class attributes (fields) which are derived from the getter methods names.
      */
-    protected val Set<GeneratedProperty> properties
+    protected val Set<BuilderGeneratedProperty> properties
 
     /**
      * GeneratedType for key type, null if this type does not have a key.
@@ -48,7 +44,7 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
     protected val GeneratedType targetType;
 
     new(AbstractJavaGeneratedType javaType, GeneratedType type, GeneratedType targetType,
-            Set<GeneratedProperty> properties, Type augmentType, Type keyType) {
+            Set<BuilderGeneratedProperty> properties, Type augmentType, Type keyType) {
         super(javaType, type)
         this.targetType = targetType
         this.properties = properties
@@ -56,13 +52,14 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
         this.keyType = keyType
     }
 
-    new(GeneratedType type, GeneratedType targetType, Set<GeneratedProperty> properties, Type augmentType,
-            Type keyType) {
+    new(GeneratedType type, GeneratedType targetType, Type keyType) {
         super(type)
         this.targetType = targetType
-        this.properties = properties
-        this.augmentType = augmentType
         this.keyType = keyType
+
+        val analysis = analyzeTypeHierarchy(targetType)
+        augmentType = analysis.key
+        properties = analysis.value
     }
 
     /**
@@ -85,26 +82,10 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
     def protected final generateAugmentField() {
         val augmentTypeRef = augmentType.importedName
         return '''
-           «Map.importedName»<«Class.importedName»<? extends «augmentTypeRef»>, «augmentTypeRef»> «AUGMENTATION_FIELD» = «Collections.importedName».emptyMap();
+           «JU_MAP.importedName»<«CLASS.importedName»<? extends «augmentTypeRef»>, «augmentTypeRef»> «AUGMENTATION_FIELD» = «Collections.importedName».emptyMap();
         '''
     }
 
-    override generateToString(Collection<GeneratedProperty> properties) '''
-        «IF properties !== null»
-            @«Override.importedName»
-            public «String.importedName» toString() {
-                final «MoreObjects.importedName».ToStringHelper helper = «MoreObjects.importedName».toStringHelper("«targetType.name»");
-                «FOR property : properties»
-                    «CodeHelpers.importedName».appendValue(helper, "«property.fieldName»", «property.fieldName»);
-                «ENDFOR»
-                «IF augmentType !== null»
-                    «CodeHelpers.importedName».appendValue(helper, "«AUGMENTATION_FIELD»", «AUGMENTATION_FIELD».values());
-                «ENDIF»
-                return helper.toString();
-            }
-        «ENDIF»
-    '''
-
     /**
      * Template method which generate getter methods for IMPL class.
      *
@@ -112,7 +93,7 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
      */
     def final generateGetters(boolean addOverride) '''
         «IF keyType !== null»
-            «IF addOverride»@«Override.importedName»«ENDIF»
+            «IF addOverride»@«OVERRIDE.importedName»«ENDIF»
             public «keyType.importedName» «BindingMapping.IDENTIFIABLE_KEY_NAME»() {
                 return key;
             }
@@ -120,44 +101,47 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
         «ENDIF»
         «IF !properties.empty»
             «FOR field : properties SEPARATOR '\n'»
-                «IF addOverride»@«Override.importedName»«ENDIF»
+                «IF addOverride»@«OVERRIDE.importedName»«ENDIF»
                 «field.getterMethod»
             «ENDFOR»
         «ENDIF»
-        «IF augmentType !== null»
-
-            @SuppressWarnings("unchecked")
-            «IF addOverride»@«Override.importedName»«ENDIF»
-            public <E extends «augmentType.importedName»> E «AUGMENTABLE_AUGMENTATION_NAME»(«Class.importedName»<E> augmentationType) {
-                return (E) «AUGMENTATION_FIELD».get(«CodeHelpers.importedName».nonNullValue(augmentationType, "augmentationType"));
-            }
-        «ENDIF»
     '''
 
     def protected final CharSequence generateCopyConstructor(Type fromType, Type implType) '''
         «type.name»(«fromType.importedName» base) {
-            «val allProps = new ArrayList(properties)»
-            «val isList = implementsIfc(targetType, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), targetType))»
-            «IF isList && keyType !== null»
+            «IF augmentType !== null»
+                «generateCopyAugmentation(implType)»
+            «ENDIF»
+            «IF keyType !== null && implementsIfc(targetType, BindingTypes.identifiable(targetType))»
                 «val keyProps = new ArrayList((keyType as GeneratedTransferObject).properties)»
                 «keyProps.sort(KEY_PROPS_COMPARATOR)»
+                «val allProps = new ArrayList(properties)»
                 «FOR field : keyProps»
                     «removeProperty(allProps, field.name)»
                 «ENDFOR»
                 «generateCopyKeys(keyProps)»
-            «ENDIF»
-            «FOR field : allProps»
-                this.«field.fieldName» = base.«field.getterMethodName»();
-            «ENDFOR»
-            «IF augmentType !== null»
-                «generateCopyAugmentation(implType)»
+                «generateCopyNonKeys(allProps)»
+            «ELSE»
+                «generateCopyNonKeys(properties)»
             «ENDIF»
         }
     '''
 
+    def protected final CharSequence generateDeprecatedAnnotation(List<AnnotationType> annotations) {
+        var AnnotationType found = annotations.findDeprecatedAnnotation
+        if (found === null) {
+            return ""
+        }
+        return generateDeprecatedAnnotation(found)
+    }
+
     def protected abstract CharSequence generateCopyKeys(List<GeneratedProperty> keyProps)
 
-    def protected abstract CharSequence generateCopyAugmentation(Type implType);
+    def protected abstract CharSequence generateCopyNonKeys(Collection<BuilderGeneratedProperty> props)
+
+    def protected abstract CharSequence generateCopyAugmentation(Type implType)
+
+    def protected abstract CharSequence generateDeprecatedAnnotation(AnnotationType ann)
 
     private def boolean implementsIfc(GeneratedType type, Type impl) {
         for (Type ifc : type.implements) {
@@ -168,15 +152,32 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
         return false;
     }
 
-    private def void removeProperty(Collection<GeneratedProperty> props, String name) {
-        var GeneratedProperty toRemove = null
-        for (p : props) {
-            if (p.name.equals(name)) {
-                toRemove = p;
+    private def void removeProperty(Collection<BuilderGeneratedProperty> props, String name) {
+        val iter = props.iterator
+        while (iter.hasNext) {
+            if (name.equals(iter.next.name)) {
+                iter.remove
+                return
             }
         }
-        if (toRemove !== null) {
-            props.remove(toRemove);
+    }
+
+    private static def findDeprecatedAnnotation(List<AnnotationType> annotations) {
+        if (annotations !== null) {
+            for (annotation : annotations) {
+                if (DEPRECATED.equals(annotation.identifier)) {
+                    return annotation
+                }
+            }
         }
+        return null
+    }
+
+    package static def hasNonDefaultMethods(GeneratedType type) {
+        !type.methodDefinitions.isEmpty && type.methodDefinitions.exists([def | !def.isDefault])
+    }
+
+    package static def nonDefaultMethods(GeneratedType type) {
+        type.methodDefinitions.filter([def | !def.isDefault])
     }
 }