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