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.binding.value.support;
017    
018    import java.beans.PropertyChangeEvent;
019    import java.beans.PropertyChangeListener;
020    
021    import org.apache.commons.logging.Log;
022    import org.apache.commons.logging.LogFactory;
023    import org.springframework.binding.value.ValueModel;
024    
025    /**
026     * Abstract base class for objects that adapt a value model to some other 
027     * model. e.g. a GUI component.
028     * 
029     * @author Oliver Hutchison
030     */
031    public abstract class AbstractValueModelAdapter {
032        protected static final Log logger = LogFactory.getLog(AbstractValueModelAdapter.class);
033    
034        private final ValueModelChangeHandler valueModelChangeHandler = new ValueModelChangeHandler();
035    
036        private ValueModel valueModel;
037    
038        public AbstractValueModelAdapter(ValueModel valueModel) {
039            this.valueModel = valueModel;
040            this.valueModel.addValueChangeListener(valueModelChangeHandler);
041        }
042        
043        /**
044         * Must be called to initialize the adapted value. Usually the
045         * last call in the constructor. 
046         */
047        protected void initalizeAdaptedValue() {
048            valueModelValueChanged(valueModel.getValue());
049        }
050    
051        protected ValueModel getValueModel() {
052            return valueModel;
053        }
054            
055        /**
056         * Subclasses must called this when the value being adapted has changed.
057         * 
058         * @param newValue the new adapted value 
059         */
060        protected void adaptedValueChanged(Object newValue) {
061            if (valueModel != null) {
062                valueModel.setValueSilently(newValue, valueModelChangeHandler);
063            }
064        }
065    
066        /**
067         * Called when the value held by the value model has changes
068         * 
069         * @param newValue the new value held by the value model
070         */
071        protected abstract void valueModelValueChanged(Object newValue);
072    
073        private class ValueModelChangeHandler implements PropertyChangeListener {
074            public void propertyChange(PropertyChangeEvent evt) {
075                valueModelValueChanged(valueModel.getValue());
076            }
077        }
078    }