Repository: wicket
Updated Branches:
  refs/heads/master a8c6daec3 -> c2e12216f


WICKET-5518 support unmodifiable collections as well as models without
setter

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c2e12216
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c2e12216
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c2e12216

Branch: refs/heads/master
Commit: c2e12216f38b4bd0517aff239f67e9925ac5a106
Parents: a8c6dae
Author: svenmeier <[email protected]>
Authored: Tue Feb 25 23:20:02 2014 +0100
Committer: svenmeier <[email protected]>
Committed: Tue Feb 25 23:20:02 2014 +0100

----------------------------------------------------------------------
 .../wicket/markup/html/form/FormComponent.java  |  43 ++--
 .../html/form/CollectionFormComponentTest.java  | 195 +++++++++++++++++++
 2 files changed, 226 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/c2e12216/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 fdeb8c6..cb4ad05 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
@@ -1610,8 +1610,8 @@ public abstract class FormComponent<T> extends 
LabeledWebMarkupContainer impleme
         * @param formComponent
         *            the form component to update
         * @see FormComponent#updateModel()
-        * @throws UnsupportedOperationException
-        *             if the existing model object Collection cannot be 
modified
+        * @throws WicketRuntimeException
+        *             if the existing model object collection is unmodifiable 
and no setter exists
         */
        public static <S> void 
updateCollectionModel(FormComponent<Collection<S>> formComponent)
        {
@@ -1625,23 +1625,42 @@ public abstract class FormComponent<T> extends 
LabeledWebMarkupContainer impleme
                }
                else
                {
+                       Exception failure;
+
                        formComponent.modelChanging();
-                       collection.clear();
-                       if (convertedInput != null)
-                       {
-                               collection.addAll(convertedInput);
-                       }
-                       formComponent.modelChanged();
+                       
+                       try {
+                               collection.clear();
+                               if (convertedInput != null)
+                               {
+                                       collection.addAll(convertedInput);
+                               }
+                               failure = null;
+                       } catch (UnsupportedOperationException unmodifiable) {
+                               logger.debug("An error occurred while trying to 
change the collection attached to " + formComponent, unmodifiable);
 
+                               failure = unmodifiable;
+                               collection = new ArrayList<>(convertedInput); 
+                       }
+                       
                        try
                        {
                                formComponent.getModel().setObject(collection);
+                               failure = null;
                        }
-                       catch (Exception e)
+                       catch (Exception noSetter)
                        {
-                               // ignore this exception because it could be 
that there
-                               // is not setter for this collection.
-                               logger.info("An error occurred while trying to 
set the new value for the property attached to " + formComponent, e);
+                               logger.debug("An error occurred while trying to 
set the collection attached to " + formComponent, noSetter);
+                               
+                               if (failure != null) {
+                                       failure = noSetter;
+                               }
+                       }
+                       
+                       if (failure == null) {
+                               formComponent.modelChanged();
+                       } else {
+                               throw new WicketRuntimeException("Unable to 
update the collection attached to " + formComponent); 
                        }
                }
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/c2e12216/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
new file mode 100644
index 0000000..81f4e80
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/form/CollectionFormComponentTest.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.model.PropertyModel;
+import org.junit.Test;
+
+/**
+ * Testing updating model collections through
+ * {@link FormComponent#updateCollectionModel(FormComponent)}.
+ * 
+ * @author svenmeier
+ */
+public class CollectionFormComponentTest extends WicketTestCase
+{
+       @Test
+       public void getSetNullCollection()
+       {
+               final AtomicBoolean setCalled = new AtomicBoolean();
+
+               Object object = new Object()
+               {
+                       private Collection<String> internal = null;
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return internal;
+                       }
+
+                       public void setStrings(Collection<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(expected = WicketRuntimeException.class)
+       public void getNullCollectionFails()
+       {
+               Object object = new Object()
+               {
+                       private Collection<String> internal = null;
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return internal;
+                       }
+               };
+
+               Choice choice = new Choice(object);
+               choice.setConvertedInput(Arrays.asList("A", "B"));
+               FormComponent.updateCollectionModel(choice);
+       }
+
+       @Test
+       public void getSetModifiableCollection()
+       {
+               final AtomicBoolean setCalled = new AtomicBoolean();
+
+               Object object = new Object()
+               {
+                       private Collection<String> internal = new ArrayList<>();
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return internal;
+                       }
+
+                       public void setStrings(Collection<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 getModifiableCollection()
+       {
+               Object object = new Object()
+               {
+                       private Collection<String> internal = new ArrayList<>();
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return internal;
+                       }
+               };
+
+               Choice choice = new Choice(object);
+               choice.setConvertedInput(Arrays.asList("A", "B"));
+               FormComponent.updateCollectionModel(choice);
+               
+               assertEquals("[A, B]", choice.getDefaultModelObjectAsString());
+       }
+
+       /**
+        * WICKET-5518
+        */
+       @Test
+       public void getSetUnmodifiableCollection()
+       {
+               final AtomicBoolean setCalled = new AtomicBoolean();
+
+               Object object = new Object()
+               {
+                       private Collection<String> internal = new ArrayList<>();
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return 
Collections.unmodifiableCollection(internal);
+                       }
+
+                       public void setStrings(Collection<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(expected = WicketRuntimeException.class)
+       public void getUnmodifiableFails()
+       {
+               Object object = new Object()
+               {
+                       private Collection<String> internal = new ArrayList<>();
+                       
+                       public Collection<String> getStrings()
+                       {
+                               return 
Collections.unmodifiableCollection(internal);
+                       }
+               };
+
+               Choice choice = new Choice(object);
+               choice.setConvertedInput(Arrays.asList("A", "B"));
+               FormComponent.updateCollectionModel(choice);
+       }
+
+       private class Choice extends FormComponent<Collection<String>>
+       {
+
+               public Choice(Object object)
+               {
+                       super("choice", new PropertyModel(object, "strings"));
+               }
+       }
+}

Reply via email to