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;
 

Reply via email to