PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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