Coverage Report - org.kuali.rice.krad.uif.field.AttributeField
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeField
0%
0/190
0%
0/90
1.754
 
 1  
 /*
 2  
  * Copyright 2007 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl1.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krad.uif.field;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.api.util.ConcreteKeyValue;
 20  
 import org.kuali.rice.core.api.util.KeyValue;
 21  
 import org.kuali.rice.core.web.format.Formatter;
 22  
 import org.kuali.rice.krad.bo.DataObjectRelationship;
 23  
 import org.kuali.rice.krad.bo.KualiCode;
 24  
 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
 25  
 import org.kuali.rice.krad.datadictionary.AttributeSecurity;
 26  
 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
 27  
 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
 28  
 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
 29  
 import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
 30  
 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
 31  
 import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
 32  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 33  
 import org.kuali.rice.krad.uif.UifConstants;
 34  
 import org.kuali.rice.krad.uif.control.MultiValueControl;
 35  
 import org.kuali.rice.krad.uif.control.UifKeyValuesFinder;
 36  
 import org.kuali.rice.krad.uif.view.FormView;
 37  
 import org.kuali.rice.krad.uif.view.View;
 38  
 import org.kuali.rice.krad.uif.control.Control;
 39  
 import org.kuali.rice.krad.uif.control.MultiValueControlBase;
 40  
 import org.kuali.rice.krad.uif.component.BindingInfo;
 41  
 import org.kuali.rice.krad.uif.component.Component;
 42  
 import org.kuali.rice.krad.uif.component.DataBinding;
 43  
 import org.kuali.rice.krad.uif.util.ClientValidationUtils;
 44  
 import org.kuali.rice.krad.uif.util.ComponentUtils;
 45  
 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
 46  
 import org.kuali.rice.krad.uif.util.ViewModelUtils;
 47  
 import org.kuali.rice.krad.uif.view.ViewModel;
 48  
 import org.kuali.rice.krad.uif.widget.DirectInquiry;
 49  
 import org.kuali.rice.krad.uif.widget.Inquiry;
 50  
 import org.kuali.rice.krad.uif.widget.QuickFinder;
 51  
 import org.kuali.rice.krad.uif.widget.Suggest;
 52  
 import org.kuali.rice.krad.util.KRADPropertyConstants;
 53  
 import org.kuali.rice.krad.util.ObjectUtils;
 54  
 import org.kuali.rice.krad.valuefinder.ValueFinder;
 55  
 
 56  
 import java.util.ArrayList;
 57  
 import java.util.List;
 58  
 
 59  
 /**
 60  
  * Field that encapsulates data input/output captured by an attribute within the
 61  
  * application
 62  
  *
 63  
  * <p>                                                                                                                                    R
 64  
  * The <code>AttributField</code> provides the majority of the data input/output
 65  
  * for the screen. Through these fields the model can be displayed and updated.
 66  
  * For data input, the field contains a <code>Control</code> instance will
 67  
  * render an HTML control element(s). The attribute field also contains a
 68  
  * <code>LabelField</code>, summary, and widgets such as a quickfinder (for
 69  
  * looking up values) and inquiry (for getting more information on the value).
 70  
  * <code>AttributeField</code> instances can have associated messages (errors)
 71  
  * due to invalid input or business rule failures. Security can also be
 72  
  * configured to restrict who may view the fields value.
 73  
  * </p>
 74  
  *
 75  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 76  
  */
 77  
 public class AttributeField extends DataField implements DataBinding {
 78  
     private static final long serialVersionUID = -3703656713706343840L;
 79  
 
 80  
     // value props
 81  
     private String defaultValue;
 82  
     private Class<? extends ValueFinder> defaultValueFinderClass;
 83  
 
 84  
     // constraint variables
 85  
     private String customValidatorClass;
 86  
     private ValidCharactersConstraint validCharactersConstraint;
 87  
     private CaseConstraint caseConstraint;
 88  
     private List<PrerequisiteConstraint> dependencyConstraints;
 89  
     private List<MustOccurConstraint> mustOccurConstraints;
 90  
     private SimpleConstraint simpleConstraint;
 91  
 
 92  
     // display props
 93  
     private Control control;
 94  
     private KeyValuesFinder optionsFinder;
 95  
     private boolean performUppercase;
 96  
 
 97  
     private String errorMessagePlacement;
 98  
     private ErrorsField errorsField;
 99  
 
 100  
     // messages
 101  
     private String constraintText;
 102  
     private String instructionalText;
 103  
 
 104  
     private MessageField instructionalMessageField;
 105  
     private MessageField constraintMessageField;
 106  
 
 107  
     private AttributeQuery fieldAttributeQuery;
 108  
 
 109  
     // widgets
 110  
     private QuickFinder fieldLookup;
 111  
     private DirectInquiry fieldDirectInquiry;
 112  
     private Suggest fieldSuggest;
 113  
 
 114  
     public AttributeField() {
 115  0
         super();
 116  
 
 117  0
         simpleConstraint = new SimpleConstraint();
 118  0
     }
 119  
 
 120  
     /**
 121  
      * The following actions are performed:
 122  
      *
 123  
      * <ul>
 124  
      * <li>Set the ids for the various attribute components</li>
 125  
      * <li>Sets up the client side validation for constraints on this field. In
 126  
      * addition, it sets up the messages applied to this field</li>
 127  
      * </ul>
 128  
      *
 129  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
 130  
      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
 131  
      */
 132  
     @Override
 133  
     public void performFinalize(View view, Object model, Component parent) {
 134  0
         super.performFinalize(view, model, parent);
 135  
 
 136  0
         setupIds();
 137  
 
 138  
         // invoke options finder if options not configured on the control
 139  0
         List<KeyValue> fieldOptions = new ArrayList<KeyValue>();
 140  
 
 141  
         // use options directly configured on the control first
 142  0
         if ((control != null) && control instanceof MultiValueControlBase) {
 143  0
             MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
 144  0
             if ((multiValueControl.getOptions() != null) && !multiValueControl.getOptions().isEmpty()) {
 145  0
                 fieldOptions = multiValueControl.getOptions();
 146  
             }
 147  
         }
 148  
 
 149  
         // if options not configured on the control, invoke configured options finder
 150  0
         if (fieldOptions.isEmpty() && (optionsFinder != null)) {
 151  0
             if (optionsFinder instanceof UifKeyValuesFinder) {
 152  0
                 fieldOptions = ((UifKeyValuesFinder) optionsFinder).getKeyValues((ViewModel) model);
 153  
 
 154  
                 // check if blank option should be added
 155  0
                 if (((UifKeyValuesFinder) optionsFinder).isAddBlankOption()) {
 156  0
                     fieldOptions.add(0, new ConcreteKeyValue("", ""));
 157  
                 }
 158  
             } else {
 159  0
                 fieldOptions = optionsFinder.getKeyValues();
 160  
             }
 161  
 
 162  0
             if ((control != null) && control instanceof MultiValueControlBase) {
 163  0
                ((MultiValueControlBase) control).setOptions(fieldOptions);
 164  
             }
 165  
         }
 166  
 
 167  
         // if read only do key/value translation if necessary (if alternative and additional properties not set)
 168  0
         if (isReadOnly()
 169  
                 && !fieldOptions.isEmpty()
 170  
                 && StringUtils.isBlank(getAlternateDisplayValue())
 171  
                 && StringUtils.isBlank(getAdditionalDisplayValue())
 172  
                 && StringUtils.isBlank(getAlternateDisplayPropertyName())
 173  
                 && StringUtils.isBlank(getAdditionalDisplayPropertyName())) {
 174  
 
 175  0
             Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
 176  0
             for (KeyValue keyValue : fieldOptions) {
 177  0
                 if (StringUtils.equals((String) fieldValue, keyValue.getKey())) {
 178  0
                     setAlternateDisplayValue(keyValue.getValue());
 179  0
                     break;
 180  
                 }
 181  
             }
 182  
         }
 183  
 
 184  
         // if read only or the control is null no input can be given so no need to setup validation
 185  0
         if (isReadOnly() || getControl() == null) {
 186  0
             return;
 187  
         }
 188  
 
 189  
         // Sets message
 190  0
         if (StringUtils.isNotBlank(instructionalText)) {
 191  0
             instructionalMessageField.setMessageText(instructionalText);
 192  
         }
 193  
 
 194  
         // Sets constraints
 195  0
         if (StringUtils.isNotBlank(constraintText)) {
 196  0
             constraintMessageField.setMessageText(constraintText);
 197  
         }
 198  
 
 199  
         // adjust paths on PrerequisiteConstraint property names
 200  0
         adjustPrerequisiteConstraintBinding(dependencyConstraints);
 201  
 
 202  
         // adjust paths on MustOccurConstraints property names
 203  0
         adjustMustOccurConstraintBinding(mustOccurConstraints);
 204  
 
 205  
         // adjust paths on CaseConstraint property names
 206  0
         if (caseConstraint != null) {
 207  0
             String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(caseConstraint.getPropertyName());
 208  0
             caseConstraint.setPropertyName(propertyName);
 209  
         }        
 210  
 
 211  0
         setupFieldQuery();
 212  
 
 213  0
         if (view instanceof FormView && ((FormView) view).isValidateClientSide()) {
 214  0
             ClientValidationUtils.processAndApplyConstraints(this, view);
 215  
         }
 216  0
     }
 217  
 
 218  
     protected void adjustMustOccurConstraintBinding(List<MustOccurConstraint> mustOccurConstraints) {
 219  0
         if (mustOccurConstraints != null) {
 220  0
             for (MustOccurConstraint mustOccurConstraint : mustOccurConstraints) {
 221  0
                 adjustPrerequisiteConstraintBinding(mustOccurConstraint.getPrerequisiteConstraints());
 222  0
                 adjustMustOccurConstraintBinding(mustOccurConstraint.getMustOccurConstraints());
 223  
             }
 224  
         }
 225  0
     }
 226  
 
 227  
     protected void adjustPrerequisiteConstraintBinding(List<PrerequisiteConstraint> prerequisiteConstraints) {
 228  0
         if (prerequisiteConstraints != null) {
 229  0
             for (PrerequisiteConstraint prerequisiteConstraint : prerequisiteConstraints) {
 230  0
                 String propertyName = getBindingInfo().getPropertyAdjustedBindingPath(prerequisiteConstraint.getPropertyName());
 231  0
                 prerequisiteConstraint.setPropertyName(propertyName);
 232  0
             }
 233  
         }
 234  0
     }
 235  
 
 236  
     /**
 237  
      * Performs setup of the field attribute query and informational display properties. Paths
 238  
      * are adjusted to match the binding for the this field, and the necessary onblur script for
 239  
      * triggering the query client side is constructed
 240  
      */
 241  
     protected void setupFieldQuery() {
 242  0
         if (getFieldAttributeQuery() != null) {
 243  
             // adjust paths on query mappings
 244  0
             getFieldAttributeQuery().updateQueryFieldMapping(getBindingInfo());
 245  0
             getFieldAttributeQuery().updateReturnFieldMapping(getBindingInfo());
 246  0
             getFieldAttributeQuery().updateQueryMethodArgumentFieldList(getBindingInfo());
 247  
 
 248  
             // build onblur script for field query
 249  0
             String script = "executeFieldQuery('" + getControl().getId() + "',";
 250  0
             script += "'" + getId() + "'," + getFieldAttributeQuery().getQueryFieldMappingJsString() + ",";
 251  0
             script += getFieldAttributeQuery().getQueryMethodArgumentFieldsJsString() + ",";
 252  0
             script += getFieldAttributeQuery().getReturnFieldMappingJsString() + ");";
 253  
 
 254  0
             if (StringUtils.isNotBlank(getControl().getOnBlurScript())) {
 255  0
                 script = getControl().getOnBlurScript() + script;
 256  
             }
 257  0
             getControl().setOnBlurScript(script);
 258  
         }
 259  0
     }
 260  
 
 261  
     /**
 262  
      * Sets the ids on all components the attribute field uses so they will all
 263  
      * contain this attribute's id in their ids. This is useful for jQuery
 264  
      * manipulation.
 265  
      */
 266  
     protected void setupIds() {
 267  
         // update ids so they all match the attribute
 268  0
         if (getControl() != null) {
 269  0
             getControl().setId(getId());
 270  
         }
 271  
 
 272  0
         setNestedComponentIdAndSuffix(getErrorsField(), UifConstants.IdSuffixes.ERRORS);
 273  0
         setNestedComponentIdAndSuffix(getLabelField(), UifConstants.IdSuffixes.LABEL);
 274  0
         setNestedComponentIdAndSuffix(getInstructionalMessageField(), UifConstants.IdSuffixes.INSTRUCTIONAL);
 275  0
         setNestedComponentIdAndSuffix(getConstraintMessageField(), UifConstants.IdSuffixes.CONSTRAINT);
 276  0
         setNestedComponentIdAndSuffix(getFieldLookup(), UifConstants.IdSuffixes.QUICK_FINDER);
 277  0
         setNestedComponentIdAndSuffix(getFieldDirectInquiry(), UifConstants.IdSuffixes.DIRECT_INQUIRY);
 278  0
         setNestedComponentIdAndSuffix(getFieldSuggest(), UifConstants.IdSuffixes.SUGGEST);
 279  
 
 280  0
         setId(getId() + UifConstants.IdSuffixes.ATTRIBUTE);
 281  0
     }
 282  
 
 283  
     /**
 284  
      * Helper method for suffixing the ids of the fields nested components
 285  
      *
 286  
      * @param component - component to adjust id for
 287  
      * @param suffix - suffix to append to id
 288  
      */
 289  
     private void setNestedComponentIdAndSuffix(Component component, String suffix) {
 290  0
         if (component != null) {
 291  0
             String fieldId = getId();
 292  0
             fieldId += suffix;
 293  
 
 294  0
             component.setId(fieldId);
 295  
         }
 296  0
     }
 297  
 
 298  
     /**
 299  
      * Defaults the properties of the <code>AttributeField</code> to the
 300  
      * corresponding properties of its <code>AttributeDefinition</code>
 301  
      * retrieved from the dictionary (if such an entry exists). If the field
 302  
      * already contains a value for a property, the definitions value is not
 303  
      * used.
 304  
      *
 305  
      * @param view - view instance the field belongs to
 306  
      * @param attributeDefinition - AttributeDefinition instance the property values should be
 307  
      * copied from
 308  
      */
 309  
     public void copyFromAttributeDefinition(View view, AttributeDefinition attributeDefinition) {
 310  0
         super.copyFromAttributeDefinition(view, attributeDefinition);
 311  
 
 312  
         // max length
 313  0
         if (getMaxLength() == null) {
 314  0
             setMaxLength(attributeDefinition.getMaxLength());
 315  
         }
 316  
 
 317  
         // min length
 318  0
         if (getMinLength() == null) {
 319  0
             setMinLength(attributeDefinition.getMinLength());
 320  
         }
 321  
 
 322  
         // valid characters
 323  0
         if (getValidCharactersConstraint() == null) {
 324  0
             setValidCharactersConstraint(attributeDefinition.getValidCharactersConstraint());
 325  
         }
 326  
 
 327  0
         if (getCaseConstraint() == null) {
 328  0
             setCaseConstraint(attributeDefinition.getCaseConstraint());
 329  
         }
 330  
 
 331  0
         if (getDependencyConstraints() == null) {
 332  0
             setDependencyConstraints(attributeDefinition.getPrerequisiteConstraints());
 333  
         }
 334  
 
 335  0
         if (getMustOccurConstraints() == null) {
 336  0
             setMustOccurConstraints(attributeDefinition.getMustOccurConstraints());
 337  
         }
 338  
 
 339  
         // required
 340  0
         if (getRequired() == null) {
 341  0
             setRequired(attributeDefinition.isRequired());
 342  
 
 343  
             //if still null, default to false
 344  0
             if (getRequired() == null) {
 345  0
                 setRequired(false);
 346  
             }
 347  
         }
 348  
 
 349  
         // control
 350  0
         if ((getControl() == null) && (attributeDefinition.getControlField() != null)) {
 351  0
             Control control = attributeDefinition.getControlField();
 352  0
             view.assignComponentIds(control);
 353  
 
 354  0
             setControl(ComponentUtils.copy(control));
 355  
         }
 356  
 
 357  
         // constraint
 358  0
         if (StringUtils.isEmpty(getConstraintText())) {
 359  0
             setConstraintText(attributeDefinition.getConstraintText());
 360  0
             getConstraintMessageField().setMessageText(attributeDefinition.getConstraintText());
 361  
         }
 362  
 
 363  
         // options
 364  0
         if (getOptionsFinder() == null) {
 365  0
             setOptionsFinder(attributeDefinition.getOptionsFinder());
 366  
         }
 367  0
     }
 368  
 
 369  
     /**
 370  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
 371  
      */
 372  
     @Override
 373  
     public List<Component> getComponentsForLifecycle() {
 374  0
         List<Component> components = super.getComponentsForLifecycle();
 375  
 
 376  0
         components.add(control);
 377  0
         components.add(errorsField);
 378  0
         components.add(fieldLookup);
 379  0
         components.add(fieldDirectInquiry);
 380  0
         components.add(fieldSuggest);
 381  
 
 382  0
         return components;
 383  
     }
 384  
 
 385  
     /**
 386  
      * Default value for the model property the field points to
 387  
      *
 388  
      * <p>
 389  
      * When a new <code>View</code> instance is requested, the corresponding
 390  
      * model will be newly created. During this initialization process the value
 391  
      * for the model property will be set to the given default value (if set)
 392  
      * </p>
 393  
      *
 394  
      * @return String default value
 395  
      */
 396  
     public String getDefaultValue() {
 397  0
         return this.defaultValue;
 398  
     }
 399  
 
 400  
     /**
 401  
      * Setter for the fields default value
 402  
      *
 403  
      * @param defaultValue
 404  
      */
 405  
     public void setDefaultValue(String defaultValue) {
 406  0
         this.defaultValue = defaultValue;
 407  0
     }
 408  
 
 409  
     /**
 410  
      * Gives Class that should be invoked to produce the default value for the
 411  
      * field
 412  
      *
 413  
      * @return Class<? extends ValueFinder> default value finder class
 414  
      */
 415  
     public Class<? extends ValueFinder> getDefaultValueFinderClass() {
 416  0
         return this.defaultValueFinderClass;
 417  
     }
 418  
 
 419  
     /**
 420  
      * Setter for the default value finder class
 421  
      *
 422  
      * @param defaultValueFinderClass
 423  
      */
 424  
     public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
 425  0
         this.defaultValueFinderClass = defaultValueFinderClass;
 426  0
     }
 427  
 
 428  
     /**
 429  
      * <code>Control</code> instance that should be used to input data for the
 430  
      * field
 431  
      *
 432  
      * <p>
 433  
      * When the field is editable, the control will be rendered so the user can
 434  
      * input a value(s). Controls typically are part of a Form and render
 435  
      * standard HTML control elements such as text input, select, and checkbox
 436  
      * </p>
 437  
      *
 438  
      * @return Control instance
 439  
      */
 440  
     public Control getControl() {
 441  0
         return this.control;
 442  
     }
 443  
 
 444  
     /**
 445  
      * Setter for the field's control
 446  
      *
 447  
      * @param control
 448  
      */
 449  
     public void setControl(Control control) {
 450  0
         this.control = control;
 451  0
     }
 452  
 
 453  
     public String getErrorMessagePlacement() {
 454  0
         return this.errorMessagePlacement;
 455  
     }
 456  
 
 457  
     public void setErrorMessagePlacement(String errorMessagePlacement) {
 458  0
         this.errorMessagePlacement = errorMessagePlacement;
 459  0
     }
 460  
 
 461  
     /**
 462  
      * Field that contains the messages (errors) for the attribute field. The
 463  
      * <code>ErrorsField</code> holds configuration on associated messages along
 464  
      * with information on rendering the messages in the user interface
 465  
      *
 466  
      * @return ErrorsField instance
 467  
      */
 468  
     public ErrorsField getErrorsField() {
 469  0
         return this.errorsField;
 470  
     }
 471  
 
 472  
     /**
 473  
      * Setter for the attribute field's errors field
 474  
      *
 475  
      * @param errorsField
 476  
      */
 477  
     public void setErrorsField(ErrorsField errorsField) {
 478  0
         this.errorsField = errorsField;
 479  0
     }
 480  
 
 481  
     /**
 482  
      * Instance of <code>KeyValluesFinder</code> that should be invoked to
 483  
      * provide a List of values the field can have. Generally used to provide
 484  
      * the options for a multi-value control or to validate the submitted field
 485  
      * value
 486  
      *
 487  
      * @return KeyValuesFinder instance
 488  
      */
 489  
     public KeyValuesFinder getOptionsFinder() {
 490  0
         return this.optionsFinder;
 491  
     }
 492  
 
 493  
     /**
 494  
      * Setter for the field's KeyValuesFinder instance
 495  
      *
 496  
      * @param optionsFinder
 497  
      */
 498  
     public void setOptionsFinder(KeyValuesFinder optionsFinder) {
 499  0
         this.optionsFinder = optionsFinder;
 500  0
     }
 501  
 
 502  
     /**
 503  
      * Setter that takes in the class name for the options finder and creates a
 504  
      * new instance to use as the finder for the attribute field
 505  
      *
 506  
      * @param optionsFinderClass
 507  
      */
 508  
     public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
 509  0
         this.optionsFinder = ObjectUtils.newInstance(optionsFinderClass);
 510  0
     }
 511  
 
 512  
     /**
 513  
      * Text explaining how to use the field, including things like what values should be selected
 514  
      * in certain cases and so on (instructions)
 515  
      *
 516  
      * @return String instructional message
 517  
      */
 518  
     public String getInstructionalText() {
 519  0
         return this.instructionalText;
 520  
     }
 521  
 
 522  
     /**
 523  
      * Setter for the instructional message
 524  
      *
 525  
      * @param instructionalText
 526  
      */
 527  
     public void setInstructionalText(String instructionalText) {
 528  0
         this.instructionalText = instructionalText;
 529  0
     }
 530  
 
 531  
     /**
 532  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getSupportsOnLoad()
 533  
      */
 534  
     @Override
 535  
     public boolean getSupportsOnLoad() {
 536  0
         return true;
 537  
     }
 538  
 
 539  
     /**
 540  
      * Lookup finder widget for the field
 541  
      *
 542  
      * <p>
 543  
      * The quickfinder widget places a small icon next to the field that allows
 544  
      * the user to bring up a search screen for finding valid field values. The
 545  
      * <code>Widget</code> instance can be configured to point to a certain
 546  
      * <code>LookupView</code>, or the framework will attempt to associate the
 547  
      * field with a lookup based on its metadata (in particular its
 548  
      * relationships in the model)
 549  
      * </p>
 550  
      *
 551  
      * @return QuickFinder lookup widget
 552  
      */
 553  
     public QuickFinder getFieldLookup() {
 554  0
         return this.fieldLookup;
 555  
     }
 556  
 
 557  
     /**
 558  
      * Setter for the lookup widget
 559  
      *
 560  
      * @param fieldLookup
 561  
      */
 562  
     public void setFieldLookup(QuickFinder fieldLookup) {
 563  0
         this.fieldLookup = fieldLookup;
 564  0
     }
 565  
 
 566  
     /**
 567  
      * Suggest box widget for the attribute field
 568  
      *
 569  
      * <p>
 570  
      * If enabled (by render flag), as the user inputs data into the
 571  
      * fields control a dynamic query is performed to provide the user
 572  
      * suggestions on values which they can then select
 573  
      * </p>
 574  
      *
 575  
      * <p>
 576  
      * Note the Suggest widget is only valid when using a standard TextControl
 577  
      * </p>
 578  
      *
 579  
      * @return Suggest instance
 580  
      */
 581  
     public Suggest getFieldSuggest() {
 582  0
         return fieldSuggest;
 583  
     }
 584  
 
 585  
     /**
 586  
      * Setter for the fields Suggest widget
 587  
      *
 588  
      * @param fieldSuggest
 589  
      */
 590  
     public void setFieldSuggest(Suggest fieldSuggest) {
 591  0
         this.fieldSuggest = fieldSuggest;
 592  0
     }
 593  
 
 594  
     /**
 595  
      * Message field that displays instructional text
 596  
      *
 597  
      * <p>
 598  
      * This message field can be configured to for adjusting how the instructional text will display. Generally
 599  
      * the styleClasses property will be of most interest
 600  
      * </p>
 601  
      *
 602  
      * @return MessageField instructional message field
 603  
      */
 604  
     public MessageField getInstructionalMessageField() {
 605  0
         return this.instructionalMessageField;
 606  
     }
 607  
 
 608  
     /**
 609  
      * Setter for the instructional text message field
 610  
      *
 611  
      * <p>
 612  
      * Note this is the setter for the field that will render the instructional text. The actual text can be
 613  
      * set on the field but can also be set using {@link #setInstructionalText(String)}
 614  
      * </p>
 615  
      *
 616  
      * @param instructionalMessageField
 617  
      */
 618  
     public void setInstructionalMessageField(MessageField instructionalMessageField) {
 619  0
         this.instructionalMessageField = instructionalMessageField;
 620  0
     }
 621  
 
 622  
     /**
 623  
      * Text that display a restriction on the value a field can hold
 624  
      *
 625  
      * <p>
 626  
      * For example when the value must be a valid format (phone number, email), certain length, min/max value and
 627  
      * so on this text can be used to indicate the constraint to the user. Generally displays with the control so
 628  
      * it is visible when the user tabs to the field
 629  
      * </p>
 630  
      *
 631  
      * @return String text to display for the constraint message
 632  
      */
 633  
     public String getConstraintText() {
 634  0
         return this.constraintText;
 635  
     }
 636  
 
 637  
     /**
 638  
      * Setter for the constraint message text
 639  
      *
 640  
      * @param constraintText
 641  
      */
 642  
     public void setConstraintText(String constraintText) {
 643  0
         this.constraintText = constraintText;
 644  0
     }
 645  
 
 646  
     /**
 647  
      * Message field that displays constraint text
 648  
      *
 649  
      * <p>
 650  
      * This message field can be configured to for adjusting how the constrain text will display. Generally
 651  
      * the styleClasses property will be of most interest
 652  
      * </p>
 653  
      *
 654  
      * @return MessageField constraint message field
 655  
      */
 656  
     public MessageField getConstraintMessageField() {
 657  0
         return this.constraintMessageField;
 658  
     }
 659  
 
 660  
     /**
 661  
      * Setter for the constraint text message field
 662  
      *
 663  
      * <p>
 664  
      * Note this is the setter for the field that will render the constraint text. The actual text can be
 665  
      * set on the field but can also be set using {@link #setConstraintText(String)}
 666  
      * </p>
 667  
      *
 668  
      * @param constraintMessageField
 669  
      */
 670  
     public void setConstraintMessageField(MessageField constraintMessageField) {
 671  0
         this.constraintMessageField = constraintMessageField;
 672  0
     }
 673  
 
 674  
     /**
 675  
      * Valid character constraint that defines regular expressions for the valid
 676  
      * characters for this field
 677  
      *
 678  
      * @return the validCharactersConstraint
 679  
      */
 680  
     public ValidCharactersConstraint getValidCharactersConstraint() {
 681  0
         return this.validCharactersConstraint;
 682  
     }
 683  
 
 684  
     /**
 685  
      * @param validCharactersConstraint the validCharactersConstraint to set
 686  
      */
 687  
     public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
 688  0
         this.validCharactersConstraint = validCharactersConstraint;
 689  0
     }
 690  
 
 691  
     /**
 692  
      * @return the caseConstraint
 693  
      */
 694  
     public CaseConstraint getCaseConstraint() {
 695  0
         return this.caseConstraint;
 696  
     }
 697  
 
 698  
     /**
 699  
      * @param caseConstraint the caseConstraint to set
 700  
      */
 701  
     public void setCaseConstraint(CaseConstraint caseConstraint) {
 702  0
         this.caseConstraint = caseConstraint;
 703  0
     }
 704  
 
 705  
     /**
 706  
      * @return the dependencyConstraints
 707  
      */
 708  
     public List<PrerequisiteConstraint> getDependencyConstraints() {
 709  0
         return this.dependencyConstraints;
 710  
     }
 711  
 
 712  
     /**
 713  
      * @param dependencyConstraints the dependencyConstraints to set
 714  
      */
 715  
     public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
 716  0
         this.dependencyConstraints = dependencyConstraints;
 717  0
     }
 718  
 
 719  
     /**
 720  
      * @return the mustOccurConstraints
 721  
      */
 722  
     public List<MustOccurConstraint> getMustOccurConstraints() {
 723  0
         return this.mustOccurConstraints;
 724  
     }
 725  
 
 726  
     /**
 727  
      * @param mustOccurConstraints the mustOccurConstraints to set
 728  
      */
 729  
     public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
 730  0
         this.mustOccurConstraints = mustOccurConstraints;
 731  0
     }
 732  
 
 733  
     /**
 734  
      * A simple constraint which store the values for required, min/max length,
 735  
      * and min/max value
 736  
      *
 737  
      * @return the simpleConstraint
 738  
      */
 739  
     public SimpleConstraint getSimpleConstraint() {
 740  0
         return this.simpleConstraint;
 741  
     }
 742  
 
 743  
     /**
 744  
      * When a simple constraint is set on this object ALL simple validation
 745  
      * constraints set directly will be overridden - recommended to use this or
 746  
      * the other gets/sets for defining simple constraints, not both
 747  
      *
 748  
      * @param simpleConstraint the simpleConstraint to set
 749  
      */
 750  
     public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
 751  0
         this.simpleConstraint = simpleConstraint;
 752  0
     }
 753  
 
 754  
     /**
 755  
      * Maximum number of the characters the attribute value is allowed to have.
 756  
      * Used to set the maxLength for supporting controls. Note this can be
 757  
      * smaller or longer than the actual control size
 758  
      *
 759  
      * @return Integer max length
 760  
      */
 761  
     public Integer getMaxLength() {
 762  0
         return simpleConstraint.getMaxLength();
 763  
     }
 764  
 
 765  
     /**
 766  
      * Setter for attributes max length
 767  
      *
 768  
      * @param maxLength
 769  
      */
 770  
     public void setMaxLength(Integer maxLength) {
 771  0
         simpleConstraint.setMaxLength(maxLength);
 772  0
     }
 773  
 
 774  
     /**
 775  
      * @return the minLength
 776  
      */
 777  
     public Integer getMinLength() {
 778  0
         return simpleConstraint.getMinLength();
 779  
     }
 780  
 
 781  
     /**
 782  
      * @param minLength the minLength to set
 783  
      */
 784  
     public void setMinLength(Integer minLength) {
 785  0
         simpleConstraint.setMinLength(minLength);
 786  0
     }
 787  
 
 788  
     /**
 789  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getRequired()
 790  
      */
 791  
     @Override
 792  
     public Boolean getRequired() {
 793  0
         return this.simpleConstraint.getRequired();
 794  
     }
 795  
 
 796  
     /**
 797  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#setRequired(java.lang.Boolean)
 798  
      */
 799  
     @Override
 800  
     public void setRequired(Boolean required) {
 801  0
         this.simpleConstraint.setRequired(required);
 802  0
     }
 803  
 
 804  
     /**
 805  
      * The exclusiveMin element determines the minimum allowable value for data
 806  
      * entry editing purposes. Value can be an integer or decimal value such as
 807  
      * -.001 or 99.
 808  
      */
 809  
     public String getExclusiveMin() {
 810  0
         return simpleConstraint.getExclusiveMin();
 811  
     }
 812  
 
 813  
     /**
 814  
      * @param exclusiveMin the minValue to set
 815  
      */
 816  
     public void setExclusiveMin(String exclusiveMin) {
 817  0
         simpleConstraint.setExclusiveMin(exclusiveMin);
 818  0
     }
 819  
 
 820  
     /**
 821  
      * The inclusiveMax element determines the maximum allowable value for data
 822  
      * entry editing purposes. Value can be an integer or decimal value such as
 823  
      * -.001 or 99.
 824  
      */
 825  
     public String getInclusiveMax() {
 826  0
         return simpleConstraint.getInclusiveMax();
 827  
     }
 828  
 
 829  
     /**
 830  
      * @param inclusiveMax the maxValue to set
 831  
      */
 832  
     public void setInclusiveMax(String inclusiveMax) {
 833  0
         simpleConstraint.setInclusiveMax(inclusiveMax);
 834  0
     }
 835  
 
 836  
     /**
 837  
      * Setter for the direct inquiry widget
 838  
      *
 839  
      * @param fieldDirectInquiry - field DirectInquiry to set
 840  
      */
 841  
     public void setFieldDirectInquiry(DirectInquiry fieldDirectInquiry) {
 842  0
         this.fieldDirectInquiry = fieldDirectInquiry;
 843  0
     }
 844  
 
 845  
     /**
 846  
      * DirectInquiry widget for the field
 847  
      *
 848  
      * <p>
 849  
      * The direct inquiry widget will render a button for the field value when
 850  
      * that field is editable. It points to the associated inquiry view for the
 851  
      * field. The inquiry can be configured to point to a certain
 852  
      * <code>InquiryView</code>, or the framework will attempt to associate the
 853  
      * field with a inquiry based on its metadata (in particular its
 854  
      * relationships in the model)
 855  
      * </p>
 856  
      *
 857  
      * @return the <code>DirectInquiry</code> field DirectInquiry
 858  
      */
 859  
     public DirectInquiry getFieldDirectInquiry() {
 860  0
         return fieldDirectInquiry;
 861  
     }
 862  
 
 863  
     /**
 864  
      * Attribute query instance configured for this field to dynamically pull information back for
 865  
      * updates other fields or providing messages
 866  
      *
 867  
      * <p>
 868  
      * If field attribute query is not null, associated event script will be generated to trigger the
 869  
      * query from the UI. This will invoke the <code>AttributeQueryService</code> to
 870  
      * execute the query and return an instance of <code>AttributeQueryResult</code> that is then
 871  
      * read by the script to update the UI. Typically used to update informational property values or
 872  
      * other field values
 873  
      * </p>
 874  
      *
 875  
      * @return AttributeQuery instance
 876  
      */
 877  
     public AttributeQuery getFieldAttributeQuery() {
 878  0
         return fieldAttributeQuery;
 879  
     }
 880  
 
 881  
     /**
 882  
      * Setter for this fields query
 883  
      *
 884  
      * @param fieldAttributeQuery
 885  
      */
 886  
     public void setFieldAttributeQuery(AttributeQuery fieldAttributeQuery) {
 887  0
         this.fieldAttributeQuery = fieldAttributeQuery;
 888  0
     }
 889  
 
 890  
     /**
 891  
      * Perform uppercase flag for this field to force input to uppercase.
 892  
      *
 893  
      * <p>
 894  
      * It this flag is set to true the 'text-transform' style on the field will be set to 'uppercase'
 895  
      * which will automatically change any text input into the field to uppercase.
 896  
      * </p>
 897  
      *
 898  
      * @return performUppercase flag
 899  
      */
 900  
     public boolean isPerformUppercase() {
 901  0
         return performUppercase;
 902  
     }
 903  
 
 904  
     /**
 905  
      * Setter for this fields performUppercase flag
 906  
      *
 907  
      * @param performUppercase flag
 908  
      */
 909  
     public void setPerformUppercase(boolean performUppercase) {
 910  0
         this.performUppercase = performUppercase;
 911  0
     }
 912  
 }