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