1 /**
2 * Copyright 2005-2012 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.validation.AttributeValueReader;
22 import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult;
23 import org.kuali.rice.krad.document.Document;
24 import org.kuali.rice.krad.document.TransactionalDocument;
25
26 import java.beans.PropertyDescriptor;
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 * Validates an object using its class name as the entry name to look up its metadata in the dictionary.
85 *
86 * @param object - an object to validate
87 * @param doOptionalProcessing true if the validation should do optional validation (e.g. to check if empty values
88 * are required or not), false otherwise
89 * @return the dictionary validation result object associated with this validation
90 */
91 public DictionaryValidationResult validate(Object object, boolean doOptionalProcessing);
92
93 /**
94 * Validates an object using the passed entry name to look up metadata in the dictionary
95 *
96 * @param object - an object to validate
97 * @param entryName - the dictionary entry name to look up the metadata associated with this object
98 * @return the dictionary validation result object associated with this validation
99 * @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 }