1 package org.nuiton.validator.bean;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.google.common.base.Preconditions;
25 import org.apache.commons.lang3.ObjectUtils;
26 import org.nuiton.util.beans.BeanUtil;
27 import org.nuiton.validator.NuitonValidator;
28 import org.nuiton.validator.NuitonValidatorModel;
29 import org.nuiton.validator.NuitonValidatorProvider;
30 import org.nuiton.validator.NuitonValidatorScope;
31
32 import javax.swing.event.EventListenerList;
33 import java.beans.PropertyChangeEvent;
34 import java.beans.PropertyChangeListener;
35 import java.beans.PropertyChangeSupport;
36 import java.util.Set;
37
38
39
40
41
42
43
44
45 public abstract class AbstractValidator<O> {
46
47
48
49
50
51
52
53 public static final String CONTEXT_PROPERTY = "context";
54
55
56
57
58
59
60
61 public static final String SCOPES_PROPERTY = "scopes";
62
63
64
65
66
67
68
69
70 public static final String VALID_PROPERTY = "valid";
71
72
73
74
75
76
77
78
79 public static final String CHANGED_PROPERTY = "changed";
80
81
82
83
84
85 protected boolean changed;
86
87
88 protected boolean valid = true;
89
90
91
92
93
94
95 protected boolean canValidate = true;
96
97
98 protected final PropertyChangeListener l;
99
100
101 protected final PropertyChangeSupport pcs;
102
103
104 protected final EventListenerList listenerList = new EventListenerList();
105
106
107
108
109
110
111
112
113 protected final NuitonValidatorProvider validatorProvider;
114
115
116 protected AbstractValidator(NuitonValidatorProvider validatorProvider,
117 Class<O> beanClass) {
118
119
120 boolean javaBeanCompiliant = BeanUtil.isJavaBeanCompiliant(beanClass);
121 Preconditions.checkState(
122 javaBeanCompiliant,
123 beanClass.getName() + " is not JavaBean compiliant (" +
124 BeanUtil.ADD_PROPERTY_CHANGE_LISTENER + ", or " +
125 BeanUtil.REMOVE_PROPERTY_CHANGE_LISTENER +
126 " method not found).");
127
128 this.validatorProvider = validatorProvider;
129
130 pcs = new PropertyChangeSupport(this);
131
132 l = new PropertyChangeListener() {
133
134 @Override
135 public void propertyChange(PropertyChangeEvent evt) {
136
137 O bean = (O) evt.getSource();
138
139
140 doValidate(bean);
141 }
142 };
143 }
144
145
146
147
148
149
150
151
152
153
154 public boolean isChanged() {
155 return changed;
156 }
157
158
159
160
161
162
163 public void setChanged(boolean changed) {
164 this.changed = changed;
165
166
167 firePropertyChange(CHANGED_PROPERTY, null, changed);
168 }
169
170 public boolean isCanValidate() {
171 return canValidate;
172 }
173
174 public void setCanValidate(boolean canValidate) {
175 this.canValidate = canValidate;
176 }
177
178
179
180
181
182
183 public boolean isValid() {
184 return valid;
185 }
186
187
188
189
190
191
192 public void setValid(boolean valid) {
193 this.valid = valid;
194
195
196 firePropertyChange(VALID_PROPERTY, null, valid);
197 }
198
199
200 public String getContext() {
201 return getModel().getContext();
202 }
203
204 public void setContext(String context) {
205
206 String oldContext = getContext();
207
208 if (ObjectUtils.equals(context, oldContext)) {
209
210
211 return;
212 }
213
214 NuitonValidatorModel<O> model = getModel();
215
216
217 NuitonValidatorScope[] scopes = model.getScopes().toArray(
218 new NuitonValidatorScope[model.getScopes().size()]);
219
220 rebuildDelegateValidator(
221 model.getType(),
222 context,
223 scopes
224 );
225
226 firePropertyChange(CONTEXT_PROPERTY,
227 oldContext,
228 context
229 );
230 }
231
232 public Set<NuitonValidatorScope> getScopes() {
233 return getModel().getScopes();
234 }
235
236 public Set<NuitonValidatorScope> getEffectiveScopes() {
237 return getDelegate().getEffectiveScopes();
238 }
239
240 public Set<String> getEffectiveFields() {
241 return getDelegate().getEffectiveFields();
242 }
243
244 public Set<String> getEffectiveFields(NuitonValidatorScope scope) {
245 return getDelegate().getEffectiveFields(scope);
246 }
247
248 public void setScopes(NuitonValidatorScope... scopes) {
249
250 Set<NuitonValidatorScope> oldScopes = getScopes();
251
252 rebuildDelegateValidator(
253 getModel().getType(),
254 getModel().getContext(),
255 scopes
256 );
257
258 firePropertyChange(SCOPES_PROPERTY,
259 oldScopes,
260 scopes
261 );
262 }
263
264 public abstract void doValidate();
265
266 public abstract boolean hasFatalErrors();
267
268 public abstract boolean hasErrors();
269
270 public abstract boolean hasWarnings();
271
272 public abstract boolean hasInfos();
273
274 public abstract boolean isValid(String fieldName);
275
276 public abstract NuitonValidatorScope getHighestScope(String field);
277
278 public abstract <T> T convert(O bean, String fieldName, String value, Class<T> valueClass);
279
280 protected abstract void doValidate(O bean);
281
282 protected abstract NuitonValidator<O> getDelegate();
283
284 protected abstract void rebuildDelegateValidator(Class<O> beanType,
285 String context,
286 NuitonValidatorScope... scopes);
287
288 public Class<O> getType() {
289 return getModel().getType();
290 }
291
292
293
294
295
296
297
298
299 public boolean containsField(String fieldName) {
300 Set<String> effectiveFields = getDelegate().getEffectiveFields();
301 boolean result = effectiveFields.contains(fieldName);
302 return result;
303 }
304
305 public void addPropertyChangeListener(PropertyChangeListener listener) {
306 pcs.addPropertyChangeListener(listener);
307 }
308
309 public void addPropertyChangeListener(String propertyName,
310 PropertyChangeListener listener) {
311 pcs.addPropertyChangeListener(propertyName, listener);
312 }
313
314 public void removePropertyChangeListener(PropertyChangeListener listener) {
315 pcs.removePropertyChangeListener(listener);
316 }
317
318 public void removePropertyChangeListener(String propertyName,
319 PropertyChangeListener listener) {
320 pcs.removePropertyChangeListener(propertyName, listener);
321 }
322
323 public void firePropertyChange(String propertyName,
324 Object oldValue,
325 Object newValue) {
326 pcs.firePropertyChange(propertyName, oldValue, newValue);
327 }
328
329 protected NuitonValidatorModel<O> getModel() {
330 return getDelegate().getModel();
331 }
332 }