001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krad.service; 017 018 import org.kuali.rice.krad.bo.BusinessObject; 019 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry; 020 import org.kuali.rice.krad.datadictionary.ReferenceDefinition; 021 import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader; 022 import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult; 023 import org.kuali.rice.krad.document.Document; 024 import org.kuali.rice.krad.document.TransactionalDocument; 025 026 import java.beans.PropertyDescriptor; 027 028 /** 029 * Defines the API for the validating against the data dictionary. 030 * 031 * @author Kuali Rice Team (rice.collab@kuali.org) 032 */ 033 public interface DictionaryValidationService { 034 035 /** 036 * Validates the contents of a document (i.e. attributes within a document) against the data dictionary. 037 * 038 * @param document - document to validate 039 */ 040 public void validateDocument(Document document); 041 042 /** 043 * Validates the contents of a document and recursively validates any of its updatable references 044 * 045 * @param document the document 046 * @param maxDepth the maximum numbers of levels to recurse 047 * @param validateRequired whether to validate whether a field is required and is currently blank 048 */ 049 public void validateDocumentAndUpdatableReferencesRecursively(Document document, int maxDepth, 050 boolean validateRequired); 051 052 /** 053 * Validates the contents of a document and recursively validates any of its updatable references 054 * 055 * @param document the document 056 * @param maxDepth the maximum numbers of levels to recurse 057 * @param validateRequired whether to validate whether a field is required and is currently blank 058 * @param chompLastLetterSFromCollectionName if true, the error path for any collections encountered will have the 059 * last "s" removed from the collection name if it ends 060 * with the letter "s". If false, this method acts like {@link #validateDocumentAndUpdatableReferencesRecursively(Document, 061 * int, boolean)} 062 */ 063 public void validateDocumentAndUpdatableReferencesRecursively(Document document, int maxDepth, 064 boolean validateRequired, boolean chompLastLetterSFromCollectionName); 065 066 /** 067 * Validates the specified attribute of the given document against the data dictionary. 068 * 069 * @param document 070 * @param attributeName 071 * @param errorPrefix 072 */ 073 public void validateDocumentAttribute(Document document, String attributeName, String errorPrefix); 074 075 /** 076 * Validates an object using its class name as the entry name to look up its metadata in the dictionary. 077 * 078 * @param object - an object to validate 079 * @return the dictionary validation result object associated with this validation 080 */ 081 public DictionaryValidationResult validate(Object object); 082 083 /** 084 * Validates an object using its class name as the entry name to look up its metadata in the dictionary. 085 * 086 * @param object - an object to validate 087 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 088 * are required or not), false otherwise 089 * @return the dictionary validation result object associated with this validation 090 */ 091 public DictionaryValidationResult validate(Object object, boolean doOptionalProcessing); 092 093 /** 094 * Validates an object using the passed entry name to look up metadata in the dictionary 095 * 096 * @param object - an object to validate 097 * @param entryName - the dictionary entry name to look up the metadata associated with this object 098 * @return the dictionary validation result object associated with this validation 099 * @since 1.1 100 */ 101 public DictionaryValidationResult validate(Object object, String entryName); 102 103 /** 104 * Same as {@link #validate(java.lang.Object, java.lang.String)} except that it provides a boolean parameter for 105 * the 106 * calling method to choose whether to do optional processing (generally to check if blank/empty values are 107 * required 108 * or not). 109 * 110 * @param object - an object to validate 111 * @param entryName - the dictionary entry name to look up the metadata associated with this object 112 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 113 * are required or not), false otherwise 114 * @return the dictionary validation result object associated with this validation 115 * @since 1.1 116 */ 117 public DictionaryValidationResult validate(Object object, String entryName, boolean doOptionalProcessing); 118 119 /** 120 * Validates a single attribute on the passed object using the passed entry name to look up 121 * metadata in the dictionary. 122 * 123 * @param object - an object to validate 124 * @param entryName - the dictionary entry name to look up the metadata associated with this object 125 * @param attributeName - the name of the attribute (field) on the object that should be validated 126 * @return the dictionary validation result object associated with this validation 127 * @since 1.1 128 */ 129 public DictionaryValidationResult validate(Object object, String entryName, String attributeName); 130 131 /** 132 * Same as {@link #validate(Object, String, String)} except that it provides a boolean parameter for the 133 * calling method to choose whether to do optional processing (generally to check if blank/empty values are 134 * required 135 * or not). 136 * 137 * @param object - an object to validate 138 * @param entryName - the dictionary entry name to look up the metadata associated with this object 139 * @param attributeName - the name of the attribute (field) on the object that should be validated 140 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 141 * are required or not), false otherwise 142 * @return the dictionary validation result object associated with this validation 143 * @since 1.1 144 */ 145 public DictionaryValidationResult validate(Object object, String entryName, String attributeName, 146 boolean doOptionalProcessing); 147 148 /** 149 * Same as {@link DictionaryValidationService#validate(Object, String, boolean) except that it provides an explicit 150 * data dictionary 151 * entry to use for the purpose of validation. 152 * 153 * @param object - an object to validate 154 * @param entryName - the dictionary entry name to use in association with error look ups 155 * @param entry - the dictionary entry to use for validation 156 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 157 * are required or not), false otherwise 158 * @return the dictionary validation result object associated with this validation 159 * @since 1.1 160 */ 161 public DictionaryValidationResult validate(Object object, String entryName, DataDictionaryEntry entry, 162 boolean doOptionalProcessing); 163 164 /** 165 * Instead of validating an object with dictionary metadata, or validating a specific member of an object by name, 166 * validates a 167 * specific attribute of an object by passing in the attribute value itself. This limits the amount of validation 168 * that can be done 169 * to constraints that directly affect this attribute. 170 * 171 * @param entryName - the dictionary entry name to use in association with error look ups 172 * @param attributeName - the dictionary entry attribute name to use in association with error look ups 173 * @param attributeValue - the value of the attribute being validated 174 */ 175 public void validate(String entryName, String attributeName, Object attributeValue); 176 177 /** 178 * Same as {@link #validate(String, String, Object)} except that it provides a boolean parameter for the 179 * calling method to choose whether to do optional processing (generally to check if blank/empty values are 180 * required 181 * or not). 182 * 183 * @param entryName - the dictionary entry name to use in association with error look ups 184 * @param attributeName - the dictionary entry attribute name to use in association with error look ups 185 * @param attributeValue - the value of the attribute being validated 186 * @param doOptionalProcessing - true if the validation should do optional validation (e.g. to check if empty 187 * values 188 * are required or not), false otherwise 189 */ 190 public void validate(String entryName, String attributeName, Object attributeValue, boolean doOptionalProcessing); 191 192 /** 193 * Same as other validate method except, allows you to provide the attributeValueReader directly for evaluation 194 * 195 * @param valueReader - an object to validate 196 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 197 * are required or not), false otherwise 198 * @return the dictionary validation result object associated with this validation 199 * @since 1.1 200 */ 201 public DictionaryValidationResult validate(AttributeValueReader valueReader, boolean doOptionalProcessing); 202 203 /** 204 * Encapsulates <code>{@link #validateBusinessObject(BusinessObject) and returns boolean so one doesn't need to 205 * check the 206 * ErrorMap.Validates the business object primitive attributes against the data dictionary. Adds errors to the map 207 * as they are 208 * encountered.<br/> 209 * <br/> 210 * Makes no error path adjustments 211 * 212 * @param businessObject - business object to validate 213 * @return boolean validOrNot 214 */ 215 public boolean isBusinessObjectValid(BusinessObject businessObject); 216 217 /** 218 * Encapsulates <code>{@link #validateBusinessObject(BusinessObject) and returns boolean so one doesn't need to 219 * check the 220 * ErrorMap.Validates the business object primitive attributes against the data dictionary. Adds errors to the map 221 * as they are 222 * encountered.<br/> 223 * <br/> 224 * Makes no error path adjustments 225 * 226 * @param businessObject - business object to validate 227 * @param prefix - error prefix 228 * @return boolean valid or not 229 */ 230 public boolean isBusinessObjectValid(BusinessObject businessObject, String prefix); 231 232 /** 233 * Validates the business object primitive attributes against the data dictionary. Adds errors to the map as they 234 * are 235 * encountered. 236 * 237 * @param businessObject - business object to validate 238 * @deprecated since 1.1 - use validate(Object.class) instead 239 */ 240 @Deprecated 241 public void validateBusinessObject(BusinessObject businessObject); 242 243 /** 244 * Validates the business object primitive attributes against the data dictionary. Adds errors to the map as they 245 * are 246 * encountered. 247 * 248 * @param businessObject - business object to validate 249 * @param validateRequired - whether to execute required field checks 250 * @deprecated since 1.1 - use validate(Object.class) instead 251 */ 252 @Deprecated 253 public void validateBusinessObject(BusinessObject businessObject, boolean validateRequired); 254 255 /** 256 * This method examines the populated BusinessObject bo instance passed in for a member named by the referenceName. 257 * If this 258 * member exists, and if this member is a descendent of BusinessObject, then an existence check proceeds. 259 * 260 * First the foreign keys for this reference are gathered, and then examined to see if they have values. If they do 261 * not have 262 * values, the method ends with a true return value. If they all have values, then an object with those primary 263 * keys 264 * is retrieve 265 * from the database. If one is retrieve, then the reference exists, and True is returned. Otherwise, false is 266 * returned. 267 * 268 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 269 * errorMap with no 270 * prefix, other than what has already been pushed onto the errorMap. 271 * 272 * @param bo - The bo whose reference is being tested. 273 * @param reference - The ReferenceDefinition to be existence tested. 274 * @return True if no exceptions occur and the object exists in the db, false otherwise. 275 */ 276 public boolean validateReferenceExists(BusinessObject bo, ReferenceDefinition reference); 277 278 /** 279 * This method examines the populated BusinessObject bo instance passed in for a member named by the referenceName. 280 * If this 281 * member exists, and if this member is a descendent of BusinessObject, then an existence check proceeds. 282 * 283 * First the foreign keys for this reference are gathered, and then examined to see if they have values. If they do 284 * not have 285 * values, the method ends with a true return value. If they all have values, then an object with those primary 286 * keys 287 * is retrieve 288 * from the database. If one is retrieve, then the reference exists, and True is returned. Otherwise, false is 289 * returned. 290 * 291 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 292 * errorMap with no 293 * prefix, other than what has already been pushed onto the errorMap. 294 * 295 * @param bo - The bo whose reference is being tested. 296 * @param referenceName - The name of the member to be existence tested. 297 * @return True if no exceptions occur and the object exists in the db, false otherwise. 298 */ 299 public boolean validateReferenceExists(BusinessObject bo, String referenceName); 300 301 /** 302 * This method retrieves the reference from the DB, and then tests whether the object is active. 303 * 304 * It will return false if there is no activeIndicator field on this object, if the object doesnt exist in the DB, 305 * if the field 306 * doesnt exist or cannot be cast as a boolean, if the field value is null, or if the field value is false. 307 * 308 * It will only return true if the reference bo is present, the field is present, it is a boolean and non-null, and 309 * the value is 310 * true. 311 * 312 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 313 * errorMap with no 314 * prefix, other than what has already been pushed onto the errorMap. 315 * 316 * @param bo 317 * @param reference 318 * @return 319 */ 320 public boolean validateReferenceIsActive(BusinessObject bo, ReferenceDefinition reference); 321 322 /** 323 * This method retrieves the reference from the DB, and then tests whether the object is active. 324 * 325 * It will return false if there is no activeIndicator field on this object, if the object doesnt exist in the DB, 326 * if the field 327 * doesnt exist or cannot be cast as a boolean, if the field value is null, or if the field value is false. 328 * 329 * It will only return true if the reference bo is present, the field is present, it is a boolean and non-null, and 330 * the value is 331 * true. 332 * 333 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 334 * errorMap with no 335 * prefix, other than what has already been pushed onto the errorMap. 336 * 337 * @param bo 338 * @param referenceName 339 * @return 340 */ 341 public boolean validateReferenceIsActive(BusinessObject bo, String referenceName); 342 343 /** 344 * This method intelligently tests the designated reference on the bo for both existence and active status, where 345 * appropriate. 346 * 347 * It will not test anything if the foreign-key fields for the given reference arent filled out with values, and it 348 * will not 349 * test active status if the reference doesnt exist. 350 * 351 * Further, it will only test active status where the correct flag is set. 352 * 353 * On failures of either sort, it will put the relevant errors into the GlobalVariables errorMap, and return a 354 * false. If there 355 * are no failures, or nothing can be tested because the foreign-key fields arent fully filled out, it will return 356 * true and add 357 * no errors. 358 * 359 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 360 * errorMap with no 361 * prefix, other than what has already been pushed onto the errorMap. 362 * 363 * @param bo - the BusinessObject instance to be tested. 364 * @param reference - the ReferenceDefinition to control the nature of the testing. 365 * @return true or false as per the criteria above 366 */ 367 public boolean validateReferenceExistsAndIsActive(BusinessObject bo, ReferenceDefinition reference); 368 369 /** 370 * This method intelligently tests the designated reference on the bo for both existence and active status, where 371 * appropriate. 372 * 373 * It will not test anything if the foreign-key fields for the given reference arent filled out with values, and it 374 * will not 375 * test active status if the reference doesnt exist. 376 * 377 * Note that it will not fail or raise any error if all of the foreign-keys are filled with a value. If this needs 378 * to be tested 379 * (ie, the 'if any field is filled, then all must be filled' rule), you'll have to do that separately. 380 * 381 * Further, it will only test active status where the correct flag is set. 382 * 383 * On failures of either sort, it will put the relevant errors into the GlobalVariables errorMap, and return a 384 * false. If there 385 * are no failures, or nothing can be tested because the foreign-key fields arent fully filled out, it will return 386 * true and add 387 * no errors. 388 * 389 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 390 * errorMap with no 391 * prefix, other than what has already been pushed onto the errorMap. 392 * 393 * @param bo - the BusinessObject instance to be tested. 394 * @param referenceName - the member name on the bo to be tested for existence and active-state 395 * @param attributeToHighlightOnFail - the fieldName to highlight with the error message on a failure 396 * @param displayFieldName - the human-readable display name of the failed field, to go in the error message 397 * @return true or false as per the criteria above 398 */ 399 public boolean validateReferenceExistsAndIsActive(BusinessObject bo, String referenceName, 400 String attributeToHighlightOnFail, String displayFieldName); 401 402 /** 403 * This method does an existence check against all references of a BusinessObject as defined in the 404 * MaintenanceDocument.xml file 405 * for that business object. 406 * 407 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 408 * 409 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 410 * errorMap with no 411 * prefix, other than what has already been pushed onto the errorMap. 412 * 413 * @param bo - BusinessObject instance that should be tested 414 * @return true if all passed existence tests, false if any failed 415 */ 416 public boolean validateDefaultExistenceChecks(BusinessObject bo); 417 418 /** 419 * Does an existence check against all references configured as a default existence check in the maintenance 420 * document data dictionary file for the given business object 421 * 422 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 423 * 424 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 425 * errorMap 426 * with no 427 * prefix, other than what has already been pushed onto the errorMap. 428 * 429 * @param bo parent business object instance to retrieve default checks for 430 * @param newCollectionItem new collection line to validate 431 * @param collectionName name of the collection in the parent 432 * @return true if all passed existence tests, false if any failed 433 */ 434 public boolean validateDefaultExistenceChecksForNewCollectionItem(BusinessObject bo, 435 BusinessObject newCollectionItem, String collectionName); 436 437 /** 438 * This method does an existence check against all references of a transactionalDocument 439 * 440 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 441 * 442 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 443 * errorMap 444 * with no 445 * prefix, other than what has already been pushed onto the errorMap. 446 * 447 * @param document document instance that should be tested 448 * @return true if all passed existence tests, false if any failed 449 */ 450 public boolean validateDefaultExistenceChecksForTransDoc(TransactionalDocument document); 451 452 /** 453 * This method does an existence check against all references of a transactionalDocument 454 * 455 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 456 * 457 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 458 * errorMap 459 * with no 460 * prefix, other than what has already been pushed onto the errorMap. 461 * 462 * @param document document instance that should be tested 463 * @param accountingLine that should be tested 464 * @param collectionName that should be tested 465 * @return true if all passed existence tests, false if any failed 466 */ 467 public boolean validateDefaultExistenceChecksForNewCollectionItem(TransactionalDocument document, 468 BusinessObject accountingLine, String collectionName); 469 470 /** 471 * @deprecated since 1.1 472 */ 473 @Deprecated 474 public void validatePrimitiveFromDescriptor(String entryName, Object object, PropertyDescriptor propertyDescriptor, 475 String errorPrefix, boolean validateRequired); 476 }