1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.nuiton.validator.xwork2.field;
23
24 import com.opensymphony.xwork2.util.ValueStack;
25 import com.opensymphony.xwork2.validator.ValidationException;
26 import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.nuiton.converter.ConverterUtil;
30
31 import java.util.Map;
32 import java.util.StringTokenizer;
33 import java.util.TreeMap;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36
37
38
39
40
41
42
43
44 public class FieldExpressionWithParamsValidator extends NuitonFieldExpressionValidator {
45
46 private static final Log log = LogFactory.getLog(FieldExpressionWithParamsValidator.class);
47
48 protected static final Pattern EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(false|true)");
49
50 protected static final Pattern EXTRA_SHORT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(-\\d+|\\d+)");
51
52 protected static final Pattern EXTRA_INT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(-\\d+|\\d+)");
53
54 protected static final Pattern EXTRA_LONG_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(-\\d+|\\d+)");
55
56 protected static final Pattern EXTRA_DOUBLE_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(-\\d+\\.\\d+|\\d+\\.\\d+)");
57
58 protected static final Pattern EXTRA_STRING_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(.+)");
59
60 protected ValueStack stack;
61
62 protected String booleanParams;
63
64 protected String shortParams;
65
66 protected String intParams;
67
68 protected String longParams;
69
70 protected String doubleParams;
71
72 protected String stringParams;
73
74 protected Map<String, Boolean> booleans;
75
76 protected Map<String, Short> shorts;
77
78 protected Map<String, Integer> ints;
79
80 protected Map<String, Long> longs;
81
82 protected Map<String, Double> doubles;
83
84 protected Map<String, String> strings;
85
86 public String getBooleanParams() {
87 return booleanParams;
88 }
89
90 public void setBooleanParams(String booleanParams) {
91 this.booleanParams = booleanParams;
92 }
93
94 public String getDoubleParams() {
95 return doubleParams;
96 }
97
98 public void setDoubleParams(String doubleParams) {
99 this.doubleParams = doubleParams;
100 }
101
102 public String getIntParams() {
103 return intParams;
104 }
105
106 public void setIntParams(String intParams) {
107 this.intParams = intParams;
108 }
109
110 public String getLongParams() {
111 return longParams;
112 }
113
114 public void setLongParams(String longParams) {
115 this.longParams = longParams;
116 }
117
118 public String getShortParams() {
119 return shortParams;
120 }
121
122 public void setShortParams(String shortParams) {
123 this.shortParams = shortParams;
124 }
125
126 public String getStringParams() {
127 return stringParams;
128 }
129
130 public void setStringParams(String stringParams) {
131 this.stringParams = stringParams;
132 }
133
134 public Map<String, Boolean> getBooleans() {
135 return booleans;
136 }
137
138 public Map<String, Double> getDoubles() {
139 return doubles;
140 }
141
142 public Map<String, Integer> getInts() {
143 return ints;
144 }
145
146 public Map<String, Long> getLongs() {
147 return longs;
148 }
149
150 public Map<String, Short> getShorts() {
151 return shorts;
152 }
153
154 public Map<String, String> getStrings() {
155 return strings;
156 }
157
158 @Override
159 public String getValidatorType() {
160 return "fieldexpressionwithparams";
161 }
162
163 @Override
164 public void setValueStack(ValueStack stack) {
165 super.setValueStack(stack);
166 this.stack = stack;
167 }
168
169 @Override
170 public void validate(Object object) throws ValidationException {
171 super.validate(object);
172 }
173
174 @Override
175 public void validateWhenNotSkip(Object object) throws ValidationException {
176
177 booleans = initParams(Boolean.class, booleanParams, EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN);
178 shorts = initParams(Short.class, shortParams, EXTRA_SHORT_PARAM_ENTRY_PATTERN);
179 ints = initParams(Integer.class, intParams, EXTRA_INT_PARAM_ENTRY_PATTERN);
180 longs = initParams(Long.class, longParams, EXTRA_LONG_PARAM_ENTRY_PATTERN);
181 doubles = initParams(Double.class, doubleParams, EXTRA_DOUBLE_PARAM_ENTRY_PATTERN);
182 strings = initParams(String.class, stringParams, EXTRA_STRING_PARAM_ENTRY_PATTERN);
183
184 boolean pop = false;
185 if (!stack.getRoot().contains(this)) {
186 stack.push(this);
187 pop = true;
188 }
189
190 try {
191 super.validateWhenNotSkip(object);
192 } finally {
193 if (pop) {
194 stack.pop();
195 }
196 }
197
198 }
199
200 protected <T> Map<String, T> initParams(Class<T> klass, String extraParams, Pattern pattern) throws ValidationException {
201
202 if (extraParams == null || extraParams.isEmpty()) {
203
204 return null;
205 }
206
207 StringTokenizer stk = new StringTokenizer(extraParams, "|");
208 Map<String, T> result = new TreeMap<String, T>();
209 while (stk.hasMoreTokens()) {
210 String entry = stk.nextToken();
211 Matcher matcher = pattern.matcher(entry);
212 if (!matcher.matches()) {
213 throw new ValidationException("could not parse for extra params " + extraParams + " for type " + klass.getName());
214 }
215 String paramName = matcher.group(1);
216 String paramValueStr = matcher.group(2);
217 T paramValue = ConverterUtil.convert(klass, paramValueStr);
218 if (log.isDebugEnabled()) {
219 log.debug("detected extra param : <type:" + klass + ", name:" + paramName + ", value:" + paramValue + ">");
220 }
221 result.put(paramName, paramValue);
222 }
223 return result;
224 }
225 }