names = new ArrayList
for (type : types) {
- names.add(type.fullyQualifiedName)
+ names.add(type.importedName)
}
return names
}
@@ -271,11 +339,15 @@ class BuilderTemplate extends AbstractBuilderTemplate {
«ENDFOR»
'''
- def private generateSetter(GeneratedProperty field) {
+ def private generateSetter(BuilderGeneratedProperty field) {
val returnType = field.returnType
if (returnType instanceof ParameterizedType) {
- if (Types.isListType(returnType)) {
- return generateListSetter(field, returnType.actualTypeArguments.get(0))
+ if (Types.isListType(returnType) || Types.isSetType(returnType)) {
+ val arguments = returnType.actualTypeArguments
+ if (arguments.isEmpty) {
+ return generateListSetter(field, Types.objectType)
+ }
+ return generateListSetter(field, arguments.get(0))
} else if (Types.isMapType(returnType)) {
return generateMapSetter(field, returnType.actualTypeArguments.get(1))
}
@@ -283,11 +355,19 @@ class BuilderTemplate extends AbstractBuilderTemplate {
return generateSimpleSetter(field, returnType)
}
- def private generateListSetter(GeneratedProperty field, Type actualType) '''
+ def private generateListSetter(BuilderGeneratedProperty field, Type actualType) '''
«val restrictions = restrictionsForSetter(actualType)»
«IF restrictions !== null»
«generateCheckers(field, restrictions, actualType)»
«ENDIF»
+
+ /**
+ * Set the property corresponding to {@link «targetType.importedName»#«field.getterName»()} to the specified
+ * value.
+ *
+ * @param values desired value
+ * @return this builder
+ */
public «type.getName» set«field.getName.toFirstUpper»(final «field.returnType.importedName» values) {
«IF restrictions !== null»
if (values != null) {
@@ -302,18 +382,23 @@ class BuilderTemplate extends AbstractBuilderTemplate {
'''
- // FIXME: MDSAL-540: remove the migration setter
- def private generateMapSetter(GeneratedProperty field, Type actualType) '''
+ def private generateMapSetter(BuilderGeneratedProperty field, Type actualType) '''
«val restrictions = restrictionsForSetter(actualType)»
- «val actualTypeRef = actualType.importedName»
- «val setterName = "set" + field.name.toFirstUpper»
«IF restrictions !== null»
«generateCheckers(field, restrictions, actualType)»
«ENDIF»
- public «type.getName» «setterName»(final «field.returnType.importedName» values) {
+
+ /**
+ * Set the property corresponding to {@link «targetType.importedName»#«field.getterName»()} to the specified
+ * value.
+ *
+ * @param values desired value
+ * @return this builder
+ */
+ public «type.getName» set«field.name.toFirstUpper»(final «field.returnType.importedName» values) {
«IF restrictions !== null»
if (values != null) {
- for («actualTypeRef» value : values.values()) {
+ for («actualType.importedName» value : values.values()) {
«checkArgument(field, restrictions, actualType, "value")»
}
}
@@ -321,33 +406,22 @@ class BuilderTemplate extends AbstractBuilderTemplate {
this.«field.fieldName» = values;
return this;
}
-
- /**
- * Utility migration setter.
- *
- * IMPORTANT NOTE: This method does not completely match previous mechanics, as the list is processed as
- * during this method's execution. Any future modifications of the list are NOT
- * reflected in this builder nor its products.
- *
- * @param values Legacy List of values
- * @return this builder
- * @throws IllegalArgumentException if the list contains entries with the same key
- * @throws NullPointerException if the list contains a null entry
- * @deprecated Use {#link #«setterName»(«JU_MAP.importedName»)} instead.
- */
- @«DEPRECATED.importedName»(forRemoval = true)
- public «type.getName» «setterName»(final «JU_LIST.importedName»<«actualTypeRef»> values) {
- return «setterName»(«CODEHELPERS.importedName».compatMap(values));
- }
'''
- def private generateSimpleSetter(GeneratedProperty field, Type actualType) '''
+ def private generateSimpleSetter(BuilderGeneratedProperty field, Type actualType) '''
«val restrictions = restrictionsForSetter(actualType)»
«IF restrictions !== null»
«generateCheckers(field, restrictions, actualType)»
«ENDIF»
+ /**
+ * Set the property corresponding to {@link «targetType.importedName»#«field.getterName»()} to the specified
+ * value.
+ *
+ * @param value desired value
+ * @return this builder
+ */
«val setterName = "set" + field.getName.toFirstUpper»
public «type.getName» «setterName»(final «field.returnType.importedName» value) {
«IF restrictions !== null»
@@ -378,30 +452,21 @@ class BuilderTemplate extends AbstractBuilderTemplate {
«IF augmentType !== null»
«val augmentTypeRef = augmentType.importedName»
- «val jlClassRef = CLASS.importedName»
«val hashMapRef = JU_HASHMAP.importedName»
/**
* Add an augmentation to this builder's product.
*
* @param augmentation augmentation to be added
* @return this builder
- * @throws NullPointerException if {@code augmentation} is null
+ * @throws «NPE.importedName» if {@code augmentation} is null
*/
public «type.name» addAugmentation(«augmentTypeRef» augmentation) {
- return doAddAugmentation(augmentation.«DATA_CONTAINER_IMPLEMENTED_INTERFACE_NAME»(), augmentation);
- }
+ if (!(this.«AUGMENTATION_FIELD» instanceof «hashMapRef»)) {
+ this.«AUGMENTATION_FIELD» = new «hashMapRef»<>();
+ }
- /**
- * Add or remove an augmentation to this builder's product.
- *
- * @param augmentationType augmentation type to be added or removed
- * @param augmentationValue augmentation value, null if the augmentation type should be removed
- * @return this builder
- * @deprecated Use either {@link #addAugmentation(«augmentType.importedJavadocName»)} or {@link #removeAugmentation(«CLASS.importedName»)} instead.
- */
- @«DEPRECATED.importedName»(forRemoval = true)
- public «type.name» addAugmentation(«jlClassRef» extends «augmentTypeRef»> augmentationType, «augmentTypeRef» augmentationValue) {
- return augmentationValue == null ? removeAugmentation(augmentationType) : doAddAugmentation(augmentationType, augmentationValue);
+ this.«AUGMENTATION_FIELD».put(augmentation.«BINDING_CONTRACT_IMPLEMENTED_INTERFACE_NAME»(), augmentation);
+ return this;
}
/**
@@ -411,26 +476,17 @@ class BuilderTemplate extends AbstractBuilderTemplate {
* @param augmentationType augmentation type to be removed
* @return this builder
*/
- public «type.name» removeAugmentation(«jlClassRef» extends «augmentTypeRef»> augmentationType) {
+ public «type.name» removeAugmentation(«CLASS.importedName» extends «augmentTypeRef»> augmentationType) {
if (this.«AUGMENTATION_FIELD» instanceof «hashMapRef») {
this.«AUGMENTATION_FIELD».remove(augmentationType);
}
return this;
}
-
- private «type.name» doAddAugmentation(«jlClassRef» extends «augmentTypeRef»> augmentationType, «augmentTypeRef» augmentationValue) {
- if (!(this.«AUGMENTATION_FIELD» instanceof «hashMapRef»)) {
- this.«AUGMENTATION_FIELD» = new «hashMapRef»<>();
- }
-
- this.«AUGMENTATION_FIELD».put(augmentationType, augmentationValue);
- return this;
- }
«ENDIF»
'''
private def createDescription(GeneratedType targetType) {
- val target = type.importedName
+ val target = targetType.importedName
return '''
Class that builds {@link «target»} instances. Overall design of the class is that of a
fluent interface, where method chaining is used.
@@ -439,7 +495,7 @@ class BuilderTemplate extends AbstractBuilderTemplate {
In general, this class is supposed to be used like this template:
- «target» createTarget(int fooXyzzy, int barBaz) {
+ «target» create«target»(int fooXyzzy, int barBaz) {
return new «target»Builder()
.setFoo(new FooBuilder().setXyzzy(fooXyzzy).build())
.setBar(new BarBuilder().setBaz(barBaz).build())
@@ -460,14 +516,13 @@ class BuilderTemplate extends AbstractBuilderTemplate {
invocation, which is terminated by {@link #build()}, which is then returned from the method
better understanding by humans, as the scope of mutable state (the builder) is kept to a minimum and is
very localized
- better optimization oportunities, as the object scope is minimized in terms of invocation (rather than
+ better optimization opportunities, as the object scope is minimized in terms of invocation (rather than
method) stack, making escape analysis a lot
easier. Given enough compiler (JIT/AOT) prowess, the cost of th builder object can be completely
eliminated
@see «target»
- @see «BUILDER.importedName»
'''
}
@@ -482,6 +537,14 @@ class BuilderTemplate extends AbstractBuilderTemplate {
}
private def generateAugmentation() '''
+ /**
+ * Return the specified augmentation, if it is present in this builder.
+ *
+ * @param augmentation type
+ * @param augmentationType augmentation type class
+ * @return Augmentation object from this builder, or {@code null} if not present
+ * @throws «NPE.importedName» if {@code augmentType} is {@code null}
+ */
@«SUPPRESS_WARNINGS.importedName»({ "unchecked", "checkstyle:methodTypeParameterName"})
public E$$ «AUGMENTABLE_AUGMENTATION_NAME»(«CLASS.importedName» augmentationType) {
return (E$$) «AUGMENTATION_FIELD».get(«JU_OBJECTS.importedName».requireNonNull(augmentationType));
@@ -501,27 +564,10 @@ class BuilderTemplate extends AbstractBuilderTemplate {
«ENDFOR»
'''
- override protected generateCopyAugmentation(Type implType) {
- val augmentationHolderRef = AugmentationHolder.importedName
- val typeRef = targetType.importedName
- val hashMapRef = JU_HASHMAP.importedName
- val augmentTypeRef = augmentType.importedName
- return '''
- if (base instanceof «augmentationHolderRef») {
- @SuppressWarnings("unchecked")
- «JU_MAP.importedName»<«CLASS.importedName» extends «augmentTypeRef»>, «augmentTypeRef»> aug =((«augmentationHolderRef»<«typeRef»>) base).augmentations();
- if (!aug.isEmpty()) {
- this.«AUGMENTATION_FIELD» = new «hashMapRef»<>(aug);
- }
- }
- '''
- }
-
- private static def hasNonDefaultMethods(GeneratedType type) {
- !type.methodDefinitions.isEmpty && type.methodDefinitions.exists([def | !def.isDefault])
- }
-
- private static def nonDefaultMethods(GeneratedType type) {
- type.methodDefinitions.filter([def | !def.isDefault])
- }
+ override protected generateCopyAugmentation(Type implType) '''
+ final var aug = base.augmentations();
+ if (!aug.isEmpty()) {
+ this.«AUGMENTATION_FIELD» = new «JU_HASHMAP.importedName»<>(aug);
+ }
+ '''
}