/* * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ 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.Collection import java.util.Collections import java.util.Map import java.util.Set import org.opendaylight.mdsal.binding.model.api.GeneratedProperty import org.opendaylight.mdsal.binding.model.api.GeneratedType import org.opendaylight.mdsal.binding.model.api.Type import org.opendaylight.yangtools.yang.binding.CodeHelpers import java.util.ArrayList import org.opendaylight.mdsal.binding.model.util.Types import org.opendaylight.yangtools.yang.binding.Identifiable import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject import org.opendaylight.mdsal.binding.spec.naming.BindingMapping import com.google.common.collect.ImmutableMap import org.opendaylight.yangtools.yang.binding.AugmentationHolder import java.util.HashMap abstract class AbstractBuilderTemplate extends BaseTemplate { /** * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME. */ protected val Type augmentType /** * Set of class attributes (fields) which are derived from the getter methods names. */ protected val Set properties /** * GeneratedType for key type, null if this type does not have a key. */ protected val Type keyType protected val GeneratedType targetType; new(AbstractJavaGeneratedType javaType, GeneratedType type, GeneratedType targetType, Set properties, Type augmentType, Type keyType) { super(javaType, type) this.targetType = targetType this.properties = properties this.augmentType = augmentType this.keyType = keyType } new(GeneratedType type, GeneratedType targetType, Set properties, Type augmentType, Type keyType) { super(type) this.targetType = targetType this.properties = properties this.augmentType = augmentType this.keyType = keyType } /** * Template method which generates class attributes. * * @param makeFinal value which specify whether field is|isn't final * @return string with class attributes and their types */ def generateFields(boolean makeFinal) ''' «IF properties !== null» «FOR f : properties» private«IF makeFinal» final«ENDIF» «f.returnType.importedName» «f.fieldName»; «ENDFOR» «ENDIF» «IF keyType !== null» private«IF makeFinal» final«ENDIF» «keyType.importedName» key; «ENDIF» ''' def generateAugmentField(boolean isPrivate) ''' «IF augmentType !== null» «IF isPrivate»private «ENDIF»«Map.importedName»<«Class.importedName», «augmentType.importedName»> «AUGMENTATION_FIELD» = «Collections.importedName».emptyMap(); «ENDIF» ''' override generateToString(Collection 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. * * @return string with getter methods */ def generateGetters(boolean addOverride) ''' «IF keyType !== null» «IF addOverride»@«Override.importedName»«ENDIF» public «keyType.importedName» «BindingMapping.IDENTIFIABLE_KEY_NAME»() { return key; } «ENDIF» «IF !properties.empty» «FOR field : properties SEPARATOR '\n'» «IF addOverride»@«Override.importedName»«ENDIF» «field.getterMethod» «ENDFOR» «ENDIF» «IF augmentType !== null» @SuppressWarnings("unchecked") «IF addOverride»@«Override.importedName»«ENDIF» public E «AUGMENTABLE_AUGMENTATION_NAME»(«Class.importedName» augmentationType) { return (E) «AUGMENTATION_FIELD».get(«CodeHelpers.importedName».nonNullValue(augmentationType, "augmentationType")); } «ENDIF» ''' def CharSequence generateCopyConstructor(boolean impl, Type fromType, Type implType) ''' «IF impl»private«ELSE»public«ENDIF» «type.name»(«fromType.importedName» base) { «val allProps = new ArrayList(properties)» «val isList = implementsIfc(targetType, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), targetType))» «IF isList && keyType !== null» «val keyProps = new ArrayList((keyType as GeneratedTransferObject).properties)» «Collections.sort(keyProps, [ p1, p2 | return p1.name.compareTo(p2.name) ])» «FOR field : keyProps» «removeProperty(allProps, field.name)» «ENDFOR» if (base.«BindingMapping.IDENTIFIABLE_KEY_NAME»() == null) { this.key = new «keyType.importedName»( «FOR keyProp : keyProps SEPARATOR ", "» base.«keyProp.getterMethodName»() «ENDFOR» ); «FOR field : keyProps» this.«field.fieldName» = base.«field.getterMethodName»(); «ENDFOR» } else { this.key = base.«BindingMapping.IDENTIFIABLE_KEY_NAME»(); «FOR field : keyProps» this.«field.fieldName» = key.«field.getterMethodName»(); «ENDFOR» } «ENDIF» «FOR field : allProps» this.«field.fieldName» = base.«field.getterMethodName»(); «ENDFOR» «IF augmentType !== null» «IF impl» this.«AUGMENTATION_FIELD» = «ImmutableMap.importedName».copyOf(base.«AUGMENTATION_FIELD»); «ELSE» if (base instanceof «implType.importedName») { «implType.importedName» impl = («implType.importedName») base; if (!impl.«AUGMENTATION_FIELD».isEmpty()) { this.«AUGMENTATION_FIELD» = new «HashMap.importedName»<>(impl.«AUGMENTATION_FIELD»); } } else if (base instanceof «AugmentationHolder.importedName») { @SuppressWarnings("unchecked") «AugmentationHolder.importedName»<«fromType.importedName»> casted =(«AugmentationHolder.importedName»<«fromType.importedName»>) base; if (!casted.augmentations().isEmpty()) { this.«AUGMENTATION_FIELD» = new «HashMap.importedName»<>(casted.augmentations()); } } «ENDIF» «ENDIF» } ''' private def boolean implementsIfc(GeneratedType type, Type impl) { for (Type ifc : type.implements) { if (ifc.equals(impl)) { return true; } } return false; } private def void removeProperty(Collection props, String name) { var GeneratedProperty toRemove = null for (p : props) { if (p.name.equals(name)) { toRemove = p; } } if (toRemove !== null) { props.remove(toRemove); } } }