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 }