Source code: com/aendvari/griffin/validation/ValidationHandler.java
1 /*
2 * ValidationHandler.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;
11
12 import java.util.*;
13 import java.beans.*;
14
15 import java.lang.reflect.*;
16 import java.lang.NoSuchMethodException;
17 import java.lang.IllegalAccessException;
18
19 import com.aendvari.common.util.*;
20
21 import com.aendvari.common.model.*;
22
23 import com.aendvari.griffin.validation.*;
24 import com.aendvari.griffin.validation.dataset.*;
25 import com.aendvari.griffin.validation.validator.*;
26
27
28 /**
29 * <p>Defines a {@link ValidationHandler}.</p>
30 *
31 * <p>This class is used to examine a handler class for its methods.</p>
32 *
33 * <p>This class is used by the {@link Validation} class to execute validate/error methods.</p>
34 *
35 * @author Scott Milne
36 *
37 */
38
39 public class ValidationHandler
40 {
41 /* Variables */
42
43 /** The name of the validation handler class. */
44 private String name;
45
46 /** The class of the validation handler class */
47 private Object handlerObject;
48
49 /** A {@link MultiHashMap} of the Method objects available in this handler. */
50 private MultiHashMap methods;
51
52
53 /* Constructors. */
54
55
56 /**
57 * Constructs an empty <code>ValidationHandler</code> instance.
58 *
59 * <p>This <b>does not</b> initialize the handler by default. All other constructors do.</p>
60 *
61 */
62
63 public ValidationHandler()
64 {
65 name = "";
66 handlerObject = null;
67 methods = new MultiHashMap();
68 }
69
70 /**
71 * Constructs a <code>ValidationHandler</code> instance.
72 *
73 * @param setName The name of the validation handler class.
74 * @param setHandler The path to a class to be used for the handler.
75 *
76 */
77
78 public ValidationHandler( String setName, String setHandler )
79 throws Exception
80 {
81 name = setName;
82 methods = new MultiHashMap();
83
84 // lookup the class object by name
85 Class handlerClass = null;
86
87 try
88 {
89 handlerClass = Class.forName(setHandler);
90 }
91 catch(ClassNotFoundException exception)
92 {
93 throw new Exception("[ValidationHandler] ClassNotFound: " + setName + " class: " + setHandler + " : " + exception.getMessage());
94 }
95
96 // now create an instance of the class
97 try
98 {
99 // create an instance of the given class
100 handlerObject = handlerClass.newInstance();
101 }
102 /*
103 * ClassNotFoundException
104 * NoSuchMethodException
105 * IllegalAccessException
106 *
107 */
108 catch (Exception exception)
109 {
110 throw new Exception("[ValidationHandler] ClassNotInstantiated: " + setName + " class: " + setHandler + " : " + exception.getMessage());
111 }
112
113 // initialize this handler
114 initializeHandler();
115 }
116
117 /**
118 * Constructs a <code>ValidationHandler</code> instance.
119 *
120 * @param setName The name of the validation handler class.
121 * @param setHandlerClass The {@link java.lang.Object java.lang.Object} to be used for the handler.
122 *
123 */
124
125 public ValidationHandler( String setName, Object setHandlerObject )
126 throws Exception
127 {
128 name = setName;
129 handlerObject = setHandlerObject;
130 methods = new MultiHashMap();
131
132 // initialize this handler
133 initializeHandler();
134 }
135
136 /**
137 * Constructs a <code>ValidationHandler</code> instance.
138 *
139 * @param setName The name of the validation handler class.
140 * @param setHandlerClass The {@link java.lang.Class java.lang.Class} to be used for the handler.
141 *
142 */
143
144 public ValidationHandler( String setName, Class setHandlerClass )
145 throws Exception
146 {
147 name = setName;
148 methods = new MultiHashMap();
149
150 // now create an instance of the class
151 try
152 {
153 // create an instance of the given class
154 handlerObject = setHandlerClass.newInstance();
155 }
156 /*
157 * ClassNotFoundException
158 * NoSuchMethodException
159 * IllegalAccessException
160 *
161 */
162 catch (Exception exception)
163 {
164 throw new Exception("[ValidationHandler] ClassNotInstantiated: " + setName + " class: " + setHandlerClass + " : " + exception.getMessage());
165 }
166
167 // initialize this handler
168 initializeHandler();
169 }
170
171 /* Initialization */
172
173 /**
174 * Examines the handler class, extracting the methods from it and storing them for later access.
175 *
176 */
177
178 public void initializeHandler()
179 throws Exception
180 {
181 try
182 {
183 // transverse the bean
184 BeanInfo beanInfo = Introspector.getBeanInfo( handlerObject.getClass() );
185
186 // get all the properties of the bean
187 MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
188
189 // for each property, get the set/get methods if available
190 int index=0;
191 for (index=0; index<methodDescriptors.length; index++)
192 {
193 MethodDescriptor methodDescriptor = methodDescriptors[index];
194 Method method = methodDescriptor.getMethod();
195
196 // make sure a valid method is available
197 if( method != null )
198 {
199 String methodName = method.getName();
200 methods.put( methodName, method );
201 }
202 }
203
204 }
205 catch (Exception exception)
206 {
207 throw new Exception("[initializeHandler]: " + " class: " + handlerObject.getClass() + " : " + exception.getMessage());
208 }
209 }
210
211
212 /* Accessors. */
213
214 /**
215 * Get the value of the validation class.
216 *
217 * @return A string representing the name of the validation handler class.
218 *
219 */
220
221 public String getName()
222 {
223 return name;
224 }
225
226 /**
227 * Set the value of the validation class.
228 *
229 * @param setName A string representing the name of the validation handler class.
230 *
231 */
232
233 public void setName( String setName )
234 {
235 name = setName;
236 }
237
238 /**
239 * Get the class of the validation class.
240 *
241 * @return A string representing the class of the validation handler class.
242 *
243 */
244
245 public Object getHandlerObject()
246 {
247 return handlerObject;
248 }
249
250 /**
251 * Set the class path of the validation class.
252 *
253 * @param setHandlerObject A string representing the class of the validation handler class.
254 *
255 */
256
257 public void setHandlerObject( String setHandlerObject )
258 {
259 handlerObject = setHandlerObject;
260 }
261
262 /**
263 * Executes this classes' part of a {@link Dataset} validation.
264 *
265 * @param methodName The name of the method to execute.
266 * @param parameters A <code>Collection</code> of {@link MethodParameter} instances.
267 * @param handler The {@link Handler} instance.
268 * @param property A {@link Property} instance for the value to test.
269 *
270 * @return true/false if the validation succeeded.
271 *
272 * @throws Throws <code>Exception</code> if no method is found.
273 *
274 */
275
276 public boolean executeMethod(
277 String methodName,
278 Collection parameters,
279 Handler handler,
280 Property property )
281 throws Exception
282 {
283 Method method = null;
284 Collection methodList = methods.getCollisionList(methodName);
285
286 boolean methodFound = false;
287 Iterator methodListIterator = methodList.iterator();
288
289 while ( methodListIterator.hasNext() )
290 {
291 boolean allMatched = true;
292
293 Method tempMethod = (Method)methodListIterator.next();
294
295 // get the list of parameters for this method
296 Class[] params = tempMethod.getParameterTypes();
297
298 //
299 // test against type and number of params
300 //
301 // throw Exception if nothing matches
302 //
303
304 // test the number of params
305 if (parameters.size() == params.length)
306 {
307 // they match, so now verify their types by order
308
309 // for each parameter
310 int paramIndex = 0;
311 Iterator paramIterator = parameters.iterator();
312
313 while ( paramIterator.hasNext() )
314 {
315 MethodParameter param = (MethodParameter)paramIterator.next();
316
317 String paramType = params[paramIndex].getName();
318
319 // if the two types do not match, then break out
320 if ( !paramType.equals(param.getType()) )
321 {
322 allMatched = false;
323 break;
324 }
325
326 paramIndex++;
327 }
328 }
329 else
330 {
331 allMatched = false;
332 }
333
334 // if everything matched, break out now to save time
335 if (allMatched)
336 {
337 method = tempMethod;
338 break;
339 }
340 }
341
342 // if the method is still null at this point, it cannot be found, give up
343 if (method == null)
344 {
345 throw new Exception("Invalid parameters were provided for method "+methodName+"\"");
346 }
347
348
349 // get the list of parameters for this method
350 Class[] params = method.getParameterTypes();
351
352 // create an argument array for holding the Objects for the parameters
353 Object[] paramValues = new Object[params.length];
354
355 // for each parameter
356 int paramIndex = 0;
357 Iterator paramIterator = parameters.iterator();
358
359 while ( paramIterator.hasNext() )
360 {
361 MethodParameter param = (MethodParameter)paramIterator.next();
362
363 Object setValue = null;
364 String paramName = param.getName();
365
366 ParameterDefine define = handler.getParameterDefine(paramName);
367
368 // if not null, the user defined this param, so use that value
369 if (define != null)
370 {
371 setValue = define.getValue();
372 }
373 // if the define is null, it means the user did not provide this parameter
374 // so we'll use the default one instead
375 else
376 {
377 setValue = param.getValue();
378 }
379
380 Class paramType = params[paramIndex];
381
382 //
383 // convert primitives into their object form using setValue as their value
384 //
385
386 if( paramType == int.class )
387 {
388 paramValues[paramIndex] = Integer.valueOf((String)setValue);
389 }
390 else if( paramType == byte.class )
391 {
392 paramValues[paramIndex] = Byte.valueOf((String)setValue);
393 }
394 else if( paramType == char.class )
395 {
396 paramValues[paramIndex] = new Character( ((Character)setValue).charValue());
397 }
398 else if( paramType == double.class )
399 {
400 paramValues[paramIndex] = Double.valueOf((String)setValue);
401 }
402 else if( paramType == float.class )
403 {
404 paramValues[paramIndex] = Float.valueOf((String)setValue);
405 }
406 else if( paramType == long.class )
407 {
408 paramValues[paramIndex] = Long.valueOf((String)setValue);
409 }
410 else if( paramType == short.class )
411 {
412 paramValues[paramIndex] = Short.valueOf((String)setValue);
413 }
414 else if( paramType == boolean.class )
415 {
416 paramValues[paramIndex] = Boolean.valueOf((String)setValue);
417 }
418 //
419 // java.lang Objects
420 //
421 else if( Boolean.class.isAssignableFrom(paramType) )
422 {
423 paramValues[paramIndex] = Boolean.valueOf((String)setValue);
424 }
425 else if( Byte.class.isAssignableFrom(paramType) )
426 {
427 paramValues[paramIndex] = Byte.valueOf((String)setValue);
428 }
429 else if( Character.class.isAssignableFrom(paramType) )
430 {
431 paramValues[paramIndex] = new Character( ((Character)setValue).charValue());
432 }
433 else if( Double.class.isAssignableFrom(paramType) )
434 {
435 paramValues[paramIndex] = Double.valueOf((String)setValue);
436 }
437 else if( Float.class.isAssignableFrom(paramType) )
438 {
439 paramValues[paramIndex] = Float.valueOf((String)setValue);
440 }
441 else if( Integer.class.isAssignableFrom(paramType) )
442 {
443 paramValues[paramIndex] = Integer.valueOf((String)setValue);
444 }
445 else if( Long.class.isAssignableFrom(paramType) )
446 {
447 paramValues[paramIndex] = Long.valueOf((String)setValue);
448 }
449 else if( Short.class.isAssignableFrom(paramType) )
450 {
451 paramValues[paramIndex] = Short.valueOf((String)setValue);
452 }
453 else if( String.class.isAssignableFrom(paramType) )
454 {
455 paramValues[paramIndex] = setValue;
456 }
457 // everything else
458 else
459 {
460 paramValues[paramIndex] = setValue;
461 }
462
463 paramIndex++;
464 }
465
466 // execute the method and get the return value from it
467 Object responseObj = method.invoke( handlerObject, paramValues );
468
469 // not sure if this is ok, but if the return type if null, then return true
470 // the is usually from "void" error methods
471 if ( responseObj == null )
472 {
473 return true;
474 }
475
476 // if the type returned is a boolean, get the value
477 if ( responseObj.getClass() == Boolean.class )
478 {
479 return ((Boolean)responseObj).booleanValue();
480 }
481
482 // for now, otherwise fail
483 return false;
484 }
485
486 /**
487 * Determines if the given method is available in this handler
488 *
489 */
490
491 public boolean isMethodAvailable( String methodName )
492 {
493 return methods.containsKey(methodName);
494 }
495
496 /**
497 * Convert this object into a String representation.
498 *
499 */
500
501 public String toString()
502 {
503 String data = "ValidationHandler [";
504
505 data += "name=" + name + ", ";
506 data += "handlerObject=" + handlerObject;
507 data += "]";
508
509 return data;
510 }
511 }
512