1   /*
2    * Copyright 2002-2004 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package org.springframework.richclient.form.binding.swing;
17  
18  import org.springframework.beans.support.PropertyComparator;
19  import org.springframework.binding.form.FieldMetadata;
20  import org.springframework.richclient.list.BeanPropertyValueListRenderer;
21  
22  import javax.swing.*;
23  import java.util.*;
24  /**
25   * Tests for ListBinder and ListBinding
26   * 
27   * @author  Oliver Hutchison
28   * @author  Andy DePue 
29   */
30  public abstract class ListBinderAbstractTests extends BindingAbstractTests {
31      private ListBinder lb;
32  
33      private Map context;
34  
35      private List selectableItems;
36  
37      private ListBinding b;
38  
39      private JList c;
40  
41      protected String setUpBinding() {
42  
43          lb = new ListBinder();
44          context = new HashMap();
45  
46          selectableItems = Arrays.asList(new Object[] {new Item("A"), new Item("B"), new Item("C"), new Item("D"),
47                  new Item("E")});
48  
49          context.put(ListBinder.SELECTABLE_ITEMS_KEY, selectableItems);
50          context.put(ListBinder.RENDERER_KEY, new BeanPropertyValueListRenderer("name"));
51          context.put(ListBinder.COMPARATOR_KEY, new PropertyComparator("name", true, false));
52  
53          return "listProperty";
54      }
55  
56      protected void setupBinding(String formPropertyPath) {
57          vm = fm.getValueModel(formPropertyPath);
58      }
59  
60      protected void setupMultipleSelectionBinding() {
61          setupBinding("listProperty");
62      }
63  
64      protected void doBinding(final String formPropertyPath) {
65          b = (ListBinding)lb.bind(fm, formPropertyPath, context);
66          c = (JList)b.getControl();
67      }
68  
69      protected void doMultipleSelectionBinding() {
70          doBinding("listProperty");
71      }
72  
73      protected void multipleSelectionBinding() {
74          setupMultipleSelectionBinding();
75          doMultipleSelectionBinding();
76      }
77  
78      protected void setupSingleSelectionBinding() {
79          setupBinding("singleSelectListProperty");
80      }
81  
82      protected void doSingleSelectionBinding() {
83          doBinding("singleSelectListProperty");
84      }
85  
86      protected void singleSelectionBinding() {
87          setupSingleSelectionBinding();
88          doSingleSelectionBinding();
89      }
90  
91      public void testComponentTracksEnabledChanges() {
92          multipleSelectionBinding();
93          assertEquals(true, c.isEnabled());
94          fm.setEnabled(false);
95          assertEquals(false, c.isEnabled());
96          fm.setEnabled(true);
97          assertEquals(true, c.isEnabled());
98      }
99  
100     public void testComponentTracksReadOnlyChanges() {
101         multipleSelectionBinding();
102         FieldMetadata state = fm.getFieldMetadata("listProperty");
103         assertEquals(true, c.isEnabled());
104         state.setReadOnly(true);
105         assertEquals(false, c.isEnabled());
106         state.setReadOnly(false);
107         assertEquals(true, c.isEnabled());
108     }
109 
110     public void testParseSingleIntervalSelection() {
111         setupMultipleSelectionBinding();
112         context.put(ListBinder.SELECTION_MODE_KEY, "SINGLE_INTERVAL_SELECTION");
113         doMultipleSelectionBinding();
114         assertEquals(ListSelectionModel.SINGLE_INTERVAL_SELECTION, c.getSelectionMode());
115     }
116 
117     public void testParseMultipleIntervalSelection() {
118         setupMultipleSelectionBinding();
119         context.put(ListBinder.SELECTION_MODE_KEY, "MULTIPLE_INTERVAL_SELECTION");
120         doMultipleSelectionBinding();
121         assertEquals(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, c.getSelectionMode());
122     }
123 
124     public void testParseSingleSelection() {
125         setupMultipleSelectionBinding();
126         context.put(ListBinder.SELECTION_MODE_KEY, "SINGLE_SELECTION");
127         doMultipleSelectionBinding();
128         assertEquals(ListSelectionModel.SINGLE_SELECTION, c.getSelectionMode());
129     }
130 
131     public void testParseIntegerSelection() {
132         setupMultipleSelectionBinding();
133         context.put(ListBinder.SELECTION_MODE_KEY, new Integer(ListSelectionModel.SINGLE_INTERVAL_SELECTION));
134         doMultipleSelectionBinding();
135         assertEquals(ListSelectionModel.SINGLE_INTERVAL_SELECTION, c.getSelectionMode());
136     }
137 
138     public void testInvalidSelection() {
139         setupMultipleSelectionBinding();
140         context.put(ListBinder.SELECTION_MODE_KEY, "INVALID_SELECTION");
141         try {
142             doMultipleSelectionBinding();
143             fail("INVALID_SELECTION should have caused IllegalArgumentException");
144         }
145         catch (IllegalArgumentException iae) {
146             // Test passed
147         }
148     }
149 
150     public void testDefaultSingleSelection() {
151         singleSelectionBinding();
152         assertEquals(ListSelectionModel.SINGLE_SELECTION, c.getSelectionMode());
153     }
154 
155     public void testDefaultMultipleSelection() {
156         multipleSelectionBinding();
157         assertEquals(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, c.getSelectionMode());
158     }
159 
160     public void testNoInitialMultipleSelection() {
161         multipleSelectionBinding();
162         assertEquals(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, c.getSelectionMode());
163         assertTrue("Expected empty selection in list.", c.getSelectedValues() == null
164                 || c.getSelectedValues().length == 0);
165     }
166 
167     public void testNoInitialSingleSelection() {
168         singleSelectionBinding();
169         assertEquals(ListSelectionModel.SINGLE_SELECTION, c.getSelectionMode());
170         assertEquals("Expected empty selection in list.", null, c.getSelectedValue());
171     }
172 
173     public void testInitialMultipleSelection() {
174         setupMultipleSelectionBinding();
175         vm.setValue(Arrays.asList(new Object[] {new Item("E"), new Item("B")}));
176         doMultipleSelectionBinding();
177 
178         // Make sure original list is intact
179         assertNotNull(vm.getValue());
180         assertEquals(2, ((List)vm.getValue()).size());
181 
182         final Object[] selection = c.getSelectedValues();
183         assertNotNull(selection);
184         assertEquals(2, selection.length);
185         assertTrue(selectableItems.contains(selection[0]));
186         assertTrue(selectableItems.contains(selection[1]));
187     }
188 
189     public void testInitialForcedSingleSelection() {
190         setupMultipleSelectionBinding();
191         context.put(ListBinder.SELECTION_MODE_KEY, "SINGLE_SELECTION");
192         final List originalList = new ArrayList(Arrays.asList(new Object[] {new Item("E"), new Item("B")}));
193         vm.setValue(originalList);
194         doMultipleSelectionBinding();
195 
196         assertNotNull(vm.getValue());
197         assertEquals(1, ((List)vm.getValue()).size());
198         assertEquals(new Item("E"), ((List)vm.getValue()).get(0));
199 
200         final Object[] selection = c.getSelectedValues();
201         assertNotNull(selection);
202         assertEquals(1, selection.length);
203         assertTrue(selection[0] == selectableItems.get(4));
204     }
205 
206     public void testInitialSingleSelection() {
207         setupSingleSelectionBinding();
208         final Item testItem = new Item("C");
209         vm.setValue(testItem);
210         doSingleSelectionBinding();
211 
212         assertTrue(vm.getValue() == testItem);
213 
214         assertEquals(testItem, c.getSelectedValue());
215         assertTrue(selectableItems.get(2) == c.getSelectedValue());
216         final Object[] selection = c.getSelectedValues();
217         assertNotNull(selection);
218         assertEquals(1, selection.length);
219         assertTrue(selectableItems.get(2) == selection[0]);
220     }
221 
222     public void testSingleSelectionTracksSelectionHolder() {
223         singleSelectionBinding();
224 
225         assertNull(vm.getValue());
226         assertNull(c.getSelectedValue());
227         Item selected = new Item("D");
228         vm.setValue(selected);
229         assertTrue(selectableItems.get(3) == c.getSelectedValue());
230         assertEquals(selected, vm.getValue());
231 
232         selected = new Item("A");
233         vm.setValue(selected);
234         assertTrue(selectableItems.get(0) == c.getSelectedValue());
235         assertEquals(selected, vm.getValue());
236     }
237 
238     public void testSelectionHolderTracksSingleSelection() {
239         singleSelectionBinding();
240 
241         assertNull(vm.getValue());
242         assertNull(c.getSelectedValue());
243 
244         Item selected = new Item("D");
245         c.setSelectedValue(selected, true);
246         assertTrue(selectableItems.get(3) == c.getSelectedValue());
247         assertEquals(selected, vm.getValue());
248 
249         selected = new Item("A");
250         c.setSelectedValue(selected, true);
251         assertTrue(selectableItems.get(0) == c.getSelectedValue());
252         assertEquals(selected, vm.getValue());
253 
254         c.clearSelection();
255         assertNull(c.getSelectedValue());
256         assertNull(vm.getValue());
257     }
258 
259     protected void assertValidMultipleSelection(final Collection original) {
260         final Collection selectedValue = (Collection)vm.getValue();
261         final Object[] selected = c.getSelectedValues();
262         if (original == null || original.size() == 0) {
263             assertTrue(selected == null || selected.length == 0);
264             assertTrue(selectedValue == null || selectedValue.size() == 0);
265         }
266         else {
267             assertNotNull(selected);
268             assertNotNull(selectedValue);
269             assertEquals(original.size(), selected.length);
270             assertEquals(original.size(), selectedValue.size());
271             assertTrue(selectedValue.containsAll(original));
272             assertTrue(original.containsAll(selectedValue));
273         }
274     }
275 
276     public void testMultipleSelectionTracksSelectionHolder() {
277         multipleSelectionBinding();
278 
279         assertNull(vm.getValue());
280         assertTrue(c.getSelectedValues() == null || c.getSelectedValues().length == 0);
281 
282         List original = Arrays.asList(new Object[] {new Item("B"), new Item("C")});
283         vm.setValue(original);
284         assertValidMultipleSelection(original);
285 
286         original = Arrays.asList(new Object[] {new Item("A"), new Item("B"), new Item("D"), new Item("E")});
287         vm.setValue(original);
288         assertValidMultipleSelection(original);
289 
290         vm.setValue(null);
291         assertValidMultipleSelection(null);
292     }
293 
294     protected void performMultipleSelection(final Collection selection) {
295         final int[] indices = new int[selection.size()];
296         int i = 0;
297         for (final Iterator iter = selection.iterator(); iter.hasNext(); i++) {
298             indices[i] = indexOf(iter.next());
299         }
300         c.setSelectedIndices(indices);
301     }
302 
303     protected int indexOf(final Object o) {
304         final ListModel model = c.getModel();
305         final int size = model.getSize();
306         for (int i = 0; i < size; i++) {
307             if (o.equals(model.getElementAt(i))) {
308                 return i;
309             }
310         }
311         return -1;
312     }
313 
314     public void testSelectionHolderTracksMultipleSelection() {
315         multipleSelectionBinding();
316 
317         assertNull(vm.getValue());
318         assertTrue(c.getSelectedValues() == null || c.getSelectedValues().length == 0);
319 
320         List original = Arrays.asList(new Object[] {new Item("A")});
321 
322         performMultipleSelection(original);
323         assertValidMultipleSelection(original);
324 
325         original = Arrays.asList(new Object[] {new Item("B"), new Item("D"), new Item("E")});
326         performMultipleSelection(original);
327         assertValidMultipleSelection(original);
328 
329         c.clearSelection();
330         assertValidMultipleSelection(null);
331     }
332 
333     public void testComponentUpdatesValueModel() {
334         // TODO Auto-generated method stub
335     }
336 
337     public void testValueModelUpdatesComponent() {
338         // TODO Auto-generated method stub
339     }
340 
341     static class Item {
342         private String name;
343 
344         public Item(final String name) {
345             this.name = name;
346         }
347 
348         public String getName() {
349             return name;
350         }
351 
352         public void setName(final String name) {
353             this.name = name;
354         }
355 
356         public boolean equals(final Object frameKey) {
357             if (this == frameKey)
358                 return true;
359             if (frameKey == null || getClass() != frameKey.getClass())
360                 return false;
361 
362             final Item item = (Item)frameKey;
363 
364             if (name != null ? !name.equals(item.name) : item.name != null)
365                 return false;
366 
367             return true;
368         }
369 
370         public int hashCode() {
371             return (name != null ? name.hashCode() : 0);
372         }
373 
374         public String toString() {
375             return "Item{" + "name='" + name + "'" + "}";
376         }
377     }
378 }