View Javadoc

1   /*
2    * Copyright 2004-2009 the original author or authors.
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  
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     //================================================== Setters =======================================================
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     //=============================================== Helper Methods ===================================================
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 }