jcommander icon indicating copy to clipboard operation
jcommander copied to clipboard

Collection parameter handling 'forgets' items if a bean manages its own collection

Open Aklakan opened this issue 6 years ago • 0 comments

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

Aklakan avatar Feb 18 '19 10:02 Aklakan