2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.binding.java.api.generator
10 import static org.opendaylight.mdsal.binding.model.ri.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
16 import java.util.Collection
18 import java.util.Optional
19 import org.opendaylight.mdsal.binding.model.api.AnnotationType
20 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
21 import org.opendaylight.mdsal.binding.model.api.GeneratedType
22 import org.opendaylight.mdsal.binding.model.api.MethodSignature
23 import org.opendaylight.mdsal.binding.model.api.MethodSignature.ValueMechanics
24 import org.opendaylight.mdsal.binding.model.api.Type
25 import org.opendaylight.mdsal.binding.model.ri.Types
26 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
27 import org.opendaylight.yangtools.yang.binding.AbstractAugmentable
29 class BuilderImplTemplate extends AbstractBuilderTemplate {
30 val BuilderTemplate builder;
32 new(BuilderTemplate builder, GeneratedType type) {
33 super(builder.javaType.getEnclosedType(type.identifier), type, builder.targetType, builder.properties,
34 builder.augmentType, builder.keyType)
35 this.builder = builder
39 «targetType.annotations.generateDeprecatedAnnotation»
40 private static final class «type.name»
41 «val impIface = targetType.importedName»
42 «IF augmentType !== null»
43 extends «AbstractAugmentable.importedName»<«impIface»>
45 implements «impIface» {
47 «generateFields(true)»
49 «generateCopyConstructor(builder.type, type)»
61 override generateDeprecatedAnnotation(AnnotationType ann) {
62 return generateAnnotation(ann)
65 def private generateGetters() '''
67 @«OVERRIDE.importedName»
68 public «keyType.importedName» «BindingMapping.IDENTIFIABLE_KEY_NAME»() {
73 «IF !properties.empty»
74 «FOR field : properties SEPARATOR '\n'»
80 private static def Optional<MethodSignature> findGetter(GeneratedType implType, String getterName) {
81 val getter = getterByName(implType.nonDefaultMethods, getterName);
82 if (getter.isPresent) {
85 for (ifc : implType.implements) {
86 if (ifc instanceof GeneratedType) {
87 val getterImpl = findGetter(ifc, getterName)
88 if (getterImpl.isPresent) {
96 override getterMethod(GeneratedProperty field) '''
97 @«OVERRIDE.importedName»
98 public «field.returnType.importedName» «field.getterMethodName»() {
99 «val fieldName = field.fieldName»
100 «IF field.returnType.name.endsWith("[]")»
101 return «fieldName» == null ? null : «fieldName».clone();
108 package def findGetter(String getterName) {
109 val ownGetter = getterByName(type.nonDefaultMethods, getterName);
110 if (ownGetter.isPresent) {
111 return ownGetter.get;
113 for (ifc : type.implements) {
114 if (ifc instanceof GeneratedType) {
115 val getter = findGetter(ifc, getterName)
116 if (getter.isPresent) {
121 throw new IllegalStateException(
122 String.format("%s should be present in %s type or in one of its ancestors as getter",
123 getterName.propertyNameFromGetter, type));
127 * Template method which generates the method <code>hashCode()</code>.
129 * @return string with the <code>hashCode()</code> method definition in JAVA format
131 def protected generateHashCode() '''
132 «IF !properties.empty || augmentType !== null»
133 private int hash = 0;
134 private volatile boolean hashValid = false;
136 @«OVERRIDE.importedName»
137 public int hashCode() {
142 final int result = «targetType.importedName».«BINDING_HASHCODE_NAME»(this);
151 * Template method which generates the method <code>equals()</code>.
153 * @return string with the <code>equals()</code> method definition in JAVA format
155 def protected generateEquals() '''
156 «IF !properties.empty || augmentType !== null»
157 @«OVERRIDE.importedName»
158 public boolean equals(«Types.objectType().importedName» obj) {
159 return «targetType.importedName».«BINDING_EQUALS_NAME»(this, obj);
165 * Template method which generates the method <code>toString()</code>.
167 * @return string with the <code>toString()</code> method definition in JAVA format
169 def protected generateToString() '''
170 @«OVERRIDE.importedName»
171 public «STRING.importedName» toString() {
172 return «targetType.importedName».«BINDING_TO_STRING_NAME»(this);
176 override protected generateCopyKeys(List<GeneratedProperty> keyProps) '''
177 if (base.«BindingMapping.IDENTIFIABLE_KEY_NAME»() != null) {
178 this.key = base.«BindingMapping.IDENTIFIABLE_KEY_NAME»();
180 this.key = new «keyType.importedName»(«FOR keyProp : keyProps SEPARATOR ", "»base.«keyProp.getterMethodName»()«ENDFOR»);
182 «FOR field : keyProps»
183 this.«field.fieldName» = key.«field.getterMethodName»();
187 override protected CharSequence generateCopyNonKeys(Collection<BuilderGeneratedProperty> props) '''
189 «IF field.mechanics === ValueMechanics.NULLIFY_EMPTY»
190 this.«field.fieldName» = «CODEHELPERS.importedName».emptyToNull(base.«field.getterName»());
192 this.«field.fieldName» = base.«field.getterName»();
197 override protected generateCopyAugmentation(Type implType) '''
198 super(base.«AUGMENTATION_FIELD»);