jcommander
jcommander copied to clipboard
Collection parameter handling 'forgets' items if a bean manages its own collection
In ParameterDescription.java a new collection is created and the bean's setter is invoked. Afterwards, the items are added to the original collection, so if the bean's setter created a copy, these additions are lost.
Suggestion: Add the initial item(s) to the original collection first, then invoke the bean's setter with the initialized collection. This would already make all beans returning a collection view work, as subsequent additions already use the bean's returned collection.
A more general solution - but with pretty bad overhead (e.g. when globbing thousands of files) might be to always assume that a bean may manage its collection itself, and thus always create copies:
Collection<Object> tmp = newCollection(type);
tmp.addAll((Collection)pd.getValue(bean)); // invoke getter
tmp.addAll(newItems);
pd.setValue(bean, tmp); // invoke settter
A more sophisticated approach would be to probe the collection behaviors and then choose the best strategy among these options:
- getter returns the same object as passed to the setter (property is a direct reference to a collection)
- adding an item to the collection returned by the getter is equivalent to the collection returned by a subsequent invocation of the getter (property is a collection view)
- bean manages its own copy of the collection, every change requires invocation of the setter with the complete collection