001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of 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,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.springframework.richclient.form.binding.support;
017    
018    import java.beans.PropertyChangeEvent;
019    import java.beans.PropertyChangeListener;
020    
021    import javax.swing.JComponent;
022    
023    import org.springframework.binding.form.FieldFace;
024    import org.springframework.binding.form.FieldMetadata;
025    import org.springframework.binding.form.FormModel;
026    import org.springframework.binding.value.ValueModel;
027    import org.springframework.richclient.factory.AbstractControlFactory;
028    import org.springframework.richclient.form.binding.Binding;
029    import org.springframework.util.Assert;
030    
031    /**
032     * Default base implementation of <code>Binding</code>. Provides helper methods for 
033     * access to commonly needed properties. 
034     * 
035     * @author Oliver Hutchison
036     */
037    public abstract class AbstractBinding extends AbstractControlFactory implements Binding {
038    
039        protected final FormModel formModel;
040    
041        protected final String formPropertyPath;
042    
043        protected final FieldMetadata fieldMetadata;
044    
045        private final FieldMetadataChangeHandler fieldMetadataChangeHandler = new FieldMetadataChangeHandler();
046    
047        private final Class requiredSourceClass;
048    
049        protected AbstractBinding(FormModel formModel, String formPropertyPath, Class requiredSourceClass) {
050            this.formModel = formModel;
051            this.formPropertyPath = formPropertyPath;
052            this.fieldMetadata = this.formModel.getFieldMetadata(formPropertyPath);
053            this.requiredSourceClass = requiredSourceClass;
054            fieldMetadata.addPropertyChangeListener(FieldMetadata.ENABLED_PROPERTY, fieldMetadataChangeHandler);
055            fieldMetadata.addPropertyChangeListener(FieldMetadata.READ_ONLY_PROPERTY, fieldMetadataChangeHandler);
056        }
057    
058        public String getProperty() {
059            return formPropertyPath;
060        }
061    
062        public FormModel getFormModel() {
063            return formModel;
064        }
065    
066        protected FieldFace getFieldFace() {
067            return formModel.getFieldFace(formPropertyPath);
068        }
069    
070        protected Class getPropertyType() {
071            return fieldMetadata.getPropertyType();
072        }
073    
074        protected JComponent createControl() {
075            JComponent control = doBindControl();
076            control.setName(getProperty());
077            readOnlyChanged();
078            enabledChanged();
079            return control;
080        }
081    
082        protected abstract JComponent doBindControl();
083    
084        /**
085         * Called when the read only state of the bound property changes.
086         * @see FormPropertyState
087         */
088        protected abstract void readOnlyChanged();
089    
090        /**
091         * Called when the enabled state of the bound property changes.
092         * @see FormPropertyState
093         */
094        protected abstract void enabledChanged();
095    
096        /**
097         * Is the bound property in the read only state.
098         * @see FormPropertyState
099         */
100        protected boolean isReadOnly() {
101            return fieldMetadata.isReadOnly();
102        }
103    
104        /**
105         * Is the bound property in the enabled state.
106         * @see FormPropertyState
107         */
108        protected boolean isEnabled() {
109            return fieldMetadata.isEnabled();
110        }
111    
112        protected ValueModel getValueModel() {
113            ValueModel valueModel = (requiredSourceClass == null) ? formModel.getValueModel(formPropertyPath)
114                    : formModel.getValueModel(formPropertyPath, requiredSourceClass);
115            Assert.notNull(valueModel, "Unable to locate value model for property '" + formPropertyPath + "'.");
116            return valueModel;
117        }
118    
119        protected Object getValue() {
120            return getValueModel().getValue();
121        }
122        
123        private class FieldMetadataChangeHandler implements PropertyChangeListener {
124            public void propertyChange(PropertyChangeEvent evt) {
125                if (FieldMetadata.ENABLED_PROPERTY.equals(evt.getPropertyName())) {
126                    enabledChanged();
127                }
128                else if (FieldMetadata.READ_ONLY_PROPERTY.equals(evt.getPropertyName())) {
129                    readOnlyChanged();
130                }
131            }
132        }
133    }