X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=code-generator%2Fbinding-java-api-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fsal%2Fjava%2Fapi%2Fgenerator%2FBuilderTemplate.xtend;h=3d0d19c436b2889f9eb5b15f664c88580d149b49;hb=cfcabe4fa638e90705bb6226500523dc40f4b9ee;hp=7dd355230387a27ca245954b12a8ab9dd826e705;hpb=135050628eb405fcb2c2b6cd66e99891c7d78507;p=yangtools.git diff --git a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend index 7dd3552303..3d0d19c436 100644 --- a/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend +++ b/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend @@ -29,6 +29,8 @@ import java.util.ArrayList import java.util.HashSet import java.util.Collection import org.opendaylight.yangtools.yang.binding.Identifiable +import com.google.common.collect.Range +import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType /** * Template for generating JAVA builder classes. @@ -154,7 +156,7 @@ class BuilderTemplate extends BaseTemplate { * @param set of method signature instances which should be transformed to list of properties * @return set of generated property instances which represents the getter methods */ - def private propertiesFromMethods(Set methods) { + def private propertiesFromMethods(Collection methods) { if (methods == null || methods.isEmpty()) { return Collections.emptySet } @@ -211,6 +213,8 @@ class BuilderTemplate extends BaseTemplate { «generateConstructorsFromIfcs(type)» + «generateCopyConstructor(false)» + «generateMethodFieldsFrom(type)» «generateGetters(false)» @@ -229,7 +233,7 @@ class BuilderTemplate extends BaseTemplate { «generateAugmentField(false)» - «generateConstructor» + «generateCopyConstructor(true)» «generateGetters(true)» @@ -390,16 +394,25 @@ class BuilderTemplate extends BaseTemplate { return names } - /** - * Template method which generates class attributes. - * - * @param boolean value which specify whether field is|isn't final - * @return string with class attributes and their types - */ + /** + * Template method which generates class attributes. + * + * @param boolean value which specify whether field is|isn't final + * @return string with class attributes and their types + */ def private generateFields(boolean _final) ''' - «IF !properties.empty» + «IF properties !== null» «FOR f : properties» private«IF _final» final«ENDIF» «f.returnType.importedName» «f.fieldName»; + «val restrictions = f.returnType.restrictions» + «IF !_final && restrictions != null» + «IF !(restrictions.lengthConstraints.empty)» + private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_length; + «ENDIF» + «IF !(restrictions.rangeConstraints.empty)» + private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_range; + «ENDIF» + «ENDIF» «ENDFOR» «ENDIF» ''' @@ -410,19 +423,22 @@ class BuilderTemplate extends BaseTemplate { «ENDIF» ''' - /** - * Template method which generates setter methods - * - * @return string with the setter methods - */ + /** + * Template method which generates setter methods + * + * @return string with the setter methods + */ def private generateSetters() ''' «FOR field : properties SEPARATOR '\n'» + «val length = field.fieldName + "_length"» + «val range = field.fieldName + "_range"» public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) { - «generateRestrictions(field, "value")» - + «generateRestrictions(field, "value", length, range)» this.«field.fieldName» = value; return this; } + «generateLengthMethod(length, field.returnType, type.name+BUILDER, length)» + «generateRangeMethod(range, field.returnType.restrictions, field.returnType, type.name+BUILDER, range)» «ENDFOR» «IF augmentField != null» @@ -433,13 +449,62 @@ class BuilderTemplate extends BaseTemplate { «ENDIF» ''' - /** - * Template method which generate constructor for IMPL class. - * - * @return string with IMPL class constructor - */ - def private generateConstructor() ''' - private «type.name»«IMPL»(«type.name»«BUILDER» builder) { + def generateRestrictions(GeneratedProperty field, String paramName, String lengthGetter, String rangeGetter) ''' + «val Type type = field.returnType» + «IF type instanceof ConcreteType» + «createRestrictions(type, paramName, type.name.contains("["), lengthGetter, rangeGetter)» + «ELSEIF type instanceof GeneratedTransferObject» + «createRestrictions(type, paramName, isArrayType(type as GeneratedTransferObject), lengthGetter, rangeGetter)» + «ENDIF» + ''' + + def private createRestrictions(Type type, String paramName, boolean isArray, String lengthGetter, String rangeGetter) ''' + «val restrictions = type.getRestrictions» + «IF restrictions !== null» + «val boolean isNestedType = !(type instanceof ConcreteType)» + «IF !restrictions.lengthConstraints.empty» + «generateLengthRestriction(type, paramName, lengthGetter, isNestedType, isArray)» + «ENDIF» + «IF !restrictions.rangeConstraints.empty» + «generateRangeRestriction(type, paramName, rangeGetter, isNestedType)» + «ENDIF» + «ENDIF» + ''' + + def private generateLengthRestriction(Type type, String paramName, String getterName, boolean isNestedType, boolean isArray) ''' + «val restrictions = type.getRestrictions» + if («paramName» != null) { + «val clazz = restrictions.lengthConstraints.iterator.next.min.class» + «printLengthConstraint(type, clazz, paramName, isNestedType, isArray)» + boolean isValidLength = false; + for («Range.importedName»<«clazz.importedNumber»> r : «getterName»()) { + if (r.contains(_constraint)) { + isValidLength = true; + } + } + if (!isValidLength) { + throw new IllegalArgumentException(String.format("Invalid length: %s, expected: %s.", «paramName», «getterName»)); + } + } + ''' + + def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType) ''' + if («paramName» != null) { + «printRangeConstraint(type, paramName, isNestedType)» + boolean isValidRange = false; + for («Range.importedName»<«type.importedNumber»> r : «getterName»()) { + if (r.contains(_constraint)) { + isValidRange = true; + } + } + if (!isValidRange) { + throw new IllegalArgumentException(String.format("Invalid range: %s, expected: %s.", «paramName», «getterName»)); + } + } + ''' + + def private CharSequence generateCopyConstructor(boolean impl) ''' + «IF impl»private«ELSE»public«ENDIF» «type.name»«IF impl»«IMPL»«ELSE»«BUILDER»«ENDIF»(«type.name»«IF impl»«BUILDER»«ENDIF» base) { «val allProps = new ArrayList(properties)» «val isList = implementsIfc(type, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), type))» «val keyType = type.getKey» @@ -454,37 +519,41 @@ class BuilderTemplate extends BaseTemplate { «removeProperty(allProps, field.name)» «ENDFOR» «removeProperty(allProps, "key")» - if (builder.getKey() == null) { + if (base.getKey() == null) { this._key = new «keyType.importedName»( «FOR keyProp : keyProps SEPARATOR ", "» - builder.«keyProp.getterMethodName»() + base.«keyProp.getterMethodName»() «ENDFOR» ); «FOR field : keyProps» - this.«field.fieldName» = builder.«field.getterMethodName»(); + this.«field.fieldName» = base.«field.getterMethodName»(); «ENDFOR» } else { - this._key = builder.getKey(); + this._key = base.getKey(); «FOR field : keyProps» this.«field.fieldName» = _key.«field.getterMethodName»(); «ENDFOR» } «ENDIF» «FOR field : allProps» - this.«field.fieldName» = builder.«field.getterMethodName»(); + this.«field.fieldName» = base.«field.getterMethodName»(); «ENDFOR» «IF augmentField != null» - switch (builder.«augmentField.name».size()) { - case 0: - this.«augmentField.name» = «Collections.importedName».emptyMap(); - break; - case 1: - final «Map.importedName».Entry<«Class.importedName», «augmentField.returnType.importedName»> e = builder.«augmentField.name».entrySet().iterator().next(); - this.«augmentField.name» = «Collections.importedName».<«Class.importedName», «augmentField.returnType.importedName»>singletonMap(e.getKey(), e.getValue()); - break; - default : - this.«augmentField.name» = new «HashMap.importedName»<>(builder.«augmentField.name»); - } + «IF !impl»if (base instanceof «type.name»«IMPL») {«ENDIF» + «IF !impl»«type.name»«IMPL» _impl = («type.name»«IMPL») base;«ENDIF» + «val prop = if (impl) "base" else "_impl"» + switch («prop».«augmentField.name».size()) { + case 0: + this.«augmentField.name» = «Collections.importedName».emptyMap(); + break; + case 1: + final «Map.importedName».Entry<«Class.importedName», «augmentField.returnType.importedName»> e = «prop».«augmentField.name».entrySet().iterator().next(); + this.«augmentField.name» = «Collections.importedName».<«Class.importedName», «augmentField.returnType.importedName»>singletonMap(e.getKey(), e.getValue()); + break; + default : + this.«augmentField.name» = new «HashMap.importedName»<>(«prop».«augmentField.name»); + } + «IF !impl»}«ENDIF» «ENDIF» } '''