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 java.lang.reflect.Field;
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.List;
22  
23  import javax.swing.JCheckBox;
24  import javax.swing.JComboBox;
25  import javax.swing.JComponent;
26  import javax.swing.JLabel;
27  import javax.swing.JList;
28  import javax.swing.JTextField;
29  
30  import org.springframework.beans.InvalidPropertyException;
31  import org.springframework.beans.support.SortDefinition;
32  import org.springframework.binding.form.support.DefaultFormModel;
33  import org.springframework.binding.support.TestBean;
34  import org.springframework.binding.value.ValueModel;
35  import org.springframework.binding.value.support.ObservableList;
36  import org.springframework.binding.value.support.ValueHolder;
37  import org.springframework.richclient.form.FormModelHelper;
38  import org.springframework.richclient.form.binding.swing.SwingBindingFactory.BeanPropertyEditorClosure;
39  import org.springframework.richclient.list.BeanPropertyValueListRenderer;
40  import org.springframework.richclient.test.SpringRichTestCase;
41  
42  /**
43   * @author Oliver Hutchison
44   */
45  public class SwingBindingFactoryTests extends SpringRichTestCase {
46  
47      private SwingBindingFactory sbf;
48  
49      public void doSetUp() {
50          sbf = new SwingBindingFactory(FormModelHelper.createFormModel(new TestBean()));
51          sbf.setBinderSelectionStrategy(new TestingBinderSelectionStrategy());
52      }
53  
54      public void testSwingBindingFactory() {
55          try {
56              new SwingBindingFactory(null);
57              fail("allowed null form model");
58          }
59          catch (IllegalArgumentException e) {
60              // expected
61          }
62      }
63  
64      public void testCreateBoundTextField() {
65          TestableBinding b = (TestableBinding)sbf.createBoundTextField("name");
66          assertBindingProperties(b, JTextField.class, null, "name");
67          assertEquals(Collections.EMPTY_MAP, b.getContext());
68      }
69  
70      public void testCreateBoundCheckBox() {
71          TestableBinding b = (TestableBinding)sbf.createBoundCheckBox("name");
72          assertBindingProperties(b, JCheckBox.class, null, "name");
73          assertEquals(Collections.EMPTY_MAP, b.getContext());
74      }
75  
76      public void testCreateBoundLabel() {
77          TestableBinding b = (TestableBinding)sbf.createBoundLabel("name");
78          assertBindingProperties(b, JLabel.class, null, "name");
79          assertEquals(Collections.EMPTY_MAP, b.getContext());
80      }
81  
82      public void testCreateBoundComboBoxString() {
83          TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name");
84          assertBindingProperties(b, JComboBox.class, null, "name");
85          assertEquals(Collections.EMPTY_MAP, b.getContext());
86      }
87  
88      public void testCreateBoundComboBoxStringObjectArray() {
89          Object[] items = new Object[0];
90          TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", items);
91          assertBindingProperties(b, JComboBox.class, null, "name");
92          assertEquals(1, b.getContext().size(), 1);
93          assertEquals(items, b.getContext().get(ComboBoxBinder.SELECTABLE_ITEMS_KEY));
94      }
95  
96      public void testCreateBoundComboBoxStringValueModel() {
97          ValueModel valueHolder = new ValueHolder();
98          TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", valueHolder);
99          assertBindingProperties(b, JComboBox.class, null, "name");
100         assertEquals(1, b.getContext().size(), 1);
101         assertEquals(valueHolder, b.getContext().get(ComboBoxBinder.SELECTABLE_ITEMS_KEY));
102     }
103 
104     public void testCreateBoundComboBoxStringStringString() {
105         TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", "listProperty", "displayProperty");
106         assertBindingProperties(b, JComboBox.class, null, "name");
107         assertEquals(4, b.getContext().size());
108         assertEquals(sbf.getFormModel().getValueModel("listProperty"), b.getContext().get(
109                 ComboBoxBinder.SELECTABLE_ITEMS_KEY));
110         assertEquals("displayProperty",
111                 ((BeanPropertyValueListRenderer)b.getContext().get(ComboBoxBinder.RENDERER_KEY)).getPropertyName());
112         assertEquals("displayProperty",
113                 ((BeanPropertyEditorClosure)b.getContext().get(ComboBoxBinder.EDITOR_KEY)).getRenderedProperty());
114         assertEquals("displayProperty", getComparatorProperty(b));
115 
116         try {
117             b = (TestableBinding)sbf.createBoundComboBox("name", "someUnknownProperty", "displayProperty");
118             fail("cant use an unknown property to provide the selectable items");
119         }
120         catch (InvalidPropertyException e) {
121             // expected
122         }
123     }
124 
125     public void testCreateBoundComboBoxStringValueModelString() {
126         ValueModel selectableItemsHolder = new ValueHolder(new Object());
127         TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", selectableItemsHolder, "displayProperty");
128         assertBindingProperties(b, JComboBox.class, null, "name");
129         assertEquals(4, b.getContext().size());
130         assertEquals(selectableItemsHolder, b.getContext().get(ComboBoxBinder.SELECTABLE_ITEMS_KEY));
131         assertEquals("displayProperty",
132                 ((BeanPropertyValueListRenderer)b.getContext().get(ComboBoxBinder.RENDERER_KEY)).getPropertyName());
133         assertEquals("displayProperty",
134                 ((BeanPropertyEditorClosure)b.getContext().get(ComboBoxBinder.EDITOR_KEY)).getRenderedProperty());
135         assertEquals("displayProperty", getComparatorProperty(b));
136     }
137 
138     public void testCreateBoundListModel() {
139         ValueModel vm = ((DefaultFormModel)sbf.getFormModel()).getFormObjectPropertyAccessStrategy().getPropertyValueModel(
140                 "listProperty");
141         ObservableList observableList = sbf.createBoundListModel("listProperty");
142 
143         ArrayList list = new ArrayList();
144         list.add(new Integer(1));
145         vm.setValue(list);
146         assertEquals(new Integer(1), observableList.get(0));
147         observableList.add(new Integer(2));
148         assertEquals(1, ((List)vm.getValue()).size());
149         sbf.getFormModel().commit();
150         assertEquals(new Integer(2), ((List)vm.getValue()).get(1));
151     }
152 
153     public void testCreateBoundListString() {
154         TestableBinding b = (TestableBinding)sbf.createBoundList("listProperty");
155         assertBindingProperties(b, JList.class, null, "listProperty");
156 
157         assertEquals(1, b.getContext().size());
158     }
159 
160     public void testCreateBoundListStringObjectString() {
161         Object selectableItems = new Object();
162         TestableBinding b = (TestableBinding)sbf.createBoundList("listProperty", selectableItems, "displayProperty");
163         assertBindingProperties(b, JList.class, null, "listProperty");
164 
165         assertEquals(3, b.getContext().size());
166         assertEquals(selectableItems,
167                 ((ValueModel)b.getContext().get(ListBinder.SELECTABLE_ITEMS_KEY)).getValue());
168         assertEquals("displayProperty",
169                 ((BeanPropertyValueListRenderer)b.getContext().get(ListBinder.RENDERER_KEY)).getPropertyName());
170         assertEquals("displayProperty", getComparatorProperty(b));
171         assertFalse(b.getContext().containsKey(ListBinder.SELECTION_MODE_KEY));
172     }
173 
174     public void testCreateBoundListStringValueModelString() {
175         ValueModel selectableItemsHolder = new ValueHolder(new Object());
176         TestableBinding b = (TestableBinding)sbf.createBoundList("listProperty", selectableItemsHolder,
177                 "displayProperty");
178         assertBindingProperties(b, JList.class, null, "listProperty");
179 
180         assertEquals(3, b.getContext().size());
181         assertEquals(selectableItemsHolder, b.getContext().get(ListBinder.SELECTABLE_ITEMS_KEY));
182         assertEquals("displayProperty",
183                 ((BeanPropertyValueListRenderer)b.getContext().get(ListBinder.RENDERER_KEY)).getPropertyName());
184         assertEquals("displayProperty", getComparatorProperty(b));
185         assertFalse(b.getContext().containsKey(ListBinder.SELECTION_MODE_KEY));
186     }
187 
188     private void assertBindingProperties(TestableBinding b, Class controlType, JComponent control, String property) {
189         assertEquals(b.getControlType(), controlType);
190         assertEquals(b.getControl(), control);
191         assertEquals(b.getFormModel(), sbf.getFormModel());
192         assertEquals(b.getProperty(), property);
193     }
194     
195     private String getComparatorProperty(TestableBinding b) {
196         // TODO: remove this nasty reflection once PropertyComparator is extended with the abbility
197         // to query the SortDefinition
198         return ((SortDefinition)getField(b.getContext().get(ListBinder.COMPARATOR_KEY),
199                 "sortDefinition")).getProperty();
200     }
201 
202     private Object getField(Object source, String fieldName) {
203         try {
204             Field field = source.getClass().getDeclaredField(fieldName);
205             field.setAccessible(true);
206             return field.get(source);
207         }
208         catch (Exception e) {
209             fail(e.toString());
210             return null;
211         }
212     }
213 }