View Javadoc

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.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 }