From 1730967bdeb028e91148d531c5fc62422f16a1df Mon Sep 17 00:00:00 2001 From: Ashley Heath Date: Mon, 1 Jul 2019 17:55:27 +0100 Subject: [PATCH 1/3] Fix typo. --- src/site/markdown/userguide-codegen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/site/markdown/userguide-codegen.md b/src/site/markdown/userguide-codegen.md index e36e74b1..d90d0b89 100644 --- a/src/site/markdown/userguide-codegen.md +++ b/src/site/markdown/userguide-codegen.md @@ -450,7 +450,7 @@ To get the correct behaviour, the `BeanDefinition` annotation value Partially final beans can extend one another, but must all declare the builder scope. The rules as to what works and what does not are complex. -It is recommended to keep is simple, and only have normal mutable beans or final immutable beans. +It is recommended to keep it simple, and only have normal mutable beans or final immutable beans. ## Light beans From fc6d93565b72f00942b826fe71eb89f63c02d6a4 Mon Sep 17 00:00:00 2001 From: Ashley Heath Date: Mon, 1 Jul 2019 17:56:24 +0100 Subject: [PATCH 2/3] First pass at add and put methods for building collections and maps within beans (#100). --- pom.xml | 4 + src/main/java/org/joda/beans/gen/BeanGen.java | 18 +++ .../org/joda/beans/gen/BeanGenConfig.java | 44 ++++- .../org/joda/beans/gen/CollectionGen.java | 61 +++++++ .../java/org/joda/beans/gen/PropertyData.java | 72 ++++++++- .../java/org/joda/beans/gen/PropertyGen.java | 150 +++++++++++++++++- .../org/joda/beans/gen/PropertyParser.java | 2 + .../java/org/joda/beans/utils/NameUtils.java | 48 ++++++ .../resources/org/joda/beans/gen/guava.ini | 30 ++++ 9 files changed, 423 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/joda/beans/gen/CollectionGen.java create mode 100644 src/main/java/org/joda/beans/utils/NameUtils.java diff --git a/pom.xml b/pom.xml index f94510d8..b8cae776 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,10 @@ Martynas Sateika https://github.com/martynassateika + + Ashley Heath + https://github.com/ashleyheath + diff --git a/src/main/java/org/joda/beans/gen/BeanGen.java b/src/main/java/org/joda/beans/gen/BeanGen.java index 0bfe1e0a..47f7c1d5 100644 --- a/src/main/java/org/joda/beans/gen/BeanGen.java +++ b/src/main/java/org/joda/beans/gen/BeanGen.java @@ -1249,6 +1249,8 @@ private void generateBuilderClass() { } generateIndentedSeparator(); generateBuilderPropertySetMethods(); + generateBuilderPropertyAddMethods(); + generateBuilderPropertyPutMethods(); generateIndentedSeparator(); generateBuilderToString(); addLine(1, "}"); @@ -1395,6 +1397,22 @@ private void generateBuilderPropertySetMethods() { } } + private void generateBuilderPropertyAddMethods() { + if (data.isEffectiveBuilderScopeVisible()) { + for (PropertyGen prop : nonDerivedProperties()) { + addLines(prop.generateBuilderAddMethod()); + } + } + } + + private void generateBuilderPropertyPutMethods() { + if (data.isEffectiveBuilderScopeVisible()) { + for (PropertyGen prop : nonDerivedProperties()) { + addLines(prop.generateBuilderPutMethod()); + } + } + } + private void generateBuilderToString() { List nonDerived = toStringProperties(); if (data.isImmutable() && data.isTypeFinal()) { diff --git a/src/main/java/org/joda/beans/gen/BeanGenConfig.java b/src/main/java/org/joda/beans/gen/BeanGenConfig.java index 0567c263..f1ba47dd 100644 --- a/src/main/java/org/joda/beans/gen/BeanGenConfig.java +++ b/src/main/java/org/joda/beans/gen/BeanGenConfig.java @@ -50,6 +50,10 @@ public final class BeanGenConfig { * The builder generators. */ private final Map builderGenerators; + /** + * The collection generators. + */ + private final Map collectionGenerators; /** * The invalid immutable types. */ @@ -96,7 +100,7 @@ public static BeanGenConfig parse(String resourceLocator) { if (loader == null) { throw new IllegalArgumentException("ClassLoader was null: " + fullFile); } - URL url = loader.getResource(fullFile); + URL url = BeanGenConfig.class.getResource("guava.ini"); if (url == null) { throw new IllegalArgumentException("Configuration file not found: " + fullFile); } @@ -131,6 +135,7 @@ private static BeanGenConfig parse(List lines) { Map immutableGetClones = new HashMap<>(); Map immutableVarArgs = new HashMap<>(); Map builderInits = new HashMap<>(); + Map builderAdds = new HashMap<>(); Map builderTypes = new HashMap<>(); Set invalidImmutableTypes = new HashSet<>(); for (ListIterator iterator = lines.listIterator(); iterator.hasNext(); ) { @@ -238,6 +243,21 @@ private static BeanGenConfig parse(List lines) { String value = line.substring(pos + 1).trim(); builderInits.put(key, value); } + } else if (line.equals("[immutable.builder.add]")){ + while (iterator.hasNext()) { + line = iterator.next().trim(); + if (line.startsWith("[")) { + iterator.previous(); + break; + } + int pos = line.indexOf('='); + if (pos <= 0) { + throw new IllegalArgumentException("Invalid ini file line: " + line); + } + String key = line.substring(0, pos).trim(); + String value = line.substring(pos + 1).trim(); + builderAdds.put(key, value); + } } else { throw new IllegalArgumentException("Invalid ini file section: " + line); } @@ -261,7 +281,13 @@ private static BeanGenConfig parse(List lines) { } copyGenerators.put(fieldType, new CopyGen.PatternCopyGen(immutableCopier, mutableCopier)); } - return new BeanGenConfig(copyGenerators, builderGenerators, builderTypes, invalidImmutableTypes, immutableVarArgs, immutableGetClones); + Map collectionGenerators = new HashMap<>(); + for (Entry entry : builderAdds.entrySet()) { + String fieldType = entry.getKey(); + String adder = entry.getValue(); + collectionGenerators.put(fieldType, new CollectionGen.PatternCollectionGen(adder)); + } + return new BeanGenConfig(copyGenerators, builderGenerators, collectionGenerators, builderTypes, invalidImmutableTypes, immutableVarArgs, immutableGetClones); } //----------------------------------------------------------------------- @@ -270,6 +296,7 @@ private static BeanGenConfig parse(List lines) { * * @param copyGenerators the copy generators, not null * @param builderGenerators the builder generators, not null + * @param collectionGenerators the collection generators, not null * @param builderTypes the builder types, not null * @param invalidImmutableTypes the invalid immutable types, not null * @param immutableVarArgs the varargs code @@ -278,12 +305,14 @@ private static BeanGenConfig parse(List lines) { private BeanGenConfig( Map copyGenerators, Map builderGenerators, + Map collectionGenerators, Map builderTypes, Set invalidImmutableTypes, Map immutableVarArgs, Map immutableGetClones) { this.copyGenerators = copyGenerators; this.builderGenerators = builderGenerators; + this.collectionGenerators = collectionGenerators; this.builderTypes = builderTypes; this.invalidImmutableTypes = invalidImmutableTypes; this.immutableVarArgs = immutableVarArgs; @@ -302,13 +331,22 @@ public Map getCopyGenerators() { /** * The builder generators. - * + * * @return the generators, not null */ public Map getBuilderGenerators() { return builderGenerators; } + /** + * The collection generators. + * + * @return the generators, not null + */ + public Map getCollectionGenerators() { + return collectionGenerators; + } + /** * The builder types. * diff --git a/src/main/java/org/joda/beans/gen/CollectionGen.java b/src/main/java/org/joda/beans/gen/CollectionGen.java new file mode 100644 index 00000000..c96606af --- /dev/null +++ b/src/main/java/org/joda/beans/gen/CollectionGen.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-present Stephen Colebourne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.joda.beans.gen; + +/** + * A generator of collection code. + */ +abstract class CollectionGen { + + /** + * Generates code to add an element to a collection. + * + * @param existing the name of an existing collection or an expression evaluating to an instance of a collection, not null + * @param collectionTypeParams the type params of the collection, may be empty + * @param value the name of the value to add to the collection or an expression evaluating to an instance of a collection, not null + * @return the generated code, not null + */ + abstract String generateAddToCollection(String existing, String collectionTypeParams, String value); + + /** + * Generates code to add a new key/value pair to a map. + * + * @param existing the name of an existing map or an expression evaluating to an instance of a map, not null + * @param mapTypeParams the type params of the map, may be empty + * @param key the name of the key to add to the map or an expression evaluating to an instance of the key type, not null + * @param value the name of the value to add to the map or an expression evaluating to an instance of the value type, not null + * @return the generated code, not null + */ + abstract String generateAddToMap(String existing, String mapTypeParams, String key, String value); + + static class PatternCollectionGen extends CollectionGen { + private final String pattern; + + PatternCollectionGen(String pattern) { + this.pattern = pattern; + } + + @Override + String generateAddToCollection(String existing, String collectionTypeParams, String value) { + return generateAddToMap(existing, collectionTypeParams, "", value); + } + + @Override + String generateAddToMap(String existing, String mapTypeParams, String key, String value) { + return pattern.replaceAll("\\$existing", existing).replaceAll("\\$params", mapTypeParams).replaceAll("\\$value", value).replaceAll("\\$key", key); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/joda/beans/gen/PropertyData.java b/src/main/java/org/joda/beans/gen/PropertyData.java index 6d54b90f..8a0e141e 100644 --- a/src/main/java/org/joda/beans/gen/PropertyData.java +++ b/src/main/java/org/joda/beans/gen/PropertyData.java @@ -20,6 +20,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -119,6 +120,8 @@ class PropertyData { private CopyGen copyGen; /** The builder generator. */ private BuilderGen builderGen; + /** The collection generator. */ + private CollectionGen collectionGen; /** The config. */ private BeanGenConfig config; @@ -658,6 +661,19 @@ public String getGenericParamType() { return type.substring(pos + 1, type.length() - 1); } + /** + * Gets the parameterisations of the property. + * {@code Map} will return a list of {@code String} and {@code Object}. + * @return the generic types, or an empty list if not generic, not null + */ + public List getGenericParamTypes() { + String params = getGenericParamType(); + if (params.isEmpty()) { + return Collections.emptyList(); + } + return separateGenericParamTypes(params); + } + /** * Checks if the type is the generic type of the bean. * For example, if the property is of type T or T[] in a bean of Foo[T]. @@ -984,7 +1000,7 @@ public CopyGen getCopyGen() { //----------------------------------------------------------------------- /** - * Resolves the copy generator. + * Resolves the builder generator. */ public void resolveBuilderGen() { if (getBean().isMutable()) { @@ -1012,6 +1028,29 @@ public BuilderGen getBuilderGen() { return builderGen; } + //----------------------------------------------------------------------- + /** + * Resolves the collection generator. + */ + public void resolveCollectionGen() { + if (getBean().isMutable()) { + if (!getBean().isBuilderScopeVisible() && !getBean().isBeanStyleLightOrMinimal()) { + return; // no builder + } + } + if (!isDerived()) { + collectionGen = config.getCollectionGenerators().get(getFieldTypeRaw()); + } + } + + /** + * Gets the collection generator. + * @return the collection generator + */ + public CollectionGen getCollectionGen() { + return collectionGen; + } + //----------------------------------------------------------------------- /** * Checks if this property is an array type. @@ -1157,4 +1196,35 @@ public String getVarArgsCode() { return config.getImmutableVarArgs().get(getTypeRaw()); } + /** + * Take a string of type parameters (such as (@code String, List} and separate it out + * into the top-level types it contains. + * + * @param typesString the param type string + * @return a list of the top-level types contained within the string (including their own parameter types) + */ + private static List separateGenericParamTypes(String typesString) { + List types = new ArrayList<>(); + + StringBuilder typeBuilder = new StringBuilder(); + int nestingDepth = 0; + for (Character character : typesString.toCharArray()) { + if (character.equals('<')) { + nestingDepth += 1; + typeBuilder.append(character); + } else if (character.equals('>')) { + nestingDepth -= 1; + typeBuilder.append(character); + } else if (character.equals(',') && nestingDepth == 0) { + types.add(typeBuilder.toString().trim()); + typeBuilder = new StringBuilder(); + } else { + typeBuilder.append(character); + } + } + + types.add(typeBuilder.toString().trim()); + + return types; + } } diff --git a/src/main/java/org/joda/beans/gen/PropertyGen.java b/src/main/java/org/joda/beans/gen/PropertyGen.java index 9cfc22b2..2958d52a 100644 --- a/src/main/java/org/joda/beans/gen/PropertyGen.java +++ b/src/main/java/org/joda/beans/gen/PropertyGen.java @@ -22,6 +22,7 @@ import org.joda.beans.MetaProperty; import org.joda.beans.Property; import org.joda.beans.impl.direct.DirectMetaProperty; +import org.joda.beans.utils.NameUtils; /** * A property parsed from the source file. @@ -242,10 +243,10 @@ List generateBuilderSetMethod() { String builderType = getBuilderType(); if (builderType.endsWith("[]") && !builderType.endsWith("[][]") && !builderType.equals("byte[]")) { list.add("\t\tpublic Builder" + data.getBean().getTypeGenericName(true) + " " + data.getPropertyName() + - "(" + builderType.substring(0, builderType.length() - 2) + "... " + data.getPropertyName() + ") {"); + "(" + builderType.substring(0, builderType.length() - 2) + "... " + data.getPropertyName() + ") {"); } else { list.add("\t\tpublic Builder" + data.getBean().getTypeGenericName(true) + " " + data.getPropertyName() + - "(" + builderType + " " + data.getPropertyName() + ") {"); + "(" + builderType + " " + data.getPropertyName() + ") {"); } if (data.isValidated()) { list.add("\t\t\t" + data.getValidationMethodName() + "(" + data.getPropertyName() + ", \"" + data.getPropertyName() + "\");"); @@ -258,6 +259,96 @@ List generateBuilderSetMethod() { return list; } + List generateBuilderAddMethod() { + List list = new ArrayList<>(); + if (!(data.isCollectionType() || data.isArrayType())) { + return list; + } + + if (data.isArrayType() && data.getFieldType().contains("[][]")) { + // Only 1 dimensional arrays are supported. + return list; + } + + String valueParamName = "value"; + String adderName = "add" + NameUtils.capitalize(data.getPropertyName()); + String collectionType = getCollectionOrArrayParamType().replaceAll("\\? extends ", ""); + + list.add("\t\t/**"); + list.add("\t\t * Adds an element to the {@code " + data.getPropertyName() + "} property"); + for (String comment : data.getComments()) { + list.add("\t\t * " + comment); + } + list.add("\t\t * @param " + valueParamName + " the new element" + data.getNotNullJavadoc()); + list.add("\t\t * @return this, for chaining, not null"); + if (data.getDeprecatedComment() != null) { + list.add("\t\t * " + data.getDeprecatedComment()); + } + list.add("\t\t */"); + if (data.isDeprecated()) { + list.add("\t\t@Deprecated"); + } + list.add("\t\tpublic Builder" + data.getBean().getTypeGenericName(true) + " " + adderName + "(" + collectionType + " " + valueParamName + ") {"); + if (data.isArrayType()) { + data.getBean().ensureImport(Arrays.class); + String newArray = "new " + data.getFieldType().replaceAll("\\[]", "") + "[1]"; + list.add("\t\t\tthis." + generateBuilderFieldName() + " = " + generateBuilderFieldName() + " == null ? " + newArray + " : Arrays.copyOf(this." + data.getFieldName() + ", this." + data.getFieldName() + ".length + 1);"); + list.add("\t\t\tthis." + generateBuilderFieldName() + "[this." + generateBuilderFieldName() + ".length - 1] = " + valueParamName + ";"); + } else { + String existing = "this." + generateBuilderFieldName() + " == null ? " + data.getBuilderGen().generateInit(data) + " : this." + generateBuilderFieldName(); + String typeParam = (data.isGenericParamType() && !data.isGenericWildcardParamType() ? "<" + data.getGenericParamType() + ">" : "").replaceAll("\\? extends ", ""); + list.add("\t\t\tthis." + generateBuilderFieldName() + " = " + data.getCollectionGen().generateAddToCollection(existing, typeParam, valueParamName) + ";"); + } + if (data.isValidated()) { + list.add("\t\t\t" + data.getValidationMethodName() + "(this." + data.getPropertyName() + ", \"" + data.getPropertyName() + "\");"); + } + list.add("\t\t\treturn this;"); + list.add("\t\t}"); + list.add(""); + return list; + } + + List generateBuilderPutMethod() { + List list = new ArrayList<>(); + if (!data.isMapType()) { + return list; + } + + String putterName = "put" + NameUtils.capitalize(data.getPropertyName()); + String keyType = parseMapKeyType().replaceAll("\\? extends ", ""); + String valueType = parseMapValueType().replaceAll("\\? extends ", ""); + String keyParamName = "key"; + String valueParamName = "value"; + + list.add("\t\t/**"); + list.add("\t\t * Adds an entry to the {@code " + data.getPropertyName() + "} property"); + for (String comment : data.getComments()) { + list.add("\t\t * " + comment); + } + list.add("\t\t * @param " + keyParamName + " the key of the new entry" + data.getNotNullJavadoc()); + list.add("\t\t * @param " + valueParamName + " the value of the new entry"); + list.add("\t\t * @return this, for chaining, not null"); + if (data.getDeprecatedComment() != null) { + list.add("\t\t * " + data.getDeprecatedComment()); + } + list.add("\t\t */"); + if (data.isDeprecated()) { + list.add("\t\t@Deprecated"); + } + list.add("\t\tpublic Builder" + data.getBean().getTypeGenericName(true) + " " + putterName + + "(" + keyType + " " + keyParamName + ", " + valueType + " " + valueParamName + ") {"); + String existing = "this." + generateBuilderFieldName() + " == null ? " + data.getBuilderGen().generateInit(data) + " : this." + generateBuilderFieldName(); + String typeParam = (data.isGenericParamType() && !data.isGenericWildcardParamType() ? "<" + data.getGenericParamType() + ">" : "").replaceAll("\\? extends ", ""); + list.add("\t\t\tthis." + generateBuilderFieldName() + " = " + data.getCollectionGen().generateAddToMap(existing, typeParam, keyParamName, valueParamName) + ";"); + if (data.isValidated()) { + list.add("\t\t\t" + data.getValidationMethodName() + "(this." + data.getPropertyName() + ", \"" + data.getPropertyName() + "\");"); + } + list.add("\t\t\treturn this;"); + list.add("\t\t}"); + list.add(""); + return list; + } + String getBuilderType() { return data.getBuilderGen().generateType(data); } @@ -380,6 +471,61 @@ private String propertyType(String type) { return type; } + + + private String getCollectionOrArrayParamType() { + if (!(data.isCollectionType() || data.isArrayType())) { + throw new IllegalStateException("Property is not a Collection or array."); + } + + if (data.isArrayType()) { + return data.getFieldType().substring(0, data.getFieldType().lastIndexOf('[')); + } + + String paramType = data.getGenericParamType(); + if (data.isGenericWildcardParamType() || paramType.isEmpty()) { + return "Object"; + } + + if (paramType.startsWith("< extends ")) { + return paramType.replaceFirst("< extends ", ""); + } + + return paramType; + } + + private String parseMapKeyType() { + if (!data.isMapType()) { + throw new IllegalStateException("Property is not a Map."); + } + + List mapParamTypes = data.getGenericParamTypes(); + if (mapParamTypes.isEmpty()) { + return "Object"; + } + if (mapParamTypes.size() != 2) { + throw new IllegalStateException("Map should have 2 parameter types"); + } + + return mapParamTypes.get(0); + } + + private String parseMapValueType() { + if (!data.isMapType()) { + throw new IllegalStateException("Property is not a Map."); + } + + List mapParamTypes = data.getGenericParamTypes(); + if (mapParamTypes.isEmpty()) { + return "Object"; + } + if (mapParamTypes.size() != 2) { + throw new IllegalStateException("Map should have 2 parameter types"); + } + + return mapParamTypes.get(1); + } + PropertyData getData() { return data; } diff --git a/src/main/java/org/joda/beans/gen/PropertyParser.java b/src/main/java/org/joda/beans/gen/PropertyParser.java index b85e118a..ea1aa2e1 100644 --- a/src/main/java/org/joda/beans/gen/PropertyParser.java +++ b/src/main/java/org/joda/beans/gen/PropertyParser.java @@ -95,6 +95,7 @@ PropertyGen parse(BeanData beanData, List content, int lineIndex) { data.resolveSetterGen(beanParser.getFile(), lineIndex); data.resolveCopyGen(beanParser.getFile(), lineIndex); data.resolveBuilderGen(); + data.resolveCollectionGen(); data.resolveEqualsHashCodeStyle(beanParser.getFile(), lineIndex); data.resolveToStringStyle(beanParser.getFile(), lineIndex); data.setMetaFieldName(beanParser.getFieldPrefix() + data.getPropertyName()); @@ -126,6 +127,7 @@ PropertyGen parseDerived(BeanData beanData, List content, int lineIndex) data.resolveSetterGen(beanParser.getFile(), lineIndex); data.resolveCopyGen(beanParser.getFile(), lineIndex); data.resolveBuilderGen(); + data.resolveCollectionGen(); data.setMetaFieldName(beanParser.getFieldPrefix() + data.getPropertyName()); parseComments(content, data); return new PropertyGen(data); diff --git a/src/main/java/org/joda/beans/utils/NameUtils.java b/src/main/java/org/joda/beans/utils/NameUtils.java new file mode 100644 index 00000000..379e447d --- /dev/null +++ b/src/main/java/org/joda/beans/utils/NameUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019-present Stephen Colebourne + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.joda.beans.utils; + +import java.util.Locale; + +/** + * Utility methods for working with names of things. + */ +public final class NameUtils { + + private NameUtils() { + + } + + /** + * Capitalize (i.e. upper-case) the first character of a string. + * + * @param string the string + * @return the string with the first character capitalized + */ + public static String capitalize(String string) { + return string.substring(0, 1).toUpperCase(Locale.ENGLISH) + string.substring(1); + } + + /** + * Lower-case the first character of a string. + * + * @param string the string + * @return the string with the first character lower-cased + */ + public static String decapitalize(String string) { + return string.substring(0, 1).toLowerCase(Locale.ENGLISH) + string.substring(1); + } +} diff --git a/src/main/resources/org/joda/beans/gen/guava.ini b/src/main/resources/org/joda/beans/gen/guava.ini index 93f124af..9f32c7f7 100644 --- a/src/main/resources/org/joda/beans/gen/guava.ini +++ b/src/main/resources/org/joda/beans/gen/guava.ini @@ -137,6 +137,36 @@ ImmutableList = ImmutableList.copyOf($value) ImmutableSet = ImmutableSet.copyOf($value) ImmutableSortedSet = ImmutableSortedSet.copyOf($value) +# how to add a new $value (by $key where appropriate) to an $existing collection +[immutable.builder.add] +Collection = ImmutableList.$paramsbuilder().addAll($existing).add($value).build() +List = ImmutableList.$paramsbuilder().addAll($existing).add($value).build() +Set = ImmutableSet.$paramsbuilder().addAll($existing).add($value).build() +SortedSet = ImmutableSortedSet.$paramsbuilder().addAll($existing).add($value).build() +Map = ImmutableMap.$paramsbuilder().putAll($existing).put($key, $value).build() +SortedMap = ImmutableSortedMap.$paramsnaturalOrder().putAll($existing).put($key, $value).build() +EnumSet = ImmutableSet.$paramsbuilder().addAll($existing).add($value).build() +BiMap = ImmutableBiMap.$paramsbuilder().putAll($existing).put($key, $value).build() +Multimap = ImmutableMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +ListMultimap = ImmutableListMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +SetMultimap = ImmutableSetMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +Multiset = ImmutableMultiset.$paramsbuilder().addAll($existing).add($value).build() +SortedMultiset = ImmutableSortedMultiset.$paramsnaturalOrder().addAll($existing).add($value).build() +Table = ImmutableTable.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableCollection = ImmutableList.$paramsbuilder().addAll($existing).add($value).build() +ImmutableList = ImmutableList.$paramsbuilder().addAll($existing).add($value).build() +ImmutableSet = ImmutableSet.$paramsbuilder().addAll($existing).add($value).build() +ImmutableSortedSet = ImmutableSortedSet.$paramsbuilder().addAll($existing).add($value).build() +ImmutableMap = ImmutableMap.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableSortedMap = ImmutableSortedMap.$paramsnaturalOrder().putAll($existing).put($key, $value).build() +ImmutableBiMap = ImmutableBiMap.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableMultimap = ImmutableMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableListMultimap = ImmutableListMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableSetMultimap = ImmutableSetMultimap.$paramsbuilder().putAll($existing).put($key, $value).build() +ImmutableMultiset = ImmutableMultiset.$paramsbuilder().addAll($existing).add($value).build() +ImmutableSortedMultiset = ImmutableSortedMultiset.$paramsnaturalOrder().putAll($existing).put($key, $value).build() +ImmutableTable = ImmutableTable.$paramsbuilder().putAll($existing).put($key, $value).build() + # provide the ability to handle clone-on-get or immutable classes [immutable.get.clone] Date = cloneCast From dc23f43d5e28cfe4ea9acd7e45e2bdb85556d4c4 Mon Sep 17 00:00:00 2001 From: Ashley Heath Date: Mon, 1 Jul 2019 17:57:09 +0100 Subject: [PATCH 3/3] Update generated sample code. --- .../org/joda/beans/sample/ImmAddress.java | 106 +++++++ .../java/org/joda/beans/sample/ImmArrays.java | 45 +++ .../java/org/joda/beans/sample/ImmClone.java | 70 +++++ .../beans/sample/ImmGenericCollections.java | 12 + .../java/org/joda/beans/sample/ImmGuava.java | 272 ++++++++++++++++++ .../org/joda/beans/sample/ImmMappedKey.java | 12 + .../java/org/joda/beans/sample/ImmPerson.java | 43 +++ .../sample/ImmSubPersonFromAbstract.java | 10 + .../beans/sample/ImmSubPersonNonFinal.java | 10 + .../org/joda/beans/sample/ImmTolerance.java | 12 + .../org/joda/beans/sample/ImmTreeNode.java | 11 + .../java/org/joda/beans/sample/ImmTypes.java | 67 +++++ .../joda/beans/sample/MinimalImmutable.java | 11 + .../beans/sample/MinimalImmutableGeneric.java | 21 ++ .../beans/sample/MutableListFinalBean.java | 21 ++ .../beans/sample/MutableListNonFinalBean.java | 21 ++ .../org/joda/beans/sample/SimpleJson.java | 86 ++++++ .../sample/SimplePersonWithBuilderFinal.java | 46 +++ .../SimplePersonWithBuilderNonFinal.java | 34 +++ 19 files changed, 910 insertions(+) diff --git a/src/test/java/org/joda/beans/sample/ImmAddress.java b/src/test/java/org/joda/beans/sample/ImmAddress.java index 3af4f058..ac5261b4 100644 --- a/src/test/java/org/joda/beans/sample/ImmAddress.java +++ b/src/test/java/org/joda/beans/sample/ImmAddress.java @@ -1715,6 +1715,112 @@ public Builder matrix(double[][] matrix) { return this; } + /** + * Adds an element to the {@code data} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addData(byte value) { + this.data = data == null ? new byte[1] : Arrays.copyOf(this.data, this.data.length + 1); + this.data[this.data.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code doubleVector} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addDoubleVector(double value) { + this.doubleVector = doubleVector == null ? new double[1] : Arrays.copyOf(this.doubleVector, this.doubleVector.length + 1); + this.doubleVector[this.doubleVector.length - 1] = value; + return this; + } + + /** + * Adds an entry to the {@code objectInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putObjectInMap(String key, Object value) { + this.objectInMap = ImmutableMap.builder().putAll(this.objectInMap == null ? ImmutableMap.of() : this.objectInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.objectInMap, "objectInMap"); + return this; + } + + /** + * Adds an entry to the {@code listInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putListInMap(String key, List value) { + this.listInMap = ImmutableMap.>builder().putAll(this.listInMap == null ? ImmutableMap.of() : this.listInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.listInMap, "listInMap"); + return this; + } + + /** + * Adds an entry to the {@code listNumericInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putListNumericInMap(String key, List value) { + this.listNumericInMap = ImmutableMap.>builder().putAll(this.listNumericInMap == null ? ImmutableMap.of() : this.listNumericInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.listNumericInMap, "listNumericInMap"); + return this; + } + + /** + * Adds an entry to the {@code listInListInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putListInListInMap(String key, List> value) { + this.listInListInMap = ImmutableMap.>>builder().putAll(this.listInListInMap == null ? ImmutableMap.of() : this.listInListInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.listInListInMap, "listInListInMap"); + return this; + } + + /** + * Adds an entry to the {@code objectListInListInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putObjectListInListInMap(String key, List> value) { + this.objectListInListInMap = ImmutableMap.>>builder().putAll(this.objectListInListInMap == null ? ImmutableMap.of() : this.objectListInListInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.objectListInListInMap, "objectListInListInMap"); + return this; + } + + /** + * Adds an entry to the {@code mapInMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMapInMap(ImmPerson key, Map value) { + this.mapInMap = ImmutableMap.>builder().putAll(this.mapInMap == null ? ImmutableMap.of() : this.mapInMap).put(key, value).build(); + JodaBeanUtils.notNull(this.mapInMap, "mapInMap"); + return this; + } + + /** + * Adds an entry to the {@code beanBeanMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putBeanBeanMap(ImmPerson key, ImmAddress value) { + this.beanBeanMap = ImmutableMap.builder().putAll(this.beanBeanMap == null ? ImmutableMap.of() : this.beanBeanMap).put(key, value).build(); + JodaBeanUtils.notNull(this.beanBeanMap, "beanBeanMap"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmArrays.java b/src/test/java/org/joda/beans/sample/ImmArrays.java index 7a23a1ef..7848d0cd 100644 --- a/src/test/java/org/joda/beans/sample/ImmArrays.java +++ b/src/test/java/org/joda/beans/sample/ImmArrays.java @@ -29,6 +29,7 @@ import org.joda.beans.impl.direct.DirectMetaBean; import org.joda.beans.impl.direct.DirectMetaProperty; import org.joda.beans.impl.direct.DirectMetaPropertyMap; +import java.util.Arrays; /** * Mock bean for primitive array testing. @@ -444,6 +445,50 @@ public Builder booleanArray(boolean... booleanArray) { return this; } + /** + * Adds an element to the {@code intArray} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addIntArray(int value) { + this.intArray = intArray == null ? new int[1] : Arrays.copyOf(this.intArray, this.intArray.length + 1); + this.intArray[this.intArray.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code longArray} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addLongArray(long value) { + this.longArray = longArray == null ? new long[1] : Arrays.copyOf(this.longArray, this.longArray.length + 1); + this.longArray[this.longArray.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code doubleArray} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addDoubleArray(double value) { + this.doubleArray = doubleArray == null ? new double[1] : Arrays.copyOf(this.doubleArray, this.doubleArray.length + 1); + this.doubleArray[this.doubleArray.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code booleanArray} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addBooleanArray(boolean value) { + this.booleanArray = booleanArray == null ? new boolean[1] : Arrays.copyOf(this.booleanArray, this.booleanArray.length + 1); + this.booleanArray[this.booleanArray.length - 1] = value; + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmClone.java b/src/test/java/org/joda/beans/sample/ImmClone.java index 06967233..c3967b8e 100644 --- a/src/test/java/org/joda/beans/sample/ImmClone.java +++ b/src/test/java/org/joda/beans/sample/ImmClone.java @@ -31,6 +31,7 @@ import org.joda.beans.impl.direct.DirectMetaBean; import org.joda.beans.impl.direct.DirectMetaProperty; import org.joda.beans.impl.direct.DirectMetaPropertyMap; +import java.util.Arrays; /** * Mock immutable bean to test cloning. @@ -650,6 +651,75 @@ public Builder array3Nullable(String... array3Nullable) { return this; } + /** + * Adds an element to the {@code array1} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addArray1(String value) { + this.array1 = array1 == null ? new String[1] : Arrays.copyOf(this.array1, this.array1.length + 1); + this.array1[this.array1.length - 1] = value; + JodaBeanUtils.notNull(this.array1, "array1"); + return this; + } + + /** + * Adds an element to the {@code array2} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addArray2(String value) { + this.array2 = array2 == null ? new String[1] : Arrays.copyOf(this.array2, this.array2.length + 1); + this.array2[this.array2.length - 1] = value; + JodaBeanUtils.notNull(this.array2, "array2"); + return this; + } + + /** + * Adds an element to the {@code array3} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addArray3(String value) { + this.array3 = array3 == null ? new String[1] : Arrays.copyOf(this.array3, this.array3.length + 1); + this.array3[this.array3.length - 1] = value; + JodaBeanUtils.notNull(this.array3, "array3"); + return this; + } + + /** + * Adds an element to the {@code array1Nullable} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addArray1Nullable(String value) { + this.array1Nullable = array1Nullable == null ? new String[1] : Arrays.copyOf(this.array1Nullable, this.array1Nullable.length + 1); + this.array1Nullable[this.array1Nullable.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code array2Nullable} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addArray2Nullable(String value) { + this.array2Nullable = array2Nullable == null ? new String[1] : Arrays.copyOf(this.array2Nullable, this.array2Nullable.length + 1); + this.array2Nullable[this.array2Nullable.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code array3Nullable} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addArray3Nullable(String value) { + this.array3Nullable = array3Nullable == null ? new String[1] : Arrays.copyOf(this.array3Nullable, this.array3Nullable.length + 1); + this.array3Nullable[this.array3Nullable.length - 1] = value; + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmGenericCollections.java b/src/test/java/org/joda/beans/sample/ImmGenericCollections.java index 633b7e2b..a6fdfae9 100644 --- a/src/test/java/org/joda/beans/sample/ImmGenericCollections.java +++ b/src/test/java/org/joda/beans/sample/ImmGenericCollections.java @@ -300,6 +300,18 @@ public Builder map(Map map) { return this; } + /** + * Adds an entry to the {@code map} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMap(String key, T value) { + this.map = ImmutableMap.builder().putAll(this.map == null ? ImmutableMap.of() : this.map).put(key, value).build(); + JodaBeanUtils.notNull(this.map, "map"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmGuava.java b/src/test/java/org/joda/beans/sample/ImmGuava.java index 61d625aa..ecfce791 100644 --- a/src/test/java/org/joda/beans/sample/ImmGuava.java +++ b/src/test/java/org/joda/beans/sample/ImmGuava.java @@ -2354,6 +2354,278 @@ public Builder mapWildKey(Map mapWildKey) { return this; } + /** + * Adds an element to the {@code collection} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addCollection(T value) { + this.collection = ImmutableList.builder().addAll(this.collection == null ? ImmutableList.of() : this.collection).add(value).build(); + JodaBeanUtils.notNull(this.collection, "collection"); + return this; + } + + /** + * Adds an element to the {@code list} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addList(T value) { + this.list = ImmutableList.builder().addAll(this.list == null ? ImmutableList.of() : this.list).add(value).build(); + JodaBeanUtils.notNull(this.list, "list"); + return this; + } + + /** + * Adds an element to the {@code set} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSet(T value) { + this.set = ImmutableSet.builder().addAll(this.set == null ? ImmutableSet.of() : this.set).add(value).build(); + JodaBeanUtils.notNull(this.set, "set"); + return this; + } + + /** + * Adds an element to the {@code sortedSet} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSortedSet(T value) { + this.sortedSet = ImmutableSortedSet.builder().addAll(this.sortedSet == null ? ImmutableSortedSet.of() : this.sortedSet).add(value).build(); + JodaBeanUtils.notNull(this.sortedSet, "sortedSet"); + return this; + } + + /** + * Adds an element to the {@code collectionInterface} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addCollectionInterface(T value) { + this.collectionInterface = ImmutableList.builder().addAll(this.collectionInterface == null ? ImmutableList.of() : this.collectionInterface).add(value).build(); + JodaBeanUtils.notNull(this.collectionInterface, "collectionInterface"); + return this; + } + + /** + * Adds an element to the {@code listInterface} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListInterface(T value) { + this.listInterface = ImmutableList.builder().addAll(this.listInterface == null ? ImmutableList.of() : this.listInterface).add(value).build(); + JodaBeanUtils.notNull(this.listInterface, "listInterface"); + return this; + } + + /** + * Adds an element to the {@code setInterface} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSetInterface(T value) { + this.setInterface = ImmutableSet.builder().addAll(this.setInterface == null ? ImmutableSet.of() : this.setInterface).add(value).build(); + JodaBeanUtils.notNull(this.setInterface, "setInterface"); + return this; + } + + /** + * Adds an element to the {@code sortedSetInterface} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSortedSetInterface(T value) { + this.sortedSetInterface = ImmutableSortedSet.builder().addAll(this.sortedSetInterface == null ? ImmutableSortedSet.of() : this.sortedSetInterface).add(value).build(); + JodaBeanUtils.notNull(this.sortedSetInterface, "sortedSetInterface"); + return this; + } + + /** + * Adds an element to the {@code listWildExtendsT} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildExtendsT(T value) { + this.listWildExtendsT = ImmutableList.builder().addAll(this.listWildExtendsT == null ? ImmutableList.of() : this.listWildExtendsT).add(value).build(); + JodaBeanUtils.notNull(this.listWildExtendsT, "listWildExtendsT"); + return this; + } + + /** + * Adds an element to the {@code listWildExtendsNumber} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildExtendsNumber(Number value) { + this.listWildExtendsNumber = ImmutableList.builder().addAll(this.listWildExtendsNumber == null ? ImmutableList.of() : this.listWildExtendsNumber).add(value).build(); + JodaBeanUtils.notNull(this.listWildExtendsNumber, "listWildExtendsNumber"); + return this; + } + + /** + * Adds an element to the {@code listWildExtendsComparable} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildExtendsComparable(Comparable value) { + this.listWildExtendsComparable = ImmutableList.>builder().addAll(this.listWildExtendsComparable == null ? ImmutableList.of() : this.listWildExtendsComparable).add(value).build(); + JodaBeanUtils.notNull(this.listWildExtendsComparable, "listWildExtendsComparable"); + return this; + } + + /** + * Adds an element to the {@code setWildExtendsT} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSetWildExtendsT(T value) { + this.setWildExtendsT = ImmutableSet.builder().addAll(this.setWildExtendsT == null ? ImmutableSet.of() : this.setWildExtendsT).add(value).build(); + JodaBeanUtils.notNull(this.setWildExtendsT, "setWildExtendsT"); + return this; + } + + /** + * Adds an element to the {@code setWildExtendsNumber} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSetWildExtendsNumber(Number value) { + this.setWildExtendsNumber = ImmutableSet.builder().addAll(this.setWildExtendsNumber == null ? ImmutableSet.of() : this.setWildExtendsNumber).add(value).build(); + JodaBeanUtils.notNull(this.setWildExtendsNumber, "setWildExtendsNumber"); + return this; + } + + /** + * Adds an element to the {@code setWildExtendsComparable} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addSetWildExtendsComparable(Comparable value) { + this.setWildExtendsComparable = ImmutableSet.>builder().addAll(this.setWildExtendsComparable == null ? ImmutableSet.of() : this.setWildExtendsComparable).add(value).build(); + JodaBeanUtils.notNull(this.setWildExtendsComparable, "setWildExtendsComparable"); + return this; + } + + /** + * Adds an element to the {@code listWildBuilder1} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildBuilder1(Object value) { + this.listWildBuilder1 = ImmutableList.builder().addAll(this.listWildBuilder1 == null ? ImmutableList.of() : this.listWildBuilder1).add(value).build(); + JodaBeanUtils.notNull(this.listWildBuilder1, "listWildBuilder1"); + return this; + } + + /** + * Adds an element to the {@code listWildBuilder2} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildBuilder2(Address value) { + this.listWildBuilder2 = ImmutableList.
builder().addAll(this.listWildBuilder2 == null ? ImmutableList.of() : this.listWildBuilder2).add(value).build(); + JodaBeanUtils.notNull(this.listWildBuilder2, "listWildBuilder2"); + return this; + } + + /** + * Adds an entry to the {@code map} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMap(T key, String value) { + this.map = ImmutableMap.builder().putAll(this.map == null ? ImmutableMap.of() : this.map).put(key, value).build(); + JodaBeanUtils.notNull(this.map, "map"); + return this; + } + + /** + * Adds an entry to the {@code sortedMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putSortedMap(T key, String value) { + this.sortedMap = ImmutableSortedMap.naturalOrder().putAll(this.sortedMap == null ? ImmutableSortedMap.of() : this.sortedMap).put(key, value).build(); + JodaBeanUtils.notNull(this.sortedMap, "sortedMap"); + return this; + } + + /** + * Adds an entry to the {@code biMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putBiMap(T key, String value) { + this.biMap = ImmutableBiMap.builder().putAll(this.biMap == null ? ImmutableBiMap.of() : this.biMap).put(key, value).build(); + JodaBeanUtils.notNull(this.biMap, "biMap"); + return this; + } + + /** + * Adds an entry to the {@code mapInterface} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMapInterface(T key, String value) { + this.mapInterface = ImmutableMap.builder().putAll(this.mapInterface == null ? ImmutableMap.of() : this.mapInterface).put(key, value).build(); + JodaBeanUtils.notNull(this.mapInterface, "mapInterface"); + return this; + } + + /** + * Adds an entry to the {@code sortedMapInterface} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putSortedMapInterface(T key, String value) { + this.sortedMapInterface = ImmutableSortedMap.naturalOrder().putAll(this.sortedMapInterface == null ? ImmutableSortedMap.of() : this.sortedMapInterface).put(key, value).build(); + JodaBeanUtils.notNull(this.sortedMapInterface, "sortedMapInterface"); + return this; + } + + /** + * Adds an entry to the {@code biMapInterface} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putBiMapInterface(T key, String value) { + this.biMapInterface = ImmutableBiMap.builder().putAll(this.biMapInterface == null ? ImmutableBiMap.of() : this.biMapInterface).put(key, value).build(); + JodaBeanUtils.notNull(this.biMapInterface, "biMapInterface"); + return this; + } + + /** + * Adds an entry to the {@code mapWildBuilder1} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMapWildBuilder1(String key, Address value) { + this.mapWildBuilder1 = ImmutableMap.builder().putAll(this.mapWildBuilder1 == null ? ImmutableMap.of() : this.mapWildBuilder1).put(key, value).build(); + JodaBeanUtils.notNull(this.mapWildBuilder1, "mapWildBuilder1"); + return this; + } + + /** + * Adds an entry to the {@code mapWildKey} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMapWildKey(Number key, String value) { + this.mapWildKey = ImmutableMap.builder().putAll(this.mapWildKey == null ? ImmutableMap.of() : this.mapWildKey).put(key, value).build(); + JodaBeanUtils.notNull(this.mapWildKey, "mapWildKey"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmMappedKey.java b/src/test/java/org/joda/beans/sample/ImmMappedKey.java index b663f30a..09152325 100644 --- a/src/test/java/org/joda/beans/sample/ImmMappedKey.java +++ b/src/test/java/org/joda/beans/sample/ImmMappedKey.java @@ -287,6 +287,18 @@ public Builder data(Map data) { return this; } + /** + * Adds an entry to the {@code data} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putData(IKey key, Object value) { + this.data = ImmutableMap.builder().putAll(this.data == null ? ImmutableMap.of() : this.data).put(key, value).build(); + JodaBeanUtils.notNull(this.data, "data"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmPerson.java b/src/test/java/org/joda/beans/sample/ImmPerson.java index f83adb30..8596282c 100644 --- a/src/test/java/org/joda/beans/sample/ImmPerson.java +++ b/src/test/java/org/joda/beans/sample/ImmPerson.java @@ -40,6 +40,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultiset; import com.google.common.collect.Multiset; +import java.util.Arrays; /** * Mock immutable person JavaBean, used for testing. @@ -837,6 +838,48 @@ public Builder codeCounts(Multiset codeCounts) { return this; } + /** + * Adds an element to the {@code middleNames} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addMiddleNames(String value) { + this.middleNames = middleNames == null ? new String[1] : Arrays.copyOf(this.middleNames, this.middleNames.length + 1); + this.middleNames[this.middleNames.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code addressList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addAddressList(Address value) { + this.addressList = ImmutableList.
builder().addAll(this.addressList == null ? ImmutableList.of() : this.addressList).add(value).build(); + return this; + } + + /** + * Adds an element to the {@code addressesList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addAddressesList(List
value) { + this.addressesList = ImmutableList.>builder().addAll(this.addressesList == null ? ImmutableList.of() : this.addressesList).add(value).build(); + return this; + } + + /** + * Adds an entry to the {@code otherAddressMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putOtherAddressMap(String key, Address value) { + this.otherAddressMap = ImmutableMap.builder().putAll(this.otherAddressMap == null ? ImmutableMap.of() : this.otherAddressMap).put(key, value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmSubPersonFromAbstract.java b/src/test/java/org/joda/beans/sample/ImmSubPersonFromAbstract.java index a2adccca..c5063803 100644 --- a/src/test/java/org/joda/beans/sample/ImmSubPersonFromAbstract.java +++ b/src/test/java/org/joda/beans/sample/ImmSubPersonFromAbstract.java @@ -348,6 +348,16 @@ public Builder addressList(Address... addressList) { return addressList(ImmutableList.copyOf(addressList)); } + /** + * Adds an element to the {@code addressList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addAddressList(Address value) { + this.addressList = ImmutableList.
builder().addAll(this.addressList == null ? ImmutableList.of() : this.addressList).add(value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmSubPersonNonFinal.java b/src/test/java/org/joda/beans/sample/ImmSubPersonNonFinal.java index 4d2f9703..a9e1b0c3 100644 --- a/src/test/java/org/joda/beans/sample/ImmSubPersonNonFinal.java +++ b/src/test/java/org/joda/beans/sample/ImmSubPersonNonFinal.java @@ -348,6 +348,16 @@ public Builder addressList(Address... addressList) { return addressList(ImmutableList.copyOf(addressList)); } + /** + * Adds an element to the {@code addressList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addAddressList(Address value) { + this.addressList = ImmutableList.
builder().addAll(this.addressList == null ? ImmutableList.of() : this.addressList).add(value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmTolerance.java b/src/test/java/org/joda/beans/sample/ImmTolerance.java index 9b6ba797..b6a8ad52 100644 --- a/src/test/java/org/joda/beans/sample/ImmTolerance.java +++ b/src/test/java/org/joda/beans/sample/ImmTolerance.java @@ -29,6 +29,7 @@ import org.joda.beans.impl.direct.DirectMetaBean; import org.joda.beans.impl.direct.DirectMetaProperty; import org.joda.beans.impl.direct.DirectMetaPropertyMap; +import java.util.Arrays; /** * Mock bean for tolerance testing. @@ -343,6 +344,17 @@ public Builder array(double... array) { return this; } + /** + * Adds an element to the {@code array} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addArray(double value) { + this.array = array == null ? new double[1] : Arrays.copyOf(this.array, this.array.length + 1); + this.array[this.array.length - 1] = value; + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmTreeNode.java b/src/test/java/org/joda/beans/sample/ImmTreeNode.java index 6c8a36ee..381993f6 100644 --- a/src/test/java/org/joda/beans/sample/ImmTreeNode.java +++ b/src/test/java/org/joda/beans/sample/ImmTreeNode.java @@ -535,6 +535,17 @@ public Builder childList(ImmTreeNode... childList) { return childList(ImmutableList.copyOf(childList)); } + /** + * Adds an element to the {@code childList} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addChildList(ImmTreeNode value) { + this.childList = ImmutableList.builder().addAll(this.childList == null ? ImmutableList.of() : this.childList).add(value).build(); + JodaBeanUtils.notNull(this.childList, "childList"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/ImmTypes.java b/src/test/java/org/joda/beans/sample/ImmTypes.java index 4bd47d7f..80737a6e 100644 --- a/src/test/java/org/joda/beans/sample/ImmTypes.java +++ b/src/test/java/org/joda/beans/sample/ImmTypes.java @@ -647,6 +647,73 @@ public Builder mapWildBuilder1(Map mapWildBuilder1 return this; } + /** + * Adds an element to the {@code listWild} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWild(Object value) { + this.listWild = ImmutableList.builder().addAll(this.listWild == null ? ImmutableList.of() : this.listWild).add(value).build(); + JodaBeanUtils.notNull(this.listWild, "listWild"); + return this; + } + + /** + * Adds an element to the {@code listWildPublic1} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildPublic1(Object value) { + this.listWildPublic1 = ImmutableList.builder().addAll(this.listWildPublic1 == null ? ImmutableList.of() : this.listWildPublic1).add(value).build(); + JodaBeanUtils.notNull(this.listWildPublic1, "listWildPublic1"); + return this; + } + + /** + * Adds an element to the {@code listWildPublic2} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildPublic2(Object value) { + this.listWildPublic2 = ImmutableList.builder().addAll(this.listWildPublic2 == null ? ImmutableList.of() : this.listWildPublic2).add(value).build(); + JodaBeanUtils.notNull(this.listWildPublic2, "listWildPublic2"); + return this; + } + + /** + * Adds an element to the {@code listWildBuilder1} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildBuilder1(Object value) { + this.listWildBuilder1 = ImmutableList.builder().addAll(this.listWildBuilder1 == null ? ImmutableList.of() : this.listWildBuilder1).add(value).build(); + JodaBeanUtils.notNull(this.listWildBuilder1, "listWildBuilder1"); + return this; + } + + /** + * Adds an element to the {@code listWildBuilder2} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addListWildBuilder2(Address value) { + this.listWildBuilder2 = ImmutableList.
builder().addAll(this.listWildBuilder2 == null ? ImmutableList.of() : this.listWildBuilder2).add(value).build(); + JodaBeanUtils.notNull(this.listWildBuilder2, "listWildBuilder2"); + return this; + } + + /** + * Adds an entry to the {@code mapWildBuilder1} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMapWildBuilder1(String key, Address value) { + this.mapWildBuilder1 = ImmutableMap.builder().putAll(this.mapWildBuilder1 == null ? ImmutableMap.of() : this.mapWildBuilder1).put(key, value).build(); + JodaBeanUtils.notNull(this.mapWildBuilder1, "mapWildBuilder1"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/MinimalImmutable.java b/src/test/java/org/joda/beans/sample/MinimalImmutable.java index a4bff1b5..b42f2e18 100644 --- a/src/test/java/org/joda/beans/sample/MinimalImmutable.java +++ b/src/test/java/org/joda/beans/sample/MinimalImmutable.java @@ -518,6 +518,17 @@ public Builder currency(Currency currency) { return this; } + /** + * Adds an element to the {@code list} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addList(String value) { + this.list = ImmutableList.builder().addAll(this.list == null ? ImmutableList.of() : this.list).add(value).build(); + JodaBeanUtils.notNull(this.list, "list"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/MinimalImmutableGeneric.java b/src/test/java/org/joda/beans/sample/MinimalImmutableGeneric.java index b581f1c2..c8e12489 100644 --- a/src/test/java/org/joda/beans/sample/MinimalImmutableGeneric.java +++ b/src/test/java/org/joda/beans/sample/MinimalImmutableGeneric.java @@ -302,6 +302,27 @@ public Builder map(Map map) { return this; } + /** + * Adds an element to the {@code list} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addList(T value) { + this.list = ImmutableList.builder().addAll(this.list == null ? ImmutableList.of() : this.list).add(value).build(); + return this; + } + + /** + * Adds an entry to the {@code map} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putMap(String key, T value) { + this.map = ImmutableMap.builder().putAll(this.map == null ? ImmutableMap.of() : this.map).put(key, value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/MutableListFinalBean.java b/src/test/java/org/joda/beans/sample/MutableListFinalBean.java index 06d40cf0..9b85ecf7 100644 --- a/src/test/java/org/joda/beans/sample/MutableListFinalBean.java +++ b/src/test/java/org/joda/beans/sample/MutableListFinalBean.java @@ -380,6 +380,27 @@ public Builder numberMap(Map numberMap) { return this; } + /** + * Adds an element to the {@code strings} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addStrings(String value) { + this.strings = ImmutableList.builder().addAll(this.strings == null ? ImmutableList.of() : this.strings).add(value).build(); + return this; + } + + /** + * Adds an entry to the {@code numberMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putNumberMap(String key, Integer value) { + this.numberMap = ImmutableMap.builder().putAll(this.numberMap == null ? ImmutableMap.of() : this.numberMap).put(key, value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/MutableListNonFinalBean.java b/src/test/java/org/joda/beans/sample/MutableListNonFinalBean.java index 851230b3..4af4a349 100644 --- a/src/test/java/org/joda/beans/sample/MutableListNonFinalBean.java +++ b/src/test/java/org/joda/beans/sample/MutableListNonFinalBean.java @@ -388,6 +388,27 @@ public Builder numberMap(Map numberMap) { return this; } + /** + * Adds an element to the {@code strings} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addStrings(String value) { + this.strings = ImmutableList.builder().addAll(this.strings == null ? ImmutableList.of() : this.strings).add(value).build(); + return this; + } + + /** + * Adds an entry to the {@code numberMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putNumberMap(String key, Integer value) { + this.numberMap = ImmutableMap.builder().putAll(this.numberMap == null ? ImmutableMap.of() : this.numberMap).put(key, value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/SimpleJson.java b/src/test/java/org/joda/beans/sample/SimpleJson.java index a5ac2052..1acb8677 100644 --- a/src/test/java/org/joda/beans/sample/SimpleJson.java +++ b/src/test/java/org/joda/beans/sample/SimpleJson.java @@ -1621,6 +1621,92 @@ public Builder listNumericInMap(Map> listNumericInMap) { return this; } + /** + * Adds an element to the {@code arrayByte} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addArrayByte(byte value) { + this.arrayByte = arrayByte == null ? new byte[1] : Arrays.copyOf(this.arrayByte, this.arrayByte.length + 1); + this.arrayByte[this.arrayByte.length - 1] = value; + return this; + } + + /** + * Adds an element to the {@code stringList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addStringList(String value) { + this.stringList = ImmutableList.builder().addAll(this.stringList == null ? ImmutableList.of() : this.stringList).add(value).build(); + return this; + } + + /** + * Adds an element to the {@code beanList} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addBeanList(ImmKey value) { + this.beanList = ImmutableList.builder().addAll(this.beanList == null ? ImmutableList.of() : this.beanList).add(value).build(); + return this; + } + + /** + * Adds an entry to the {@code stringMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putStringMap(String key, String value) { + this.stringMap = ImmutableMap.builder().putAll(this.stringMap == null ? ImmutableMap.of() : this.stringMap).put(key, value).build(); + return this; + } + + /** + * Adds an entry to the {@code intKeyMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putIntKeyMap(Integer key, String value) { + this.intKeyMap = ImmutableMap.builder().putAll(this.intKeyMap == null ? ImmutableMap.of() : this.intKeyMap).put(key, value).build(); + return this; + } + + /** + * Adds an entry to the {@code beanMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putBeanMap(String key, ImmKey value) { + this.beanMap = ImmutableMap.builder().putAll(this.beanMap == null ? ImmutableMap.of() : this.beanMap).put(key, value).build(); + return this; + } + + /** + * Adds an entry to the {@code listInMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putListInMap(String key, List value) { + this.listInMap = ImmutableMap.>builder().putAll(this.listInMap == null ? ImmutableMap.of() : this.listInMap).put(key, value).build(); + return this; + } + + /** + * Adds an entry to the {@code listNumericInMap} property + * @param key the key of the new entry + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putListNumericInMap(String key, List value) { + this.listNumericInMap = ImmutableMap.>builder().putAll(this.listNumericInMap == null ? ImmutableMap.of() : this.listNumericInMap).put(key, value).build(); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderFinal.java b/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderFinal.java index 3f7b8644..3c9d79ae 100644 --- a/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderFinal.java +++ b/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderFinal.java @@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import java.util.Arrays; /** * Mock person JavaBean, used for testing. @@ -826,6 +827,51 @@ public Builder tags(String... tags) { return this; } + /** + * Adds an element to the {@code addressList} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addAddressList(Address value) { + this.addressList = ImmutableList.
builder().addAll(this.addressList == null ? ImmutableList.of() : this.addressList).add(value).build(); + JodaBeanUtils.notNull(this.addressList, "addressList"); + return this; + } + + /** + * Adds an element to the {@code addressesList} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addAddressesList(List
value) { + this.addressesList = ImmutableList.>builder().addAll(this.addressesList == null ? ImmutableList.of() : this.addressesList).add(value).build(); + JodaBeanUtils.notNull(this.addressesList, "addressesList"); + return this; + } + + /** + * Adds an element to the {@code tags} property + * @param value the new element + * @return this, for chaining, not null + */ + public Builder addTags(String value) { + this.tags = tags == null ? new String[1] : Arrays.copyOf(this.tags, this.tags.length + 1); + this.tags[this.tags.length - 1] = value; + return this; + } + + /** + * Adds an entry to the {@code otherAddressMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putOtherAddressMap(String key, Address value) { + this.otherAddressMap = ImmutableMap.builder().putAll(this.otherAddressMap == null ? ImmutableMap.of() : this.otherAddressMap).put(key, value).build(); + JodaBeanUtils.notNull(this.otherAddressMap, "otherAddressMap"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() { diff --git a/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderNonFinal.java b/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderNonFinal.java index 2c1443f4..6a50d7fc 100644 --- a/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderNonFinal.java +++ b/src/test/java/org/joda/beans/sample/SimplePersonWithBuilderNonFinal.java @@ -765,6 +765,40 @@ public Builder mainAddress(Address mainAddress) { return this; } + /** + * Adds an element to the {@code addressList} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addAddressList(Address value) { + this.addressList = ImmutableList.
builder().addAll(this.addressList == null ? ImmutableList.of() : this.addressList).add(value).build(); + JodaBeanUtils.notNull(this.addressList, "addressList"); + return this; + } + + /** + * Adds an element to the {@code addressesList} property + * @param value the new element, not null + * @return this, for chaining, not null + */ + public Builder addAddressesList(List
value) { + this.addressesList = ImmutableList.>builder().addAll(this.addressesList == null ? ImmutableList.of() : this.addressesList).add(value).build(); + JodaBeanUtils.notNull(this.addressesList, "addressesList"); + return this; + } + + /** + * Adds an entry to the {@code otherAddressMap} property + * @param key the key of the new entry, not null + * @param value the value of the new entry + * @return this, for chaining, not null + */ + public Builder putOtherAddressMap(String key, Address value) { + this.otherAddressMap = ImmutableMap.builder().putAll(this.otherAddressMap == null ? ImmutableMap.of() : this.otherAddressMap).put(key, value).build(); + JodaBeanUtils.notNull(this.otherAddressMap, "otherAddressMap"); + return this; + } + //----------------------------------------------------------------------- @Override public String toString() {