Coverage Report - org.kuali.rice.krad.uif.field.AttributeField
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeField
0%
0/294
0%
0/132
1.793
 
 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.StringEscapeUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.core.util.KeyValue;
 21  
 import org.kuali.rice.core.web.format.Formatter;
 22  
 import org.kuali.rice.krad.bo.BusinessObjectRelationship;
 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.valuefinder.ValueFinder;
 33  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 34  
 import org.kuali.rice.krad.uif.UifConstants;
 35  
 import org.kuali.rice.krad.uif.container.FormView;
 36  
 import org.kuali.rice.krad.uif.container.View;
 37  
 import org.kuali.rice.krad.uif.control.Control;
 38  
 import org.kuali.rice.krad.uif.control.MultiValueControlBase;
 39  
 import org.kuali.rice.krad.uif.core.BindingInfo;
 40  
 import org.kuali.rice.krad.uif.core.Component;
 41  
 import org.kuali.rice.krad.uif.core.DataBinding;
 42  
 import org.kuali.rice.krad.uif.util.ClientValidationUtils;
 43  
 import org.kuali.rice.krad.uif.util.ComponentUtils;
 44  
 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
 45  
 import org.kuali.rice.krad.uif.widget.DirectInquiry;
 46  
 import org.kuali.rice.krad.uif.widget.Inquiry;
 47  
 import org.kuali.rice.krad.uif.widget.QuickFinder;
 48  
 import org.kuali.rice.krad.uif.widget.Suggest;
 49  
 import org.kuali.rice.krad.util.KRADPropertyConstants;
 50  
 import org.kuali.rice.krad.util.ObjectUtils;
 51  
 
 52  
 import java.util.ArrayList;
 53  
 import java.util.List;
 54  
 
 55  
 /**
 56  
  * Field that encapsulates data input/output captured by an attribute within the
 57  
  * application
 58  
  * 
 59  
  * <p>
 60  
  * The <code>AttributField</code> provides the majority of the data input/output
 61  
  * for the screen. Through these fields the model can be displayed and updated.
 62  
  * For data input, the field contains a <code>Control</code> instance will
 63  
  * render an HTML control element(s). The attribute field also contains a
 64  
  * <code>LabelField</code>, summary, and widgets such as a quickfinder (for
 65  
  * looking up values) and inquiry (for getting more information on the value).
 66  
  * <code>AttributeField</code> instances can have associated messages (errors)
 67  
  * due to invalid input or business rule failures. Security can also be
 68  
  * configured to restrict who may view the fields value.
 69  
  * </p>
 70  
  * 
 71  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 72  
  */
 73  
 public class AttributeField extends FieldBase implements DataBinding {
 74  
     private static final long serialVersionUID = -3703656713706343840L;
 75  
 
 76  
     // value props
 77  
     private String defaultValue;
 78  
     private Class<? extends ValueFinder> defaultValueFinderClass;
 79  
 
 80  
     // Constraint variables
 81  
     private String customValidatorClass;
 82  
     private ValidCharactersConstraint validCharactersConstraint;
 83  
     private CaseConstraint caseConstraint;
 84  
     private List<PrerequisiteConstraint> dependencyConstraints;
 85  
     private List<MustOccurConstraint> mustOccurConstraints;
 86  
     private SimpleConstraint simpleConstraint;
 87  
 
 88  
     private Formatter formatter;
 89  
     private KeyValuesFinder optionsFinder;
 90  
 
 91  
     // binding
 92  
     private String propertyName;
 93  
     private BindingInfo bindingInfo;
 94  
 
 95  
     private String dictionaryAttributeName;
 96  
     private String dictionaryObjectEntry;
 97  
 
 98  
     // display props
 99  
     private Control control;
 100  
 
 101  
     private String errorMessagePlacement;
 102  
     private ErrorsField errorsField;
 103  
 
 104  
     // messages
 105  
     private String summary;
 106  
     private String constraint;
 107  
     private String description;
 108  
 
 109  
     private AttributeSecurity attributeSecurity;
 110  
     private MessageField summaryMessageField;
 111  
     private MessageField constraintMessageField;
 112  
 
 113  
     // Alternate and additional display properties
 114  
     protected String alternateDisplayPropertyName;
 115  
     protected String additionalDisplayPropertyName;
 116  
     
 117  
     private BindingInfo alternateDisplayPropertyBindingInfo;
 118  
         private BindingInfo additionalDisplayPropertyBindingInfo;
 119  
 
 120  
         private String alternateDisplayValue;
 121  
         private String additionalDisplayValue;
 122  
     
 123  
     private List<String> informationalDisplayPropertyNames;
 124  
 
 125  
     private List<String> hiddenPropertyNames;
 126  
 
 127  
     private AttributeQuery fieldAttributeQuery;
 128  
         
 129  
     private boolean escapeHtmlInPropertyValue;
 130  
     
 131  
         // widgets
 132  
     private Inquiry fieldInquiry;
 133  
     private QuickFinder fieldLookup;
 134  
     private DirectInquiry fieldDirectInquiry;
 135  
     private Suggest fieldSuggest;
 136  
 
 137  
     public AttributeField() {
 138  0
         super();
 139  
 
 140  0
         simpleConstraint = new SimpleConstraint();
 141  0
         informationalDisplayPropertyNames = new ArrayList<String>();
 142  0
         hiddenPropertyNames = new ArrayList<String>();
 143  0
     }
 144  
 
 145  
     /**
 146  
      * The following initialization is performed:
 147  
      *
 148  
      * <ul>
 149  
      * <li>Set defaults for binding</li>
 150  
      * <li>Default the model path if not set</li>
 151  
      * </ul>
 152  
      *
 153  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#performInitialization(org.kuali.rice.krad.uif.container.View)
 154  
      */
 155  
     @Override
 156  
     public void performInitialization(View view) {
 157  0
         super.performInitialization(view);
 158  
 
 159  0
         if (bindingInfo != null) {
 160  0
             bindingInfo.setDefaults(view, getPropertyName());
 161  
         }
 162  0
     }
 163  
 
 164  
     /**
 165  
      * The following actions are performed:
 166  
      *
 167  
      * <ul>
 168  
      * <li>Set the ids for the various attribute components</li>
 169  
      * <li>Sets up the client side validation for constraints on this field. In
 170  
      * addition, it sets up the messages applied to this field</li>
 171  
      * </ul>
 172  
      * 
 173  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#performFinalize(org.kuali.rice.krad.uif.container.View,
 174  
      *      java.lang.Object, org.kuali.rice.krad.uif.core.Component)
 175  
      */
 176  
     @Override
 177  
     public void performFinalize(View view, Object model, Component parent) {
 178  0
         super.performFinalize(view, model, parent);
 179  
 
 180  0
         setupIds();
 181  
 
 182  
         // Sets message
 183  0
         if (StringUtils.isNotBlank(summary)) {
 184  0
             summaryMessageField.setMessageText(summary);
 185  
         }
 186  
 
 187  
         // Sets constraints
 188  0
         if (StringUtils.isNotBlank(constraint)) {
 189  0
             constraintMessageField.setMessageText(constraint);
 190  
         }
 191  
 
 192  
         // Additional and Alternate display value
 193  0
                setAlternateAndAdditionalDisplayValue(view,model);
 194  
 
 195  
         // if read only or the control is not set no need to set client side
 196  
         // validation
 197  0
         if (isReadOnly() || getControl() == null) {
 198  0
             return;
 199  
         }
 200  
 
 201  0
         setupInformationalFieldQuery();
 202  
 
 203  
         // Adjust the path for hidden fields
 204  0
         List<String> hiddenPropertyPaths = new ArrayList<String>();
 205  
 
 206  0
         for (String hiddenPropertyName : getHiddenPropertyNames()) {
 207  0
             String hiddenPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(hiddenPropertyName);
 208  0
             hiddenPropertyPaths.add(hiddenPropertyPath);
 209  0
         }
 210  
 
 211  0
         this.hiddenPropertyNames = hiddenPropertyPaths;
 212  
 
 213  
         // TODO: remove later, this should be done within the service lifecycle
 214  0
         if ((optionsFinder != null) && (control != null) && control instanceof MultiValueControlBase) {
 215  0
             MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
 216  0
             if ((multiValueControl.getOptions() == null) || multiValueControl.getOptions().isEmpty()) {
 217  0
                 multiValueControl.setOptions(optionsFinder.getKeyValues());
 218  
             }
 219  
         }
 220  
         
 221  0
         if(view instanceof FormView && ((FormView) view).isValidateClientSide()){
 222  0
             ClientValidationUtils.processAndApplyConstraints(this, view);
 223  
         }
 224  0
     }
 225  
     
 226  
     /**
 227  
      * Performs setup of the field attribute query and informational display properties. Paths
 228  
      * are adjusted to match the binding for the this field, and the necessary onblur script for
 229  
      * triggering the query client side is constructed
 230  
      */
 231  
     protected void setupInformationalFieldQuery() {
 232  
         // adjust paths on informational property names
 233  0
         List<String> informationalPropertyPaths = new ArrayList<String>();
 234  0
         for (String infoPropertyName : getInformationalDisplayPropertyNames()) {
 235  0
             String infoPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(infoPropertyName);
 236  0
             informationalPropertyPaths.add(infoPropertyPath);
 237  0
         }
 238  0
         this.informationalDisplayPropertyNames = informationalPropertyPaths;
 239  
 
 240  0
         if (getFieldAttributeQuery() != null) {
 241  
             // adjust paths on query mappings
 242  0
             getFieldAttributeQuery().updateQueryFieldMapping(getBindingInfo());
 243  0
             getFieldAttributeQuery().updateReturnFieldMapping(getBindingInfo());
 244  0
             getFieldAttributeQuery().updateQueryMethodArgumentFieldList(getBindingInfo());
 245  
 
 246  
             // build onblur script for field query
 247  0
             String script = "executeFieldQuery('" + getControl().getId() + "',";
 248  0
             script += "'" + getId() + "'," + getFieldAttributeQuery().getQueryFieldMappingJsString() + ",";
 249  0
             script += getFieldAttributeQuery().getQueryMethodArgumentFieldsJsString() + ",";
 250  0
             script += getFieldAttributeQuery().getReturnFieldMappingJsString() + ");";
 251  
 
 252  0
             if (StringUtils.isNotBlank(getControl().getOnBlurScript())) {
 253  0
                 script = getControl().getOnBlurScript() + script;
 254  
             }
 255  0
             getControl().setOnBlurScript(script);
 256  
         }
 257  0
     }
 258  
 
 259  
      /**
 260  
      * Sets alternate and additional property value for this field.
 261  
      *
 262  
      * <p>
 263  
      * If <code>AttributeSecurity</code> present in this field, make sure the current user has permission to view the field value. If user doesn't
 264  
      * have permission to view the value, mask the value as configured and set it as alternate value for display. If security doesn't exists for
 265  
      * this field but <code>alternateDisplayPropertyName</code> present, get its value and format it based on that fields formatting and set for display.
 266  
      * </p>
 267  
      *
 268  
      * <p>
 269  
      * For additional display value, if <code>AttributeSecurity</code> not present, sets the value if <code>additionalDisplayPropertyName</code> present.
 270  
      * If not present, check whether this field is a <code>KualiCode</code> and get the relationship configured in the datadictionary file and set the name
 271  
      * additional display value which will be displayed along with the code. If additional display property not present, check whether this field is has
 272  
      * <code>MultiValueControlBase</code>. If yes, get the Label for the value and set it as additional display value.
 273  
      * </p>
 274  
      *
 275  
      * @param view - the current view instance
 276  
      * @param model - model instance
 277  
      */
 278  
     private void setAlternateAndAdditionalDisplayValue(View view, Object model){
 279  0
             boolean isSecure = false;
 280  0
             boolean additionalValueSet = false;
 281  0
             boolean alternateValueSet = false;
 282  
 
 283  0
             if (getAttributeSecurity() != null){
 284  
                     //TODO: Check authorization
 285  
                     // if (attributeSecurity.isMask() && !boAuthzService.canFullyUnmaskField(user,dataObjectClass, field.getPropertyName(), null)) {
 286  0
                     Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
 287  0
                         alternateDisplayValue = getSecuredFieldValue(attributeSecurity, fieldValue);
 288  0
                         setReadOnly(true);
 289  0
                         isSecure = true;
 290  
             }
 291  
 
 292  
             //If not read only, return without trying to set alternate and additional values
 293  0
             if (!isReadOnly()){
 294  0
                     return;
 295  
             }
 296  
 
 297  
             // If AttributeSecurity not found, check for AlternateDisplayPropertyName
 298  0
             if (!isSecure && StringUtils.isNotBlank(getAlternateDisplayPropertyName())){
 299  0
                     alternateDisplayPropertyBindingInfo.setDefaults(view, getAlternateDisplayPropertyName());
 300  0
                     AttributeField alternateField = view.getViewIndex().getAttributeField(getAlternateDisplayPropertyBindingInfo());
 301  
 
 302  0
                     if (alternateField != null){
 303  0
                             Object alterateFieldValue = ObjectPropertyUtils.getPropertyValue(model, getAlternateDisplayPropertyBindingInfo().getBindingPath());
 304  0
                             if (alternateField.getFormatter() != null){
 305  0
                                     alternateDisplayValue = (String)alternateField.getFormatter().formatForPresentation(alterateFieldValue);
 306  
                             }else{
 307  0
                                     alternateDisplayValue = org.apache.commons.lang.ObjectUtils.toString(alterateFieldValue);
 308  
                             }
 309  0
                             if (alternateField.isEscapeHtmlInPropertyValue()){
 310  0
                                     alternateDisplayValue = StringEscapeUtils.escapeHtml(alternateDisplayValue);
 311  
                             }
 312  0
                             alternateValueSet = true;
 313  
                     }
 314  
             }
 315  
 
 316  0
             if (!isSecure){
 317  
 
 318  
                     //If additional display property name present, set it to display
 319  0
                     if (StringUtils.isNotBlank(getAdditionalDisplayPropertyName())) {
 320  0
                         additionalDisplayPropertyBindingInfo.setDefaults(view, getAdditionalDisplayPropertyName());
 321  0
                         AttributeField additionalPropertyField = view.getViewIndex().getAttributeField(getAdditionalDisplayPropertyBindingInfo());
 322  0
                         Object additionalFieldValue = ObjectPropertyUtils.getPropertyValue(model, additionalDisplayPropertyBindingInfo.getBindingPath());
 323  0
                         additionalValueSet = true;
 324  0
                         if (additionalPropertyField != null && additionalPropertyField.getFormatter() != null){
 325  0
                                 additionalDisplayValue = (String)additionalPropertyField.getFormatter().formatForPresentation(additionalFieldValue);
 326  
                         }else {
 327  0
                                 additionalDisplayValue = org.apache.commons.lang.ObjectUtils.toString(additionalFieldValue);
 328  
                         }
 329  0
                         if (additionalPropertyField != null && additionalPropertyField.isEscapeHtmlInPropertyValue()){
 330  0
                                 additionalDisplayValue = StringEscapeUtils.escapeHtml(additionalDisplayValue);
 331  
                             }
 332  0
                     }else if (view.isTranslateCodes()){
 333  
                             //If translate code is enabled, check for any relationship present for this field and it's of type KualiCode
 334  0
                         BusinessObjectRelationship relationship = KRADServiceLocatorWeb.getDataObjectMetaDataService().getDataObjectRelationship(model,model.getClass(),getBindingInfo().getBindingPath(),"",true,true,true);
 335  0
                         if (relationship != null && getPropertyName().startsWith(relationship.getParentAttributeName())
 336  
                                             && KualiCode.class.isAssignableFrom(relationship.getRelatedClass())) {
 337  0
                                 additionalDisplayPropertyName = relationship.getParentAttributeName() + "." + KRADPropertyConstants.NAME;
 338  0
                                 additionalDisplayPropertyBindingInfo.setDefaults(view, getAdditionalDisplayPropertyName());
 339  0
                                 Object value = ObjectPropertyUtils.getPropertyValue(model, additionalDisplayPropertyBindingInfo.getBindingPath());
 340  0
                                 additionalDisplayValue = org.apache.commons.lang.ObjectUtils.toString(value);;
 341  0
                                 additionalValueSet = true;
 342  
                             }
 343  
                     }
 344  
 
 345  
                     // alternateValue and additionalValue not set yet? Check whether the field has multi value control
 346  0
                     if (!alternateValueSet && !additionalValueSet && (control != null && control instanceof MultiValueControlBase)){
 347  0
                             MultiValueControlBase multiValueControl = (MultiValueControlBase) control;
 348  0
                             if (multiValueControl.getOptions() != null){
 349  0
                                     for (KeyValue keyValue : multiValueControl.getOptions()) {
 350  0
                                             Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
 351  0
                                                 if (StringUtils.equals((String)fieldValue, keyValue.getKey())){
 352  0
                                                         alternateDisplayValue = keyValue.getValue();
 353  0
                                                         break;
 354  
                                                 }
 355  0
                                         }
 356  
                             }
 357  
                     }
 358  
 
 359  
             }
 360  
 
 361  0
     }
 362  
 
 363  
 
 364  
     /**
 365  
      * Helper method which returns the masked value based on the <code>AttributeSecurity</code>
 366  
      *
 367  
      * @param attributeSecurity attribute security to check
 368  
      * @param fieldValue field value
 369  
      * @return masked value
 370  
      */
 371  
     private String getSecuredFieldValue(AttributeSecurity attributeSecurity, Object fieldValue){
 372  0
             if(attributeSecurity.isMask()){
 373  0
                         return attributeSecurity.getMaskFormatter().maskValue(fieldValue);
 374  0
                 }else if(getAttributeSecurity().isPartialMask()){
 375  0
                         return attributeSecurity.getPartialMaskFormatter().maskValue(fieldValue);
 376  
                 }else{
 377  0
                         throw new RuntimeException("Encountered unsupported Attribute Security..");
 378  
                 }
 379  
     }
 380  
     
 381  
     /**
 382  
      * Sets the ids on all components the attribute field uses so they will all
 383  
      * contain this attribute's id in their ids. This is useful for jQuery
 384  
      * manipulation.
 385  
      */
 386  
     private void setupIds() {
 387  
         // update ids so they all match the attribute
 388  0
         if (getControl() != null) {
 389  0
             getControl().setId(getId());
 390  
         }
 391  
 
 392  0
         setNestedComponentIdAndSuffix(getErrorsField(), UifConstants.IdSuffixes.ERRORS);
 393  0
         setNestedComponentIdAndSuffix(getLabelField(), UifConstants.IdSuffixes.LABEL);
 394  0
         setNestedComponentIdAndSuffix(getSummaryMessageField(), UifConstants.IdSuffixes.SUMMARY);
 395  0
         setNestedComponentIdAndSuffix(getConstraintMessageField(), UifConstants.IdSuffixes.CONSTRAINT);
 396  0
         setNestedComponentIdAndSuffix(getFieldLookup(), UifConstants.IdSuffixes.QUICK_FINDER);
 397  
 
 398  0
         setId(getId() + UifConstants.IdSuffixes.ATTRIBUTE);
 399  0
     }
 400  
 
 401  
     /**
 402  
      * Helper method for suffixing the ids of the fields nested components
 403  
      *
 404  
      * @param component - component to adjust id for
 405  
      * @param suffix - suffix to append to id
 406  
      */
 407  
     private void setNestedComponentIdAndSuffix(Component component, String suffix) {
 408  0
         if (component != null) {
 409  0
             String fieldId = getId();
 410  0
             fieldId += suffix;
 411  
 
 412  0
             component.setId(fieldId);
 413  
         }
 414  0
     }
 415  
 
 416  
     /**
 417  
      * Defaults the properties of the <code>AttributeField</code> to the
 418  
      * corresponding properties of its <code>AttributeDefinition</code>
 419  
      * retrieved from the dictionary (if such an entry exists). If the field
 420  
      * already contains a value for a property, the definitions value is not
 421  
      * used.
 422  
      * 
 423  
      * @param attributeDefinition
 424  
      *            - AttributeDefinition instance the property values should be
 425  
      *            copied from
 426  
      */
 427  
     public void copyFromAttributeDefinition(AttributeDefinition attributeDefinition) {
 428  
         // label
 429  0
         if (StringUtils.isEmpty(getLabel())) {
 430  0
             setLabel(attributeDefinition.getLabel());
 431  
         }
 432  
 
 433  
         // short label
 434  0
         if (StringUtils.isEmpty(getShortLabel())) {
 435  0
             setShortLabel(attributeDefinition.getShortLabel());
 436  
         }
 437  
 
 438  
         // max length
 439  0
         if (getMaxLength() == null) {
 440  0
             setMaxLength(attributeDefinition.getMaxLength());
 441  
         }
 442  
 
 443  
         // max length
 444  0
         if (getMinLength() == null) {
 445  0
             setMinLength(attributeDefinition.getMinLength());
 446  
         }
 447  
 
 448  
         // valid characters
 449  0
         if (getValidCharactersConstraint() == null) {
 450  0
             setValidCharactersConstraint(attributeDefinition.getValidCharactersConstraint());
 451  
         }
 452  
 
 453  0
         if (getCaseConstraint() == null) {
 454  0
             setCaseConstraint(attributeDefinition.getCaseConstraint());
 455  
         }
 456  
 
 457  0
         if (getDependencyConstraints() == null) {
 458  0
             setDependencyConstraints(attributeDefinition.getPrerequisiteConstraints());
 459  
         }
 460  
 
 461  0
         if (getMustOccurConstraints() == null) {
 462  0
             setMustOccurConstraints(attributeDefinition.getMustOccurConstraints());
 463  
         }
 464  
 
 465  
         // required
 466  0
         if (getRequired() == null) {
 467  0
             setRequired(attributeDefinition.isRequired());
 468  
         }
 469  
 
 470  
         // control
 471  0
         if ((getControl() == null) && (attributeDefinition.getControlField() != null)) {
 472  0
             setControl(ComponentUtils.copy(attributeDefinition.getControlField()));
 473  
         }
 474  
 
 475  
         // summary
 476  0
         if (StringUtils.isEmpty(getSummary())) {
 477  0
             setSummary(attributeDefinition.getSummary());
 478  0
             getSummaryMessageField().setMessageText(attributeDefinition.getSummary());
 479  
         }
 480  
 
 481  
         // description
 482  0
         if (StringUtils.isEmpty(getDescription())) {
 483  0
             setDescription(attributeDefinition.getDescription());
 484  
         }
 485  
 
 486  
         // security
 487  0
         if (getAttributeSecurity() == null) {
 488  0
                 attributeSecurity = attributeDefinition.getAttributeSecurity();
 489  
         }
 490  
 
 491  
         // constraint
 492  0
         if (StringUtils.isEmpty(getConstraint())) {
 493  0
             setConstraint(attributeDefinition.getConstraint());
 494  0
             getConstraintMessageField().setMessageText(attributeDefinition.getConstraint());
 495  
         }
 496  
         
 497  
         // options
 498  0
         if (getOptionsFinder() == null) {
 499  0
             setOptionsFinder(attributeDefinition.getOptionsFinder());
 500  
         }
 501  
 
 502  
         //alternate property name and binding object
 503  0
         if (getAlternateDisplayPropertyName() == null && StringUtils.isNotBlank(attributeDefinition.getAlternateDisplayAttributeName())){
 504  0
                 setAlternateDisplayPropertyName(attributeDefinition.getAlternateDisplayAttributeName());
 505  
         }
 506  
 
 507  
         //additional property display name and binding object
 508  0
         if (getAdditionalDisplayPropertyName() == null && StringUtils.isNotBlank(attributeDefinition.getAdditionalDisplayAttributeName())){
 509  0
                 setAdditionalDisplayPropertyName(attributeDefinition.getAdditionalDisplayAttributeName());
 510  
         }
 511  
 
 512  0
         if (getFormatter() == null && StringUtils.isNotBlank(attributeDefinition.getFormatterClass())) {
 513  0
             Class clazz = null;
 514  
             try {
 515  0
                 clazz = Class.forName(attributeDefinition.getFormatterClass());
 516  0
             } catch (ClassNotFoundException e) {
 517  0
                 throw new RuntimeException("Unable to get class from name: " + attributeDefinition.getFormatterClass(),
 518  
                         e);
 519  0
             }
 520  
 
 521  0
             Formatter formatter = (Formatter) ObjectUtils.newInstance(clazz);
 522  0
             setFormatter(formatter);
 523  
         }
 524  0
     }
 525  
 
 526  
     /**
 527  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#getNestedComponents()
 528  
      */
 529  
     @Override
 530  
     public List<Component> getNestedComponents() {
 531  0
         List<Component> components = super.getNestedComponents();
 532  
 
 533  0
         components.add(control);
 534  0
         components.add(errorsField);
 535  0
         components.add(fieldLookup);
 536  0
         components.add(fieldInquiry);
 537  0
         components.add(fieldDirectInquiry);
 538  0
         components.add(fieldSuggest);
 539  
 
 540  0
         return components;
 541  
     }
 542  
 
 543  
     /**
 544  
      * @see org.kuali.rice.krad.uif.core.DataBinding#getPropertyName()
 545  
      */
 546  
     public String getPropertyName() {
 547  0
         return this.propertyName;
 548  
     }
 549  
 
 550  
     /**
 551  
      * Setter for the component's property name
 552  
      * 
 553  
      * @param propertyName
 554  
      */
 555  
     public void setPropertyName(String propertyName) {
 556  0
         this.propertyName = propertyName;
 557  0
     }
 558  
 
 559  
     /**
 560  
      * Default value for the model property the field points to
 561  
      * 
 562  
      * <p>
 563  
      * When a new <code>View</code> instance is requested, the corresponding
 564  
      * model will be newly created. During this initialization process the value
 565  
      * for the model property will be set to the given default value (if set)
 566  
      * </p>
 567  
      * 
 568  
      * @return String default value
 569  
      */
 570  
     public String getDefaultValue() {
 571  0
         return this.defaultValue;
 572  
     }
 573  
 
 574  
     /**
 575  
      * Setter for the fields default value
 576  
      * 
 577  
      * @param defaultValue
 578  
      */
 579  
     public void setDefaultValue(String defaultValue) {
 580  0
         this.defaultValue = defaultValue;
 581  0
     }
 582  
 
 583  
     /**
 584  
      * Gives Class that should be invoked to produce the default value for the
 585  
      * field
 586  
      * 
 587  
      * @return Class<? extends ValueFinder> default value finder class
 588  
      */
 589  
     public Class<? extends ValueFinder> getDefaultValueFinderClass() {
 590  0
         return this.defaultValueFinderClass;
 591  
     }
 592  
 
 593  
     /**
 594  
      * Setter for the default value finder class
 595  
      * 
 596  
      * @param defaultValueFinderClass
 597  
      */
 598  
     public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
 599  0
         this.defaultValueFinderClass = defaultValueFinderClass;
 600  0
     }
 601  
 
 602  
     /**
 603  
      * <code>Formatter</code> instance that should be used when displaying and
 604  
      * accepting the field's value in the user interface
 605  
      * 
 606  
      * <p>
 607  
      * Formatters can provide conversion between datatypes in addition to
 608  
      * special string formatting such as currency display
 609  
      * </p>
 610  
      * 
 611  
      * @return Formatter instance
 612  
      * @see org.kuali.rice.krad.web.format.Formatter
 613  
      */
 614  
     public Formatter getFormatter() {
 615  0
         return this.formatter;
 616  
     }
 617  
 
 618  
     /**
 619  
      * Setter for the field's formatter
 620  
      * 
 621  
      * @param formatter
 622  
      */
 623  
     public void setFormatter(Formatter formatter) {
 624  0
         this.formatter = formatter;
 625  0
     }
 626  
 
 627  
     /**
 628  
      * @see org.kuali.rice.krad.uif.core.DataBinding#getBindingInfo()
 629  
      */
 630  
     public BindingInfo getBindingInfo() {
 631  0
         return this.bindingInfo;
 632  
     }
 633  
 
 634  
     /**
 635  
      * Setter for the field's binding info
 636  
      * 
 637  
      * @param bindingInfo
 638  
      */
 639  
     public void setBindingInfo(BindingInfo bindingInfo) {
 640  0
         this.bindingInfo = bindingInfo;
 641  0
     }
 642  
 
 643  
     /**
 644  
      * <code>Control</code> instance that should be used to input data for the
 645  
      * field
 646  
      * 
 647  
      * <p>
 648  
      * When the field is editable, the control will be rendered so the user can
 649  
      * input a value(s). Controls typically are part of a Form and render
 650  
      * standard HTML control elements such as text input, select, and checkbox
 651  
      * </p>
 652  
      * 
 653  
      * @return Control instance
 654  
      */
 655  
     public Control getControl() {
 656  0
         return this.control;
 657  
     }
 658  
 
 659  
     /**
 660  
      * Setter for the field's control
 661  
      * 
 662  
      * @param control
 663  
      */
 664  
     public void setControl(Control control) {
 665  0
         this.control = control;
 666  0
     }
 667  
 
 668  
     public String getErrorMessagePlacement() {
 669  0
         return this.errorMessagePlacement;
 670  
     }
 671  
 
 672  
     public void setErrorMessagePlacement(String errorMessagePlacement) {
 673  0
         this.errorMessagePlacement = errorMessagePlacement;
 674  0
     }
 675  
 
 676  
     /**
 677  
      * Field that contains the messages (errors) for the attribute field. The
 678  
      * <code>ErrorsField</code> holds configuration on associated messages along
 679  
      * with information on rendering the messages in the user interface
 680  
      * 
 681  
      * @return ErrorsField instance
 682  
      */
 683  
     public ErrorsField getErrorsField() {
 684  0
         return this.errorsField;
 685  
     }
 686  
 
 687  
     /**
 688  
      * Setter for the attribute field's errors field
 689  
      * 
 690  
      * @param errorsField
 691  
      */
 692  
     public void setErrorsField(ErrorsField errorsField) {
 693  0
         this.errorsField = errorsField;
 694  0
     }
 695  
 
 696  
     /**
 697  
      * Name of the attribute within the data dictionary the attribute field is
 698  
      * associated with
 699  
      * 
 700  
      * <p>
 701  
      * During the initialize phase for the <code>View</code>, properties for
 702  
      * attribute fields are defaulted from a corresponding
 703  
      * <code>AttributeDefinition</code> in the data dictionary. Based on the
 704  
      * propertyName and parent object class the framework attempts will
 705  
      * determine the attribute definition that is associated with the field and
 706  
      * set this property. However this property can also be set in the fields
 707  
      * configuration to use another dictionary attribute.
 708  
      * </p>
 709  
      * <p>
 710  
      * The attribute name is used along with the dictionary object entry to find
 711  
      * the <code>AttributeDefinition</code>
 712  
      * </p>
 713  
      * 
 714  
      * @return String attribute name
 715  
      */
 716  
     public String getDictionaryAttributeName() {
 717  0
         return this.dictionaryAttributeName;
 718  
     }
 719  
 
 720  
     /**
 721  
      * Setter for the dictionary attribute name
 722  
      * 
 723  
      * @param dictionaryAttributeName
 724  
      */
 725  
     public void setDictionaryAttributeName(String dictionaryAttributeName) {
 726  0
         this.dictionaryAttributeName = dictionaryAttributeName;
 727  0
     }
 728  
 
 729  
     /**
 730  
      * Object entry name in the data dictionary the associated attribute is
 731  
      * apart of
 732  
      * 
 733  
      * <p>
 734  
      * During the initialize phase for the <code>View</code>, properties for
 735  
      * attribute fields are defaulted from a corresponding
 736  
      * <code>AttributeDefinition</code> in the data dictionary. Based on the
 737  
      * parent object class the framework will determine the object entry for the
 738  
      * associated attribute. However the object entry can be set in the field's
 739  
      * configuration to use another object entry for the attribute
 740  
      * </p>
 741  
      * 
 742  
      * <p>
 743  
      * The attribute name is used along with the dictionary object entry to find
 744  
      * the <code>AttributeDefinition</code>
 745  
      * </p>
 746  
      * 
 747  
      * @return
 748  
      */
 749  
     public String getDictionaryObjectEntry() {
 750  0
         return this.dictionaryObjectEntry;
 751  
     }
 752  
 
 753  
     /**
 754  
      * Setter for the dictionary object entry
 755  
      * 
 756  
      * @param dictionaryObjectEntry
 757  
      */
 758  
     public void setDictionaryObjectEntry(String dictionaryObjectEntry) {
 759  0
         this.dictionaryObjectEntry = dictionaryObjectEntry;
 760  0
     }
 761  
 
 762  
     /**
 763  
      * Instance of <code>KeyValluesFinder</code> that should be invoked to
 764  
      * provide a List of values the field can have. Generally used to provide
 765  
      * the options for a multi-value control or to validate the submitted field
 766  
      * value
 767  
      * 
 768  
      * @return KeyValuesFinder instance
 769  
      */
 770  
     public KeyValuesFinder getOptionsFinder() {
 771  0
         return this.optionsFinder;
 772  
     }
 773  
 
 774  
     /**
 775  
      * Setter for the field's KeyValuesFinder instance
 776  
      * 
 777  
      * @param optionsFinder
 778  
      */
 779  
     public void setOptionsFinder(KeyValuesFinder optionsFinder) {
 780  0
         this.optionsFinder = optionsFinder;
 781  0
     }
 782  
     
 783  
     /**
 784  
      * Setter that takes in the class name for the options finder and creates a
 785  
      * new instance to use as the finder for the attribute field
 786  
      * 
 787  
      * @param optionsFinderClass
 788  
      */
 789  
     public void setOptionsFinderClass(Class<? extends KeyValuesFinder> optionsFinderClass) {
 790  0
         this.optionsFinder = ObjectUtils.newInstance(optionsFinderClass);
 791  0
     }
 792  
 
 793  
     /**
 794  
      * Brief statement of the field (attribute) purpose. Used to display helpful
 795  
      * information to the user on the form
 796  
      * 
 797  
      * @return String summary message
 798  
      */
 799  
     public String getSummary() {
 800  0
         return this.summary;
 801  
     }
 802  
 
 803  
     /**
 804  
      * Setter for the summary message
 805  
      * 
 806  
      * @param summary
 807  
      */
 808  
     public void setSummary(String summary) {
 809  0
         this.summary = summary;
 810  0
     }
 811  
 
 812  
     /**
 813  
      * Full explanation of the field (attribute). Used in help contents
 814  
      * 
 815  
      * @return String description message
 816  
      */
 817  
     public String getDescription() {
 818  0
         return this.description;
 819  
     }
 820  
 
 821  
     /**
 822  
      * Setter for the description message
 823  
      * 
 824  
      * @param description
 825  
      */
 826  
     public void setDescription(String description) {
 827  0
         this.description = description;
 828  0
     }
 829  
 
 830  
     /**
 831  
      * Holds security configuration for the attribute field. This triggers
 832  
      * corresponding permission checks in KIM and can result in an update to the
 833  
      * field state (such as read-only or hidden) and masking of the value
 834  
      * 
 835  
      * @return AttributeSecurity instance configured for field or Null if no
 836  
      *         restrictions are defined
 837  
      */
 838  
     public AttributeSecurity getAttributeSecurity() {
 839  0
         return this.attributeSecurity;
 840  
     }
 841  
 
 842  
     /**
 843  
      * Setter for the AttributeSecurity instance that defines restrictions for
 844  
      * the field
 845  
      * 
 846  
      * @param attributeSecurity
 847  
      */
 848  
     public void setAttributeSecurity(AttributeSecurity attributeSecurity) {
 849  0
         this.attributeSecurity = attributeSecurity;
 850  0
     }
 851  
 
 852  
     /**
 853  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#getSupportsOnLoad()
 854  
      */
 855  
     @Override
 856  
     public boolean getSupportsOnLoad() {
 857  0
         return true;
 858  
     }
 859  
 
 860  
     /**
 861  
      * Lookup finder widget for the field
 862  
      * 
 863  
      * <p>
 864  
      * The quickfinder widget places a small icon next to the field that allows
 865  
      * the user to bring up a search screen for finding valid field values. The
 866  
      * <code>Widget</code> instance can be configured to point to a certain
 867  
      * <code>LookupView</code>, or the framework will attempt to associate the
 868  
      * field with a lookup based on its metadata (in particular its
 869  
      * relationships in the model)
 870  
      * </p>
 871  
      * 
 872  
      * @return QuickFinder lookup widget
 873  
      */
 874  
     public QuickFinder getFieldLookup() {
 875  0
         return this.fieldLookup;
 876  
     }
 877  
 
 878  
     /**
 879  
      * Setter for the lookup widget
 880  
      * 
 881  
      * @param fieldLookup
 882  
      */
 883  
     public void setFieldLookup(QuickFinder fieldLookup) {
 884  0
         this.fieldLookup = fieldLookup;
 885  0
     }
 886  
 
 887  
     /**
 888  
      * Inquiry widget for the field
 889  
      * 
 890  
      * <p>
 891  
      * The inquiry widget will render a link for the field value when read-only
 892  
      * that points to the associated inquiry view for the field. The inquiry can
 893  
      * be configured to point to a certain <code>InquiryView</code>, or the
 894  
      * framework will attempt to associate the field with a inquiry based on its
 895  
      * metadata (in particular its relationships in the model)
 896  
      * </p>
 897  
      * 
 898  
      * @return Inquiry field inquiry
 899  
      */
 900  
     public Inquiry getFieldInquiry() {
 901  0
         return this.fieldInquiry;
 902  
     }
 903  
 
 904  
     /**
 905  
      * Setter for the inquiry widget
 906  
      * 
 907  
      * @param fieldInquiry
 908  
      */
 909  
     public void setFieldInquiry(Inquiry fieldInquiry) {
 910  0
         this.fieldInquiry = fieldInquiry;
 911  0
     }
 912  
 
 913  
     /**
 914  
      * Suggest box widget for the attribute field
 915  
      *
 916  
      * <p>
 917  
      * If enabled (by render flag), as the user inputs data into the
 918  
      * fields control a dynamic query is performed to provide the user
 919  
      * suggestions on values which they can then select
 920  
      * </p>
 921  
      *
 922  
      * <p>
 923  
      * Note the Suggest widget is only valid when using a standard TextControl
 924  
      * </p>
 925  
      *
 926  
      * @return Suggest instance
 927  
      */
 928  
     public Suggest getFieldSuggest() {
 929  0
         return fieldSuggest;
 930  
     }
 931  
 
 932  
     /**
 933  
      * Setter for the fields Suggest widget
 934  
      *
 935  
      * @param fieldSuggest
 936  
      */
 937  
     public void setFieldSuggest(Suggest fieldSuggest) {
 938  0
         this.fieldSuggest = fieldSuggest;
 939  0
     }
 940  
 
 941  
     /**
 942  
      * @return the summaryField
 943  
      */
 944  
     public MessageField getSummaryMessageField() {
 945  0
         return this.summaryMessageField;
 946  
     }
 947  
 
 948  
     /**
 949  
      * Sets the summary message field. Developers can use the setSummary method
 950  
      * which would set the summary text.
 951  
      * 
 952  
      * @param summary
 953  
      *            field to set
 954  
      * @see setSummary
 955  
      */
 956  
     public void setSummaryMessageField(MessageField summaryField) {
 957  0
         this.summaryMessageField = summaryField;
 958  0
     }
 959  
 
 960  
     /**
 961  
      * Returns the contraint set on the field
 962  
      * 
 963  
      * @return the constraint
 964  
      */
 965  
     public String getConstraint() {
 966  0
         return this.constraint;
 967  
     }
 968  
 
 969  
     /**
 970  
      * Sets the constraint text. This text will be displayed below the
 971  
      * component.
 972  
      * 
 973  
      * @param constraint
 974  
      *            for this field
 975  
      */
 976  
     public void setConstraint(String constraint) {
 977  0
         this.constraint = constraint;
 978  0
     }
 979  
 
 980  
     /**
 981  
      * Sets the constraint message field. Developers can use the setContraint
 982  
      * method which would set the constraint text.
 983  
      * 
 984  
      * @param constraint
 985  
      *            field to set
 986  
      * @see setContraint
 987  
      */
 988  
     public void setConstraintMessageField(MessageField constraintMessageField) {
 989  0
         this.constraintMessageField = constraintMessageField;
 990  0
     }
 991  
 
 992  
     /**
 993  
      * Returns the contraint message field.
 994  
      * 
 995  
      * @return constraint Message Field
 996  
      */
 997  
     public MessageField getConstraintMessageField() {
 998  0
         return this.constraintMessageField;
 999  
     }
 1000  
 
 1001  
     /**
 1002  
      * Valid character constraint that defines regular expressions for the valid
 1003  
      * characters for this field
 1004  
      * 
 1005  
      * @return the validCharactersConstraint
 1006  
      */
 1007  
     public ValidCharactersConstraint getValidCharactersConstraint() {
 1008  0
         return this.validCharactersConstraint;
 1009  
     }
 1010  
 
 1011  
     /**
 1012  
      * @param validCharactersConstraint
 1013  
      *            the validCharactersConstraint to set
 1014  
      */
 1015  
     public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
 1016  0
         this.validCharactersConstraint = validCharactersConstraint;
 1017  0
     }
 1018  
 
 1019  
     /**
 1020  
      * @return the caseConstraint
 1021  
      */
 1022  
     public CaseConstraint getCaseConstraint() {
 1023  0
         return this.caseConstraint;
 1024  
     }
 1025  
 
 1026  
     /**
 1027  
      * @param caseConstraint
 1028  
      *            the caseConstraint to set
 1029  
      */
 1030  
     public void setCaseConstraint(CaseConstraint caseConstraint) {
 1031  0
         this.caseConstraint = caseConstraint;
 1032  0
     }
 1033  
 
 1034  
     /**
 1035  
      * @return the dependencyConstraints
 1036  
      */
 1037  
     public List<PrerequisiteConstraint> getDependencyConstraints() {
 1038  0
         return this.dependencyConstraints;
 1039  
     }
 1040  
 
 1041  
     /**
 1042  
      * @param dependencyConstraints
 1043  
      *            the dependencyConstraints to set
 1044  
      */
 1045  
     public void setDependencyConstraints(List<PrerequisiteConstraint> dependencyConstraints) {
 1046  0
         this.dependencyConstraints = dependencyConstraints;
 1047  0
     }
 1048  
 
 1049  
     /**
 1050  
      * @return the mustOccurConstraints
 1051  
      */
 1052  
     public List<MustOccurConstraint> getMustOccurConstraints() {
 1053  0
         return this.mustOccurConstraints;
 1054  
     }
 1055  
 
 1056  
     /**
 1057  
      * @param mustOccurConstraints
 1058  
      *            the mustOccurConstraints to set
 1059  
      */
 1060  
     public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
 1061  0
         this.mustOccurConstraints = mustOccurConstraints;
 1062  0
     }
 1063  
 
 1064  
     /**
 1065  
      * A simple constraint which store the values for required, min/max length,
 1066  
      * and min/max value
 1067  
      * 
 1068  
      * @return the simpleConstraint
 1069  
      */
 1070  
     public SimpleConstraint getSimpleConstraint() {
 1071  0
         return this.simpleConstraint;
 1072  
     }
 1073  
 
 1074  
     /**
 1075  
      * When a simple constraint is set on this object ALL simple validation
 1076  
      * constraints set directly will be overridden - recommended to use this or
 1077  
      * the other gets/sets for defining simple constraints, not both
 1078  
      * 
 1079  
      * @param simpleConstraint
 1080  
      *            the simpleConstraint to set
 1081  
      */
 1082  
     public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
 1083  0
         this.simpleConstraint = simpleConstraint;
 1084  0
     }
 1085  
 
 1086  
     /**
 1087  
      * Maximum number of the characters the attribute value is allowed to have.
 1088  
      * Used to set the maxLength for supporting controls. Note this can be
 1089  
      * smaller or longer than the actual control size
 1090  
      * 
 1091  
      * @return Integer max length
 1092  
      */
 1093  
     public Integer getMaxLength() {
 1094  0
         return simpleConstraint.getMaxLength();
 1095  
     }
 1096  
 
 1097  
     /**
 1098  
      * Setter for attributes max length
 1099  
      * 
 1100  
      * @param maxLength
 1101  
      */
 1102  
     public void setMaxLength(Integer maxLength) {
 1103  0
         simpleConstraint.setMaxLength(maxLength);
 1104  0
     }
 1105  
 
 1106  
     /**
 1107  
      * @return the minLength
 1108  
      */
 1109  
     public Integer getMinLength() {
 1110  0
         return simpleConstraint.getMinLength();
 1111  
     }
 1112  
 
 1113  
     /**
 1114  
      * @param minLength
 1115  
      *            the minLength to set
 1116  
      */
 1117  
     public void setMinLength(Integer minLength) {
 1118  0
         simpleConstraint.setMinLength(minLength);
 1119  0
     }
 1120  
 
 1121  
     /**
 1122  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#getRequired()
 1123  
      */
 1124  
     @Override
 1125  
     public Boolean getRequired() {
 1126  0
         return this.simpleConstraint.getRequired();
 1127  
     }
 1128  
 
 1129  
     /**
 1130  
      * @see org.kuali.rice.krad.uif.core.ComponentBase#setRequired(java.lang.Boolean)
 1131  
      */
 1132  
     @Override
 1133  
     public void setRequired(Boolean required) {
 1134  0
         this.simpleConstraint.setRequired(required);
 1135  0
     }
 1136  
 
 1137  
     /**
 1138  
      * The exclusiveMin element determines the minimum allowable value for data
 1139  
      * entry editing purposes. Value can be an integer or decimal value such as
 1140  
      * -.001 or 99.
 1141  
      */
 1142  
     public String getExclusiveMin() {
 1143  0
         return simpleConstraint.getExclusiveMin();
 1144  
     }
 1145  
 
 1146  
     /**
 1147  
      * @param minValue
 1148  
      *            the minValue to set
 1149  
      */
 1150  
     public void setExclusiveMin(String exclusiveMin) {
 1151  0
         simpleConstraint.setExclusiveMin(exclusiveMin);
 1152  0
     }
 1153  
 
 1154  
     /**
 1155  
      * The inclusiveMax element determines the maximum allowable value for data
 1156  
      * entry editing purposes. Value can be an integer or decimal value such as
 1157  
      * -.001 or 99.
 1158  
      * 
 1159  
      * JSTL: This field is mapped into the field named "exclusiveMax".
 1160  
      */
 1161  
     public String getInclusiveMax() {
 1162  0
         return simpleConstraint.getInclusiveMax();
 1163  
     }
 1164  
 
 1165  
     /**
 1166  
      * @param maxValue
 1167  
      *            the maxValue to set
 1168  
      */
 1169  
     public void setInclusiveMax(String inclusiveMax) {
 1170  0
         simpleConstraint.setInclusiveMax(inclusiveMax);
 1171  0
     }
 1172  
 
 1173  
       /**
 1174  
      * Additional display attribute name, which will be displayed next to the actual field value
 1175  
      * when the field is readonly with hypen inbetween like PropertyValue - AdditionalPropertyValue
 1176  
      *
 1177  
      * @param additionalDisplayPropertyName - Name of the additional display property
 1178  
      */
 1179  
         public void setAdditionalDisplayPropertyName(String additionalDisplayPropertyName) {
 1180  0
                 this.additionalDisplayPropertyName = additionalDisplayPropertyName;
 1181  0
         }
 1182  
 
 1183  
         /**
 1184  
          * Returns the additional display attribute name to be displayed when the field is readonly
 1185  
          *
 1186  
          * @return Additional Display Attribute Name
 1187  
          */
 1188  
         public String getAdditionalDisplayPropertyName() {
 1189  0
                 return this.additionalDisplayPropertyName;
 1190  
         }
 1191  
 
 1192  
         /**
 1193  
      * Additional display attribute's binding info. Based on the object path, the additional display
 1194  
      * attribute's value will be used to display when the field is readonly
 1195  
      *
 1196  
      * @param alternateDisplayPropertyBindingInfo - <code>BindingInfo</code> for the additional display property to set
 1197  
      */
 1198  
         public void setAdditionalDisplayPropertyBindingInfo(BindingInfo additionalDisplayPropertyBindingInfo) {
 1199  0
                 this.additionalDisplayPropertyBindingInfo = additionalDisplayPropertyBindingInfo;
 1200  0
         }
 1201  
 
 1202  
         /**
 1203  
          * Returns the additional display attribute's binding info object
 1204  
          *
 1205  
          * @return <code>BindingInfo</code> of the additional display property
 1206  
          */
 1207  
         public BindingInfo getAdditionalDisplayPropertyBindingInfo() {
 1208  0
                 return this.additionalDisplayPropertyBindingInfo;
 1209  
         }
 1210  
 
 1211  
         /**
 1212  
          * Sets the alternate display attribute name to be displayed when the field is readonly.
 1213  
          * This properties value will be displayed instead of actual fields value when the field is readonly.
 1214  
          *
 1215  
          * @param alternateDisplayPropertyName - alternate display property name
 1216  
          */
 1217  
         public void setAlternateDisplayPropertyName(String alternateDisplayPropertyName) {
 1218  0
                 this.alternateDisplayPropertyName = alternateDisplayPropertyName;
 1219  0
         }
 1220  
 
 1221  
         /**
 1222  
          * Returns the alternate display attribute name to be displayed when the field is readonly.
 1223  
          *
 1224  
          * @return alternate Display Property Name
 1225  
          */
 1226  
         public String getAlternateDisplayPropertyName() {
 1227  0
                 return this.alternateDisplayPropertyName;
 1228  
         }
 1229  
 
 1230  
         /**
 1231  
          * Sets the binding info for the alternate display attribute name. If it's set, it's object path
 1232  
          * will be used to determine the alternate display attributes value.
 1233  
          *
 1234  
          * @param alternateDisplayPropertyBindingInfo - <code>BindingInfo</code> of the alternate display property to set
 1235  
          */
 1236  
         public void setAlternateDisplayPropertyBindingInfo(BindingInfo alternateDisplayPropertyBindingInfo) {
 1237  0
                 this.alternateDisplayPropertyBindingInfo = alternateDisplayPropertyBindingInfo;
 1238  0
         }
 1239  
 
 1240  
         /**
 1241  
          * Returns the binding info object of the alternate display attribute
 1242  
          *
 1243  
          * @return <code>BindingInfo</code> of the alternate display property
 1244  
          */
 1245  
         public BindingInfo getAlternateDisplayPropertyBindingInfo() {
 1246  0
                 return this.alternateDisplayPropertyBindingInfo;
 1247  
         }
 1248  
 
 1249  
         /**
 1250  
          * Returns the alternate display value
 1251  
          *
 1252  
          * @return the alternate display value set for this field
 1253  
          */
 1254  
         public String getAlternateDisplayValue(){
 1255  0
                 return alternateDisplayValue;
 1256  
         }
 1257  
 
 1258  
     /**
 1259  
      * Returns the additional display value.
 1260  
      *
 1261  
      * @return the additional display value set for this field
 1262  
      */
 1263  
     public String getAdditionalDisplayValue() {
 1264  0
         return additionalDisplayValue;
 1265  
     }
 1266  
         
 1267  
         /**
 1268  
          * Setter for the direct inquiry widget
 1269  
          * 
 1270  
          * @param the <code>DirectInquiry</code> field DirectInquiry to set
 1271  
          */
 1272  
         public void setFieldDirectInquiry(DirectInquiry fieldDirectInquiry) {
 1273  0
                 this.fieldDirectInquiry = fieldDirectInquiry;
 1274  0
         }
 1275  
 
 1276  
     /**
 1277  
      * DirectInquiry widget for the field
 1278  
      *
 1279  
      * <p>
 1280  
      * The direct inquiry widget will render a button for the field value when
 1281  
      * that field is editable. It points to the associated inquiry view for the
 1282  
      * field. The inquiry can be configured to point to a certain
 1283  
      * <code>InquiryView</code>, or the framework will attempt to associate the
 1284  
      * field with a inquiry based on its metadata (in particular its
 1285  
      * relationships in the model)
 1286  
      * </p>
 1287  
      * 
 1288  
      * @return the <code>DirectInquiry</code> field DirectInquiry
 1289  
      */
 1290  
     public DirectInquiry getFieldDirectInquiry() {
 1291  0
         return fieldDirectInquiry;
 1292  
     }
 1293  
 
 1294  
     /**
 1295  
      * List of property names whose values should be displayed read-only under this field
 1296  
      *
 1297  
      * <p>
 1298  
      * In the attribute field template for each information property name given its values is
 1299  
      * outputted read-only. Informational property values can also be updated dynamically with
 1300  
      * the use of field attribute query
 1301  
      * </p>
 1302  
      *
 1303  
      * <p>
 1304  
      * Simple property names can be given if the property has the same binding parent as this
 1305  
      * field, in which case the binding path will be adjusted by the framework. If the property
 1306  
      * names starts with org.kuali.rice.krad.uif.UifConstants#NO_BIND_ADJUST_PREFIX, no binding
 1307  
      * prefix will be added.
 1308  
      * </p>
 1309  
      *
 1310  
      * @return List<String> informational property names
 1311  
      */
 1312  
     public List<String> getInformationalDisplayPropertyNames() {
 1313  0
         return informationalDisplayPropertyNames;
 1314  
     }
 1315  
 
 1316  
     /**
 1317  
      * Setter for the list of informational property names
 1318  
      *
 1319  
      * @param informationalDisplayPropertyNames
 1320  
      */
 1321  
     public void setInformationalDisplayPropertyNames(List<String> informationalDisplayPropertyNames) {
 1322  0
         this.informationalDisplayPropertyNames = informationalDisplayPropertyNames;
 1323  0
     }
 1324  
 
 1325  
     /**
 1326  
      * Allows specifying hidden property names without having to specify as a
 1327  
      * field in the group config (that might impact layout)
 1328  
      *
 1329  
      * @return List<String> hidden property names
 1330  
      */
 1331  
     public List<String> getHiddenPropertyNames() {
 1332  0
         return hiddenPropertyNames;
 1333  
     }
 1334  
 
 1335  
     /**
 1336  
      * Setter for the hidden property names
 1337  
      *
 1338  
      * @param hiddenPropertyNames
 1339  
      */
 1340  
     public void setHiddenPropertyNames(List<String> hiddenPropertyNames) {
 1341  0
         this.hiddenPropertyNames = hiddenPropertyNames;
 1342  0
     }
 1343  
 
 1344  
     /**
 1345  
      * Attribute query instance configured for this field to dynamically pull information back for
 1346  
      * updates other fields or providing messages
 1347  
      *
 1348  
      * <p>
 1349  
      * If field attribute query is not null, associated event script will be generated to trigger the
 1350  
      * query from the UI. This will invoke the <code>AttributeQueryService</code> to
 1351  
      * execute the query and return an instance of <code>AttributeQueryResult</code> that is then
 1352  
      * read by the script to update the UI. Typically used to update informational property values or
 1353  
      * other field values
 1354  
      * </p>
 1355  
      *
 1356  
      * @return AttributeQuery instance
 1357  
      */
 1358  
     public AttributeQuery getFieldAttributeQuery() {
 1359  0
         return fieldAttributeQuery;
 1360  
     }
 1361  
 
 1362  
     /**
 1363  
      * Setter for this fields query
 1364  
      *
 1365  
      * @param fieldAttributeQuery
 1366  
      */
 1367  
     public void setFieldAttributeQuery(AttributeQuery fieldAttributeQuery) {
 1368  0
         this.fieldAttributeQuery = fieldAttributeQuery;
 1369  0
     }
 1370  
     
 1371  
     /**
 1372  
          * Sets HTML escaping for this property value. HTML escaping will be handled in alternate and additional fields also.
 1373  
          * 
 1374  
          */
 1375  
         public void setEscapeHtmlInPropertyValue(boolean escapeHtmlInPropertyValue) {
 1376  0
                 this.escapeHtmlInPropertyValue = escapeHtmlInPropertyValue;
 1377  0
         }
 1378  
         
 1379  
     /**
 1380  
      * Returns true if HTML escape allowed for this field
 1381  
      * 
 1382  
          * @return true if escaping allowed
 1383  
          */
 1384  
         public boolean isEscapeHtmlInPropertyValue() {
 1385  0
                 return this.escapeHtmlInPropertyValue;
 1386  
         }
 1387  
         
 1388  
 }