001    // Copyright 2007, 2008, 2009, 2010, 2011 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.tapestry5.beaneditor;
016    
017    import org.apache.tapestry5.PropertyConduit;
018    
019    import java.util.List;
020    
021    /**
022     * Provides the information necessary to build a user interface to view, create or edit an instance of a particular
023     * type.
024     * <p/>
025     * BeanModels are not thread-safe, they are also not serializable.
026     * <p/>
027     * Here, and in {@link org.apache.tapestry5.beaneditor.PropertyModel}, the term "propertyName" is used for simplicitly.
028     * However, a full {@linkplain org.apache.tapestry5.services.PropertyConduitSource#create(Class, String) property
029     * expression} may be utilized when {@linkplain #add(String) adding new properties to an existing BeanModel}.
030     *
031     * @see org.apache.tapestry5.services.BeanModelSource
032     */
033    public interface BeanModel<T>
034    {
035        /**
036         * Returns the type of bean for which this model was initially created.
037         */
038        Class<T> getBeanType();
039    
040    
041        /**
042         * Creates a new bean instance.  This is based on {@link org.apache.tapestry5.ioc.ObjectLocator#autobuild(Class)},
043         * so a public constructor will be used, and dependencies injected.
044         *
045         * @return new instance of the bean
046         */
047        T newInstance();
048    
049        /**
050         * Returns a list of the editable properties of the bean, in <em>presentation</em> order.
051         */
052        List<String> getPropertyNames();
053    
054        /**
055         * Returns the named model.
056         *
057         * @param propertyName name of property to retrieve model for (case is ignored)
058         * @return the model for the property
059         * @throws RuntimeException if the bean editor model does not have a property model for the provided name
060         */
061        PropertyModel get(String propertyName);
062    
063        /**
064         * Returns the identified model.  Property ids are a stripped version of the property name. Case is ignored.
065         *
066         * @param propertyId matched caselessly against {@link org.apache.tapestry5.beaneditor.PropertyModel#getId()}
067         * @throws RuntimeException if the bean editor model does not have a property model with the indicated id
068         */
069        PropertyModel getById(String propertyId);
070    
071        /**
072         * Adds a new property to the model, returning its mutable model for further refinement. The property is added to
073         * the <em>end</em> of the list of properties. The property must be real (but may have been excluded if there was no
074         * {@linkplain org.apache.tapestry5.beaneditor.DataType datatype} associated with the property). To add a synthetic
075         * property, use {@link #add(String, org.apache.tapestry5.PropertyConduit)}
076         *
077         * @param propertyName name of property to add
078         * @return the new property model (for further configuration)
079         * @throws RuntimeException if the property already exists
080         */
081        PropertyModel add(String propertyName);
082    
083    
084        /**
085         * Adds a new synthetic property to the model, returning its mutable model for further refinement. The property is added to
086         * the <em>end</em> of the list of properties.
087         *
088         * @param propertyName name of property to add
089         * @param expression   expression for the property
090         * @return the new property model (for further configuration)
091         * @throws RuntimeException if the property already exists
092         * @since 5.3
093         */
094        PropertyModel addExpression(String propertyName, String expression);
095    
096        /**
097         * Adds an empty property (one with no property conduit).
098         *
099         * @param propertyName name of property to add
100         * @return the new property model (for further configuration)
101         * @throws RuntimeException if the property already exists
102         * @since 5.3
103         */
104        PropertyModel addEmpty(String propertyName);
105    
106        /**
107         * Adds a new property to the model (as with {@link #add(String)}), ordered before or after an existing property.
108         *
109         * @param position             controls whether the new property is ordered before or after the existing property
110         * @param existingPropertyName the name of an existing property (this must exist)
111         * @param propertyName         the new property to add
112         * @return the new property model (for further configuration)
113         * @throws RuntimeException if the existing property does not exist, or if the new property already does exist
114         */
115        PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName);
116    
117        /**
118         * Adds a new property to the model, ordered before or after an existing property.
119         *
120         * @param position             controls whether the new property is ordered before or after the existing property
121         * @param existingPropertyName the name of an existing property (this must exist)
122         * @param propertyName         the new property to add
123         * @param conduit              conduit used to read or update the property; this may be null for a synthetic or
124         *                             placeholder property
125         * @return the new property model (for further configuration)
126         * @throws RuntimeException if the existing property does not exist, or if the new property already does exist
127         */
128        PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName,
129                          PropertyConduit conduit);
130    
131        /**
132         * Adds a new, synthetic property to the model, returning its mutable model for further refinement.
133         *
134         * @param propertyName name of property to add
135         * @param conduit      the conduit used to read or update the property; this may be null for a synthetic or
136         *                     placeholder property.  Instead of passing null, please invoke {@link #addEmpty(String)}.
137         * @return the model for the property
138         * @throws RuntimeException if the property already exists
139         * @see #addExpression(String, String)
140         */
141        PropertyModel add(String propertyName, PropertyConduit conduit);
142    
143        /**
144         * Removes the named properties from the model, if present. It is not considered an error to remove a property that
145         * does not exist.
146         *
147         * @param propertyNames the names of properties to be removed (case insensitive)
148         * @return the model for further modifications
149         */
150        BeanModel<T> exclude(String... propertyNames);
151    
152        /**
153         * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are
154         * retained, but ordered to the end of the list.
155         *
156         * @param propertyNames property names in order they should be displayed (case insensitive)
157         * @return the model for further modifications
158         */
159        BeanModel<T> reorder(String... propertyNames);
160    
161        /**
162         * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are
163         * <<removed>>.
164         *
165         * @param propertyNames the names of properties to be retained
166         * @return the model for further modifications
167         */
168        BeanModel<T> include(String... propertyNames);
169    }