WICKET-6451 enhance support for unmodifiable or null sets
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/10f5f76e Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/10f5f76e Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/10f5f76e Branch: refs/heads/WICKET-6105-java.time Commit: 10f5f76e5d84a85a8aa260b1fd0502bb29a3cc7e Parents: 7646010 Author: Sven Meier <svenme...@apache.org> Authored: Thu Aug 31 11:28:43 2017 +0200 Committer: Sven Meier <svenme...@apache.org> Committed: Thu Aug 31 11:28:43 2017 +0200 ---------------------------------------------------------------------- .../wicket/markup/html/form/FormComponent.java | 33 +++++++- .../html/form/CollectionFormComponentTest.java | 81 +++++++++++++++++--- 2 files changed, 102 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/10f5f76e/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java index 9d4460e..37722d8 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java +++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -42,12 +43,14 @@ import org.apache.wicket.core.util.lang.WicketObjects; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.form.AutoLabelResolver.AutoLabelMarker; import org.apache.wicket.model.IModel; +import org.apache.wicket.model.IObjectClassAwareModel; import org.apache.wicket.model.IPropertyReflectionAwareModel; import org.apache.wicket.model.Model; import org.apache.wicket.util.convert.ConversionException; import org.apache.wicket.util.convert.IConverter; import org.apache.wicket.util.lang.Args; import org.apache.wicket.util.lang.Classes; +import org.apache.wicket.util.lang.Objects; import org.apache.wicket.util.string.StringList; import org.apache.wicket.util.string.StringValue; import org.apache.wicket.util.string.Strings; @@ -1575,7 +1578,7 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer impleme /** * Update the model of a {@link FormComponent} containing a {@link Collection}. * - * If the model object does not yet exists, a new {@link ArrayList} is filled with the converted + * If the model object does not yet exists, a new suitable collection is filled with the converted * input and used as the new model object. Otherwise the existing collection is modified * in-place, then {@link Model#setObject(Object)} is called with the same instance: it allows * the Model to be notified of changes even when {@link Model#getObject()} returns a different @@ -1599,7 +1602,14 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer impleme Collection<S> collection = formComponent.getModelObject(); if (collection == null) { - collection = new ArrayList<>(convertedInput); + Class<?> hint = null; + if (formComponent.getModel() instanceof IObjectClassAwareModel) { + hint = ((IObjectClassAwareModel)formComponent.getModel()).getObjectClass(); + } + if (hint == null) { + hint = List.class; + } + collection = newCollection(hint, convertedInput); formComponent.setModelObject(collection); } else @@ -1621,7 +1631,7 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer impleme logger.debug("An error occurred while trying to modify the collection attached to " + formComponent, unmodifiable); } - collection = new ArrayList<>(convertedInput); + collection = newCollection(collection.getClass(), convertedInput); } try @@ -1645,4 +1655,21 @@ public abstract class FormComponent<T> extends LabeledWebMarkupContainer impleme formComponent.modelChanged(); } } + + /** + * Creates a new collection. + * + * @param hint type deciding the type of the returned collection + * @param elements elements for the new collection + * @return collection + * @throws IllegalArgumentException if type is not supported + */ + private static <S> Collection<S> newCollection(Class<?> hint, Collection<S> elements) + { + if (Set.class.isAssignableFrom(hint)) { + return new HashSet<>(elements); + } else { + return new ArrayList<>(elements); + } + } } http://git-wip-us.apache.org/repos/asf/wicket/blob/10f5f76e/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java index a208b2d..55ca02b 100644 --- a/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.wicket.WicketRuntimeException; @@ -38,20 +41,50 @@ import org.junit.Test; public class CollectionFormComponentTest extends WicketTestCase { @Test - public void getSetNullCollection() + public void getSetNullList() { final AtomicBoolean setCalled = new AtomicBoolean(); Object object = new Object() { - private Collection<String> internal = null; + private List<String> internal = null; - public Collection<String> getStrings() + public List<String> getStrings() { return internal; } - public void setStrings(Collection<String> strings) + public void setStrings(List<String> strings) + { + this.internal = strings; + + setCalled.set(true); + } + }; + + Choice choice = new Choice(object); + choice.setConvertedInput(Arrays.asList("A", "B")); + FormComponent.updateCollectionModel(choice); + + assertEquals(true, setCalled.get()); + assertEquals("[A, B]", choice.getDefaultModelObjectAsString()); + } + + @Test + public void getSetNullSet() + { + final AtomicBoolean setCalled = new AtomicBoolean(); + + Object object = new Object() + { + private Set<String> internal = null; + + public Set<String> getStrings() + { + return internal; + } + + public void setStrings(Set<String> strings) { this.internal = strings; @@ -139,20 +172,50 @@ public class CollectionFormComponentTest extends WicketTestCase * WICKET-5518 */ @Test - public void getSetUnmodifiableCollection() + public void getSetUnmodifiableList() { final AtomicBoolean setCalled = new AtomicBoolean(); Object object = new Object() { - private Collection<String> internal = new ArrayList<>(); + private List<String> internal = new ArrayList<>(); - public Collection<String> getStrings() + public List<String> getStrings() { - return Collections.unmodifiableCollection(internal); + return Collections.unmodifiableList(internal); } - public void setStrings(Collection<String> strings) + public void setStrings(List<String> strings) + { + this.internal = strings; + + setCalled.set(true); + } + }; + + Choice choice = new Choice(object); + choice.setConvertedInput(Arrays.asList("A", "B")); + FormComponent.updateCollectionModel(choice); + + assertEquals(true, setCalled.get()); + assertEquals("[A, B]", choice.getDefaultModelObjectAsString()); + } + + @Test + public void getSetUnmodifiableSet() + { + final AtomicBoolean setCalled = new AtomicBoolean(); + + Object object = new Object() + { + private Set<String> internal = new HashSet<>(); + + public Set<String> getStrings() + { + return Collections.unmodifiableSet(internal); + } + + public void setStrings(Set<String> strings) { this.internal = strings;