PageRenderTime 36ms CodeModel.GetById 20ms app.highlight 10ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/struts-2.2.1/src/xwork-core/src/main/java/com/opensymphony/xwork2/validator/Validator.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 490 lines | 17 code | 17 blank | 456 comment | 0 complexity | 32db42cca4512fdc79f311c4846c57ec MD5 | raw file
  1/*
  2 * Copyright 2002-2007,2009 The Apache Software Foundation.
  3 * 
  4 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
  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 */
 16package com.opensymphony.xwork2.validator;
 17
 18import com.opensymphony.xwork2.util.ValueStack;
 19
 20
 21/**
 22 * <!-- START SNIPPET: validatorFlavours -->
 23 * <p>The validators supplied by the XWork distribution (and any validators you
 24 * might write yourself) come in two different flavors:</p>
 25 * <p/>
 26 * <ol>
 27 * <li> Plain Validators / Non-Field validators </li>
 28 * <li> FieldValidators </li>
 29 * </ol>
 30 * <p/>
 31 * <p>Plain Validators (such as the ExpressionValidator) perform validation checks
 32 * that are not inherently tied to a single specified field. When you declare a
 33 * plain Validator in your -validation.xml file you do not associate a fieldname
 34 * attribute with it. (You should avoid using plain Validators within the
 35 * <field-validator> syntax described below.)</p>
 36 * <p/>
 37 * <p>FieldValidators (such as the EmailValidator) are designed to perform
 38 * validation checks on a single field. They require that you specify a fieldname
 39 * attribute in your -validation.xml file. There are two different (but equivalent)
 40 * XML syntaxes you can use to declare FieldValidators (see "<validator> vs.
 41 * <field-Validator> syntax" below).</p>
 42 * <p/>
 43 * <p>There are two places where the differences between the two validator flavors
 44 * are important to keep in mind:</p>
 45 * <p/>
 46 * <ol>
 47 * <li> when choosing the xml syntax used for declaring a validator
 48 * (either <validator> or <field-validator>)</li>
 49 * <li> when using the short-circuit capability</li>
 50 * </ol>
 51 * <p/>
 52 * <p><b>NOTE:</b>Note that you do not declare what "flavor" of validator you are
 53 * using in your -validation.xml file, you just declare the name of the validator
 54 * to use and Struts will know whether it's a "plain Validator" or a "FieldValidator"
 55 * by looking at the validation class that the validator's programmer chose
 56 * to implement.</p>
 57 * <!-- END SNIPPET: validatorFlavours -->
 58 * <p/>
 59 * <p/>
 60 * <p/>
 61 * <p/>
 62 * <!-- START SNIPPET: validationRules -->
 63 * <p>To define validation rules for an Action, create a file named ActionName-validation.xml
 64 * in the same package as the Action. You may also create alias-specific validation rules which
 65 * add to the default validation rules defined in ActionName-validation.xml by creating
 66 * another file in the same directory named ActionName-aliasName-validation.xml. In both
 67 * cases, ActionName is the name of the Action class, and aliasName is the name of the
 68 * Action alias defined in the xwork.xml configuration for the Action.</p>
 69 * <p/>
 70 * <p>The framework will also search up the inheritance tree of the Action to
 71 * find validation rules for directly implemented interfaces and parent classes of the Action.
 72 * This is particularly powerful when combined with ModelDriven Actions and the VisitorFieldValidator.
 73 * Here's an example of how validation rules are discovered. Given the following class structure:</p>
 74 * <p/>
 75 * <ul>
 76 * <li>interface Animal;</li>
 77 * <li>interface Quadraped extends Animal;</li>
 78 * <li>class AnimalImpl implements Animal;</li>
 79 * <li>class QuadrapedImpl extends AnimalImpl implements Quadraped;</li>
 80 * <li>class Dog extends QuadrapedImpl;</li>
 81 * </ul>
 82 * <p/>
 83 * <p>The framework method will look for the following config files if Dog is to be validated:</p>
 84 * <p/>
 85 * <ul>
 86 * <li>Animal</li>
 87 * <li>Animal-aliasname</li>
 88 * <li>AnimalImpl</li>
 89 * <li>AnimalImpl-aliasname</li>
 90 * <li>Quadraped</li>
 91 * <li>Quadraped-aliasname</li>
 92 * <li>QuadrapedImpl</li>
 93 * <li>QuadrapedImpl-aliasname</li>
 94 * <li>Dog</li>
 95 * <li>Dog-aliasname</li>
 96 * </ul>
 97 * <p/>
 98 * <p>While this process is similar to what the XW:Localization framework does
 99 * when finding messages, there are some subtle differences. The most important
100 * difference is that validation rules are discovered from the parent downwards.
101 * </p>
102 * <p/>
103 * <p><b>NOTE:</b>Child's *-validation.xml will add on to parent's *-validation.xml
104 * according to the class hierarchy defined above. With this feature, one could have
105 * more generic validation rule at the parent and more specific validation rule at
106 * the child.</p>
107 * <p/>
108 * <!-- END SNIPPET: validationRules -->
109 * <p/>
110 * <p/>
111 * <!-- START SNIPPET: validatorVsFieldValidators1 -->
112 * <p>There are two ways you can define validators in your -validation.xml file:</p>
113 * <ol>
114 * <li> &lt;validator&gt; </li>
115 * <li> &lt;field-validator&gt; </li>
116 * </ol>
117 * <p>Keep the following in mind when using either syntax:</p>
118 * <p/>
119 * <p><b>Non-Field-Validator</b>
120 * The &lt;validator&gt; element allows you to declare both types of validators
121 * (either a plain Validator a field-specific FieldValidator).</p>
122 * <!-- END SNIPPET: validatorVsFieldValidators1 -->
123 * <p/>
124 * <pre>
125 * <!-- START SNIPPET: nonFieldValidatorUsingValidatorSyntax -->
126 *    &lt;!-- Declaring a plain Validator using the &lt;validator&gt; syntax: --&gt;
127 * <p/>
128 *    &lt;validator type="expression&gt;
129 *          &lt;param name="expression">foo gt bar&lt;/param&gt;
130 *          &lt;message&gt;foo must be great than bar.&lt;/message&gt;
131 *    &lt;/validator&gt;
132 * <!-- END SNIPPET: nonFieldValidatorUsingValidatorSyntax -->
133 * </pre>
134 * <p/>
135 * <pre>
136 * <!-- START SNIPPET: fieldValidatorUsingValidatorSyntax -->
137 *    &lt;!-- Declaring a field validator using the &lt;validator&gt; syntax; --&gt;
138 * <p/>
139 *    &lt;validator type="required"&gt;
140 *         &lt;param name="fieldName"&gt;bar&lt;/param&gt;
141 *         &lt;message&gt;You must enter a value for bar.&lt;/message&gt;
142 *    &lt/validator&gt;
143 * <!-- END SNIPPET: fieldValidatorUsingValidatorSyntax -->
144 * </pre>
145 * <p/>
146 * <p/>
147 * <!-- START SNIPPET: validatorVsFieldValidators2 -->
148 * <p><b>field-validator</b>
149 * The &lt;field-validator&gt; elements are basically the same as the &lt;validator&gt; elements
150 * except that they inherit the fieldName attribute from the enclosing &lt;field&gt; element.
151 * FieldValidators defined within a &lt;field-validator&gt; element will have their fieldName
152 * automatically filled with the value of the parent &lt;field&gt; element's fieldName
153 * attribute. The reason for this structure is to conveniently group the validators
154 * for a particular field under one element, otherwise the fieldName attribute
155 * would have to be repeated, over and over, for each individual &lt;validator&gt;.</p>
156 * <p/>
157 * <p><b>HINT:</b>
158 * It is always better to defined field-validator inside a &lt;field&gt; tag instead of
159 * using a &lt;validator&gt; tag and supplying fieldName as its param as the xml code itself
160 * is clearer (grouping of field is clearer)</p>
161 * <p/>
162 * <p><b>NOTE:</b>
163 * Note that you should only use FieldValidators (not plain Validators) within a
164 * <field-validator> block. A plain Validator inside a &lt;field&gt; will not be
165 * allowed and would generate error when parsing the xml, as it is not allowed in
166 * the defined dtd (xwork-validator-1.0.2.dtd)</p>
167 * <!-- END SNIPPET: validatorVsFieldValidators2 -->
168 * <p/>
169 * <pre>
170 * <!-- START SNIPPET: fieldValidatorUsingFieldValidatorSyntax -->
171 * Declaring a FieldValidator using the &lt;field-validator&gt; syntax:
172 * <p/>
173 * &lt;field name="email_address"&gt;
174 *   &lt;field-validator type="required"&gt;
175 *       &lt;message&gt;You cannot leave the email address field empty.&lt;/message&gt;
176 *   &lt;/field-validator&gt;
177 *   &lt;field-validator type="email"&gt;
178 *       &lt;message&gt;The email address you entered is not valid.&lt;/message&gt;
179 *   &lt;/field-validator&gt;
180 * &lt;/field&gt;
181 * <!-- END SNIPPET: fieldValidatorUsingFieldValidatorSyntax -->
182 * </pre>
183 * <p/>
184 * <p/>
185 * <!-- START SNIPPET: validatorVsFieldValidators3 -->
186 * <p>The choice is yours. It's perfectly legal to only use <validator> elements
187 * without the <field> elements and set the fieldName attribute for each of them.
188 * The following are effectively equal:</P>
189 * <!-- END SNIPPET: validatorVsFieldValidators3 -->
190 * <p/>
191 * <pre>
192 * <!-- START SNIPPET: similarVaidatorDeclaredInDiffSyntax -->
193 * &lt;field name="email_address"&gt;
194 *   &lt;field-validator type="required"&gt;
195 *       &lt;message&gt;You cannot leave the email address field empty.&lt;/message&gt;
196 *   &lt;/field-validator&gt;
197 *   &lt;field-validator type="email"&gt;
198 *       &lt;message&gt;The email address you entered is not valid.&lt;/message&gt;
199 *   &lt;/field-validator&gt;
200 * &lt;/field&gt;
201 * <p/>
202 * <p/>
203 * &lt;validator type="required"&gt;
204 *   &lt;param name="fieldName"&gt;email_address&lt;/param&gt;
205 *   &lt;message&gt;You cannot leave the email address field empty.&lt;/message&gt;
206 * &lt;/validator&gt;
207 * &lt;validator type="email"&gt;
208 *   &lt;param name="fieldName"&gt;email_address&lt;/param&gt;
209 *   &lt;message&gt;The email address you entered is not valid.&lt;/message&gt;
210 * &lt;/validator&gt;
211 * <!-- END SNIPPET: similarVaidatorDeclaredInDiffSyntax -->
212 * </pre>
213 * <p/>
214 * <p/>
215 * <!-- START SNIPPET: shortCircuitingValidators1 -->
216 * <p>It is possible to short-circuit a stack of validators.
217 * Here is another sample config file containing validation rules from the
218 * Xwork test cases: Notice that some of the &lt;field-validator&gt; and
219 * &lt;validator&gt; elements have the short-circuit attribute set to true.</p>
220 * <!-- END SNIPPET : shortCircuitingValidators1 -->
221 * <p/>
222 * <pre>
223 * &lt;!-- START SNIPPET: exShortCircuitingValidators --&gt;
224 * &lt;!DOCTYPE validators PUBLIC
225 *         "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
226 *         "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"&gt;
227 * &lt;validators&gt;
228 *   &lt;!-- Field Validators for email field --&gt;
229 *   &lt;field name="email"&gt;
230 *       &lt;field-validator type="required" short-circuit="true"&gt;
231 *           &lt;message&gt;You must enter a value for email.&lt;/message&gt;
232 *       &lt;/field-validator&gt;
233 *       &lt;field-validator type="email" short-circuit="true"&gt;
234 *           &lt;message&gt;Not a valid e-mail.&lt;/message&gt;
235 *       &lt;/field-validator&gt;
236 *   &lt;/field&gt;
237 *   &lt;!-- Field Validators for email2 field --&gt;
238 *   &lt;field name="email2"&gt;
239 *      &lt;field-validator type="required"&gt;
240 *           &lt;message&gt;You must enter a value for email2.&lt;/message&gt;
241 *       &lt;/field-validator&gt;
242 *      &lt;field-validator type="email"&gt;
243 *           &lt;message&gt;Not a valid e-mail2.&lt;/message&gt;
244 *       &lt;/field-validator&gt;
245 *   &lt;/field&gt;
246 *   &lt;!-- Plain Validator 1 --&gt;
247 *   &lt;validator type="expression"&gt;
248 *       &lt;param name="expression"&gt;email.equals(email2)&lt;/param&gt;
249 *       &lt;message&gt;Email not the same as email2&lt;/message&gt;
250 *   &lt;/validator&gt;
251 *   &lt;!-- Plain Validator 2 --&gt;
252 *   &lt;validator type="expression" short-circuit="true"&gt;
253 *       &lt;param name="expression"&gt;email.startsWith('mark')&lt;/param&gt;
254 *       &lt;message&gt;Email does not start with mark&lt;/message&gt;
255 *   &lt;/validator&gt;
256 * &lt;/validators&gt;
257 * &lt;!-- END SNIPPET: exShortCircuitingValidators --&gt;
258 * </pre>
259 * <p/>
260 * <!-- START SNIPPET:shortCircuitingValidators2  -->
261 * <p><b>short-circuiting and Validator flavors</b></p>
262 * <p>Plain validator takes precedence over field-validator. They get validated
263 * first in the order they are defined and then the field-validator in the order
264 * they are defined. Failure of a particular validator marked as short-circuit
265 * will prevent the evaluation of subsequent validators and an error (action
266 * error or field error depending on the type of validator) will be added to
267 * the ValidationContext of the object being validated.</p>
268 * <p/>
269 * <p>In the example above, the actual execution of validator would be as follows:</p>
270 * <p/>
271 * <ol>
272 * <li> Plain Validator 1</li>
273 * <li> Plain Validator 2</li>
274 * <li> Field Validators for email field</li>
275 * <li> Field Validators for email2 field</li>
276 * </ol>
277 * <p/>
278 * <p>Since Plain Validator 2 is short-circuited, if its validation failed,
279 * it will causes Field validators for email field and Field validators for email2
280 * field to not be validated as well.</p>
281 * <p/>
282 * <p><b>Usefull Information:</b>
283 * More complicated validation should probably be done in the validate()
284 * method on the action itself (assuming the action implements Validatable
285 * interface which ActionSupport already does).</p>
286 * <p/>
287 * <p>
288 * A plain Validator (non FieldValidator) that gets short-circuited will
289 * completely break out of the validation stack. No other validators will be
290 * evaluated and plain validators takes precedence over field validators meaning
291 * that they get evaluated in the order they are defined before field validators
292 * get a chance to be evaluated.
293 * </p>
294 * <!-- END SNIPPET: shortCircuitingValidators2 -->
295 * <p/>
296 * <p/>
297 * <!-- START SNIPPET: scAndValidatorFlavours1 -->
298 * <p><b>Short cuircuiting and validator flavours</b></p>
299 * <p>A FieldValidator that gets short-circuited will only prevent other
300 * FieldValidators for the same field from being evaluated. Note that this
301 * "same field" behavior applies regardless of whether the <validator> or
302 * <field-validator> syntax was used to declare the validation rule.
303 * By way of example, given this -validation.xml file:</p>
304 * <!-- END SNIPPET: scAndValidatorFlavours1 -->
305 * <p/>
306 * <pre>
307 * <!-- START SNIPPET: exScAndValidatorFlavours -->
308 * &lt;validator type="required" short-circuit="true"&gt;
309 *   &lt;param name="fieldName"&gt;bar&lt;/param&gt;
310 *   &lt;message&gt;You must enter a value for bar.&lt;/message&gt;
311 * &lt;/validator&gt;
312 * <p/>
313 * &lt;validator type="expression"&gt;
314 *   &lt;param name="expression">foo gt bar&lt;/param&gt;
315 *   &lt;message&gt;foo must be great than bar.&lt;/message&gt;
316 * &lt;/validator&gt;
317 * <!-- END SNIPPET: exScAndValidatorFlavours -->
318 * </pre>
319 * <p/>
320 * <!-- START SNIPPET: scAndValidatorFlavours2 -->
321 * <p>both validators will be run, even if the "required" validator short-circuits.
322 * "required" validators are FieldValidator's and will not short-circuit the plain
323 * ExpressionValidator because FieldValidators only short-circuit other checks on
324 * that same field. Since the plain Validator is not field specific, it is
325 * not short-circuited.</p>
326 * <!-- END SNIPPET: scAndValidatorFlavours2 -->
327 * <p/>
328 * <p/>
329 * <!-- START SNIPPET: howXworkFindsValidatorForAction -->
330 * <p>As mentioned above, the framework will also search up the inheritance tree
331 * of the action to find default validations for interfaces and parent classes of
332 * the Action. If you are using the short-circuit attribute and relying on
333 * default validators higher up in the inheritance tree, make sure you don't
334 * accidentally short-circuit things higher in the tree that you really want!</p>
335 * <p>
336 * The effect of having common validators on both
337 * </p>
338 * <ul>
339 * 	<li>&lt;actionClass&gt;-validation.xml</li>
340 *     <li>&lt;actionClass&gt;-&lt;actionAlias&gt;-validation.xml</li>
341 * </ul>
342 * <p>
343 * It should be noted that the nett effect will be validation on both the validators available
344 * in both validation configuration file. For example if we have 'requiredstring' validators defined
345 * in both validation xml file for field named 'address', we will see 2 validation error indicating that
346 * the the address cannot be empty (assuming validation failed). This is due to WebWork
347 * will merge validators found in both validation configuration files.
348 * </p>
349 * <p>
350 * The logic behind this design decision is such that we could have common validators in
351 * &lt;actionClass&gt;-validation.xml and more context specific validators to be located
352 * in &lt;actionClass&gt;-&lt;actionAlias&gt;-validation.xml
353 * </p>
354 * <!-- END SNIPPET: howXworkFindsValidatorForAction -->
355 *
356 * <p/>
357 * <!-- START SNIPPET: i18n -->
358 * Validator's validation messages could be internatinalized. For example,
359 * <pre>
360 *   &lt;field-validator type="required"&gt;
361 *      &lt;message key="required.field" /&gt;
362 *   &lt;/field-validator&gt;
363 * </pre>
364 * or
365 * <pre>
366 *   &lt;validator type="expression"&gt;
367 *      &lt;param name="expression"&gt;email.startsWith('Mark')&lt;/param&gt;
368 *      &lt;message key="email.invalid" /&gt;
369 *   &lt;/validator&gt;
370 * </pre>
371 * In the first case, WebWork would look for i18n with key 'required.field' as the validation error message if
372 * validation fails, and 'email.invalid' in the second case.
373 * <p/>
374 * We could also provide a default message such that if validation failed and the i18n key for the message
375 * cannot be found, WebWork would fall back and use the default message. An example would be as follows :-
376 * <pre>
377 *   &lt;field-validator type="required"&gt;
378 *      &lt;message key="required.field"&gt;This field is required.&lt;/message&gt;
379 *   &lt;/field-validator&gt;
380 * </pre>
381 * or
382 * <pre>
383 *   &lt;validator type="expression"&gt;
384 *      &lt;param name="expression"&gt;email.startsWith('Mark')&lt;/param&gt;
385 *      &lt;message key="email.invalid"&gt;Email needs with starts with Mark&lt;/message&gt;
386 *   &lt;/validator&gt;
387 * </pre>
388 *
389 *
390 * <!-- END SNIPPET: i18n -->
391 * @author Jason Carreira
392 */
393public interface Validator<T> {
394
395    /**
396     * Sets the default message to use for validation failure
397     *
398     * @param message the default message
399     */
400    void setDefaultMessage(String message);
401
402    /**
403     * Gets the default message used for validation failures
404     *
405     * @return the default message
406     */
407    String getDefaultMessage();
408
409    /**
410     * Gets the validation failure message for the given object
411     *
412     * @param object object being validated (eg. a domain model object)
413     * @return the validation failure message
414     */
415    String getMessage(Object object);
416
417    /**
418     * Sets a resource bundle key to be used for lookup of validation failure message
419     *
420     * @param key the resource bundle key
421     */
422    void setMessageKey(String key);
423
424    /**
425     * Gets the resource bundle key used for lookup of validation failure message
426     *
427     * @return the resource bundle key
428     */
429    String getMessageKey();
430
431    /**
432     * Sets the messsage parameters to be used when parsing i18n messages
433     *
434     * @param messageParameters  the messsage parameters
435     */
436    void setMessageParameters(String[] messageParameters);
437
438    /**
439     * Gets the messsage parameters to be used when parsing i18n messages
440     *
441     * @return the messsage parameters
442     */
443    String[] getMessageParameters();
444
445    /**
446     * This method will be called before validate with a non-null ValidatorContext.
447     *
448     * @param validatorContext the validation context to use.
449     */
450    void setValidatorContext(ValidatorContext validatorContext);
451
452    /**
453     * Gets the validation context used
454     *
455     * @return the validation context
456     */
457    ValidatorContext getValidatorContext();
458
459    /**
460     * The validation implementation must guarantee that setValidatorContext will
461     * be called with a non-null ValidatorContext before validate is called.
462     *
463     * @param object the object to be validated.
464     * @throws ValidationException is thrown if there is validation error(s).
465     */
466    void validate(Object object) throws ValidationException;
467
468    /**
469     * Sets the validator type to use (see class javadoc).
470     *
471     * @param type the type to use.
472     */
473    void setValidatorType(String type);
474
475    /**
476     * Gets the vaildator type used (see class javadoc).
477     *
478     * @return the type used
479     */
480    String getValidatorType();
481
482    /**
483     * Sets the value stack to use to resolve values and parameters
484     *
485     * @param stack The value stack for the request
486     * @since 2.1.1
487     */
488    void setValueStack(ValueStack stack);
489
490}