1 /** 2 * Copyright 2005-2013 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.service; 17 18 import org.kuali.rice.krad.bo.BusinessObject; 19 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry; 20 import org.kuali.rice.krad.datadictionary.ReferenceDefinition; 21 import org.kuali.rice.krad.datadictionary.state.StateMapping; 22 import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader; 23 import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult; 24 import org.kuali.rice.krad.document.Document; 25 import org.kuali.rice.krad.document.TransactionalDocument; 26 27 import java.beans.PropertyDescriptor; 28 29 /** 30 * Defines the API for the validating against the data dictionary. 31 * 32 * @author Kuali Rice Team (rice.collab@kuali.org) 33 */ 34 public interface DictionaryValidationService { 35 36 /** 37 * Validates the contents of a document (i.e. attributes within a document) against the data dictionary. 38 * 39 * @param document - document to validate 40 */ 41 public void validateDocument(Document document); 42 43 /** 44 * Validates the contents of a document and recursively validates any of its updatable references 45 * 46 * @param document the document 47 * @param maxDepth the maximum numbers of levels to recurse 48 * @param validateRequired whether to validate whether a field is required and is currently blank 49 */ 50 public void validateDocumentAndUpdatableReferencesRecursively(Document document, int maxDepth, 51 boolean validateRequired); 52 53 /** 54 * Validates the contents of a document and recursively validates any of its updatable references 55 * 56 * @param document the document 57 * @param maxDepth the maximum numbers of levels to recurse 58 * @param validateRequired whether to validate whether a field is required and is currently blank 59 * @param chompLastLetterSFromCollectionName if true, the error path for any collections encountered will have the 60 * last "s" removed from the collection name if it ends 61 * with the letter "s". If false, this method acts like {@link #validateDocumentAndUpdatableReferencesRecursively(Document, 62 * int, boolean)} 63 */ 64 public void validateDocumentAndUpdatableReferencesRecursively(Document document, int maxDepth, 65 boolean validateRequired, boolean chompLastLetterSFromCollectionName); 66 67 /** 68 * Validates the specified attribute of the given document against the data dictionary. 69 * 70 * @param document 71 * @param attributeName 72 * @param errorPrefix 73 */ 74 public void validateDocumentAttribute(Document document, String attributeName, String errorPrefix); 75 76 /** 77 * Validates an object using its class name as the entry name to look up its metadata in the dictionary. 78 * 79 * @param object - an object to validate 80 * @return the dictionary validation result object associated with this validation 81 */ 82 public DictionaryValidationResult validate(Object object); 83 84 /** 85 * Validate an object with the passed in dictionary entryName and the specific attribute to be evaluated 86 * 87 * @param object - an object to validate 88 * @param entryName - the dictionary entry name to look up the metadata associated with this object 89 * @param attributeName - the name of the attribute (field) on the object that should be validated 90 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 91 * are required or not), false otherwise 92 * @return the dictionary validation result object associated with this validation 93 * @since 1.1 94 */ 95 public DictionaryValidationResult validate(Object object, String entryName, String attributeName, 96 boolean doOptionalProcessing); 97 98 /** 99 * Same as {@link DictionaryValidationService#validate(Object, String, String, boolean) except that it provides an 100 * explicit 101 * data dictionary 102 * entry to use for the purpose of validation. 103 * 104 * @param object - an object to validate 105 * @param entryName - the dictionary entry name to use in association with error look ups 106 * @param entry - the dictionary entry to use for validation 107 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 108 * are required or not), false otherwise 109 * @return the dictionary validation result object associated with this validation 110 * @since 1.1 111 */ 112 public DictionaryValidationResult validate(Object object, String entryName, DataDictionaryEntry entry, 113 boolean doOptionalProcessing); 114 115 /** 116 * Validates the object agains the next state (or current state if there is no next state). 117 * 118 * <p>When no stateMapping exists on the DataDictionaryEntry that applies for this object, validation is considered 119 * stateless and all constraints are processed regardless of their states attribute.</p> 120 * 121 * @param object 122 * @return the dictionary validation result object associated with this validation 123 * @since 2.2 124 */ 125 public DictionaryValidationResult validateAgainstNextState(Object object); 126 127 /** 128 * Validates the object against the state specified. 129 * 130 * <p>Important note: Alternatively the state can be changed on the 131 * object itself and another validation method can be used instead of this one (in practice, you'd revert the 132 * state on the object if validation returns errors).</p> 133 * 134 * @param object 135 * @param validationState 136 * @return the dictionary validation result object associated with this validation 137 * @since 2.2 138 */ 139 public DictionaryValidationResult validateAgainstState(Object object, String validationState); 140 141 /** 142 * Same as other validate methods, except allows you to provide the attributeValueReader directly for evaluation 143 * 144 * @param valueReader - an object to validate 145 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values 146 * are required or not), false otherwise 147 * @return the dictionary validation result object associated with this validation 148 * @since 1.1 149 */ 150 public DictionaryValidationResult validate(AttributeValueReader valueReader, boolean doOptionalProcessing, 151 String validationState, StateMapping stateMapping); 152 153 /** 154 * Encapsulates <code>{@link #validateBusinessObject(BusinessObject) and returns boolean so one doesn't need to 155 * check the 156 * ErrorMap.Validates the business object primitive attributes against the data dictionary. Adds errors to the map 157 * as they are 158 * encountered.<br/> 159 * <br/> 160 * Makes no error path adjustments 161 * 162 * @param businessObject - business object to validate 163 * @return boolean validOrNot 164 */ 165 public boolean isBusinessObjectValid(BusinessObject businessObject); 166 167 /** 168 * Encapsulates <code>{@link #validateBusinessObject(BusinessObject) and returns boolean so one doesn't need to 169 * check the 170 * ErrorMap.Validates the business object primitive attributes against the data dictionary. Adds errors to the map 171 * as they are 172 * encountered.<br/> 173 * <br/> 174 * Makes no error path adjustments 175 * 176 * @param businessObject - business object to validate 177 * @param prefix - error prefix 178 * @return boolean valid or not 179 */ 180 public boolean isBusinessObjectValid(BusinessObject businessObject, String prefix); 181 182 /** 183 * Validates the business object primitive attributes against the data dictionary. Adds errors to the map as they 184 * are 185 * encountered. 186 * 187 * @param businessObject - business object to validate 188 * @deprecated since 1.1 - use validate(Object.class) instead 189 */ 190 @Deprecated 191 public void validateBusinessObject(BusinessObject businessObject); 192 193 /** 194 * Validates the business object primitive attributes against the data dictionary. Adds errors to the map as they 195 * are 196 * encountered. 197 * 198 * @param businessObject - business object to validate 199 * @param validateRequired - whether to execute required field checks 200 * @deprecated since 1.1 - use validate(Object.class) instead 201 */ 202 @Deprecated 203 public void validateBusinessObject(BusinessObject businessObject, boolean validateRequired); 204 205 /** 206 * This method examines the populated BusinessObject bo instance passed in for a member named by the referenceName. 207 * If this 208 * member exists, and if this member is a descendent of BusinessObject, then an existence check proceeds. 209 * 210 * First the foreign keys for this reference are gathered, and then examined to see if they have values. If they do 211 * not have 212 * values, the method ends with a true return value. If they all have values, then an object with those primary 213 * keys 214 * is retrieve 215 * from the database. If one is retrieve, then the reference exists, and True is returned. Otherwise, false is 216 * returned. 217 * 218 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 219 * errorMap with no 220 * prefix, other than what has already been pushed onto the errorMap. 221 * 222 * @param bo - The bo whose reference is being tested. 223 * @param reference - The ReferenceDefinition to be existence tested. 224 * @return True if no exceptions occur and the object exists in the db, false otherwise. 225 */ 226 public boolean validateReferenceExists(BusinessObject bo, ReferenceDefinition reference); 227 228 /** 229 * This method examines the populated BusinessObject bo instance passed in for a member named by the referenceName. 230 * If this 231 * member exists, and if this member is a descendent of BusinessObject, then an existence check proceeds. 232 * 233 * First the foreign keys for this reference are gathered, and then examined to see if they have values. If they do 234 * not have 235 * values, the method ends with a true return value. If they all have values, then an object with those primary 236 * keys 237 * is retrieve 238 * from the database. If one is retrieve, then the reference exists, and True is returned. Otherwise, false is 239 * returned. 240 * 241 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 242 * errorMap with no 243 * prefix, other than what has already been pushed onto the errorMap. 244 * 245 * @param bo - The bo whose reference is being tested. 246 * @param referenceName - The name of the member to be existence tested. 247 * @return True if no exceptions occur and the object exists in the db, false otherwise. 248 */ 249 public boolean validateReferenceExists(BusinessObject bo, String referenceName); 250 251 /** 252 * This method retrieves the reference from the DB, and then tests whether the object is active. 253 * 254 * It will return false if there is no activeIndicator field on this object, if the object doesnt exist in the DB, 255 * if the field 256 * doesnt exist or cannot be cast as a boolean, if the field value is null, or if the field value is false. 257 * 258 * It will only return true if the reference bo is present, the field is present, it is a boolean and non-null, and 259 * the value is 260 * true. 261 * 262 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 263 * errorMap with no 264 * prefix, other than what has already been pushed onto the errorMap. 265 * 266 * @param bo 267 * @param reference 268 * @return 269 */ 270 public boolean validateReferenceIsActive(BusinessObject bo, ReferenceDefinition reference); 271 272 /** 273 * This method retrieves the reference from the DB, and then tests whether the object is active. 274 * 275 * It will return false if there is no activeIndicator field on this object, if the object doesnt exist in the DB, 276 * if the field 277 * doesnt exist or cannot be cast as a boolean, if the field value is null, or if the field value is false. 278 * 279 * It will only return true if the reference bo is present, the field is present, it is a boolean and non-null, and 280 * the value is 281 * true. 282 * 283 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 284 * errorMap with no 285 * prefix, other than what has already been pushed onto the errorMap. 286 * 287 * @param bo 288 * @param referenceName 289 * @return 290 */ 291 public boolean validateReferenceIsActive(BusinessObject bo, String referenceName); 292 293 /** 294 * validateReferenceExistsAndIsActive intelligently tests the designated reference on the bo for both existence and 295 * active status, where 296 * appropriate 297 * 298 * <p>It will not test anything if the foreign-key fields for the given reference aren't filled out with values, 299 * and 300 * it 301 * will not test active status if the reference doesn't exist.</p> 302 * 303 * <p>Further, it will only test active status where the correct flag is set.</p> 304 * 305 * <p>On failures of either sort, it will put the relevant errors into the GlobalVariables errorMap, and return a 306 * false. If there 307 * are no failures, or nothing can be tested because the foreign-key fields arent fully filled out, it will return 308 * true and add 309 * no errors.</p> 310 * 311 * <p>This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 312 * errorMap with no 313 * prefix, other than what has already been pushed onto the errorMap.</p> 314 * 315 * @param bo - the BusinessObject instance to be tested. 316 * @param reference - the ReferenceDefinition to control the nature of the testing. 317 * @return true or false as per the criteria above 318 */ 319 public boolean validateReferenceExistsAndIsActive(BusinessObject bo, ReferenceDefinition reference); 320 321 /** 322 * This method intelligently tests the designated reference on the bo for both existence and active status, where 323 * appropriate. 324 * 325 * It will not test anything if the foreign-key fields for the given reference arent filled out with values, and it 326 * will not 327 * test active status if the reference doesnt exist. 328 * 329 * Note that it will not fail or raise any error if all of the foreign-keys are filled with a value. If this needs 330 * to be tested 331 * (ie, the 'if any field is filled, then all must be filled' rule), you'll have to do that separately. 332 * 333 * Further, it will only test active status where the correct flag is set. 334 * 335 * On failures of either sort, it will put the relevant errors into the GlobalVariables errorMap, and return a 336 * false. If there 337 * are no failures, or nothing can be tested because the foreign-key fields arent fully filled out, it will return 338 * true and add 339 * no errors. 340 * 341 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 342 * errorMap with no 343 * prefix, other than what has already been pushed onto the errorMap. 344 * 345 * @param bo - the BusinessObject instance to be tested. 346 * @param referenceName - the member name on the bo to be tested for existence and active-state 347 * @param attributeToHighlightOnFail - the fieldName to highlight with the error message on a failure 348 * @param displayFieldName - the human-readable display name of the failed field, to go in the error message 349 * @return true or false as per the criteria above 350 */ 351 public boolean validateReferenceExistsAndIsActive(BusinessObject bo, String referenceName, 352 String attributeToHighlightOnFail, String displayFieldName); 353 354 /** 355 * This method does an existence check against all references of a BusinessObject as defined in the 356 * MaintenanceDocument.xml file 357 * for that business object. 358 * 359 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 360 * 361 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 362 * errorMap with no 363 * prefix, other than what has already been pushed onto the errorMap. 364 * 365 * @param bo - BusinessObject instance that should be tested 366 * @return true if all passed existence tests, false if any failed 367 */ 368 public boolean validateDefaultExistenceChecks(BusinessObject bo); 369 370 /** 371 * Does an existence check against all references configured as a default existence check in the maintenance 372 * document data dictionary file for the given business object 373 * 374 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 375 * 376 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 377 * errorMap 378 * with no 379 * prefix, other than what has already been pushed onto the errorMap. 380 * 381 * @param bo parent business object instance to retrieve default checks for 382 * @param newCollectionItem new collection line to validate 383 * @param collectionName name of the collection in the parent 384 * @return true if all passed existence tests, false if any failed 385 */ 386 public boolean validateDefaultExistenceChecksForNewCollectionItem(BusinessObject bo, 387 BusinessObject newCollectionItem, String collectionName); 388 389 /** 390 * This method does an existence check against all references of a transactionalDocument 391 * 392 * Appropriate errors will also be placed in the GlobalVariables.ErrorMap. 393 * 394 * This method assumes that you already have the errorPath set exactly as desired, and adds new errors to the 395 * errorMap 396 * with no 397 * prefix, other than what has already been pushed onto the errorMap. 398 * 399 * @param document document instance that should be tested 400 * @return true if all passed existence tests, false if any failed 401 */ 402 public boolean validateDefaultExistenceChecksForTransDoc(TransactionalDocument document); 403 404 /** 405 * This method does an existence check against all references of a transactionalDocument 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 411 * with no 412 * prefix, other than what has already been pushed onto the errorMap. 413 * 414 * @param document document instance that should be tested 415 * @param accountingLine that should be tested 416 * @param collectionName that should be tested 417 * @return true if all passed existence tests, false if any failed 418 */ 419 public boolean validateDefaultExistenceChecksForNewCollectionItem(TransactionalDocument document, 420 BusinessObject accountingLine, String collectionName); 421 422 /** 423 * @deprecated since 1.1 424 */ 425 @Deprecated 426 public void validatePrimitiveFromDescriptor(String entryName, Object object, PropertyDescriptor propertyDescriptor, 427 String errorPrefix, boolean validateRequired); 428 }