Improve often-used class imports
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / BuilderImplTemplate.xtend
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.java.api.generator
9
10 import static org.opendaylight.mdsal.binding.model.util.BindingTypes.DATA_OBJECT
11 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
12 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTABLE_AUGMENTATION_NAME
13 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME
14
15 import java.util.List
16 import org.opendaylight.mdsal.binding.model.api.AnnotationType
17 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
18 import org.opendaylight.mdsal.binding.model.api.GeneratedType
19 import org.opendaylight.mdsal.binding.model.api.Type
20 import org.opendaylight.mdsal.binding.model.util.Types
21 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
22 import org.opendaylight.yangtools.yang.binding.AbstractAugmentable
23
24 class BuilderImplTemplate extends AbstractBuilderTemplate {
25     val Type builderType;
26
27     new(BuilderTemplate builder, GeneratedType type) {
28         super(builder.javaType.getEnclosedType(type.identifier), type, builder.targetType, builder.properties,
29             builder.augmentType, builder.keyType)
30         this.builderType = builder.type
31     }
32
33     override body() '''
34         «targetType.annotations.generateDeprecatedAnnotation»
35         private static final class «type.name»
36             «val impIface = targetType.importedName»
37             «IF augmentType !== null»
38                 extends «AbstractAugmentable.importedName»<«impIface»>
39             «ENDIF»
40             implements «impIface» {
41
42             «generateFields(true)»
43
44             «generateCopyConstructor(builderType, type)»
45
46             «generateGetters(true)»
47
48             «generateHashCode()»
49
50             «generateEquals()»
51
52             «generateToString(properties)»
53         }
54     '''
55
56     override generateDeprecatedAnnotation(AnnotationType ann) {
57         return generateAnnotation(ann)
58     }
59
60     /**
61      * Template method which generates the method <code>hashCode()</code>.
62      *
63      * @return string with the <code>hashCode()</code> method definition in JAVA format
64      */
65     def protected generateHashCode() '''
66         «IF !properties.empty || augmentType !== null»
67             private int hash = 0;
68             private volatile boolean hashValid = false;
69
70             @«OVERRIDE.importedName»
71             public int hashCode() {
72                 if (hashValid) {
73                     return hash;
74                 }
75
76                 «hashCodeResult(properties)»
77                 «IF augmentType !== null»
78                     result = prime * result + «JU_OBJECTS.importedName».hashCode(augmentations());
79                 «ENDIF»
80
81                 hash = result;
82                 hashValid = true;
83                 return result;
84             }
85         «ENDIF»
86     '''
87
88     /**
89      * Template method which generates the method <code>equals()</code>.
90      *
91      * @return string with the <code>equals()</code> method definition in JAVA format
92      */
93     def protected generateEquals() '''
94         «IF !properties.empty || augmentType !== null»
95             @«OVERRIDE.importedName»
96             public boolean equals(«Types.objectType().importedName» obj) {
97                 if (this == obj) {
98                     return true;
99                 }
100                 if (!(obj instanceof «DATA_OBJECT.importedName»)) {
101                     return false;
102                 }
103                 if (!«targetType.importedName».class.equals(((«DATA_OBJECT.importedName»)obj).«DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME»())) {
104                     return false;
105                 }
106                 «targetType.importedName» other = («targetType.importedName»)obj;
107                 «FOR property : properties»
108                     «val fieldName = property.fieldName»
109                     if (!«property.importedUtilClass».equals(«fieldName», other.«property.getterMethodName»())) {
110                         return false;
111                     }
112                 «ENDFOR»
113                 «IF augmentType !== null»
114                     if (getClass() == obj.getClass()) {
115                         // Simple case: we are comparing against self
116                         «type.name» otherImpl = («type.name») obj;
117                         if (!«JU_OBJECTS.importedName».equals(augmentations(), otherImpl.augmentations())) {
118                             return false;
119                         }
120                     } else {
121                         // Hard case: compare our augments with presence there...
122                         for («JU_MAP.importedName».Entry<«CLASS.importedName»<? extends «augmentType.importedName»>, «augmentType.importedName»> e : augmentations().entrySet()) {
123                             if (!e.getValue().equals(other.«AUGMENTABLE_AUGMENTATION_NAME»(e.getKey()))) {
124                                 return false;
125                             }
126                         }
127                         // .. and give the other one the chance to do the same
128                         if (!obj.equals(this)) {
129                             return false;
130                         }
131                     }
132                 «ENDIF»
133                 return true;
134             }
135         «ENDIF»
136     '''
137
138     override protected generateCopyKeys(List<GeneratedProperty> keyProps) '''
139         if (base.«BindingMapping.IDENTIFIABLE_KEY_NAME»() != null) {
140             this.key = base.«BindingMapping.IDENTIFIABLE_KEY_NAME»();
141         } else {
142             this.key = new «keyType.importedName»(«FOR keyProp : keyProps SEPARATOR ", "»base.«keyProp.getterMethodName»()«ENDFOR»);
143         }
144         «FOR field : keyProps»
145             this.«field.fieldName» = key.«field.getterMethodName»();
146         «ENDFOR»
147     '''
148
149     override protected generateCopyAugmentation(Type implType) '''
150         super(base.«AUGMENTATION_FIELD»);
151     '''
152 }