1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springmodules.validation.bean.rule;
18
19 import org.springmodules.validation.bean.rule.resolver.ErrorArgumentsResolver;
20 import org.springmodules.validation.util.condition.Condition;
21 import org.springmodules.validation.util.condition.common.AlwaysTrueCondition;
22 import org.springmodules.validation.bean.context.ValidationContextHolder;
23 import org.springmodules.validation.bean.context.ValidationContext;
24 import org.springmodules.validation.bean.context.ValidationContextUtils;
25
26 /**
27 * A super class for all specific validation rules.
28 *
29 * @author Uri Boness
30 */
31 public abstract class AbstractValidationRule implements ValidationRule {
32
33 private String errorCode;
34
35 private String defaultErrorMessage;
36
37 private ErrorArgumentsResolver errorArgumentsResolver;
38
39 private Condition applicabilityCondition;
40
41 private String[] contextTokens;
42
43 /**
44 * Constructs a new AbstractValidationRule with a default error code. By default, the error arguments
45 * of this validation rule will only return the validated object itself.
46 *
47 * @param defaultErrorCode
48 */
49 protected AbstractValidationRule(String defaultErrorCode) {
50 this(defaultErrorCode, createErrorArgumentsResolver(new Object[0]));
51 }
52
53 /**
54 * Constructs a new AbstractValidationRule with a default error code and error argument resolver.
55 *
56 * @param defaultErrorCode The default error code for this validation rule.
57 * @param defaultErrorArgumentsResolver The argument resolver for this validation rule.
58 */
59 protected AbstractValidationRule(String defaultErrorCode, ErrorArgumentsResolver defaultErrorArgumentsResolver) {
60 this.errorCode = defaultErrorCode;
61 this.defaultErrorMessage = this.errorCode;
62 this.errorArgumentsResolver = defaultErrorArgumentsResolver;
63 this.applicabilityCondition = new AlwaysTrueCondition();
64 this.contextTokens = null;
65 }
66
67 /**
68 * Checks if this validation rule is applicable on a given object by performing the following two steps:
69 * <ol>
70 * <li>If the object is <code>null</code> and {@link #supportsNullValues()} returns <code>false</code>
71 * then returning <code>false</code>.</li>
72 * <li>Returning whatever the applicablity condition check returns for the given object
73 * ({@link #setApplicabilityCondition(org.springmodules.validation.util.condition.Condition)})</li>
74 *
75 * @see ValidationRule#isApplicable(Object)
76 */
77 public boolean isApplicable(Object obj) {
78 if (contextTokens != null && !checkContexts(contextTokens)) {
79 return false;
80 }
81 if (obj == null && !supportsNullValues()) {
82 return false;
83 }
84 return applicabilityCondition.check(obj);
85 }
86
87 /**
88 * @see org.springmodules.validation.bean.rule.ValidationRule#getErrorCode()
89 */
90 public String getErrorCode() {
91 return errorCode;
92 }
93
94 /**
95 * Returns the error arguments for this validation rule based on the given validated object. The arguments are
96 * determined by the associated {@link ErrorArgumentsResolver}.
97 *
98 * @see #setErrorArgumentsResolver(org.springmodules.validation.bean.rule.resolver.ErrorArgumentsResolver)
99 * @see ValidationRule#getErrorArguments(Object)
100 */
101 public Object[] getErrorArguments(Object obj) {
102 return errorArgumentsResolver.resolveArguments(obj);
103 }
104
105 /**
106 * @see org.springmodules.validation.bean.rule.ValidationRule#getDefaultErrorMessage()
107 */
108 public String getDefaultErrorMessage() {
109 return defaultErrorMessage;
110 }
111
112 /**
113 * Determines whether this validation rule supports <code>null</code> values. This method by default returns false,
114 * any sub-class that supports <code>null</code> values should override this method and return <code>true</code>.
115 *
116 * @return whether this validation rule supports <code>null</code> values.
117 */
118 protected boolean supportsNullValues() {
119 return false;
120 }
121
122
123
124 /**
125 * Sets the error code of this validation rule.
126 *
127 * @param errorCode The error code of this validation rule.
128 */
129 public void setErrorCode(String errorCode) {
130 this.errorCode = errorCode;
131 }
132
133 /**
134 * Sets the default error message of this validation rule.
135 *
136 * @param defaultErrorMessage The default error message of this validation rule.
137 */
138 public void setDefaultErrorMessage(String defaultErrorMessage) {
139 this.defaultErrorMessage = defaultErrorMessage;
140 }
141
142 /**
143 * Sets the {@link ErrorArgumentsResolver} that will be used by this validation to extract the error arguments
144 * based on the validated object.
145 *
146 * @param errorArgumentsResolver The error argument resolver that will be used by this validator.
147 */
148 public void setErrorArgumentsResolver(ErrorArgumentsResolver errorArgumentsResolver) {
149 this.errorArgumentsResolver = errorArgumentsResolver;
150 }
151
152 /**
153 * Sets the applicability condition that along with the {@link #supportsNullValues()} method determines whether
154 * this condition is applicable on a given object or not.
155 *
156 * @param applicabilityCondition The applicability condition that will be used by this validation rule when deciding
157 * whether it is applicable on a given object.
158 */
159 public void setApplicabilityCondition(Condition applicabilityCondition) {
160 this.applicabilityCondition = applicabilityCondition;
161 }
162
163 /**
164 * Sets the validation contexts names in which this validation rule is applicable.
165 *
166 * @param contextTokens The validation context names in which this validation rule is applicable. <code>null</code>
167 * represents applicability in any context (even if one doesn't exsit).
168 */
169 public void setContextTokens(String[] contextTokens) {
170 this.contextTokens = contextTokens;
171 }
172
173
174
175 /**
176 * A helper method for sub-classes helping with the creation of error argument resolvers. The resolver created by
177 * this method will return an array that contains the validated object and the given <code>arg</code> as the error
178 * arguments.
179 *
180 * @param arg The error argument to be returned along with the validated object.
181 * @return The created error arguments resolver.
182 */
183 protected static ErrorArgumentsResolver createErrorArgumentsResolver(Object arg) {
184 return createErrorArgumentsResolver(new Object[]{arg});
185 }
186
187 /**
188 * A helper method for sub-classes helping with the creation of error argument resolvers. The resolver created by
189 * this method will return an array that contains the validated object and the given arguments as the error
190 * arguments.
191 *
192 * @param arg1 The error argument to be returned in position {1}
193 * @param arg2 The error argument to be returned in position {2}
194 * @return The created error arguments resolver.
195 */
196 protected static ErrorArgumentsResolver createErrorArgumentsResolver(Object arg1, Object arg2) {
197 return createErrorArgumentsResolver(new Object[]{arg1, arg2});
198 }
199
200 /**
201 * A helper method for sub-classes helping with the creation of error argument resolvers. The resolver created by
202 * this method will return an array that contains the validated object and the given arguments as the error
203 * arguments.
204 *
205 * @param arg1 The error argument to be returned in position {1}
206 * @param arg2 The error argument to be returned in position {2}
207 * @param arg3 The error argument to be returned in position {3}
208 * @return The created error arguments resolver.
209 */
210 protected static ErrorArgumentsResolver createErrorArgumentsResolver(Object arg1, Object arg2, Object arg3) {
211 return createErrorArgumentsResolver(new Object[]{arg1, arg2, arg3});
212 }
213
214 /**
215 * A helper method for sub-classes helping with the creation of error argument resolvers. The resolver created by
216 * this method will return an array that contains the validated object and the given arguments as the error
217 * arguments.
218 *
219 * @param arguments The error arguments that will be return along with the validated object, starting in position {1}.
220 * @return The created error arguments resolver.
221 */
222 protected static ErrorArgumentsResolver createErrorArgumentsResolver(final Object[] arguments) {
223 return new ErrorArgumentsResolver() {
224 public Object[] resolveArguments(Object obj) {
225 Object[] result = new Object[arguments.length + 1];
226 System.arraycopy(arguments, 0, result, 1, arguments.length);
227 result[0] = obj;
228 return result;
229 }
230 };
231 }
232
233 protected static boolean checkContexts(String[] contextTokens) {
234 return ValidationContextUtils.tokensSupportedByCurrentContext(contextTokens);
235 }
236
237 }