Coverage Report - org.kuali.rice.krad.datadictionary.FieldDefinition
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldDefinition
0%
0/128
0%
0/42
1.74
 
 1  
 /*
 2  
  * Copyright 2005-2007 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  
 
 17  
 package org.kuali.rice.krad.datadictionary;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
 21  
 import org.kuali.rice.krad.datadictionary.exception.ClassValidationException;
 22  
 import org.kuali.rice.krad.datadictionary.mask.Mask;
 23  
 import org.kuali.rice.krad.lookup.valuefinder.ValueFinder;
 24  
 import org.kuali.rice.krad.service.BusinessObjectMetaDataService;
 25  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 26  
 
 27  
 /**
 28  
  * Contains field-related information for DataDictionary entries.  Used by lookups and inquiries.
 29  
  *
 30  
  * Note: the setters do copious amounts of validation, to facilitate generating errors during the parsing process.
 31  
  */
 32  
 public class FieldDefinition extends DataDictionaryDefinitionBase implements FieldDefinitionI {
 33  
     private static final long serialVersionUID = -3426603523049661524L;
 34  
     
 35  
         protected String attributeName;
 36  0
     protected boolean required = false;
 37  0
     protected boolean forceInquiry = false;
 38  0
     protected boolean noInquiry = false;
 39  0
     protected boolean noDirectInquiry = false;
 40  0
     protected boolean forceLookup = false;
 41  0
     protected boolean noLookup = false;
 42  0
     protected boolean useShortLabel = false;
 43  
     protected String defaultValue;
 44  
     protected Class<? extends ValueFinder> defaultValueFinderClass;
 45  
     protected String quickfinderParameterString;
 46  
     protected Class<? extends ValueFinder> quickfinderParameterStringBuilderClass;
 47  
 
 48  0
     protected Integer maxLength = null;
 49  
 
 50  
     protected String displayEditMode;
 51  
     protected Mask displayMask;
 52  
 
 53  0
         protected boolean hidden         = false;
 54  0
         protected boolean readOnly         = false;
 55  
 
 56  0
         protected boolean treatWildcardsAndOperatorsAsLiteral = false;
 57  
         
 58  
     protected String alternateDisplayAttributeName;
 59  
     protected String additionalDisplayAttributeName;
 60  
         
 61  
         protected boolean triggerOnChange;
 62  0
         protected boolean total = false;
 63  
         
 64  0
     public FieldDefinition() {
 65  0
     }
 66  
 
 67  
 
 68  
     /**
 69  
      * @return attributeName
 70  
      */
 71  
     public String getAttributeName() {
 72  0
         return attributeName;
 73  
     }
 74  
 
 75  
     /**
 76  
      * Sets attributeName to the given value.
 77  
      *
 78  
      * @param attributeName
 79  
      * @throws IllegalArgumentException if the given attributeName is blank
 80  
      */
 81  
     public void setAttributeName(String attributeName) {
 82  0
         if (StringUtils.isBlank(attributeName)) {
 83  0
             throw new IllegalArgumentException("invalid (blank) attributeName");
 84  
         }
 85  0
         this.attributeName = attributeName;
 86  0
     }
 87  
 
 88  
 
 89  
     /**
 90  
      * @return true if this attribute is required
 91  
      */
 92  
     public boolean isRequired() {
 93  0
         return required;
 94  
     }
 95  
 
 96  
 
 97  
     /**
 98  
                     required = true means that the user must enter something
 99  
                         into the search criterion lookup field
 100  
      */
 101  
     public void setRequired(boolean required) {
 102  0
         this.required = required;
 103  0
     }
 104  
 
 105  
 
 106  
     /**
 107  
      * @return Returns the forceInquiry.
 108  
      */
 109  
     public boolean isForceInquiry() {
 110  0
         return forceInquiry;
 111  
     }
 112  
 
 113  
 
 114  
     /**
 115  
      * forceInquiry = true means that the displayed field value will
 116  
                     always be made inquirable (this attribute is not used within the code).
 117  
      */
 118  
     public void setForceInquiry(boolean forceInquiry) {
 119  0
         this.forceInquiry = forceInquiry;
 120  0
     }
 121  
 
 122  
     /**
 123  
      * @return Returns the forceLookup.
 124  
      */
 125  
     public boolean isForceLookup() {
 126  0
         return forceLookup;
 127  
     }
 128  
 
 129  
     /**
 130  
      * forceLookup = this attribute is not used
 131  
      */
 132  
     public void setForceLookup(boolean forceLookup) {
 133  0
         this.forceLookup = forceLookup;
 134  0
     }
 135  
 
 136  
     /**
 137  
      * @return Returns the noInquiry.
 138  
      */
 139  
     public boolean isNoInquiry() {
 140  0
         return noInquiry;
 141  
     }
 142  
 
 143  
     /**
 144  
      * @return Returns a boolean value indicating whether or not to provide
 145  
      *          a direct inquiry for the lookup field
 146  
      */
 147  
     public boolean isNoDirectInquiry()
 148  
     {
 149  0
         return noDirectInquiry;
 150  
     }
 151  
 
 152  
     /**
 153  
      * noInquiry = true means that the displayed field will never be made inquirable.
 154  
      */
 155  
     public void setNoInquiry(boolean noInquiry) {
 156  0
         this.noInquiry = noInquiry;
 157  0
     }
 158  
 
 159  
     /**
 160  
      * @param noInquiry If true, the displayed field will not have a direct
 161  
          *     inquiry facility
 162  
      */
 163  
     public void setNoDirectInquiry(boolean noDirectInquiry) {
 164  0
         this.noDirectInquiry = noDirectInquiry;
 165  0
     }
 166  
 
 167  
     /**
 168  
      * @return Returns the noLookup.
 169  
      */
 170  
     public boolean isNoLookup() {
 171  0
         return noLookup;
 172  
     }
 173  
 
 174  
     /**
 175  
      * noLookup = true means that field should not include magnifying glass (i.e. quickfinder)
 176  
      */
 177  
     public void setNoLookup(boolean noLookup) {
 178  0
         this.noLookup = noLookup;
 179  0
     }
 180  
 
 181  
 
 182  
     /**
 183  
          * @return the useShortLabel
 184  
          */
 185  
         public boolean isUseShortLabel() {
 186  0
                 return this.useShortLabel;
 187  
         }
 188  
 
 189  
 
 190  
         /**
 191  
          * @param useShortLabel the useShortLabel to set
 192  
          */
 193  
         public void setUseShortLabel(boolean useShortLabel) {
 194  0
                 this.useShortLabel = useShortLabel;
 195  0
         }
 196  
 
 197  
 
 198  
         /**
 199  
      * @return Returns the defaultValue.
 200  
      */
 201  
     public String getDefaultValue() {
 202  0
         return defaultValue;
 203  
     }
 204  
 
 205  
 
 206  
     /**
 207  
            The defaultValue element will pre-load the specified value
 208  
            into the field.
 209  
      */
 210  
     public void setDefaultValue(String defaultValue) {
 211  0
         this.defaultValue = defaultValue;
 212  0
     }
 213  
 
 214  
     /**
 215  
          * the quickfinderParameterString is a comma separated list of parameter/value pairs, of the format
 216  
          * "param1=value1,param2=value2", where the parameters correspond to attributes of the target class
 217  
          * for the quickfinder, and the values to literals that those attributes will default to when the
 218  
          * quickfinder is used.
 219  
          * @return the quickfinderParameterString
 220  
          */
 221  
         public String getQuickfinderParameterString() {
 222  0
                 return this.quickfinderParameterString;
 223  
         }
 224  
 
 225  
         /**
 226  
          * @param quickfinderParameterString the quickfinderParameterString to set.  See {@link #getQuickfinderParameterString()}
 227  
          */
 228  
         public void setQuickfinderParameterString(String quickfinderParameterString) {
 229  0
                 this.quickfinderParameterString = quickfinderParameterString;
 230  0
         }
 231  
 
 232  
 
 233  
     /**
 234  
      * the quickfinderParameterStringBuilderClass specifies the java class that will be used
 235  
      * to determine the default value(s) for field(s) on the target lookup when the quickfinder
 236  
      * is used. The classname specified in this field must implement
 237  
      * {@link org.kuali.rice.krad.lookup.valuefinder.ValueFinder}.  See {@link #getQuickfinderParameterString()}
 238  
      * for the result string format.
 239  
          * @return the quickfinderParameterStringBuilderClass
 240  
          */
 241  
         public Class<? extends ValueFinder> getQuickfinderParameterStringBuilderClass() {
 242  0
                 return this.quickfinderParameterStringBuilderClass;
 243  
         }
 244  
 
 245  
     /**
 246  
      * See {@link #getQuickfinderParameterStringBuilderClass()}
 247  
          * @param quickfinderParameterStringBuilderClass the quickfinderParameterStringBuilderClass to set
 248  
      */
 249  
         public void setQuickfinderParameterStringBuilderClass(
 250  
                         Class<? extends ValueFinder> quickfinderParameterStringBuilderClass) {
 251  0
         if (quickfinderParameterStringBuilderClass == null) {
 252  0
             throw new IllegalArgumentException("invalid (null) quickfinderParameterStringBuilderClass");
 253  
         }
 254  0
                 this.quickfinderParameterStringBuilderClass = quickfinderParameterStringBuilderClass;
 255  0
     }
 256  
 
 257  
     /**
 258  
      * Directly validate simple fields.
 259  
      *
 260  
      * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
 261  
      */
 262  
     public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
 263  0
             BusinessObjectMetaDataService boMetadataService = KRADServiceLocatorWeb.getBusinessObjectMetaDataService();
 264  
 
 265  0
         if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAttributeName())) {
 266  0
             throw new AttributeValidationException("unable to find attribute '" + attributeName + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
 267  
         }
 268  
 
 269  0
         if (StringUtils.isNotBlank(getAlternateDisplayAttributeName())) {
 270  0
             if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAlternateDisplayAttributeName())) {
 271  0
                 throw new AttributeValidationException("unable to find attribute named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
 272  
             }
 273  
         }
 274  
         
 275  0
         if (StringUtils.isNotBlank(getAdditionalDisplayAttributeName())) {
 276  0
             if (!DataDictionary.isPropertyOf(rootBusinessObjectClass, getAdditionalDisplayAttributeName())) {
 277  0
                 throw new AttributeValidationException("unable to find attribute named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
 278  
             }
 279  
         }
 280  
 
 281  0
         if (defaultValueFinderClass != null && defaultValue != null) {
 282  0
             throw new AttributeValidationException("Both defaultValue and defaultValueFinderClass can not be specified on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
 283  
         }
 284  
 
 285  0
         validateQuickfinderParameters(rootBusinessObjectClass, boMetadataService);
 286  
 
 287  0
         if (forceInquiry == true && noInquiry == true) {
 288  0
             throw new AttributeValidationException("Both forceInquiry and noInquiry can not be set to true on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
 289  
         }
 290  0
         if (forceLookup == true && noLookup == true) {
 291  0
             throw new AttributeValidationException("Both forceLookup and noLookup can not be set to true on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
 292  
         }
 293  0
     }
 294  
 
 295  
 
 296  
     /**
 297  
          * This method does validation on the quickfinderParameterString and quickfinderParameterStringBuilderClass members
 298  
          *
 299  
          * @param rootBusinessObjectClass
 300  
          * @param boMetadataService
 301  
          */
 302  
         private void validateQuickfinderParameters(Class rootBusinessObjectClass,
 303  
                         BusinessObjectMetaDataService boMetadataService) {
 304  0
                 if (quickfinderParameterStringBuilderClass != null && quickfinderParameterString != null) {
 305  0
             throw new AttributeValidationException("Both quickfinderParameterString and quickfinderParameterStringBuilderClass can not be specified on attribute " + getAttributeName() + " in rootBusinessObjectClass " + rootBusinessObjectClass.getName());
 306  
         }
 307  
 
 308  
         // String used for building exception messages
 309  0
         String quickfinderParameterStringSource = "quickfinderParameterString";
 310  
 
 311  0
         if (quickfinderParameterStringBuilderClass != null) {
 312  
                 try {
 313  0
                         quickfinderParameterStringSource = "quickfinderParameterStringBuilderClass " + quickfinderParameterStringBuilderClass.getCanonicalName();
 314  0
                                 quickfinderParameterString = quickfinderParameterStringBuilderClass.newInstance().getValue();
 315  0
                         } catch (InstantiationException e) {
 316  0
                                 throw new ClassValidationException("unable to create new instance of "+  quickfinderParameterStringSource +" while validating rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'", e);
 317  0
                         } catch (IllegalAccessException e) {
 318  0
                                 throw new ClassValidationException("unable to create new instance of "+  quickfinderParameterStringSource +" while validating rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'", e);
 319  0
                         }
 320  
         }
 321  
 
 322  0
         if (!StringUtils.isEmpty(quickfinderParameterString)) {
 323  
                 // quickfinderParameterString will look something like "campusTypeCode=P,active=Y"
 324  0
                 for (String quickfinderParam : quickfinderParameterString.split(",")) { // this is guaranteed to return at least one
 325  0
                         if (quickfinderParam.contains("=")) {
 326  0
                                 String propertyName = quickfinderParam.split("=")[0];
 327  0
                                 RelationshipDefinition relationship = boMetadataService.getBusinessObjectRelationshipDefinition(rootBusinessObjectClass, attributeName);
 328  0
                                 Class targetClass = relationship.getTargetClass();
 329  
 
 330  
                                 // This is insufficient to ensure the property is valid for a lookup default, but it's better than nothing.
 331  0
                             if (!DataDictionary.isPropertyOf(targetClass, propertyName)) {
 332  0
                                     throw new ClassValidationException("malformed parameter string  '"+ quickfinderParameterString +"' from "+ quickfinderParameterStringSource +
 333  
                                                     ", '"+ propertyName +"' is not a property of "+ targetClass +"' for rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'");
 334  
                             }
 335  
 
 336  0
                         } else {
 337  0
                                 throw new ClassValidationException("malformed parameter string '"+ quickfinderParameterString +"' from "+ quickfinderParameterStringSource +
 338  
                                                 " for rootBusinessObjectClass '"+ rootBusinessObjectClass.getName() +"'");
 339  
                         }
 340  
                 }
 341  
         }
 342  0
         }
 343  
 
 344  
 
 345  
     /**
 346  
      * @see java.lang.Object#toString()
 347  
      */
 348  
     public String toString() {
 349  0
         return "FieldDefinition for attribute " + getAttributeName();
 350  
     }
 351  
 
 352  
 
 353  
     public String getName() {
 354  0
         return attributeName;
 355  
     }
 356  
 
 357  
 
 358  
     public String getDisplayEditMode() {
 359  0
         return displayEditMode;
 360  
     }
 361  
 
 362  
 
 363  
     /*
 364  
                         The document authorizer classes have a method getEditMode, which is a map of edit mode to
 365  
                         value mappings.  Depending on the context, the value of the mapping may be relevant, and the logic determining
 366  
                         whether the value is relevant is often implemented in the JSP/tag layer.
 367  
 
 368  
                         Fields on a document (particularily maintenance documents) may be associated with
 369  
                         an edit mode.  If the edit mode is mapped to a relevant value, then the all fields associated with the edit mode
 370  
                         will be rendered unhidden.
 371  
 
 372  
                         The displayEditMode element is used to specify the edit mode that will be associated with the field.
 373  
                         If the document authorizer returns a map with this edit mode mapped to a proper value, then the field will be unhidden to the user.
 374  
      */
 375  
     public void setDisplayEditMode(String displayEditMode) {
 376  0
         this.displayEditMode = displayEditMode;
 377  0
     }
 378  
 
 379  
 
 380  
     public Mask getDisplayMask() {
 381  0
         return displayMask;
 382  
     }
 383  
 
 384  
     /**
 385  
      * The displayMask element specifies the type of masking to
 386  
                     be used to hide the value from un-authorized users.
 387  
                     There are three types of masking.
 388  
      */
 389  
     public void setDisplayMask(Mask displayMask) {
 390  0
         this.displayMask = displayMask;
 391  0
     }
 392  
 
 393  
 
 394  
 
 395  
     public boolean isReadOnlyAfterAdd() {
 396  0
         return false;
 397  
     }
 398  
 
 399  
 
 400  
     /**
 401  
      * Gets the maxLength attribute.
 402  
      * @return Returns the maxLength.
 403  
      */
 404  
     public Integer getMaxLength() {
 405  0
         return maxLength;
 406  
     }
 407  
 
 408  
 
 409  
     /**
 410  
      * maxLength = the maximum allowable length of the field in the lookup result fields.  In other contexts,
 411  
                     like inquiries, this field has no effect.
 412  
      */
 413  
     public void setMaxLength(Integer maxLength) {
 414  0
         this.maxLength = maxLength;
 415  0
     }
 416  
 
 417  
     /**
 418  
      * @return custom defaultValue class
 419  
      */
 420  
     public Class<? extends ValueFinder> getDefaultValueFinderClass() {
 421  0
         return this.defaultValueFinderClass;
 422  
     }
 423  
 
 424  
     /**
 425  
                       The defaultValueFinderClass specifies the java class that will be
 426  
                       used to determine the default value of a field.  The classname
 427  
                       specified in this field must implement ValueFinder
 428  
      */
 429  
     public void setDefaultValueFinderClass(Class<? extends ValueFinder> defaultValueFinderClass) {
 430  0
         if (defaultValueFinderClass == null) {
 431  0
             throw new IllegalArgumentException("invalid (null) defaultValueFinderClass");
 432  
         }
 433  0
         this.defaultValueFinderClass = defaultValueFinderClass;
 434  0
     }
 435  
     
 436  
         /**
 437  
          * @return the hidden
 438  
          */
 439  
         public boolean isHidden() {
 440  0
                 return this.hidden;
 441  
         }
 442  
 
 443  
         /**
 444  
          * @param hidden
 445  
      *  If the ControlDefinition.isHidden == true then a corresponding LookupDefinition would
 446  
      *  automatically be removed from the search criteria.  In some cases you might want the
 447  
      *  hidden field to be used as a search criteria.  For example, in PersonImpl.xml a client
 448  
      *  might want to have the campus code hidden and preset to Bloomington.  So when the search
 449  
      *  is run, only people from the bloomington campus are returned.
 450  
      *
 451  
      *   So, if you want to have a hidden search criteria, set this variable to true. Defaults to
 452  
      *   false.
 453  
      */
 454  
         public void setHidden(boolean hidden) {
 455  0
                 this.hidden = hidden;
 456  0
         }
 457  
         
 458  
         /**
 459  
          * @return the readOnly
 460  
          */
 461  
         public boolean isReadOnly() {
 462  0
                 return this.readOnly;
 463  
         }
 464  
         
 465  
         /**
 466  
          * @param readOnly the readOnly to set
 467  
          */
 468  
         public void setReadOnly(boolean readOnly) {
 469  0
                 this.readOnly = readOnly;
 470  0
         }
 471  
         
 472  
         public boolean isTriggerOnChange() {
 473  0
                 return this.triggerOnChange;
 474  
         }
 475  
 
 476  
         public void setTriggerOnChange(boolean triggerOnChange) {
 477  0
                 this.triggerOnChange = triggerOnChange;
 478  0
         }
 479  
 
 480  
         /**
 481  
          * @return the treatWildcardsAndOperatorsAsLiteralOnLookups
 482  
          */
 483  
         public boolean isTreatWildcardsAndOperatorsAsLiteral() {
 484  0
                 return this.treatWildcardsAndOperatorsAsLiteral;
 485  
         }
 486  
 
 487  
 
 488  
         /**
 489  
          * @param treatWildcardsAndOperatorsAsLiteralOnLookups the treatWildcardsAndOperatorsAsLiteralOnLookups to set
 490  
          */
 491  
         public void setTreatWildcardsAndOperatorsAsLiteral(
 492  
                         boolean treatWildcardsAndOperatorsAsLiteralOnLookups) {
 493  0
                 this.treatWildcardsAndOperatorsAsLiteral = treatWildcardsAndOperatorsAsLiteralOnLookups;
 494  0
         }
 495  
 
 496  
 
 497  
         public String getAlternateDisplayAttributeName() {
 498  0
                 return this.alternateDisplayAttributeName;
 499  
         }
 500  
 
 501  
 
 502  
         public void setAlternateDisplayAttributeName(String alternateDisplayAttributeName) {
 503  0
                 this.alternateDisplayAttributeName = alternateDisplayAttributeName;
 504  0
         }
 505  
 
 506  
 
 507  
         public String getAdditionalDisplayAttributeName() {
 508  0
                 return this.additionalDisplayAttributeName;
 509  
         }
 510  
 
 511  
 
 512  
         public void setAdditionalDisplayAttributeName(String additionalDisplayAttributeName) {
 513  0
                 this.additionalDisplayAttributeName = additionalDisplayAttributeName;
 514  0
         }
 515  
 
 516  
 
 517  
         public boolean isTotal() {
 518  0
                 return this.total;
 519  
         }
 520  
 
 521  
 
 522  
         public void setTotal(boolean total) {
 523  0
                 this.total = total;
 524  0
         }
 525  
         
 526  
 }