1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.form.validator; |
16 |
| |
17 |
| import java.util.ArrayList; |
18 |
| import java.util.Collections; |
19 |
| import java.util.List; |
20 |
| import java.util.Map; |
21 |
| |
22 |
| import org.apache.hivemind.ApplicationRuntimeException; |
23 |
| import org.apache.hivemind.HiveMind; |
24 |
| import org.apache.hivemind.util.Defense; |
25 |
| import org.apache.hivemind.util.PropertyUtils; |
26 |
| import org.apache.tapestry.IComponent; |
27 |
| import org.apache.tapestry.util.RegexpMatch; |
28 |
| import org.apache.tapestry.util.RegexpMatcher; |
29 |
| |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| public class ValidatorFactoryImpl implements ValidatorFactory |
38 |
| { |
39 |
| private static final String PATTERN = "^\\s*(\\$?\\w+)\\s*(=\\s*(((?!,|\\[).)*))?"; |
40 |
| |
41 |
| private RegexpMatcher _matcher = new RegexpMatcher(); |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| |
47 |
| private Map _validators; |
48 |
| |
49 |
14
| public List constructValidatorList(IComponent component, String specification)
|
50 |
| { |
51 |
14
| Defense.notNull(component, "component");
|
52 |
| |
53 |
14
| if (HiveMind.isBlank(specification))
|
54 |
1
| return Collections.EMPTY_LIST;
|
55 |
| |
56 |
13
| List result = new ArrayList();
|
57 |
13
| String chopped = specification;
|
58 |
| |
59 |
13
| while (true)
|
60 |
| { |
61 |
19
| if (chopped.length() == 0)
|
62 |
3
| break;
|
63 |
| |
64 |
16
| if (!result.isEmpty())
|
65 |
| { |
66 |
3
| if (chopped.charAt(0) != ',')
|
67 |
0
| throw new ApplicationRuntimeException(ValidatorMessages
|
68 |
| .badSpecification(specification)); |
69 |
| |
70 |
3
| chopped = chopped.substring(1);
|
71 |
| } |
72 |
| |
73 |
16
| RegexpMatch[] matches = _matcher.getMatches(PATTERN, chopped);
|
74 |
| |
75 |
16
| if (matches.length != 1)
|
76 |
1
| throw new ApplicationRuntimeException(ValidatorMessages
|
77 |
| .badSpecification(specification)); |
78 |
| |
79 |
15
| RegexpMatch match = matches[0];
|
80 |
| |
81 |
15
| String name = match.getGroup(1);
|
82 |
15
| String value = match.getGroup(3);
|
83 |
15
| String message = null;
|
84 |
| |
85 |
15
| int length = match.getMatchLength();
|
86 |
| |
87 |
15
| if (chopped.length() > length)
|
88 |
| { |
89 |
7
| char lastChar = chopped.charAt(length);
|
90 |
7
| if (lastChar == ',')
|
91 |
2
| length--;
|
92 |
5
| else if (lastChar == '[')
|
93 |
| { |
94 |
5
| int messageClose = chopped.indexOf(']', length);
|
95 |
5
| message = chopped.substring(length + 1, messageClose);
|
96 |
5
| length = messageClose;
|
97 |
| } |
98 |
| } |
99 |
| |
100 |
15
| Validator validator = buildValidator(component, name, value, message);
|
101 |
| |
102 |
9
| result.add(validator);
|
103 |
| |
104 |
9
| if (length >= chopped.length())
|
105 |
3
| break;
|
106 |
| |
107 |
6
| chopped = chopped.substring(length + 1);
|
108 |
| |
109 |
| } |
110 |
| |
111 |
6
| return Collections.unmodifiableList(result);
|
112 |
| } |
113 |
| |
114 |
15
| private Validator buildValidator(IComponent component, String name, String value, String message)
|
115 |
| { |
116 |
15
| if (name.startsWith("$"))
|
117 |
4
| return extractValidatorBean(component, name, value, message);
|
118 |
| |
119 |
11
| ValidatorContribution vc = (ValidatorContribution) _validators.get(name);
|
120 |
| |
121 |
11
| if (vc == null)
|
122 |
1
| throw new ApplicationRuntimeException(ValidatorMessages.unknownValidator(name));
|
123 |
| |
124 |
10
| if (value == null && vc.isConfigurable())
|
125 |
1
| throw new ApplicationRuntimeException(ValidatorMessages.needsConfiguration("name"));
|
126 |
| |
127 |
9
| if (value != null && !vc.isConfigurable())
|
128 |
1
| throw new ApplicationRuntimeException(ValidatorMessages.notConfigurable(name, value));
|
129 |
| |
130 |
8
| try
|
131 |
| { |
132 |
8
| Object result = vc.getValidatorClass().newInstance();
|
133 |
| |
134 |
8
| if (vc.isConfigurable())
|
135 |
3
| PropertyUtils.smartWrite(result, name, value);
|
136 |
| |
137 |
8
| if (message != null)
|
138 |
4
| PropertyUtils.write(result, "message", message);
|
139 |
| |
140 |
8
| return (Validator) result;
|
141 |
| } |
142 |
| catch (Exception ex) |
143 |
| { |
144 |
1
| throw new ApplicationRuntimeException(ValidatorMessages.errorInitializingValidator(
|
145 |
| name, |
146 |
| vc.getValidatorClass(), |
147 |
| ex), ex); |
148 |
| } |
149 |
| } |
150 |
| |
151 |
4
| private Validator extractValidatorBean(IComponent component, String validatorName,
|
152 |
| String value, String message) |
153 |
| { |
154 |
4
| String beanName = validatorName.substring(1);
|
155 |
| |
156 |
4
| if (HiveMind.isNonBlank(value) || HiveMind.isNonBlank(message))
|
157 |
2
| throw new ApplicationRuntimeException(ValidatorMessages
|
158 |
| .noValueOrMessageForBean(beanName)); |
159 |
| |
160 |
2
| return new BeanValidatorWrapper(component, beanName);
|
161 |
| } |
162 |
| |
163 |
13
| public void setValidators(Map validators)
|
164 |
| { |
165 |
13
| _validators = validators;
|
166 |
| } |
167 |
| } |