001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.form.binding.swing;
017    
018    import java.lang.reflect.Field;
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.List;
022    
023    import javax.swing.JCheckBox;
024    import javax.swing.JComboBox;
025    import javax.swing.JComponent;
026    import javax.swing.JLabel;
027    import javax.swing.JList;
028    import javax.swing.JTextField;
029    
030    import org.springframework.beans.InvalidPropertyException;
031    import org.springframework.beans.support.SortDefinition;
032    import org.springframework.binding.form.support.DefaultFormModel;
033    import org.springframework.binding.support.TestBean;
034    import org.springframework.binding.value.ValueModel;
035    import org.springframework.binding.value.support.ObservableList;
036    import org.springframework.binding.value.support.ValueHolder;
037    import org.springframework.richclient.form.FormModelHelper;
038    import org.springframework.richclient.form.binding.swing.SwingBindingFactory.BeanPropertyEditorClosure;
039    import org.springframework.richclient.list.BeanPropertyValueListRenderer;
040    import org.springframework.richclient.test.SpringRichTestCase;
041    
042    /**
043     * @author Oliver Hutchison
044     */
045    public class SwingBindingFactoryTests extends SpringRichTestCase {
046    
047        private SwingBindingFactory sbf;
048    
049        public void doSetUp() {
050            sbf = new SwingBindingFactory(FormModelHelper.createFormModel(new TestBean()));
051            sbf.setBinderSelectionStrategy(new TestingBinderSelectionStrategy());
052        }
053    
054        public void testSwingBindingFactory() {
055            try {
056                new SwingBindingFactory(null);
057                fail("allowed null form model");
058            }
059            catch (IllegalArgumentException e) {
060                // expected
061            }
062        }
063    
064        public void testCreateBoundTextField() {
065            TestableBinding b = (TestableBinding)sbf.createBoundTextField("name");
066            assertBindingProperties(b, JTextField.class, null, "name");
067            assertEquals(Collections.EMPTY_MAP, b.getContext());
068        }
069    
070        public void testCreateBoundCheckBox() {
071            TestableBinding b = (TestableBinding)sbf.createBoundCheckBox("name");
072            assertBindingProperties(b, JCheckBox.class, null, "name");
073            assertEquals(Collections.EMPTY_MAP, b.getContext());
074        }
075    
076        public void testCreateBoundLabel() {
077            TestableBinding b = (TestableBinding)sbf.createBoundLabel("name");
078            assertBindingProperties(b, JLabel.class, null, "name");
079            assertEquals(Collections.EMPTY_MAP, b.getContext());
080        }
081    
082        public void testCreateBoundComboBoxString() {
083            TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name");
084            assertBindingProperties(b, JComboBox.class, null, "name");
085            assertEquals(Collections.EMPTY_MAP, b.getContext());
086        }
087    
088        public void testCreateBoundComboBoxStringObjectArray() {
089            Object[] items = new Object[0];
090            TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", items);
091            assertBindingProperties(b, JComboBox.class, null, "name");
092            assertEquals(1, b.getContext().size(), 1);
093            assertEquals(items, b.getContext().get(ComboBoxBinder.SELECTABLE_ITEMS_KEY));
094        }
095    
096        public void testCreateBoundComboBoxStringValueModel() {
097            ValueModel valueHolder = new ValueHolder();
098            TestableBinding b = (TestableBinding)sbf.createBoundComboBox("name", valueHolder);
099            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    }