View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.dynaForm.metadata;
20  
21  import org.apache.myfaces.orchestra.dynaForm.lib.SelectionSourceEnum;
22  
23  import javax.faces.component.UIComponent;
24  import javax.faces.convert.Converter;
25  import javax.persistence.TemporalType;
26  
27  /**
28   * Read-only representation of meta-data about a single property of an entity.
29   * <p>
30   * This is similar to java.beans.PropertyDescriptor, but customised for the
31   * needs of the DynaForm component.
32   * <p>
33   * An instance of this type is generally configured via one or more implementations
34   * of the Extractor interface. For example an Extractor could introspect java beans,
35   * or introspect a database report definition, or scan the current page template for
36   * configuration for the named field. Any settings found are then used to create
37   * MetaField definitions for fields, or when multiple Extractors are configured
38   * then later ones can override settings from earlier extractors.
39   * <p>
40   * Note that it is very important that all Extractor implementations properly set
41   * the canRead/canWrite properties on MetaFields. These values default to null
42   * (ie false), so if they are not correctly set then UI components can behave
43   * oddly (eg be readonly when not expected).
44   */
45  public interface MetaField
46  {
47      /**
48       * The "name" of this field.
49       * <p>
50       * The name property can contain dots, eg "foo.bar.lastname".
51       */
52      public String getName();
53  
54      /**
55       * Returns the part of the "name" property following the last dot.
56       * If "name" has no dots, then this returns name.
57       */
58      public String getBaseName();
59  
60      /**
61       * The type of the property that this Field instance represents.
62       */
63      public Class<?> getType();
64  
65      /**
66       * Returns true if the type of this field is a persistent class.
67       * <p>
68       * This should be set if the type of this field is some kind of class
69       * (ie not a primitive) and that class has the @Entity annotation on it.
70       */
71      public boolean isEntityType();
72  
73      /**
74       * Returns true when this field belongs to a persistent entity and this field
75       * is part of the entity key. In this situation, the field is automatically
76       * marked as "readonly" because key fields of persistent entities cannot
77       * be edited.
78       */
79      public boolean isId();
80  
81      /**
82       * Specify whether this field should be regarded as "disabled for user input".
83       * <p>
84       * There is logically no difference between "disabled" and "display only", so it is
85       * strongly recommended that extractors set the displayOnly property and ignore this
86       * one (ie leave disabled as effectively "false"), and that UI frameworks always use
87       * displayOnly and ignore this property.
88       * <p>
89       * In HTML there is a difference between a "disabled" and a "readonly" input field.
90       * However as an HTML post does not include data from "disabled" fields, and the JSF
91       * 1.2 framework (at least) really screws up when expected fields are not present,
92       * "disabled" HTML inputs should not be used in JSF.
93       */
94      public boolean getDisabled();
95  
96  
97      /**
98       * Indicates whether the model object has a getter method for this property.
99       * When no, then obviously this property cannot be displayed to the user
100      * <p>
101      * It is expected that one or both of getCanRead/getCanWrite is defined; if
102      * both are false then the property doesn't exist!
103      * <p>
104      * Normally, this would be true; write-only properties are not common. However
105      * they are technically possible. Handling these may be difficult/impossible in
106      * some presentation frameworks though; for example JSF value bindings simply
107      * don't work with write-only fields.
108      */
109     public boolean getCanRead();
110 
111     /**
112      * Indicates whether the model object has a setter method for this property.
113      * When no, then obviously this property is effectively read-only, as no
114      * user changes can be stored.
115      * <p>
116      * It is expected that one or both of getCanRead/getCanWrite is defined; if
117      * both are false then the property doesn't exist!
118      */
119     public boolean getCanWrite();
120 
121     /**
122      * Indicates whether the user should be allowed to edit this field.
123      * This is equivalent to "getReadOnly".
124      * <p>
125      * Note that when getCanWrite is false, then this should be true. However
126      * even when there is a property setter (getCanWrite is true), a property
127      * may be configured as display-only for the user.
128      */
129     public boolean getDisplayOnly();
130 
131     /**
132      * Returns true if this field must have a value defined before the
133      * object is "valid".
134      */
135     public boolean getRequired();
136 
137     // TODO: document me
138     public Selection[] getAllowedSelections();
139 
140     /**
141      * Indicates whether this property is a <i>relation</i> to some other object.
142      * <p>
143      * For primitive fields, this returns NONE.
144      * <p>
145      * Obviously, fields that are relations need special handling in the user interface;
146      * it is generally not a good idea to just display their raw value and allow the
147      * user to enter any other raw value they like.
148      */
149     public RelationType getRelationType();
150 
151     /**
152      * In case of hierarchical structures this defines if a child class should be treatened
153      * as "embedded".
154      * <ul>
155      * <li>Embedded: like a composite key in hibernate</li>
156      * <li>Not Embedded: like a relation to another entity (ManyToOne)</li>
157      * </ul>
158      * This is not a metadata for the field itself, but for the context in which this field
159      * (or its entity) will be used
160      */
161     public boolean isEmbedded();
162 
163     /**
164      *  For text fields, this limits the number of characters that can be entered.
165      *  <p>
166      *  Question: does this limit #chars for numeric and date fields too?
167      */
168     public Integer getMaxSize();
169 
170     /**
171      * For numeric fields, this specifies the maximum value permitted for this field.
172      * Returns null for non-numeric fields.
173      */
174     public Double getMaxValue();
175 
176     // Used only for text fields. Limits the number of characters.
177     // must be less than maxSize.
178     public Integer getMinSize();
179 
180     /**
181      * Specifies how much space should the input/output component take up on the screen. If
182      * this is less than maxSize then the field will usually allow scrolling internally.
183      */
184     public Integer getDisplaySize();
185 
186     /**
187      * For numeric fields, this specifies the minimum value permitted for this field.
188      * Returns null for non-numeric fields.
189      */
190     public Double getMinValue();
191 
192     // Explicitly allow control over what JSF component is created to
193     // represent this field.
194     //
195     // TODO: possibly remove this field, and just rely on the componentHandler
196     // functionality instead.
197     public UIComponent getWantedComponent();
198 
199     // TODO: possibly remove this field and just rely on the componentHandler
200     // functionality instead.
201     public FieldRepresentation getWantedComponentType();
202 
203     public TemporalType getTemporalType();
204 
205     public boolean getAllowMultipleSelections();
206 
207     public SelectionSourceEnum getSelectionSource();
208 
209     public String getDataSource();
210 
211     public String getDataSourceDescription();
212 
213     public String getDataComparator();
214 
215     public String getConverterId();
216 
217     // TODO: remove this method, it is jsf-specific
218     public Class<? extends Converter> getConverterClass();
219 
220     public String getConverterBean();
221 
222     /**
223      * Get the custom "renderer" (if any) for this field.
224      * <p>
225      * This method may return:
226      * <ul>
227      * <li>Null when there is no special component-handler.</li>
228      * <li>A String which is the name of a managed-bean that implements an appropriate renderer class</li>
229      * <li>An instance of an appropriate renderer class</li>
230      * <li>A ValueBinding object whose getValue method returns an instance of an appropriate renderer class</li>
231      * </ul>
232      * <p>
233      * When a MetaField is populated by introspecting a java bean, this value could be set by
234      * an annotations on a bean properties. It could also be set via configuration components
235      * in the current page template, or 
236      * <p>
237      * The "appropriate renderer class" depends upon the "gui builder" implementation being used.
238      * When the presentation layer is JSF (ie the "gui builder" is "dynaform.jsf.GuiBuilder") then
239      * the "appropriate renderer class" must be a subclass of the "dynaform.jsf.DynaFormComponentHandler"
240      * class.
241      */
242     public Object getComponentHandler();
243 
244     public Object getAttribute(String name);
245 }