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.form;
017    
018    import java.util.Set;
019    
020    import org.springframework.beans.InvalidPropertyException;
021    import org.springframework.binding.convert.Converter;
022    import org.springframework.binding.value.PropertyChangePublisher;
023    import org.springframework.binding.value.ValueModel;
024    import org.springframework.richclient.core.Authorizable;
025    
026    /**
027     * <p>
028     * A formModel groups valueModels and actions that are related to the same
029     * backing object. It will manage the creation/handling of the valueModels,
030     * their associated metadata and an overal state.
031     * </p>
032     *
033     * <p>
034     * The formModel can be in one of three 'user' states:
035     * <ul>
036     * <li><em>Disabled:</em> all user interaction should be ignored.</li>
037     * <li><em>Enabled and readOnly:</em> user may interact, but not edit.</li>
038     * <li><em>Enabled and editable:</em> user may interact and edit where
039     * needed.</li>
040     * </ul>
041     * These states are counterparts of the enabled/editable state of a
042     * component/textcomponent.
043     * </p>
044     *
045     * <p>
046     * The formModel also tracks its inner states:
047     * <ul>
048     * <li><em>Dirty:</em> one of its valueModels has a changed value.</li>
049     * <li><em>Committable:</em> all valueModels are in an 'error-free' state.</li>
050     * </ul>
051     * </>
052     *
053     * @see ConfigurableFormModel
054     *
055     * @author Keith Donald
056     * @author Oliver Hutchison
057     */
058    public interface FormModel extends PropertyChangePublisher, Authorizable {
059    
060            /** The name of the bound property <em>dirty</em>. */
061            static final String DIRTY_PROPERTY = "dirty";
062    
063            /** The name of the bound property <em>enabled</em>. */
064            static final String ENABLED_PROPERTY = "enabled";
065    
066            /** The name of the bound property <em>readonly</em>. */
067            static final String READONLY_PROPERTY = "readOnly";
068    
069            /** The name of the bound property <em>committable</em>. */
070            static final String COMMITTABLE_PROPERTY = "committable";
071    
072            /**
073             * Returns the id that is used to identify this form model.
074             */
075            String getId();
076    
077            /**
078             * Returns the object currently backing this form. This object is held by
079             * the FormObjectHolder.
080             */
081            Object getFormObject();
082    
083            /**
084             * Sets the object currently backing this form.
085             */
086            void setFormObject(Object formObject);
087    
088            /**
089             * Returns the value model which holds the object currently backing this
090             * form.
091             */
092            ValueModel getFormObjectHolder();
093    
094            /**
095             * Returns a value model that holds the value of the specified form
096             * property.
097             *
098             * @throws InvalidPropertyException if the form has no such property
099             */
100            ValueModel getValueModel(String formProperty);
101    
102            /**
103             * Returns a type converting value model for the given form property. The
104             * type of the value returned from the returned value model is guaranteed to
105             * be of class targetClass.
106             *
107             * @throws InvalidPropertyException if the form has no such property
108             * @throws IllegalArgumentException if no suitable converter from the
109             * original property class to the targetClass can be found
110             */
111            ValueModel getValueModel(String formProperty, Class targetClass);
112    
113            /**
114             * Returns the metadata for the given form field.
115             */
116            FieldMetadata getFieldMetadata(String field);
117    
118            /**
119             * Returns the fields that are used by this formModel. Each field has an
120             * associated ValueModel.
121             */
122            Set getFieldNames();
123    
124            /**
125             * Register converters for a given property name.
126             *
127             * @param propertyName name of property on which to register converters
128             * @param toConverter Convert from source to target type
129             * @param fromConverter Convert from target to source type
130             */
131            void registerPropertyConverter(String propertyName, Converter toConverter, Converter fromConverter);
132    
133            /**
134             * Returns true if the form has a value model for the provided property
135             * name.
136             */
137            boolean hasValueModel(String formProperty);
138    
139            /**
140             * Commits any changes buffered by the form property value models into the
141             * current form backing object.
142             *
143             * @throws IllegalStateException if the form model is not committable
144             * @see #isCommittable()
145             */
146            void commit();
147    
148            /**
149             * Reverts any dirty value models back to the original values that were
150             * loaded from the current form backing object since last call to either
151             * commit or revert or since the last change of the form backing object.
152             */
153            void revert();
154    
155            /**
156             * Reset the form by replacing the form object with a newly instantiated
157             * object of the type of the current form object. Note that this may lead to
158             * NPE's if the newly created object has null sub-objects and this form
159             * references any of these objects.
160             */
161            void reset();
162    
163            /**
164             * Does this form model buffer changes?
165             */
166            boolean isBuffered();
167    
168            /**
169             * Returns true if any of the value models holding properties of this form
170             * have been modified since the last call to either commit or revert or
171             * since the last change of the form backing object.
172             */
173            boolean isDirty();
174    
175            /**
176             * A form can be enabled/disabled which reflects a global state on the
177             * associated valueModels and their metaData. It may be viewed as enabling
178             * the visual representatives of the valuemodels. All user related
179             * interaction should be disabled. This is usually viewed as a grey-out of
180             * the visual form.
181             *
182             * Returns <code>true</code> if this form is enabled.
183             */
184            boolean isEnabled();
185    
186            /**
187             * A form can be set as readOnly which reflects a global state on the
188             * valueModels and their metaData. A form may be enabled and readonly when
189             * all values are accessible, but not changeable. A form can be seen as not
190             * readOnly if some visual representatives of the valuemodels are set to
191             * editable/changeable.
192             *
193             * @return <code>true</code> if this form is readOnly.
194             */
195            boolean isReadOnly();
196    
197            /**
198             * Returns true if the changes held by this form are able to be committed. A
199             * form is committable when it and it's child form models have no validation
200             * errors.
201             */
202            boolean isCommittable();
203    
204            /**
205             * Adds the specified listener to the list if listeners notified when a
206             * commit happens.
207             */
208            void addCommitListener(CommitListener listener);
209    
210            /**
211             * Removes the specified listener to the list if listeners notified when a
212             * commit happens.
213             */
214            void removeCommitListener(CommitListener listener);
215    
216            /**
217             * FIXME: this should be on the FieldMetadata class
218             */
219            FieldFace getFieldFace(String field);
220    }