    001// Licensed under the Apache License, Version 2.0 (the "License");
    002// you may not use this file except in compliance with the License.
    003// You may obtain a copy of the License at
    004//
    005// http://www.apache.org/licenses/LICENSE-2.0
    006//
    007// Unless required by applicable law or agreed to in writing, software
    008// distributed under the License is distributed on an "AS IS" BASIS,
    009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    010// See the License for the specific language governing permissions and
    011// limitations under the License.
    012
    013package org.apache.tapestry5.corelib.components;
    014
    015import org.apache.tapestry5.BindingConstants;
    016import org.apache.tapestry5.ComponentResources;
    017import org.apache.tapestry5.annotations.Parameter;
    018import org.apache.tapestry5.annotations.Property;
    019import org.apache.tapestry5.annotations.SupportsInformalParameters;
    020import org.apache.tapestry5.beaneditor.BeanModel;
    021import org.apache.tapestry5.beaneditor.PropertyModel;
    022import org.apache.tapestry5.internal.beaneditor.BeanModelUtils;
    023import org.apache.tapestry5.ioc.annotations.Inject;
    024import org.apache.tapestry5.services.BeanModelSource;
    025
    026/**
    027 * Used to display the properties of a bean, using an underlying {@link BeanModel}. The output definition list: a
    028 * &lt;dl&gt; element containing a series of &lt;dt&gt;/&lt;dd&gt; pairs. The property label is used as the &lt;dt&gt;
    029 * and the property value (formatted as per the datatype) is the &lt;dd&gt;. Only properties that have a known data type
    030 * are displayed.
    031 *
    032 * The property id is used as the class attribute of the &lt;dt&gt; and &lt;dd&gt; element, allowing CSS customization
    033 * per property. This does not occur when lean is bound to true.
    034 *
    035 * The outer &lt;dl&gt; element has the CSS class "t-beandisplay".
    036 *
    037 * @see org.apache.tapestry5.beaneditor.DataType
    038 * @see BeanModel
    039 * @tapestrydoc
    040 * @see BeanEditForm
    041 * @see Grid
    042 */
    043@SupportsInformalParameters
    044public class BeanDisplay
    045{
    046
    047    /**
    048     * The object to be rendered; if not explicitly bound, a default binding to a property whose name matches this
    049     * component's id will be used.
    050     */
    051    @Parameter(required = true, allowNull = false, autoconnect = true)
    052    @Property(write = false)
    053    private Object object;
    054
    055    /**
    056     * If true, then the CSS class attribute on the &lt;dt&gt; and &lt;dd&gt; elements will be ommitted.
    057     */
    058    @Parameter(value = "false")
    059    private boolean lean;
    060
    061    /**
    062     * The model that identifies the parameters to be edited, their order, and every other aspect. If not specified, a
    063     * default bean model will be created from the type of the object bound to the object parameter. The add, include,
    064     * exclude and reorder
    065     * parameters are <em>only</em> applied to a default model, not an explicitly provided one.
    066     */
    067    @Parameter
    068    private BeanModel model;
    069    /**
    070     * A comma-separated list of property names to be retained from the
    071     * {@link org.apache.tapestry5.beaneditor.BeanModel} (only used
    072     * when a default model is created automatically).
    073     * Only these properties will be retained, and the properties will also be reordered. The names are
    074     * case-insensitive.
    075     */
    076    @Parameter(defaultPrefix = BindingConstants.LITERAL)
    077    private String include;
    078
    079    /**
    080     * A comma-separated list of property names to be removed from the {@link org.apache.tapestry5.beaneditor.BeanModel}
    081     * (only used
    082     * when a default model is created automatically).
    083     * The names are case-insensitive.
    084     */
    085    @Parameter(defaultPrefix = BindingConstants.LITERAL)
    086    private String exclude;
    087
    088    /**
    089     * A comma-separated list of property names indicating the order in which the properties should be presented. The
    090     * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
    091     * orde. Only used
    092     * when a default model is created automatically.
    093     */
    094    @Parameter(defaultPrefix = BindingConstants.LITERAL)
    095    private String reorder;
    096
    097    /**
    098     * A comma-separated list of property names to be added to the {@link org.apache.tapestry5.beaneditor.BeanModel}
    099     * (only used
    100     * when a default model is created automatically).
    101     */
    102    @Parameter(defaultPrefix = BindingConstants.LITERAL)
    103    private String add;
    104
    105    /**
    106     * Where to search for local overrides of property display blocks as block parameters. Further, the container of the
    107     * overrides is used as the source for overridden validation messages. This is normally the component itself, but
    108     * when the component is used within a BeanEditForm, it will be the BeanEditForm's block parameter that will be
    109     * searched.
    110     */
    111    @Parameter(value = "componentResources")
    112    @Property(write = false)
    113    private ComponentResources overrides;
    114
    115    @Inject
    116    private ComponentResources resources;
    117
    118    @Inject
    119    private BeanModelSource modelSource;
    120
    121    @Property
    122    private String propertyName;
    123
    124    public BeanModel getModel()
    125    {
    126        if (model == null)
    127        {
    128            model = modelSource.createDisplayModel(object.getClass(), overrides.getContainerMessages());
    129
    130            BeanModelUtils.modify(model, add, include, exclude, reorder);
    131        }
    132        return model;
    133    }
    134
    135    /**
    136     * Returns the property model for the current property.
    137     */
    138    public PropertyModel getPropertyModel()
    139    {
    140        return getModel().get(propertyName);
    141    }
    142
    143    public String getPropertyClass()
    144    {
    145        return lean ? null : getPropertyModel().getId();
    146    }
    147}