Coverage Report - org.kuali.rice.kns.datadictionary.AttributeDefinition
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeDefinition
0%
0/90
0%
0/32
1.65
 
 1  
 /*
 2  
  * Copyright 2005-2008 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.kns.datadictionary;
 18  
 
 19  
 import java.math.BigDecimal;
 20  
 
 21  
 import org.apache.commons.lang.ClassUtils;
 22  
 import org.apache.commons.lang.StringUtils;
 23  
 import org.apache.log4j.Logger;
 24  
 import org.kuali.rice.core.util.ClassLoaderUtils;
 25  
 import org.kuali.rice.kns.datadictionary.control.ControlDefinition;
 26  
 import org.kuali.rice.kns.datadictionary.exception.AttributeValidationException;
 27  
 import org.kuali.rice.kns.datadictionary.exception.ClassValidationException;
 28  
 import org.kuali.rice.kns.datadictionary.validation.ValidationPattern;
 29  
 import org.kuali.rice.kns.web.format.Formatter;
 30  
 import org.springframework.beans.factory.InitializingBean;
 31  
 
 32  
 
 33  
 /**
 34  
  * A single attribute definition in the DataDictionary, which contains information relating to the display, validation, and general
 35  
  * maintenance of a specific attribute of an entry.
 36  
  * 
 37  
  * 
 38  
  */
 39  
 public class AttributeDefinition extends DataDictionaryDefinitionBase implements InitializingBean {
 40  
     private static final long serialVersionUID = -2490613377818442742L;
 41  
 
 42  0
         protected Boolean forceUppercase = Boolean.FALSE;
 43  
 
 44  
     protected String name;
 45  
     protected String label;
 46  
     protected String shortLabel;
 47  
     protected String displayLabelAttribute;
 48  
 
 49  
     protected Integer maxLength;
 50  
     protected Boolean unique;
 51  
     
 52  
     protected BigDecimal exclusiveMin;
 53  
     protected BigDecimal inclusiveMax;
 54  
 
 55  
     protected ValidationPattern validationPattern;
 56  0
     protected Boolean required = Boolean.FALSE;
 57  
 
 58  
     protected ControlDefinition control;
 59  
 
 60  
     protected String summary;
 61  
     protected String description;
 62  
 
 63  
     protected String formatterClass;
 64  
 
 65  
     protected AttributeSecurity attributeSecurity;
 66  
 
 67  0
     public AttributeDefinition() {}
 68  
 
 69  
 
 70  
     /**
 71  
         * forceUppercase = convert user entry to uppercase and always display
 72  
             database value as uppercase.
 73  
      */
 74  
     public void setForceUppercase(Boolean forceUppercase) {
 75  0
         this.forceUppercase = forceUppercase;
 76  0
     }
 77  
 
 78  
     public Boolean getForceUppercase() {
 79  0
         return this.forceUppercase;
 80  
     }
 81  
 
 82  
     public String getName() {
 83  0
         return name;
 84  
     }
 85  
 
 86  
     /*
 87  
      * name = name of attribute
 88  
      */
 89  
     public void setName(String name) {
 90  0
         if (StringUtils.isBlank(name)) {
 91  0
             throw new IllegalArgumentException("invalid (blank) name");
 92  
         }
 93  0
         this.name = name;
 94  0
     }
 95  
 
 96  
     public String getLabel() {
 97  0
         return label;
 98  
     }
 99  
 
 100  
     /**
 101  
                     The label element is the field or collection name that will be shown on inquiry and
 102  
                     maintenance screens.
 103  
                     This will be overridden by presence of displayLabelAttribute element.
 104  
      */
 105  
     public void setLabel(String label) {
 106  0
         if (StringUtils.isBlank(label)) {
 107  0
             throw new IllegalArgumentException("invalid (blank) label");
 108  
         }
 109  0
         this.label = label;
 110  0
     }
 111  
 
 112  
     /**
 113  
      * @return the shortLabel, or the label if no shortLabel has been set
 114  
      */
 115  
     public String getShortLabel() {
 116  0
         return (shortLabel != null) ? shortLabel : getLabel();
 117  
     }
 118  
 
 119  
     /**
 120  
      * @return the shortLabel directly, without substituting in the label
 121  
      */
 122  
     protected String getDirectShortLabel() {
 123  0
         return shortLabel;
 124  
     }
 125  
 
 126  
     /**
 127  
                     The shortLabel element is the field or collection name that will be used
 128  
                     in applications when a shorter name (than the label element) is required.
 129  
                     This will be overridden by presence of displayLabelAttribute element.
 130  
      */
 131  
     public void setShortLabel(String shortLabel) {
 132  0
         if (StringUtils.isBlank(shortLabel)) {
 133  0
             throw new IllegalArgumentException("invalid (blank) shortLabel");
 134  
         }
 135  0
         this.shortLabel = shortLabel;
 136  0
     }
 137  
 
 138  
     public Integer getMaxLength() {
 139  0
         return maxLength;
 140  
     }
 141  
 
 142  
     /**
 143  
                     The maxLength element determines the maximum size of the field
 144  
                     for data entry edit purposes and for display purposes.
 145  
      */
 146  
     public void setMaxLength(Integer maxLength) {
 147  0
         this.maxLength = maxLength;
 148  0
     }
 149  
 
 150  
     public BigDecimal getExclusiveMin() {
 151  0
         return exclusiveMin;
 152  
     }
 153  
 
 154  
     /**
 155  
                     The exclusiveMin element determines the minimum allowable value
 156  
                     for data entry editing purposes.  Value can be an integer or decimal
 157  
                     value such as -.001 or 99.
 158  
      */
 159  
     public void setExclusiveMin(BigDecimal exclusiveMin) {
 160  0
         this.exclusiveMin = exclusiveMin;
 161  0
     }
 162  
 
 163  
     /**
 164  
                     The inclusiveMax element determines the maximum allowable value
 165  
                     for data entry editing purposes. Value can be an integer or decimal
 166  
                     value such as -.001 or 99.
 167  
 
 168  
                     JSTL: This field is mapped into the field named "exclusiveMax".
 169  
      */
 170  
     public BigDecimal getInclusiveMax() {
 171  0
         return inclusiveMax;
 172  
     }
 173  
 
 174  
     /**
 175  
                     The inclusiveMax element determines the maximum allowable value
 176  
                     for data entry editing purposes. Value can be an integer or decimal
 177  
                     value such as -.001 or 99.
 178  
 
 179  
                     JSTL: This field is mapped into the field named "exclusiveMax".
 180  
      */
 181  
     public void setInclusiveMax(BigDecimal inclusiveMax) {
 182  0
         this.inclusiveMax = inclusiveMax;
 183  0
     }
 184  
 
 185  
     /**
 186  
      * @return true if a validationPattern has been set
 187  
      */
 188  
     public boolean hasValidationPattern() {
 189  0
         return (validationPattern != null);
 190  
     }
 191  
 
 192  
     public ValidationPattern getValidationPattern() {
 193  0
         return this.validationPattern;
 194  
     }
 195  
 
 196  
     /**
 197  
                     The validationPattern element defines the allowable character-level
 198  
                     or field-level values for an attribute.
 199  
 
 200  
                     JSTL: validationPattern is a Map which is accessed using a key
 201  
                     of "validationPattern". Each entry may contain some of the keys
 202  
                     listed below.  The keys that may be present for a given attribute
 203  
                     are dependent upon the type of validationPattern.
 204  
 
 205  
                         * maxLength (String)
 206  
                         * exactLength
 207  
                         * type
 208  
                         * allowWhitespace
 209  
                         * allowUnderscore
 210  
                         * allowPeriod
 211  
                         * validChars
 212  
                         * precision
 213  
                         * scale
 214  
                         * allowNegative
 215  
 
 216  
                     The allowable keys (in addition to type) for each type are:
 217  
                         ****Type****    ***Keys***
 218  
                         alphanumeric    exactLength
 219  
                                         maxLength
 220  
                                         allowWhitespace
 221  
                                         allowUnderscore
 222  
                                         allowPeriod
 223  
 
 224  
                         alpha           exactLength
 225  
                                         maxLength
 226  
                                         allowWhitespace
 227  
 
 228  
                         anyCharacter    exactLength
 229  
                                         maxLength
 230  
                                         allowWhitespace
 231  
 
 232  
                         charset         validChars
 233  
 
 234  
                         numeric         exactLength
 235  
                                         maxLength
 236  
 
 237  
                         fixedPoint      allowNegative
 238  
                                         precision
 239  
                                         scale
 240  
 
 241  
                         floatingPoint   allowNegative
 242  
 
 243  
                         date            n/a
 244  
                         emailAddress    n/a
 245  
                         javaClass       n/a
 246  
                         month           n/a
 247  
                         phoneNumber     n/a
 248  
                         timestamp       n/a
 249  
                         year            n/a
 250  
                         zipcode         n/a
 251  
 
 252  
                     Note: maxLength and exactLength are mutually exclusive.
 253  
                     If one is entered, the other may not be entered.
 254  
 
 255  
                     Note:  See ApplicationResources.properties for
 256  
                     exact regex patterns.
 257  
                     e.g. validationPatternRegex.date for regex used in date validation.
 258  
      */
 259  
     public void setValidationPattern(ValidationPattern validationPattern) {
 260  0
         this.validationPattern = validationPattern;
 261  0
     }
 262  
 
 263  
 
 264  
     /**
 265  
                     The required element allows values of "true" or "false".
 266  
                     A value of "true" indicates that a value must be entered for this
 267  
                     business object when creating or editing a new business object.
 268  
      */
 269  
     public void setRequired(Boolean required) {
 270  0
         this.required = required;
 271  0
     }
 272  
 
 273  
     public Boolean isRequired() {
 274  0
         return this.required;
 275  
     }
 276  
 
 277  
 
 278  
     /**
 279  
      * @return control
 280  
      */
 281  
     public ControlDefinition getControl() {
 282  0
         return control;
 283  
     }
 284  
 
 285  
     /**
 286  
      *                     The control element defines the manner in which an attribute is
 287  
                     displayed and the manner in which the attribute value is entered.
 288  
 
 289  
                     JSTL: control is a Map representing an HTML control.  It is accessed
 290  
                     using a key of "control".  The table below shows the types of entries
 291  
                     associated with each type of control.
 292  
 
 293  
                     **Control Type**    **Key**             **Value**
 294  
                     checkbox            checkbox            boolean String
 295  
 
 296  
                     hidden              hidden              boolean String
 297  
 
 298  
                     radio               radio               boolean String
 299  
                                         valuesFinder        valuesFinder class name
 300  
                                         businessObjectClass String
 301  
                                         keyAttribute        String
 302  
                                         labelAttribute      String
 303  
                                         includeKeyInLabel   boolean String
 304  
 
 305  
                     select              select              boolean String
 306  
                                         valuesFinder        valuesFinder class name
 307  
                                         businessObjectClass String
 308  
                                         keyAttribute        String
 309  
                                         labelAttribute      String
 310  
                                         includeBlankRow                boolean String
 311  
                                         includeKeyInLabel   boolean String
 312  
 
 313  
                     apcSelect           apcSelect           boolean String
 314  
                                         paramNamespace      String
 315  
                                         parameterDetailType String
 316  
                                         parameterName       String
 317  
 
 318  
                     text                text                boolean String
 319  
                                         size                String
 320  
 
 321  
                     textarea            textarea            boolean String
 322  
                                         rows
 323  
                                         cols
 324  
 
 325  
                     currency            currency            boolean String
 326  
                                         size                String
 327  
                                         formattedMaxLength  String
 328  
 
 329  
                     kualiUser           kualiUser           boolean String
 330  
                                         universalIdAttributeName    String
 331  
                                         userIdAttributeName         String
 332  
                                         personNameAttributeName     String
 333  
 
 334  
                     lookupHidden        lookupHidden        boolean String
 335  
 
 336  
                     lookupReadonly      lookupReadonly      boolean String
 337  
 
 338  
      * @param control
 339  
      * @throws IllegalArgumentException if the given control is null
 340  
      */
 341  
     public void setControl(ControlDefinition control) {
 342  0
         if (control == null) {
 343  0
             throw new IllegalArgumentException("invalid (null) control");
 344  
         }
 345  0
         this.control = control;
 346  0
     }
 347  
 
 348  
     public String getSummary() {
 349  0
         return summary;
 350  
     }
 351  
 
 352  
     /**
 353  
                       The summary element is used to provide a short description of the
 354  
                       attribute or collection.  This is designed to be used for help purposes.
 355  
      */
 356  
     public void setSummary(String summary) {
 357  0
         this.summary = summary;
 358  0
     }
 359  
 
 360  
     public String getDescription() {
 361  0
         return description;
 362  
     }
 363  
 
 364  
     /**
 365  
      *                       The description element is used to provide a long description of the
 366  
                       attribute or collection.  This is designed to be used for help purposes.
 367  
      */
 368  
     public void setDescription(String description) {
 369  0
         this.description = description;
 370  0
     }
 371  
 
 372  
     public boolean hasFormatterClass() {
 373  0
         return (formatterClass != null);
 374  
     }
 375  
 
 376  
     public String getFormatterClass() {
 377  0
         return formatterClass;
 378  
     }
 379  
 
 380  
     /**
 381  
                       The formatterClass element is used when custom formatting is
 382  
                       required for display of the field value.  This field specifies
 383  
                       the name of the java class to be used for the formatting.  About
 384  
                       15 different classes are available including BooleanFormatter,
 385  
                       CurrencyFormatter, DateFormatter, etc.
 386  
      */
 387  
     public void setFormatterClass(String formatterClass) {
 388  0
         if (formatterClass == null) {
 389  0
             throw new IllegalArgumentException("invalid (null) formatterClass");
 390  
         }
 391  0
         this.formatterClass = formatterClass;
 392  0
     }
 393  
 
 394  
     /**
 395  
      * Directly validate simple fields, call completeValidation on Definition fields.
 396  
      * 
 397  
      * @see org.kuali.rice.kns.datadictionary.DataDictionaryEntry#completeValidation()
 398  
      */
 399  
     public void completeValidation(Class rootObjectClass, Class otherObjectClass) {
 400  
         try {
 401  0
             if (!DataDictionary.isPropertyOf(rootObjectClass, getName())) {
 402  0
                 throw new AttributeValidationException("property '" + getName() + "' is not a property of class '" + rootObjectClass.getName() + "' (" + "" + ")");
 403  
             }
 404  
     
 405  0
             if ( getControl() == null ) {
 406  0
                 throw new AttributeValidationException( "property '" + getName() + "' in class '" + rootObjectClass.getName() + " does not have a control defined" );
 407  
             }
 408  
             
 409  0
             getControl().completeValidation(rootObjectClass, otherObjectClass);    
 410  
     
 411  0
             if(attributeSecurity != null){
 412  0
                     attributeSecurity.completeValidation(rootObjectClass, otherObjectClass);
 413  
             }
 414  
             
 415  0
             if (validationPattern != null) {
 416  0
                     validationPattern.completeValidation();
 417  
             }
 418  
             
 419  0
             if (formatterClass != null) {
 420  
                     try {
 421  0
                             Class formatterClassObject = ClassUtils.getClass(ClassLoaderUtils.getDefaultClassLoader(), getFormatterClass());
 422  0
                             if (!Formatter.class.isAssignableFrom(formatterClassObject)) {
 423  0
                                     throw new ClassValidationException("formatterClass is not a valid instance of " + Formatter.class.getName() + " instead was: " + formatterClassObject.getName());
 424  
                             }
 425  0
                     } catch (ClassNotFoundException e) {
 426  0
                             throw new ClassValidationException("formatterClass could not be found: " + getFormatterClass(), e);
 427  0
                     }
 428  
             }
 429  0
         } catch ( RuntimeException ex ) {
 430  0
             Logger.getLogger(getClass()).error("Unable to validate attribute " + rootObjectClass + "." + getName() + ": " + ex.getMessage(), ex );
 431  0
             throw ex;
 432  0
         }
 433  0
     }
 434  
 
 435  
 
 436  
     /**
 437  
      * @see java.lang.Object#toString()
 438  
      */
 439  
     @Override
 440  
     public String toString() {
 441  0
         return "AttributeDefinition for attribute " + getName();
 442  
     }
 443  
 
 444  
 
 445  
     public String getDisplayLabelAttribute() {
 446  0
         return displayLabelAttribute;
 447  
     }
 448  
 
 449  
 
 450  
     /**
 451  
                     The displayLabelAttribute element is used to indicate that the
 452  
                     label and short label should be obtained from another attribute.
 453  
 
 454  
                     The label element and short label element defined for this attribute
 455  
                     will be overridden.  Instead, the label and short label values
 456  
                     will be obtained by referencing the corresponding values from the
 457  
                     attribute indicated by this element.
 458  
      */
 459  
     public void setDisplayLabelAttribute(String displayLabelAttribute) {
 460  0
         this.displayLabelAttribute = displayLabelAttribute;
 461  0
     }
 462  
 
 463  
 
 464  
         /**
 465  
          * @return the attributeSecurity
 466  
          */
 467  
         public AttributeSecurity getAttributeSecurity() {
 468  0
                 return this.attributeSecurity;
 469  
         }
 470  
 
 471  
 
 472  
         /**
 473  
          * @param attributeSecurity the attributeSecurity to set
 474  
          */
 475  
         public void setAttributeSecurity(AttributeSecurity attributeSecurity) {
 476  0
                 this.attributeSecurity = attributeSecurity;
 477  0
         }
 478  
         
 479  
          public boolean hasAttributeSecurity() {
 480  0
                 return (attributeSecurity != null);
 481  
     }
 482  
          
 483  
          
 484  
     /**
 485  
      * This overridden method ...
 486  
      * 
 487  
      * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 488  
      */
 489  
     public void afterPropertiesSet() throws Exception {
 490  0
             if ( StringUtils.isEmpty(name) ) {
 491  0
                     throw new RuntimeException( "blank name for bean: " + id );
 492  
             }
 493  
             
 494  0
     }
 495  
 
 496  
 
 497  
         /**
 498  
          * @return the unique
 499  
          */
 500  
         public Boolean getUnique() {
 501  0
                 return this.unique;
 502  
         }
 503  
 
 504  
 
 505  
         /**
 506  
          * @param unique the unique to set
 507  
          */
 508  
         public void setUnique(Boolean unique) {
 509  0
                 this.unique = unique;
 510  0
         }
 511  
 }