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     * <dl> element containing a series of <dt>/<dd> pairs. The property label is used as the <dt>
031     * and the property value (formatted as per the datatype) is the <dd>. 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        @Property(write = false)
071        private BeanModel model;
072        /**
073         * A comma-separated list of property names to be retained from the
074         * {@link org.apache.tapestry5.beaneditor.BeanModel} (only used
075         * when a default model is created automatically).
076         * Only these properties will be retained, and the properties will also be reordered. The names are
077         * case-insensitive.
078         */
079        @Parameter(defaultPrefix = BindingConstants.LITERAL)
080        private String include;
081    
082        /**
083         * A comma-separated list of property names to be removed from the {@link org.apache.tapestry5.beaneditor.BeanModel}
084         * (only used
085         * when a default model is created automatically).
086         * The names are case-insensitive.
087         */
088        @Parameter(defaultPrefix = BindingConstants.LITERAL)
089        private String exclude;
090    
091        /**
092         * A comma-separated list of property names indicating the order in which the properties should be presented. The
093         * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
094         * orde. Only used
095         * when a default model is created automatically.
096         */
097        @Parameter(defaultPrefix = BindingConstants.LITERAL)
098        private String reorder;
099    
100        /**
101         * A comma-separated list of property names to be added to the {@link org.apache.tapestry5.beaneditor.BeanModel}
102         * (only used
103         * when a default model is created automatically).
104         */
105        @Parameter(defaultPrefix = BindingConstants.LITERAL)
106        private String add;
107    
108        /**
109         * Where to search for local overrides of property display blocks as block parameters. Further, the container of the
110         * overrides is used as the source for overridden validation messages. This is normally the component itself, but
111         * when the component is used within a BeanEditForm, it will be the BeanEditForm's block parameter that will be
112         * searched.
113         */
114        @Parameter(value = "componentResources")
115        @Property(write = false)
116        private ComponentResources overrides;
117    
118        @Inject
119        private ComponentResources resources;
120    
121        @Inject
122        private BeanModelSource modelSource;
123    
124        @Property
125        private String propertyName;
126    
127        void setupRender()
128        {
129            if (model == null)
130            {
131                model = modelSource.createDisplayModel(object.getClass(), overrides.getContainerMessages());
132    
133                BeanModelUtils.modify(model, add, include, exclude, reorder);
134            }
135        }
136    
137        /**
138         * Returns the property model for the current property.
139         */
140        public PropertyModel getPropertyModel()
141        {
142            return model.get(propertyName);
143        }
144    
145        public String getPropertyClass()
146        {
147            return lean ? null : getPropertyModel().getId();
148        }
149    }