040e392cc5a8019d935869301d2f30aa9bff6459
[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.Types.STRING;
11 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.AUGMENTATION_FIELD
12 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_EQUALS_NAME
13 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_HASHCODE_NAME
14 import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.BINDING_TO_STRING_NAME
15
16 import java.util.Collection
17 import java.util.List
18 import org.opendaylight.mdsal.binding.model.api.AnnotationType
19 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
20 import org.opendaylight.mdsal.binding.model.api.GeneratedType
21 import org.opendaylight.mdsal.binding.model.api.MethodSignature.ValueMechanics
22 import org.opendaylight.mdsal.binding.model.api.Type
23 import org.opendaylight.mdsal.binding.model.util.Types
24 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
25 import org.opendaylight.yangtools.yang.binding.AbstractAugmentable
26
27 class BuilderImplTemplate extends AbstractBuilderTemplate {
28     val Type builderType;
29
30     new(BuilderTemplate builder, GeneratedType type) {
31         super(builder.javaType.getEnclosedType(type.identifier), type, builder.targetType, builder.properties,
32             builder.augmentType, builder.keyType)
33         this.builderType = builder.type
34     }
35
36     override body() '''
37         «targetType.annotations.generateDeprecatedAnnotation»
38         private static final class «type.name»
39             «val impIface = targetType.importedName»
40             «IF augmentType !== null»
41                 extends «AbstractAugmentable.importedName»<«impIface»>
42             «ENDIF»
43             implements «impIface» {
44
45             «generateFields(true)»
46
47             «generateCopyConstructor(builderType, type)»
48
49             «generateGetters(true)»
50
51             «generateHashCode()»
52
53             «generateEquals()»
54
55             «generateToString()»
56         }
57     '''
58
59     override generateDeprecatedAnnotation(AnnotationType ann) {
60         return generateAnnotation(ann)
61     }
62
63     /**
64      * Template method which generates the method <code>hashCode()</code>.
65      *
66      * @return string with the <code>hashCode()</code> method definition in JAVA format
67      */
68     def protected generateHashCode() '''
69         «IF !properties.empty || augmentType !== null»
70             private int hash = 0;
71             private volatile boolean hashValid = false;
72
73             @«OVERRIDE.importedName»
74             public int hashCode() {
75                 if (hashValid) {
76                     return hash;
77                 }
78
79                 final int result = «targetType.importedName».«BINDING_HASHCODE_NAME»(this);
80                 hash = result;
81                 hashValid = true;
82                 return result;
83             }
84         «ENDIF»
85     '''
86
87     /**
88      * Template method which generates the method <code>equals()</code>.
89      *
90      * @return string with the <code>equals()</code> method definition in JAVA format
91      */
92     def protected generateEquals() '''
93         «IF !properties.empty || augmentType !== null»
94             @«OVERRIDE.importedName»
95             public boolean equals(«Types.objectType().importedName» obj) {
96                 return «targetType.importedName».«BINDING_EQUALS_NAME»(this, obj);
97             }
98         «ENDIF»
99     '''
100
101     /**
102      * Template method which generates the method <code>toString()</code>.
103      *
104      * @return string with the <code>toString()</code> method definition in JAVA format
105      */
106     def protected generateToString() '''
107         @«OVERRIDE.importedName»
108         public «STRING.importedName» toString() {
109             return «targetType.importedName».«BINDING_TO_STRING_NAME»(this);
110         }
111     '''
112
113     override protected generateCopyKeys(List<GeneratedProperty> keyProps) '''
114         if (base.«BindingMapping.IDENTIFIABLE_KEY_NAME»() != null) {
115             this.key = base.«BindingMapping.IDENTIFIABLE_KEY_NAME»();
116         } else {
117             this.key = new «keyType.importedName»(«FOR keyProp : keyProps SEPARATOR ", "»base.«keyProp.getterMethodName»()«ENDFOR»);
118         }
119         «FOR field : keyProps»
120             this.«field.fieldName» = key.«field.getterMethodName»();
121         «ENDFOR»
122     '''
123
124     override protected CharSequence generateCopyNonKeys(Collection<BuilderGeneratedProperty> props) '''
125         «FOR field : props»
126             «IF field.mechanics === ValueMechanics.NULLIFY_EMPTY»
127                 this.«field.fieldName» = «CODEHELPERS.importedName».emptyToNull(base.«field.getterName»());
128             «ELSE»
129                 this.«field.fieldName» = base.«field.getterName»();
130             «ENDIF»
131         «ENDFOR»
132     '''
133
134     override protected generateCopyAugmentation(Type implType) '''
135         super(base.«AUGMENTATION_FIELD»);
136     '''
137 }