Source code: com/aendvari/griffin/validation/dataset/Property.java
1 /*
2 * Property.java
3 *
4 * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5 *
6 * See the file LICENSE for terms of use.
7 *
8 */
9
10 package com.aendvari.griffin.validation.dataset;
11
12 import java.io.*;
13 import java.util.*;
14 import java.beans.*;
15
16 import java.lang.reflect.*;
17 import java.lang.NoSuchMethodException;
18 import java.lang.IllegalAccessException;
19
20 import com.aendvari.common.util.*;
21
22 import com.aendvari.common.model.*;
23
24 import com.aendvari.griffin.validation.*;
25 import com.aendvari.griffin.validation.validator.*;
26
27
28 /**
29 * <p>Defines a {@link Property}.</p>
30 *
31 * <p>A property is a single item in which a validation is wish to be run upon.</p>
32 *
33 * @author Scott Milne
34 *
35 */
36
37 public class Property
38 {
39 /* Constants */
40
41 /** Constants for the type of the property. */
42 public interface Type
43 {
44 public static String None = "";
45 public static String Collection = "collection";
46 }
47
48
49 /* Variables */
50
51 /** The path to retrieve the value of the property. */
52 private String path;
53
54 /** The type of the property. */
55 private String type;
56
57 /**
58 * The value of the property. This is only set within executeValidation and the value
59 * is derived from the ModelNode that is passed into that method call.
60 *
61 */
62 private Object value;
63
64 /** The name of the {@link Validator} in which to call on this property. */
65 private String validator;
66
67 /** A <code>HashMap</code> of name/{@link ParameterDefine} pairs for the validator's method. */
68 private HashMap validatorParameterDefines;
69
70 /** The name of the {@link ErrorHandler} in which to call on this property. */
71 private String errorHandler;
72
73 /** A <code>HashMap</code> of name/{@link ParameterDefine} pairs for the error handler's method. */
74 private HashMap errorHandlerParameterDefines;
75
76
77 /* Constructors. */
78
79
80 /**
81 * Constructs an empty <code>Validator</code> instance.
82 *
83 */
84
85 public Property()
86 {
87 validatorParameterDefines = new HashMap();
88 errorHandlerParameterDefines = new HashMap();
89
90 path = "";
91 value = null;
92 type = Type.None;
93 validator = "";
94 }
95
96
97 /* Accessors */
98
99 /**
100 * Get the value of the property.
101 *
102 */
103 public Object getValue()
104 {
105 return value;
106 }
107
108 /**
109 * Get the path of the property.
110 *
111 * @return A string representing the path of the property.
112 *
113 */
114
115 public String getPath()
116 {
117 return path;
118 }
119
120 /**
121 * Set the path of the property.
122 *
123 * @param setPath A string representing the path of the property.
124 *
125 */
126
127 public void setPath( String setPath )
128 {
129 path = setPath;
130 }
131
132 /**
133 * Get the type of the property.
134 *
135 * @return A string representing the type of the property.
136 *
137 */
138
139 public String getType()
140 {
141 return type;
142 }
143
144 /**
145 * Set the type of the property.
146 *
147 * @param setType A string representing the type of the property.
148 *
149 */
150
151 public void setType( String setType )
152 {
153 type = setType;
154 }
155
156 /**
157 * Get the validator of the property.
158 *
159 * @return A string representing the validator of the property.
160 *
161 */
162
163 public String getValidator()
164 {
165 return validator;
166 }
167
168 /**
169 * Set the validator of the property.
170 *
171 * @param setValidator A string representing the validator of the property.
172 *
173 */
174
175 public void setValidator( String setValidator )
176 {
177 validator = setValidator;
178 }
179
180 /**
181 * Get the validator of the property.
182 *
183 * @return A string representing the validator of the property.
184 *
185 */
186
187 public String setErrorHandler()
188 {
189 return errorHandler;
190 }
191
192 /**
193 * Set the error handler of the property.
194 *
195 * @param setErrorHandler A string representing the error handler of the property.
196 *
197 */
198
199 public void setErrorHandler( String setErrorHandler )
200 {
201 errorHandler = setErrorHandler;
202 }
203
204 /**
205 * Add a validator parameter.
206 *
207 * @param name The name of the parameter define.
208 * @param value The {@link ParameterDefine} instance for the parameter.
209 *
210 */
211
212 public void setValidatorParameterDefine( String name, ParameterDefine value )
213 {
214 validatorParameterDefines.put(name, value);
215 }
216
217 /**
218 * Get a validator parameter.
219 *
220 * @return A {@link ParameterDefine} of the parameter.
221 *
222 */
223
224 public ParameterDefine getValidatorParameterDefine( String name )
225 {
226 return (ParameterDefine)validatorParameterDefines.get(name);
227 }
228
229 /**
230 * Add a validator parameter.
231 *
232 * @param name The name of the parameter define.
233 * @param value The {@link ParameterDefine} instance for the parameter.
234 *
235 */
236
237 public void setErrorHandlerParameterDefine( String name, ParameterDefine value )
238 {
239 errorHandlerParameterDefines.put(name, value);
240 }
241
242 /**
243 * Get a validator parameter.
244 *
245 * @param name The key for the error handler define.
246 *
247 * @return A {@link ParameterDefine} of the parameter.
248 *
249 */
250
251 public ParameterDefine getErrorHandlerParameterDefine( String name )
252 {
253 return (ParameterDefine)errorHandlerParameterDefines.get(name);
254 }
255
256 /**
257 * Sets the parameter values for each of the handlers' {@link ParameterDefine}.
258 * The values of the parameter are derived from the defined values of this property.
259 *
260 * @param modelTree The {@link ModelTree} of which to do xpath queries.
261 * @param datasetNode The {@link ModelNode} of which to extract the data to be validated from.
262 * @param Object The default value as an <code>Object</code>.
263 * @param handler A {@link ValidationHandler} instance.
264 *
265 */
266
267 private void adjustParameters( ModelTree modelTree, ModelNode datasetNode, Object defaultValue, Handler handler )
268 {
269 // extract the values for each ParameterDefine
270 Iterator paramIterator = null;
271
272 if (handler instanceof Validator)
273 {
274 paramIterator = validatorParameterDefines.values().iterator();
275 }
276 else
277 {
278 paramIterator = errorHandlerParameterDefines.values().iterator();
279 }
280
281 while ( paramIterator.hasNext() )
282 {
283 ParameterDefine param = (ParameterDefine)paramIterator.next();
284
285 // if the param type is property
286 if (param.getType().equals(ParameterDefine.Type.Property))
287 {
288 param.setValue(defaultValue);
289 }
290 // if there is a valid xpath
291 else if (!param.getPath().equals(""))
292 {
293 // if the type is collection, collect all the xpath values
294 // and set the param type to this collection
295 if (param.getType().equals(ParameterDefine.Type.Collection))
296 {
297 ArrayList propertyParams = new ArrayList();
298
299 // collect a list of all the items (could be only 1)
300 // and run this validation on each one.
301 Iterator iterator = modelTree.getNodes(datasetNode, param.getPath()).iterator();
302
303 // if there were item(s) selected
304 if (iterator.hasNext())
305 {
306 while ( iterator.hasNext() )
307 {
308 ModelNode valueNode = (ModelNode)iterator.next();
309
310 String tmpValue = valueNode.getNodeValue();
311
312 propertyParams.add(tmpValue);
313 }
314
315 param.setValue( propertyParams );
316 }
317 }
318 // the type is not collection, so even if the xpath returns more than
319 // one value, only use the first one found
320 else
321 {
322 // get the node list
323 Iterator iterator = modelTree.getNodes(datasetNode, param.getPath()).iterator();
324
325 // if there were item(s) selected
326 if (iterator.hasNext())
327 {
328 ModelNode paramValueNode = (ModelNode)iterator.next();
329
330 if (paramValueNode != null)
331 {
332 param.setValue( paramValueNode.getNodeValue() );
333 }
334 }
335 }
336 }
337
338 // add this altered parameter to the handler list of defined params
339 handler.setParameterDefine( param.getName(), param );
340 }
341 }
342
343 /**
344 * Gets the matching {@link Validator} instance from the collection of instances.
345 *
346 * The matching {@link Validator} is found by matching the names of the {@link ParameterDefine}'s
347 * of this <code>Property</code> and {@link MethodDefine}'s of the {@link Validator}.
348 *
349 * @param list The list of {@link Validator} instances.
350 *
351 */
352
353 private Validator getMatchingValidator( Collection list )
354 {
355 Validator validator = null;
356
357 Collection thisValues = validatorParameterDefines.values();
358
359 Iterator iterator = list.iterator();
360 while (iterator.hasNext())
361 {
362 Validator tempValidator = (Validator)iterator.next();
363
364 // get the HandlerMethod of this validator
365 HandlerMethod method = tempValidator.getValidateMethod();
366
367 // get the list of params for this handler
368 Collection params = method.getParameters();
369
370 // create a temp list of params
371 ArrayList tempParams = new ArrayList(params);
372
373 // loop through the param defines, and it a match is found, remove it from the tempParams
374 Iterator paramIterator = thisValues.iterator();
375 while (paramIterator.hasNext())
376 {
377 ParameterDefine paramDefine = (ParameterDefine)paramIterator.next();
378
379 Iterator tempParamsIter = tempParams.iterator();
380 while (tempParamsIter.hasNext())
381 {
382 MethodParameter methodParam = (MethodParameter)tempParamsIter.next();
383
384 if (methodParam.getName().equals(paramDefine.getName()))
385 {
386 int index = tempParams.indexOf(methodParam);
387 tempParams.remove(index);
388 break;
389 }
390 }
391 }
392
393 // if nothing is left inside the tempParams list return this validator
394 if (tempParams.size() == 0)
395 {
396 validator = tempValidator;
397 }
398 }
399
400 return validator;
401 }
402
403 /**
404 * Executes this classes' part of a <code>Dataset</code> validation.
405 *
406 * @param datasetNode The {@link ModelNode} of which to extract the data to be validated from.
407 * @param validators A <code>MultiHashMap</code> of {@link Validator} instances.
408 * @param handlers A <code>HashMap</code> of {@link ValidationHandler} instances.
409 *
410 */
411
412 public void executeValidation( ModelNode datasetNode, MultiHashMap validators, HashMap handlers )
413 throws Exception
414 {
415 // get the validator instance derived from the configuration
416 Collection collisionList = validators.getCollisionList(validator);
417 Validator validatorInstance = getMatchingValidator(collisionList);
418
419 // in case an incorrect name of validator is used
420 if (validatorInstance == null )
421 {
422 throw new Exception("[executeValidation] Validator \""+validator+"\" could not be found.");
423 }
424
425 // get the error handler instance derived from the configuration
426 ErrorHandler errorHandlerInstance = (ErrorHandler)handlers.get(errorHandler);
427
428 // in case an incorrect name of validator is used
429 if (errorHandlerInstance == null )
430 {
431 throw new Exception("[executeValidation] ErrorHandler \""+errorHandler+"\" could not be found.");
432 }
433
434 // get the owner ModelTree of the node so it can be used for querying other nodes
435 ModelTree modelTree = datasetNode.getOwnerModelTree();
436
437 //
438 // extract the value of the property from the datasetNode
439 //
440
441 // if the type is collection, make a collection from the nodes
442 if (type.equals(Property.Type.Collection) )
443 {
444 ArrayList propertyParams = new ArrayList();
445
446 // collect a list of all the items (could be only 1)
447 // and run this validation on each one.
448 Iterator iterator = modelTree.getNodes(datasetNode, path).iterator();
449
450 // if there were item(s) selected
451 if (iterator.hasNext())
452 {
453 while ( iterator.hasNext() )
454 {
455 ModelNode valueNode = (ModelNode)iterator.next();
456
457 String tmpValue = valueNode.getNodeValue();
458
459 propertyParams.add(tmpValue);
460 }
461 }
462
463 // set the property value
464 value = propertyParams;
465
466 // set the parameters for this handler from the parameters available in this property
467 adjustParameters(modelTree, datasetNode, value, validatorInstance);
468
469 // execute the handler
470 boolean bSuccessful = validatorInstance.executeValidation( this, handlers );
471
472 // if the validation failed, call the error message
473 if (!bSuccessful)
474 {
475 // set the parameters for this handler from the parameters available in this property
476 adjustParameters(modelTree, datasetNode, value, errorHandlerInstance);
477
478 // execute the handler
479 errorHandlerInstance.executeValidation( this, handlers );
480 }
481 }
482 else
483 {
484 // collect a list of all the items (could be only 1)
485 // and run this validation on each one.
486 Iterator iterator = modelTree.getNodes(datasetNode, path).iterator();
487
488 // if there were item(s) selected
489 if (iterator.hasNext())
490 {
491 while ( iterator.hasNext() )
492 {
493 ModelNode valueNode = (ModelNode)iterator.next();
494
495 value = valueNode.getNodeValue();
496
497 // set the parameters for this handler from the parameters available in this property
498 adjustParameters(modelTree, datasetNode, value, validatorInstance);
499
500 // execute the handler
501 boolean bSuccessful = validatorInstance.executeValidation( this, handlers );
502
503 // if the validation failed, call the error message
504 if (!bSuccessful)
505 {
506 // set the parameters for this handler from the parameters available in this property
507 adjustParameters(modelTree, datasetNode, value, errorHandlerInstance);
508
509 // execute the handler
510 errorHandlerInstance.executeValidation( this, handlers );
511 }
512 }
513 }
514 // the property was empty, so it's still ok
515 else
516 {
517 value = "";
518
519 // set the parameters for this handler from the parameters available in this property
520 adjustParameters(modelTree, datasetNode, value, validatorInstance);
521
522 // execute the handler
523 boolean bSuccessful = validatorInstance.executeValidation( this, handlers );
524
525 // if the validation failed, call the error message
526 if (!bSuccessful)
527 {
528 // set the parameters for this handler from the parameters available in this property
529 adjustParameters(modelTree, datasetNode, value, errorHandlerInstance);
530
531 // execute the handler
532 errorHandlerInstance.executeValidation( this, handlers );
533 }
534 }
535 }
536 }
537
538 /**
539 * Convert this object into a String representation.
540 *
541 */
542
543 public String toString()
544 {
545 String data = "Property[";
546 data += "path="+path + ",";
547 data += "value="+value + ",";
548 data += "type="+type + ",";
549 data += "validator="+validator + ",";
550 data += "errorHandler="+errorHandler + ",";
551 data += "]";
552 return data;
553 }
554 }
555