Coverage Report - org.kuali.rice.krad.uif.field.DataField
 
Classes in this File Line Coverage Branch Coverage Complexity
DataField
5%
8/143
0%
0/60
1.809
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.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/ecl2.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.web.format.Formatter;
 20  
 import org.kuali.rice.krad.bo.DataObjectRelationship;
 21  
 import org.kuali.rice.krad.bo.KualiCode;
 22  
 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
 23  
 import org.kuali.rice.krad.datadictionary.AttributeSecurity;
 24  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 25  
 import org.kuali.rice.krad.uif.component.BindingInfo;
 26  
 import org.kuali.rice.krad.uif.component.Component;
 27  
 import org.kuali.rice.krad.uif.component.DataBinding;
 28  
 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
 29  
 import org.kuali.rice.krad.uif.util.ViewModelUtils;
 30  
 import org.kuali.rice.krad.uif.view.View;
 31  
 import org.kuali.rice.krad.uif.widget.Inquiry;
 32  
 import org.kuali.rice.krad.util.KRADPropertyConstants;
 33  
 import org.kuali.rice.krad.util.ObjectUtils;
 34  
 import org.kuali.rice.krad.valuefinder.ValueFinder;
 35  
 
 36  
 import java.util.ArrayList;
 37  
 import java.util.List;
 38  
 
 39  
 /**
 40  
  * Field that renders data from the application, such as the value of a data object property
 41  
  *
 42  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 43  
  */
 44  
 public class DataField extends FieldBase implements DataBinding {
 45  
     private static final long serialVersionUID = -4129678891948564724L;
 46  
 
 47  
     // binding
 48  
     private String propertyName;
 49  
     private BindingInfo bindingInfo;
 50  
 
 51  
     private String dictionaryAttributeName;
 52  
     private String dictionaryObjectEntry;
 53  
 
 54  
     // value props
 55  
     private String defaultValue;
 56  
     private Class<? extends ValueFinder> defaultValueFinderClass;
 57  
 
 58  
     private Formatter formatter;
 59  
     private AttributeSecurity attributeSecurity;
 60  
 
 61  
     private boolean readOnlyHidden;
 62  
 
 63  
     // alternate and additional display properties
 64  
     protected String alternateDisplayPropertyName;
 65  
     protected String additionalDisplayPropertyName;
 66  
 
 67  
     private String alternateDisplayValue;
 68  
     private String additionalDisplayValue;
 69  
 
 70  
     private List<String> hiddenPropertyNames;
 71  
     private List<String> informationalDisplayPropertyNames;
 72  
 
 73  
     private boolean escapeHtmlInPropertyValue;
 74  
 
 75  
     private String helpSummary;
 76  
     private String helpDescription;
 77  
 
 78  
     // widgets
 79  
     private Inquiry fieldInquiry;
 80  
 
 81  
     public DataField() {
 82  2
         super();
 83  
 
 84  2
         readOnlyHidden = false;
 85  2
         hiddenPropertyNames = new ArrayList<String>();
 86  2
         informationalDisplayPropertyNames = new ArrayList<String>();
 87  2
     }
 88  
 
 89  
     /**
 90  
      * The following initialization is performed:
 91  
      *
 92  
      * <ul>
 93  
      * <li>Set defaults for binding</li>
 94  
      * <li>Default the model path if not set</li>
 95  
      * </ul>
 96  
      *
 97  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View,
 98  
      *      java.lang.Object)
 99  
      */
 100  
     @Override
 101  
     public void performInitialization(View view, Object model) {
 102  0
         super.performInitialization(view, model);
 103  
 
 104  0
         if (bindingInfo != null) {
 105  0
             bindingInfo.setDefaults(view, getPropertyName());
 106  
         }
 107  0
     }
 108  
 
 109  
     /**
 110  
      * The following updates are done here:
 111  
      *
 112  
      * <ul>
 113  
      * <li>If readOnlyHidden set to true, set field to readonly and add to hidden property names</li>
 114  
      * </ul>
 115  
      */
 116  
     public void performApplyModel(View view, Object model, Component parent) {
 117  0
         super.performApplyModel(view, model, parent);
 118  
 
 119  0
         if (isReadOnlyHidden()) {
 120  0
             setReadOnly(true);
 121  0
             getHiddenPropertyNames().add(getPropertyName());
 122  
         }
 123  0
     }
 124  
 
 125  
     /**
 126  
      * The following actions are performed:
 127  
      *
 128  
      * <ul>
 129  
      * <li>Set the ids for the various attribute components</li>
 130  
      * <li>Sets up the client side validation for constraints on this field. In
 131  
      * addition, it sets up the messages applied to this field</li>
 132  
      * </ul>
 133  
      *
 134  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#performFinalize(org.kuali.rice.krad.uif.view.View,
 135  
      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
 136  
      */
 137  
     @Override
 138  
     public void performFinalize(View view, Object model, Component parent) {
 139  0
         super.performFinalize(view, model, parent);
 140  
 
 141  
         // adjust the path for hidden fields
 142  
         // TODO: should this check the view#readOnly?
 143  0
         List<String> hiddenPropertyPaths = new ArrayList<String>();
 144  0
         for (String hiddenPropertyName : getHiddenPropertyNames()) {
 145  0
             String hiddenPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(hiddenPropertyName);
 146  0
             hiddenPropertyPaths.add(hiddenPropertyPath);
 147  0
         }
 148  0
         this.hiddenPropertyNames = hiddenPropertyPaths;
 149  
 
 150  
         // adjust paths on informational property names
 151  0
         List<String> informationalPropertyPaths = new ArrayList<String>();
 152  0
         for (String infoPropertyName : getInformationalDisplayPropertyNames()) {
 153  0
             String infoPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(infoPropertyName);
 154  0
             informationalPropertyPaths.add(infoPropertyPath);
 155  0
         }
 156  0
         this.informationalDisplayPropertyNames = informationalPropertyPaths;
 157  
 
 158  
         // Additional and Alternate display value
 159  0
         setAlternateAndAdditionalDisplayValue(view, model);
 160  0
     }
 161  
 
 162  
     /**
 163  
      * Sets alternate and additional property value for this field.
 164  
      *
 165  
      * <p>
 166  
      * If <code>AttributeSecurity</code> present in this field, make sure the current user has permission to view the
 167  
      * field value. If user doesn't have permission to view the value, mask the value as configured and set it
 168  
      * as alternate value for display. If security doesn't exists for this field but
 169  
      * <code>alternateDisplayPropertyName</code> present, get its value and format it based on that
 170  
      * fields formatting and set for display.
 171  
      * </p>
 172  
      *
 173  
      * <p>
 174  
      * For additional display value, if <code>AttributeSecurity</code> not present, sets the value if
 175  
      * <code>additionalDisplayPropertyName</code> present. If not present, check whether this field is a
 176  
      * <code>KualiCode</code> and get the relationship configured in the datadictionary file and set the name
 177  
      * additional display value which will be displayed along with the code. If additional display property not
 178  
      * present,
 179  
      * check whether this field is has <code>MultiValueControlBase</code>. If yes, get the Label for the value and
 180  
      * set it as additional display value.
 181  
      * </p>
 182  
      *
 183  
      * @param view - the current view instance
 184  
      * @param model - model instance
 185  
      */
 186  
     protected void setAlternateAndAdditionalDisplayValue(View view, Object model) {
 187  
         // if alternate or additional display values set don't use property names
 188  0
         if (StringUtils.isNotBlank(alternateDisplayValue) || StringUtils.isNotBlank(additionalDisplayValue)) {
 189  0
             return;
 190  
         }
 191  
 
 192  
         // check whether field value needs to be masked, and if so apply masking as alternateDisplayValue
 193  0
         if (getAttributeSecurity() != null) {
 194  
             //TODO: Check authorization
 195  
             // if (attributeSecurity.isMask() && !boAuthzService.canFullyUnmaskField(user,dataObjectClass, field.getPropertyName(), null)) {
 196  0
             Object fieldValue = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
 197  0
             alternateDisplayValue = getSecuredFieldValue(attributeSecurity, fieldValue);
 198  
 
 199  0
             setReadOnly(true);
 200  0
             return;
 201  
         }
 202  
 
 203  
         // if not read only, return without trying to set alternate and additional values
 204  0
         if (!isReadOnly()) {
 205  0
             return;
 206  
         }
 207  
 
 208  
         // if field is not secure, check for alternate and additional display properties
 209  0
         if (StringUtils.isNotBlank(getAlternateDisplayPropertyName())) {
 210  0
             String alternateDisplayPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(
 211  
                     getAlternateDisplayPropertyName());
 212  
 
 213  0
             Object alternateFieldValue = ObjectPropertyUtils.getPropertyValue(model, alternateDisplayPropertyPath);
 214  0
             if (alternateFieldValue != null) {
 215  
                 // TODO: format by type
 216  0
                 alternateDisplayValue = alternateFieldValue.toString();
 217  
             }
 218  
         }
 219  
 
 220  
         // perform automatic translation for code references if enabled on view
 221  0
         if (StringUtils.isBlank(getAdditionalDisplayPropertyName()) && view.isTranslateCodes()) {
 222  
             // check for any relationship present for this field and it's of type KualiCode
 223  0
             Class<?> parentObjectClass = ViewModelUtils.getParentObjectClassForMetadata(view, model, this);
 224  0
             DataObjectRelationship relationship =
 225  
                     KRADServiceLocatorWeb.getDataObjectMetaDataService().getDataObjectRelationship(null,
 226  
                             parentObjectClass, getBindingInfo().getBindingName(), "", true, false, false);
 227  
 
 228  0
             if (relationship != null
 229  
                     && getPropertyName().startsWith(relationship.getParentAttributeName())
 230  
                     && KualiCode.class.isAssignableFrom(relationship.getRelatedClass())) {
 231  0
                 additionalDisplayPropertyName =
 232  
                         relationship.getParentAttributeName() + "." + KRADPropertyConstants.NAME;
 233  
             }
 234  
         }
 235  
 
 236  
         // now check for an additional display property and if set get the value
 237  0
         if (StringUtils.isNotBlank(getAdditionalDisplayPropertyName())) {
 238  0
             String additionalDisplayPropertyPath = getBindingInfo().getPropertyAdjustedBindingPath(
 239  
                     getAdditionalDisplayPropertyName());
 240  
 
 241  0
             Object additionalFieldValue = ObjectPropertyUtils.getPropertyValue(model, additionalDisplayPropertyPath);
 242  0
             if (additionalFieldValue != null) {
 243  
                 // TODO: format by type
 244  0
                 additionalDisplayValue = additionalFieldValue.toString();
 245  
             }
 246  
         }
 247  0
     }
 248  
 
 249  
     /**
 250  
      * Helper method which returns the masked value based on the <code>AttributeSecurity</code>
 251  
      *
 252  
      * @param attributeSecurity attribute security to check
 253  
      * @param fieldValue field value
 254  
      * @return masked value
 255  
      */
 256  
     protected String getSecuredFieldValue(AttributeSecurity attributeSecurity, Object fieldValue) {
 257  0
         if (attributeSecurity.isMask()) {
 258  0
             return attributeSecurity.getMaskFormatter().maskValue(fieldValue);
 259  0
         } else if (getAttributeSecurity().isPartialMask()) {
 260  0
             return attributeSecurity.getPartialMaskFormatter().maskValue(fieldValue);
 261  
         } else {
 262  0
             throw new RuntimeException("Encountered unsupported Attribute Security..");
 263  
         }
 264  
     }
 265  
 
 266  
     /**
 267  
      * Defaults the properties of the <code>DataField</code> to the
 268  
      * corresponding properties of its <code>AttributeDefinition</code>
 269  
      * retrieved from the dictionary (if such an entry exists). If the field
 270  
      * already contains a value for a property, the definitions value is not
 271  
      * used.
 272  
      *
 273  
      * @param view - view instance the field belongs to
 274  
      * @param attributeDefinition - AttributeDefinition instance the property values should be
 275  
      * copied from
 276  
      */
 277  
     public void copyFromAttributeDefinition(View view, AttributeDefinition attributeDefinition) {
 278  
         // label
 279  0
         if (StringUtils.isEmpty(getLabel())) {
 280  0
             setLabel(attributeDefinition.getLabel());
 281  
         }
 282  
 
 283  
         // short label
 284  0
         if (StringUtils.isEmpty(getShortLabel())) {
 285  0
             setShortLabel(attributeDefinition.getShortLabel());
 286  
         }
 287  
 
 288  
         // summary
 289  0
         if (StringUtils.isEmpty(getHelpSummary())) {
 290  0
             setHelpSummary(attributeDefinition.getSummary());
 291  
         }
 292  
 
 293  
         // description
 294  0
         if (StringUtils.isEmpty(getHelpDescription())) {
 295  0
             setHelpDescription(attributeDefinition.getDescription());
 296  
         }
 297  
 
 298  
         // security
 299  0
         if (getAttributeSecurity() == null) {
 300  0
             attributeSecurity = attributeDefinition.getAttributeSecurity();
 301  
         }
 302  
 
 303  
         // alternate property name
 304  0
         if (getAlternateDisplayPropertyName() == null && StringUtils.isNotBlank(
 305  
                 attributeDefinition.getAlternateDisplayAttributeName())) {
 306  0
             setAlternateDisplayPropertyName(attributeDefinition.getAlternateDisplayAttributeName());
 307  
         }
 308  
 
 309  
         // additional property display name
 310  0
         if (getAdditionalDisplayPropertyName() == null && StringUtils.isNotBlank(
 311  
                 attributeDefinition.getAdditionalDisplayAttributeName())) {
 312  0
             setAdditionalDisplayPropertyName(attributeDefinition.getAdditionalDisplayAttributeName());
 313  
         }
 314  
 
 315  0
         if (getFormatter() == null && StringUtils.isNotBlank(attributeDefinition.getFormatterClass())) {
 316  0
             Class clazz = null;
 317  
             try {
 318  0
                 clazz = Class.forName(attributeDefinition.getFormatterClass());
 319  0
             } catch (ClassNotFoundException e) {
 320  0
                 throw new RuntimeException("Unable to get class from name: " + attributeDefinition.getFormatterClass(),
 321  
                         e);
 322  0
             }
 323  
 
 324  0
             Formatter formatter = (Formatter) ObjectUtils.newInstance(clazz);
 325  0
             setFormatter(formatter);
 326  
         }
 327  0
     }
 328  
 
 329  
     /**
 330  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
 331  
      */
 332  
     @Override
 333  
     public List<Component> getComponentsForLifecycle() {
 334  0
         List<Component> components = super.getComponentsForLifecycle();
 335  
 
 336  0
         components.add(fieldInquiry);
 337  
 
 338  0
         return components;
 339  
     }
 340  
 
 341  
     /**
 342  
      * Indicates whether the data field instance allows input, subclasses should override and set to
 343  
      * true if input is allowed
 344  
      *
 345  
      * @return boolean true if input is allowed, false if read only
 346  
      */
 347  
     public boolean isInputAllowed() {
 348  0
         return false;
 349  
     }
 350  
 
 351  
     /**
 352  
      * @see org.kuali.rice.krad.uif.component.DataBinding#getPropertyName()
 353  
      */
 354  
     public String getPropertyName() {
 355  0
         return this.propertyName;
 356  
     }
 357  
 
 358  
     /**
 359  
      * Setter for the component's property name
 360  
      *
 361  
      * @param propertyName
 362  
      */
 363  
     public void setPropertyName(String propertyName) {
 364  0
         this.propertyName = propertyName;
 365  0
     }
 366  
 
 367  
     /**
 368  
      * <code>Formatter</code> instance that should be used when displaying and
 369  
      * accepting the field's value in the user interface
 370  
      *
 371  
      * <p>
 372  
      * Formatters can provide conversion between datatypes in addition to
 373  
      * special string formatting such as currency display
 374  
      * </p>
 375  
      *
 376  
      * @return Formatter instance
 377  
      * @see org.kuali.rice.core.web.format.Formatter
 378  
      */
 379  
     public Formatter getFormatter() {
 380  0
         return this.formatter;
 381  
     }
 382  
 
 383  
     /**
 384  
      * Setter for the field's formatter
 385  
      *
 386  
      * @param formatter
 387  
      */
 388  
     public void setFormatter(Formatter formatter) {
 389  0
         this.formatter = formatter;
 390  0
     }
 391  
 
 392  
     /**
 393  
      * @see org.kuali.rice.krad.uif.component.DataBinding#getBindingInfo()
 394  
      */
 395  
     public BindingInfo getBindingInfo() {
 396  2
         return this.bindingInfo;
 397  
     }
 398  
 
 399  
     /**
 400  
      * Setter for the field's binding info
 401  
      *
 402  
      * @param bindingInfo
 403  
      */
 404  
     public void setBindingInfo(BindingInfo bindingInfo) {
 405  2
         this.bindingInfo = bindingInfo;
 406  2
     }
 407  
 
 408  
     /**
 409  
      * Name of the attribute within the data dictionary the attribute field is
 410  
      * associated with
 411  
      *
 412  
      * <p>
 413  
      * During the initialize phase for the <code>View</code>, properties for
 414  
      * attribute fields are defaulted from a corresponding
 415  
      * <code>AttributeDefinition</code> in the data dictionary. Based on the
 416  
      * propertyName and parent object class the framework attempts will
 417  
      * determine the attribute definition that is associated with the field and
 418  
      * set this property. However this property can also be set in the fields
 419  
      * configuration to use another dictionary attribute.
 420  
      * </p>
 421  
      * <p>
 422  
      * The attribute name is used along with the dictionary object entry to find
 423  
      * the <code>AttributeDefinition</code>
 424  
      * </p>
 425  
      *
 426  
      * @return String attribute name
 427  
      */
 428  
     public String getDictionaryAttributeName() {
 429  0
         return this.dictionaryAttributeName;
 430  
     }
 431  
 
 432  
     /**
 433  
      * Setter for the dictionary attribute name
 434  
      *
 435  
      * @param dictionaryAttributeName
 436  
      */
 437  
     public void setDictionaryAttributeName(String dictionaryAttributeName) {
 438  0
         this.dictionaryAttributeName = dictionaryAttributeName;
 439  0
     }
 440  
 
 441  
     /**
 442  
      * Object entry name in the data dictionary the associated attribute is
 443  
      * apart of
 444  
      *
 445  
      * <p>
 446  
      * During the initialize phase for the <code>View</code>, properties for
 447  
      * attribute fields are defaulted from a corresponding
 448  
      * <code>AttributeDefinition</code> in the data dictionary. Based on the
 449  
      * parent object class the framework will determine the object entry for the
 450  
      * associated attribute. However the object entry can be set in the field's
 451  
      * configuration to use another object entry for the attribute
 452  
      * </p>
 453  
      *
 454  
      * <p>
 455  
      * The attribute name is used along with the dictionary object entry to find
 456  
      * the <code>AttributeDefinition</code>
 457  
      * </p>
 458  
      *
 459  
      * @return
 460  
      */
 461  
     public String getDictionaryObjectEntry() {
 462  0
         return this.dictionaryObjectEntry;
 463  
     }
 464  
 
 465  
     /**
 466  
      * Setter for the dictionary object entry
 467  
      *
 468  
      * @param dictionaryObjectEntry
 469  
      */
 470  
     public void setDictionaryObjectEntry(String dictionaryObjectEntry) {
 471  0
         this.dictionaryObjectEntry = dictionaryObjectEntry;
 472  0
     }
 473  
 
 474  
     /**
 475  
      * Default value for the model property the field points to
 476  
      *
 477  
      * <p>
 478  
      * When a new <code>View</code> instance is requested, the corresponding
 479  
      * model will be newly created. During this initialization process the value
 480  
      * for the model property will be set to the given default value (if set)
 481  
      * </p>
 482  
      *
 483  
      * @return String default value
 484  
      */
 485  
     public String getDefaultValue() {
 486  0
         return this.defaultValue;
 487  
     }
 488  
 
 489  
     /**
 490  
      * Setter for the fields default value
 491  
      *
 492  
      * @param defaultValue
 493  
      */
 494  
     public void setDefaultValue(String defaultValue) {
 495  0
         this.defaultValue = defaultValue;
 496  0
     }
 497  
 
 498  
     /**
 499  
      * Gives Class that should be invoked to produce the default value for the
 500  
      * field
 501  
      *
 502  
      * @return Class<? extends ValueFinder> default value finder class
 503  
      */
 504  
     public Class<? extends ValueFinder> getDefaultValueFinderClass() {
 505  0
         return this.defaultValueFinderClass;
 506  
     }
 507  
 
 508  
     /**
 509  
      * Setter for the default value finder class
 510  
      *
 511  
      * @param defaultValueFinderClass
 512  
      */
 513  
     public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
 514  0
         this.defaultValueFinderClass = defaultValueFinderClass;
 515  0
     }
 516  
 
 517  
     /**
 518  
      * Summary help text for the field
 519  
      *
 520  
      * @return String summary help text
 521  
      */
 522  
     public String getHelpSummary() {
 523  0
         return helpSummary;
 524  
     }
 525  
 
 526  
     /**
 527  
      * Setter for the summary help text
 528  
      *
 529  
      * @param helpSummary
 530  
      */
 531  
     public void setHelpSummary(String helpSummary) {
 532  0
         this.helpSummary = helpSummary;
 533  0
     }
 534  
 
 535  
     /**
 536  
      * Full help information text for the field
 537  
      *
 538  
      * @return String help description text
 539  
      */
 540  
     public String getHelpDescription() {
 541  0
         return this.helpDescription;
 542  
     }
 543  
 
 544  
     /**
 545  
      * Setter for the help description text
 546  
      *
 547  
      * @param helpDescription
 548  
      */
 549  
     public void setHelpDescription(String helpDescription) {
 550  0
         this.helpDescription = helpDescription;
 551  0
     }
 552  
 
 553  
     /**
 554  
      * Holds security configuration for the attribute field. This triggers
 555  
      * corresponding permission checks in KIM and can result in an update to the
 556  
      * field state (such as read-only or hidden) and masking of the value
 557  
      *
 558  
      * @return AttributeSecurity instance configured for field or Null if no
 559  
      *         restrictions are defined
 560  
      */
 561  
     public AttributeSecurity getAttributeSecurity() {
 562  0
         return this.attributeSecurity;
 563  
     }
 564  
 
 565  
     /**
 566  
      * Setter for the AttributeSecurity instance that defines restrictions for
 567  
      * the field
 568  
      *
 569  
      * @param attributeSecurity
 570  
      */
 571  
     public void setAttributeSecurity(AttributeSecurity attributeSecurity) {
 572  0
         this.attributeSecurity = attributeSecurity;
 573  0
     }
 574  
 
 575  
     /**
 576  
      * Indicates the field should be read-only but also a hidden should be generated for the field
 577  
      *
 578  
      * <p>
 579  
      * Useful for when a value is just displayed but is needed by script
 580  
      * </p>
 581  
      *
 582  
      * @return boolean true if field should be readOnly hidden, false if not
 583  
      */
 584  
     public boolean isReadOnlyHidden() {
 585  0
         return readOnlyHidden;
 586  
     }
 587  
 
 588  
     /**
 589  
      * Setter for the read-only hidden indicator
 590  
      *
 591  
      * @param readOnlyHidden
 592  
      */
 593  
     public void setReadOnlyHidden(boolean readOnlyHidden) {
 594  0
         this.readOnlyHidden = readOnlyHidden;
 595  0
     }
 596  
 
 597  
     /**
 598  
      * Inquiry widget for the field
 599  
      *
 600  
      * <p>
 601  
      * The inquiry widget will render a link for the field value when read-only
 602  
      * that points to the associated inquiry view for the field. The inquiry can
 603  
      * be configured to point to a certain <code>InquiryView</code>, or the
 604  
      * framework will attempt to associate the field with a inquiry based on its
 605  
      * metadata (in particular its relationships in the model)
 606  
      * </p>
 607  
      *
 608  
      * @return Inquiry field inquiry
 609  
      */
 610  
     public Inquiry getFieldInquiry() {
 611  0
         return this.fieldInquiry;
 612  
     }
 613  
 
 614  
     /**
 615  
      * Setter for the inquiry widget
 616  
      *
 617  
      * @param fieldInquiry
 618  
      */
 619  
     public void setFieldInquiry(Inquiry fieldInquiry) {
 620  0
         this.fieldInquiry = fieldInquiry;
 621  0
     }
 622  
 
 623  
     /**
 624  
      * Additional display attribute name, which will be displayed next to the actual field value
 625  
      * when the field is readonly with hypen inbetween like PropertyValue - AdditionalPropertyValue
 626  
      *
 627  
      * @param additionalDisplayPropertyName - Name of the additional display property
 628  
      */
 629  
     public void setAdditionalDisplayPropertyName(String additionalDisplayPropertyName) {
 630  0
         this.additionalDisplayPropertyName = additionalDisplayPropertyName;
 631  0
     }
 632  
 
 633  
     /**
 634  
      * Returns the additional display attribute name to be displayed when the field is readonly
 635  
      *
 636  
      * @return Additional Display Attribute Name
 637  
      */
 638  
     public String getAdditionalDisplayPropertyName() {
 639  0
         return this.additionalDisplayPropertyName;
 640  
     }
 641  
 
 642  
     /**
 643  
      * Sets the alternate display attribute name to be displayed when the field is readonly.
 644  
      * This properties value will be displayed instead of actual fields value when the field is readonly.
 645  
      *
 646  
      * @param alternateDisplayPropertyName - alternate display property name
 647  
      */
 648  
     public void setAlternateDisplayPropertyName(String alternateDisplayPropertyName) {
 649  0
         this.alternateDisplayPropertyName = alternateDisplayPropertyName;
 650  0
     }
 651  
 
 652  
     /**
 653  
      * Returns the alternate display attribute name to be displayed when the field is readonly.
 654  
      *
 655  
      * @return alternate Display Property Name
 656  
      */
 657  
     public String getAlternateDisplayPropertyName() {
 658  0
         return this.alternateDisplayPropertyName;
 659  
     }
 660  
 
 661  
     /**
 662  
      * Returns the alternate display value
 663  
      *
 664  
      * @return the alternate display value set for this field
 665  
      */
 666  
     public String getAlternateDisplayValue() {
 667  0
         return alternateDisplayValue;
 668  
     }
 669  
 
 670  
     /**
 671  
      * Setter for the alternative display value
 672  
      *
 673  
      * @param value
 674  
      */
 675  
     public void setAlternateDisplayValue(String value) {
 676  0
         this.alternateDisplayValue = value;
 677  0
     }
 678  
 
 679  
     /**
 680  
      * Returns the additional display value.
 681  
      *
 682  
      * @return the additional display value set for this field
 683  
      */
 684  
     public String getAdditionalDisplayValue() {
 685  0
         return additionalDisplayValue;
 686  
     }
 687  
 
 688  
     /**
 689  
      * Setter for the additional display value
 690  
      *
 691  
      * @param value
 692  
      */
 693  
     public void setAdditionalDisplayValue(String value) {
 694  0
         this.additionalDisplayValue = value;
 695  0
     }
 696  
 
 697  
     /**
 698  
      * Allows specifying hidden property names without having to specify as a
 699  
      * field in the group config (that might impact layout)
 700  
      *
 701  
      * @return List<String> hidden property names
 702  
      */
 703  
     public List<String> getHiddenPropertyNames() {
 704  0
         return hiddenPropertyNames;
 705  
     }
 706  
 
 707  
     /**
 708  
      * Setter for the hidden property names
 709  
      *
 710  
      * @param hiddenPropertyNames
 711  
      */
 712  
     public void setHiddenPropertyNames(List<String> hiddenPropertyNames) {
 713  0
         this.hiddenPropertyNames = hiddenPropertyNames;
 714  0
     }
 715  
 
 716  
     /**
 717  
      * List of property names whose values should be displayed read-only under this field
 718  
      *
 719  
      * <p>
 720  
      * In the attribute field template for each information property name given its values is
 721  
      * outputted read-only. Informational property values can also be updated dynamically with
 722  
      * the use of field attribute query
 723  
      * </p>
 724  
      *
 725  
      * <p>
 726  
      * Simple property names can be given if the property has the same binding parent as this
 727  
      * field, in which case the binding path will be adjusted by the framework. If the property
 728  
      * names starts with org.kuali.rice.krad.uif.UifConstants#NO_BIND_ADJUST_PREFIX, no binding
 729  
      * prefix will be added.
 730  
      * </p>
 731  
      *
 732  
      * @return List<String> informational property names
 733  
      */
 734  
     public List<String> getInformationalDisplayPropertyNames() {
 735  0
         return informationalDisplayPropertyNames;
 736  
     }
 737  
 
 738  
     /**
 739  
      * Setter for the list of informational property names
 740  
      *
 741  
      * @param informationalDisplayPropertyNames
 742  
      */
 743  
     public void setInformationalDisplayPropertyNames(List<String> informationalDisplayPropertyNames) {
 744  0
         this.informationalDisplayPropertyNames = informationalDisplayPropertyNames;
 745  0
     }
 746  
 
 747  
     /**
 748  
      * Sets HTML escaping for this property value. HTML escaping will be handled in alternate and additional fields
 749  
      * also.
 750  
      */
 751  
     public void setEscapeHtmlInPropertyValue(boolean escapeHtmlInPropertyValue) {
 752  0
         this.escapeHtmlInPropertyValue = escapeHtmlInPropertyValue;
 753  0
     }
 754  
 
 755  
     /**
 756  
      * Returns true if HTML escape allowed for this field
 757  
      *
 758  
      * @return true if escaping allowed
 759  
      */
 760  
     public boolean isEscapeHtmlInPropertyValue() {
 761  0
         return this.escapeHtmlInPropertyValue;
 762  
     }
 763  
 
 764  
 }