001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.form;
016    
017    /**
018     * Decorates an underlying {@link IPropertySelectionModel}adding an initial property. The label,
019     * option, and value of the initial property are configurable.<p/>
020     *
021     * By default, the label will be rendered as disabled if its option is null. This behavior can be
022     * changed by {@link #setLabelAlwaysEnabled(boolean)}.
023     *  
024     * @author Paul Ferraro
025     * @since 4.0
026     */
027    public class LabeledPropertySelectionModel implements IPropertySelectionModel
028    {
029        /**
030         * Empty model implementation. Avoids NullPointerExceptions when default constructor is used.
031         */
032        private static final IPropertySelectionModel EMPTY_MODEL = new IPropertySelectionModel()
033        {
034            /**
035             * @see org.apache.tapestry.form.IPropertySelectionModel#getOptionCount()
036             */
037            public int getOptionCount()
038            {
039                return 0;
040            }
041    
042            /**
043             * @see org.apache.tapestry.form.IPropertySelectionModel#getOption(int)
044             */
045            public Object getOption(int index)
046            {
047                return null;
048            }
049    
050            /**
051             * @see org.apache.tapestry.form.IPropertySelectionModel#getLabel(int)
052             */
053            public String getLabel(int index)
054            {
055                return null;
056            }
057    
058            /**
059             * @see org.apache.tapestry.form.IPropertySelectionModel#getValue(int)
060             */
061            public String getValue(int index)
062            {
063                return null;
064            }
065    
066            public boolean isDisabled(int index)
067            {
068                return false;
069            }
070            
071            /**
072             * @see org.apache.tapestry.form.IPropertySelectionModel#translateValue(java.lang.String)
073             */
074            public Object translateValue(String value)
075            {
076                return null;
077            }
078        };
079        
080        private IPropertySelectionModel _model;
081    
082        private String _label = "";
083    
084        private Object _option = null;
085    
086        private String _value = "";
087    
088        private boolean _labelAlwaysEnabled;
089        
090        /**
091         * Constructs a new LabeledPropertySelectionModel using an empty model and default label,
092         * option, and value. Default constructor is made available so that this model may be specified
093         * as a component helper bean.
094         */
095        public LabeledPropertySelectionModel()
096        {
097            this(EMPTY_MODEL);
098        }
099    
100        /**
101         * Constructs a new LabeledPropertySelectionModel using the specified model and default label,
102         * option, and value.
103         * 
104         * @param model
105         *            the underlying model to decorate
106         */
107        public LabeledPropertySelectionModel(IPropertySelectionModel model)
108        {
109            _model = model;
110        }
111    
112        /**
113         * Constructs a new LabeledPropertySelectionModel using the specified model and label, and
114         * default option and value.
115         * 
116         * @param model
117         *            the underlying model to decorate
118         * @param label
119         *            the label of the initial property
120         */
121        public LabeledPropertySelectionModel(IPropertySelectionModel model, String label)
122        {
123            this(model);
124    
125            _label = label;
126        }
127    
128        /**
129         * Constructs a new LabeledPropertySelectionModel using the specified model, label, and option;
130         * and default value.
131         * 
132         * @param model
133         *            the underlying model to decorate
134         * @param label
135         *            the label of the initial property
136         * @param option
137         *            the option value of the initial property
138         */
139        public LabeledPropertySelectionModel(IPropertySelectionModel model, String label, Object option)
140        {
141            this(model, label);
142    
143            _option = option;
144        }
145    
146        /**
147         * Constructs a new LabeledPropertySelectionModel using the specified model, label, option, and
148         * value.
149         * 
150         * @param model
151         *            the underlying model to decorate
152         * @param label
153         *            the label of the initial property
154         * @param option
155         *            the option value of the initial property
156         * @param value
157         *            the value of the initial property
158         */
159        public LabeledPropertySelectionModel(IPropertySelectionModel model, String label, Object option, String value)
160        {
161            this(model, label, option);
162    
163            _value = value;
164        }
165    
166        /**
167         * Constructs a new LabeledPropertySelectionModel using the specified model, label, option, and
168         * value.
169         *
170         * @param model
171         *            the underlying model to decorate
172         * @param label
173         *            the label of the initial property
174         * @param option
175         *            the option value of the initial property
176         * @param value
177         *            the value of the initial property
178         * @param labelAlwaysEnabled
179         *            if the label should always be enabled
180         */
181        public LabeledPropertySelectionModel(IPropertySelectionModel model, String label, Object option, String value,
182                                             boolean labelAlwaysEnabled)
183        {
184            this(model, label, option, value);
185    
186            _labelAlwaysEnabled = labelAlwaysEnabled;
187        }
188    
189        /**
190         * Returns the underlying IPropertySelectionModel.
191         * 
192         * @return the underlying IPropertySelectionModel
193         */
194        public IPropertySelectionModel getModel()
195        {
196            return _model;
197        }
198    
199        /**
200         * Sets the underlying IPropertySelectionModel.
201         * 
202         * @param model
203         *            the IPropertySelectionModel to set
204         */
205        public void setModel(IPropertySelectionModel model)
206        {
207            _model = model;
208        }
209    
210        /**
211         * @see org.apache.tapestry.form.IPropertySelectionModel#getOptionCount()
212         */
213        public int getOptionCount()
214        {
215            return _model.getOptionCount() + 1;
216        }
217    
218        /**
219         * @see org.apache.tapestry.form.IPropertySelectionModel#getOption(int)
220         */
221        public Object getOption(int index)
222        {
223            return (index == 0) ? _option : _model.getOption(index - 1);
224        }
225    
226        /**
227         * @see org.apache.tapestry.form.IPropertySelectionModel#getLabel(int)
228         */
229        public String getLabel(int index)
230        {
231            return (index == 0) ? _label : _model.getLabel(index - 1);
232        }
233    
234        /**
235         * @see org.apache.tapestry.form.IPropertySelectionModel#getValue(int)
236         */
237        public String getValue(int index)
238        {
239            return (index == 0) ? _value : _model.getValue(index - 1);
240        }
241    
242        public boolean isDisabled(int index)
243        {
244            return index == 0 ? (!_labelAlwaysEnabled && _option == null) : _model.isDisabled(index - 1);
245        }
246        
247        /**
248         * @see org.apache.tapestry.form.IPropertySelectionModel#translateValue(java.lang.String)
249         */
250        public Object translateValue(String value)
251        {
252            if (value == null)
253                return null;
254            
255            return value.equals(_value) ? _option : _model.translateValue(value);
256        }
257    
258        /**
259         * Returns the label of the initial IPropertySelectionModel option.
260         * 
261         * @return a IPropertySelectionModel option label
262         */
263        public String getLabel()
264        {
265            return _label;
266        }
267    
268        /**
269         * Sets the label of the initial IPropertySelectionModel option.
270         * 
271         * @param label
272         *            a IPropertySelectionModel option label
273         */
274        public void setLabel(String label)
275        {
276            _label = label;
277        }
278    
279        /**
280         * Returns the value of the initial IPropertySelectionModel option.
281         * 
282         * @return a IPropertySelectionModel option value
283         */
284        public String getValue()
285        {
286            return _value;
287        }
288    
289        /**
290         * Sets the value of the initial IPropertySelectionModel option.
291         * 
292         * @param value
293         *            a IPropertySelectionModel option value
294         */
295        public void setValue(String value)
296        {
297            _value = value;
298        }
299    
300        /**
301         * Returns the initial option.
302         * 
303         * @return a PropertySelectionModel option
304         */
305        public Object getOption()
306        {
307            return _option;
308        }
309    
310        /**
311         * Sets the initial IPropertySelectionModel option.
312         * 
313         * @param option
314         *            a IPropertySelectionModel option
315         */
316        public void setOption(Object option)
317        {
318            _option = option;
319        }
320    
321        /**
322         * Returns if label should always be enabled.
323         */
324        public boolean isLabelAlwaysEnabled()
325        {
326            return _labelAlwaysEnabled;
327        }
328    
329        /**
330         * Sets the state of the label.
331         */
332        public void setLabelAlwaysEnabled(boolean labelAlwaysEnabled)
333        {
334            _labelAlwaysEnabled = labelAlwaysEnabled;
335        }
336    }