View Javadoc
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 }