It was possible to change resources, that should actually be immutable, by
using the copy-of constructor of the respective builder class. A simple
test case that was working:
def 'Can change immutable User'() {
given:
def notSoImmutableUser = new User.Builder('tester').build()
when:
new User.Builder(notSoImmutableUser)
.addExtension(new Extension.Builder('urn:tester').build())
then:
notSoImmutableUser.getSchemas().contains('urn:tester')
}
This is also true for all other collection-based attributes, like
emails, photos, etc.
Fix this behavior by:
Make a defensive copy of all collections in the resource's
constructor. Make this copy an ImmutableList/ImmutableSet. This
way, only immutable objects are stored in the resource.
Copy all elements of collection-based attributes in the copy-of
constructor of the builders into the builders' own collection.
Remove the creation of ImmutableList/ImmutableSet in the getters, as
this is not necessary anymore. All fields store immutable objects now.
This PR additionally contains a bunch of small refactorings. See the
individual commits for details:
Remove constructors that take the builder as parameter
It was possible to change resources, that should actually be immutable, by using the copy-of constructor of the respective builder class. A simple test case that was working:
This is also true for all other collection-based attributes, like
emails
,photos
, etc.Fix this behavior by:
ImmutableList
/ImmutableSet
. This way, only immutable objects are stored in the resource.Remove the creation of
ImmutableList
/ImmutableSet
in the getters, as this is not necessary anymore. All fields store immutable objects now.This PR additionally contains a bunch of small refactorings. See the individual commits for details: