001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kns.datadictionary;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.bo.BusinessObject;
020import org.kuali.rice.krad.datadictionary.DataDictionary;
021import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
022import org.kuali.rice.krad.valuefinder.ValueFinder;
023
024import java.util.List;
025
026/**
027 * The maintainableField element defines the specifications for one data field.
028 * JSTL: maintainableField is a Map accessed by the field name.
029 * It contains entries with the following keys:
030 *      * field (boolean String)
031 *      * name (String)
032 *      * required (boolean String)
033 *
034 * name is the name of the field
035 * required is true if the field must contain a non-null value
036 * readOnly is true if it cannot be updated
037 * template documentation from MaintenanceUtils.java:
038 *      Field templates are used in relation to multiple value lookups.  When doing a MV lookup on a collection, the
039 *      returned BOs are not necessarily of the same type as the elements of the collection. Therefore, a means of
040 *      mapping between the fields for the 2 BOs are necessary. The template attribute of <maintainableField> contained
041 *      within <maintainableCollection> tells us this mapping.
042 *      Example:
043 *          <maintainableField name="collectionAttrib" template="lookupBOAttrib"> means that when a list of BOs are
044 *          returned, the lookupBOAttrib value of the looked up BO will be placed into the collectionAttrib value of the
045 *          BO added to the collection
046 * webUILeaveFieldFunction - The name of a javascript function to called when when the user tabs out of the field.
047 * webUILeaveFieldCallbackFunction - This is the call javascript function related to the webUILeaveFieldFunction.
048 * readOnlyAfterAdd - This is used to indicate that the field is read-only after the record has been initially created.
049 *
050 * @deprecated Use {@link org.kuali.rice.krad.uif.field.Field} subclasses.
051 */
052@Deprecated
053public class MaintainableFieldDefinition extends MaintainableItemDefinition implements FieldDefinitionI{
054    private static final long serialVersionUID = -1176087424343479963L;
055    
056        protected boolean required = false;
057    protected boolean unconditionallyReadOnly = false;
058    protected boolean readOnlyAfterAdd = false;
059    protected boolean noLookup = false;
060    protected boolean lookupReadOnly = false;
061    
062    protected String defaultValue;
063    protected String template;
064    protected Class<? extends ValueFinder> defaultValueFinderClass;
065
066    protected String webUILeaveFieldFunction = "";
067    protected String webUILeaveFieldCallbackFunction = "";
068    protected List<String> webUILeaveFieldFunctionParameters;
069
070    protected Class<? extends BusinessObject> overrideLookupClass;
071    protected String overrideFieldConversions;
072    
073    protected String alternateDisplayAttributeName;
074    protected String additionalDisplayAttributeName;
075    
076    protected boolean triggerOnChange;
077    
078    protected Boolean showFieldLevelHelp = null; // use default from system
079    protected String fieldLevelHelpUrl = null;
080    
081    public MaintainableFieldDefinition() {}
082
083    /**
084     * @return true if this attribute is required
085     */
086    public boolean isRequired() {
087        return required;
088    }
089
090    /**
091required is true if the field must contain a non-null value
092     */
093    public void setRequired(boolean required) {
094        this.required = required;
095    }
096
097    /**
098     * @return Returns the defaultValue.
099     */
100    public String getDefaultValue() {
101        return defaultValue;
102    }
103
104
105    /**
106     * 
107                       The defaultValue element will pre-load the specified value
108                       into the lookup field.
109     */
110    public void setDefaultValue(String defaultValue) {
111        this.defaultValue = defaultValue;
112    }
113
114
115    /**
116     * @return custom defaultValue class
117     */
118    public Class<? extends ValueFinder> getDefaultValueFinderClass() {
119        return defaultValueFinderClass;
120    }
121
122    /**
123         * @return the unconditionallyReadOnly
124         */
125        public boolean isUnconditionallyReadOnly() {
126                return this.unconditionallyReadOnly;
127        }
128
129        /**
130         * @param unconditionallyReadOnly the unconditionallyReadOnly to set
131         */
132        public void setUnconditionallyReadOnly(boolean unconditionallyReadOnly) {
133                this.unconditionallyReadOnly = unconditionallyReadOnly;
134        }
135
136    /**
137     * Gets the overrideFieldConversions attribute. 
138     * @return Returns the overrideFieldConversions.
139     */
140    public String getOverrideFieldConversions() {
141        return overrideFieldConversions;
142    }
143
144
145    /**
146     * Single value lookups expect field conversions to be passed in as a HTTP parameter when the lookups is invoked from a quickfinder icon (i.e. magnifying glass on page).
147                        Field conversions are normally used to determine which fields will be returned when the "return value" link is clicked.
148
149                        For example, if we're performing a quickfinder lookup and the field conversion string "a:document.someObject.a1,b:document.someObject.b1" is passed into the lookup,
150                        this means that when we click on a lookup result row to be returned:
151
152                        * the value of property "a" from the selected result bo will be passed as the value of the HTTP parameter named "document.someObject.a1",
153                          which, in turn, populates the POJO property of the same name on the form
154                        * the value of property "b" from the selected result bo will be passed as the value of the HTTP parameter named "document.someObject.b1",
155                          which, in turn, populates the POJO property of the same name on the form
156
157                        Normally, the field conversion string is automatically computed by the framework to return all of the primary key values of the looked up BO into the corresponding
158                        foreign key values of the destination BO (i.e. document.someObject in the example above).  However, putting in this element will allow for the overriding of the
159                        field conversions string.
160     */
161    public void setOverrideFieldConversions(String overrideFieldConversions) {
162        this.overrideFieldConversions = overrideFieldConversions;
163    }
164
165
166    /**
167     * Gets the overrideLookupClass attribute. 
168     * @return Returns the overrideLookupClass.
169     */
170    public Class<? extends BusinessObject> getOverrideLookupClass() {
171        return overrideLookupClass;
172    }
173
174
175
176
177    /**
178     * Directly validate simple fields.
179     * 
180     * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
181     */
182    public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
183        if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getName())) {
184            throw new AttributeValidationException("unable to find attribute or collection named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
185        }
186
187        if (StringUtils.isNotBlank(getAlternateDisplayAttributeName())) {
188            if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAlternateDisplayAttributeName())) {
189                throw new AttributeValidationException("unable to find attribute or collection named '" + getAlternateDisplayAttributeName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
190            }
191        }
192        
193        if (StringUtils.isNotBlank(getAdditionalDisplayAttributeName())) {
194            if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAdditionalDisplayAttributeName())) {
195                throw new AttributeValidationException("unable to find attribute or collection named '" + getAdditionalDisplayAttributeName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
196            }
197        }
198
199        if (defaultValueFinderClass != null && defaultValue != null) {
200            throw new AttributeValidationException("Both defaultValue and defaultValueFinderClass can not be specified on attribute " + getName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
201        }
202   }
203
204    /**
205     * @see java.lang.Object#toString()
206     */
207    public String toString() {
208        return "MaintainableFieldDefinition for field " + getName();
209    }
210
211
212    public String getTemplate() {
213        return template;
214    }
215
216
217    /**
218template documentation from MaintenanceUtils.java:
219                            Field templates are used in relation to multiple value lookups.
220                            When doing a MV lookup on a collection, the returned BOs
221                            are not necessarily of the same type as the elements of the
222                            collection. Therefore, a means of mapping between the fields
223                            for the 2 BOs are necessary. The template attribute of
224                            <maintainableField> contained within <maintainableCollection>
225                            tells us this mapping.
226                            Example:
227                            <maintainableField name="collectionAttrib" template="lookupBOAttrib">
228                            means that when a list of BOs are returned, the lookupBOAttrib value
229                            of the looked up BO will be placed into the collectionAttrib
230                            value of the BO added to the collection
231 */
232    public void setTemplate(String template) {
233        this.template = template;
234    }
235
236
237    public String getWebUILeaveFieldCallbackFunction() {
238        return webUILeaveFieldCallbackFunction;
239    }
240
241
242    /**
243                        * webUILeaveFieldCallbackFunction
244                            This is the call javascript function related to the webUILeaveFieldFunction.
245     */
246    public void setWebUILeaveFieldCallbackFunction(String webUILeaveFieldCallbackFunction) {
247        this.webUILeaveFieldCallbackFunction = webUILeaveFieldCallbackFunction;
248    }
249
250
251    public String getWebUILeaveFieldFunction() {
252        return webUILeaveFieldFunction;
253    }
254
255
256    /**
257                        * webUILeaveFieldFunction is the name of a javascript function to called when
258                            when the user tabs out of the field.
259     */
260    public void setWebUILeaveFieldFunction(String webUILeaveFieldFunction) {
261        this.webUILeaveFieldFunction = webUILeaveFieldFunction;
262    }
263
264
265    public boolean isReadOnlyAfterAdd() {
266        return readOnlyAfterAdd;
267    }
268
269
270    /**
271     * This is used to indicate that the field is read-only after the record has been
272                            initially created.
273     */
274    public void setReadOnlyAfterAdd(boolean readOnlyAfterAdd) {
275        this.readOnlyAfterAdd = readOnlyAfterAdd;
276    }
277
278
279    /**
280The defaultValueFinderClass specifies the java class that will be
281                      used to determine the default value of a lookup field.  The classname
282                      specified in this field must implement ValueFinder
283   */
284    public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
285        this.defaultValueFinderClass = defaultValueFinderClass;
286    }
287
288
289    /**
290     * The overrideLookupClass element is used to indicate the
291                        class that should be used for the magnifying glass lookup.
292                        The specified class must be a subclass of the business object
293                        class.
294     */
295    public void setOverrideLookupClass(Class<? extends BusinessObject> overrideLookupClass) {
296        this.overrideLookupClass = overrideLookupClass;
297    }
298    
299        /**
300         * @return the noLookup
301         */
302        public boolean isNoLookup() {
303                return this.noLookup;
304        }
305
306        /**
307         * @param noLookup the noLookup to set
308         */
309        public void setNoLookup(boolean noLookup) {
310                this.noLookup = noLookup;
311        }
312        
313        public boolean isLookupReadOnly() {
314                return lookupReadOnly;
315        }
316    
317        public void setLookupReadOnly(boolean lookupReadOnly) {
318        this.lookupReadOnly = lookupReadOnly;
319    }
320        
321    public Boolean isShowFieldLevelHelp() {
322        return showFieldLevelHelp;
323    }
324
325    public void setShowFieldLevelHelp(Boolean showFieldLevelHelp) {
326        this.showFieldLevelHelp = showFieldLevelHelp;
327    }
328
329    public String getFieldLevelHelpUrl() {
330        return fieldLevelHelpUrl;
331    }
332
333    public void setFieldLevelHelpUrl(String fieldLevelHelpUrl) {
334        this.fieldLevelHelpUrl = fieldLevelHelpUrl;
335    }
336        
337        /**
338         * The alternateDisplayAttributeName is the name of the attribute whose value will be displayed instead
339         * of the actual maintenance field attribute. Only applies when field is read-only.
340         */
341    public String getAlternateDisplayAttributeName() {
342                return this.alternateDisplayAttributeName;
343        }
344
345        public void setAlternateDisplayAttributeName(String alternateDisplayAttributeName) {
346                this.alternateDisplayAttributeName = alternateDisplayAttributeName;
347        }
348
349        /**
350         * The additionalDisplayAttributeName is the name of the attribute whose value will be displayed in addition
351         * to the actual maintenance field attribute. Only applies when field is read-only.
352         */
353        public String getAdditionalDisplayAttributeName() {
354                return this.additionalDisplayAttributeName;
355        }
356
357        public void setAdditionalDisplayAttributeName(String additionalDisplayAttributeName) {
358                this.additionalDisplayAttributeName = additionalDisplayAttributeName;
359        }
360        
361        public boolean isTriggerOnChange() {
362                return this.triggerOnChange;
363        }
364
365        public void setTriggerOnChange(boolean triggerOnChange) {
366                this.triggerOnChange = triggerOnChange;
367        }
368
369        /**
370         * @return the webUILeaveFieldFunctionParameters
371         */
372        public List<String> getWebUILeaveFieldFunctionParameters() {
373                return this.webUILeaveFieldFunctionParameters;
374        }
375
376        /**
377         * @param webUILeaveFieldFunctionParameters the webUILeaveFieldFunctionParameters to set
378         */
379        public void setWebUILeaveFieldFunctionParameters(
380                        List<String> webUILeaveFieldFunctionParameters) {
381                this.webUILeaveFieldFunctionParameters = webUILeaveFieldFunctionParameters;
382        }
383
384}