1 package org.apache.turbine.services.intake.model;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24
25 import java.util.Locale;
26
27 import org.apache.commons.lang.StringUtils;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 import org.apache.turbine.om.Retrievable;
33 import org.apache.turbine.services.TurbineServices;
34 import org.apache.turbine.services.intake.IntakeException;
35 import org.apache.turbine.services.intake.TurbineIntake;
36 import org.apache.turbine.services.intake.validator.DefaultValidator;
37 import org.apache.turbine.services.intake.validator.InitableByConstraintMap;
38 import org.apache.turbine.services.intake.validator.ValidationException;
39 import org.apache.turbine.services.intake.validator.Validator;
40 import org.apache.turbine.services.intake.xmlmodel.Rule;
41 import org.apache.turbine.services.intake.xmlmodel.XmlField;
42 import org.apache.turbine.services.localization.Localization;
43 import org.apache.turbine.services.localization.LocalizationService;
44 import org.apache.turbine.util.SystemError;
45 import org.apache.turbine.util.parser.ParameterParser;
46 import org.apache.turbine.util.parser.ValueParser;
47
48 /***
49 * Base class for Intake generated input processing classes.
50 *
51 * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
52 * @author <a href="mailto:dlr@finemaltcoding.com>Daniel Rall</a>
53 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
54 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
55 * @author <a href="mailto:jh@byteaction.de">Jürgen Hoffmann</a>
56 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
57 * @version $Id: Field.java 538811 2007-05-17 05:55:42Z seade $
58 */
59 public abstract class Field
60 {
61 /*** Empty Value */
62 private static final String EMPTY = "";
63
64 /*** CGI Key for "value if absent" */
65 private static final String VALUE_IF_ABSENT_KEY = "_vifa_";
66
67 /*** Default Validator Package */
68 public static final String defaultValidatorPackage = "org.apache.turbine.services.intake.validator.";
69
70 /*** Default Field Package */
71 public static final String defaultFieldPackage = "org.apache.turbine.services.intake.model.";
72
73
74
75 /*** Name of the field. */
76 protected final String name;
77
78 /*** Key used to identify the field in the parser */
79 protected final String key;
80
81 /*** Display name of the field to be used on data entry forms... */
82 protected String displayName;
83
84 /*** Class name of the object to which the field is mapped */
85 protected final String mapToObject;
86
87 /*** Used to validate the contents of the field */
88 protected Validator validator;
89
90 /*** Getter method in the mapped object used to populate the field */
91 protected final Method getter;
92
93 /*** Setter method in the mapped object used to store the value of field */
94 protected final Method setter;
95
96 /*** Error message set on the field if required and not set by parser */
97 protected String ifRequiredMessage;
98
99 /*** Does this field accept multiple values? */
100 protected final boolean isMultiValued;
101
102 /*** Group to which the field belongs */
103 protected final Group group;
104
105 /*** Is this field always required? This is only set through the XML file */
106 protected boolean alwaysRequired;
107
108 /***
109 * Value of the field if an error occurs while getting
110 * the value from the mapped object
111 */
112 protected Object onError;
113
114 /*** Default value of the field */
115 protected Object defaultValue;
116
117 /*** Value of the field to use if the mapped parameter is empty or non-existant */
118 protected Object emptyValue;
119
120 /*** Display size of the field */
121 private String displaySize;
122
123 /*** Max size of the field */
124 private String maxSize;
125
126
127
128 /*** Has the field has been set from the parser? */
129 protected boolean setFlag;
130
131 /*** Has the field passed the validation test? */
132 protected boolean validFlag;
133
134 /*** Has the field been validated? */
135 protected boolean validated;
136
137 /*** Does the field require a value? */
138 protected boolean required;
139
140 /*** Has the field has been set from the parser? */
141 protected boolean initialized;
142
143 /*** Error message, is any, resulting from validation */
144 protected String message;
145
146 /*** Mapped object used to set the initial field value */
147 protected Retrievable retrievable;
148
149 private Locale locale;
150 /*** String value of the field */
151 private String stringValue;
152 /*** String valuess of the field if isMultiValued=true */
153 private String[] stringValues;
154 /*** Stores the value of the field from the Retrievable object */
155 private Object validValue;
156 /*** Stores the value of the field from the parser */
157 private Object testValue;
158 /*** Used to pass testValue to the setter mathod through reflection */
159 private Object[] valArray;
160 /*** The object containing the field data. */
161 protected ValueParser parser;
162
163 /*** Logging */
164 protected Log log = LogFactory.getLog(this.getClass());
165 protected boolean isDebugEnabled = false;
166
167 /***
168 * Constructs a field based on data in the xml specification
169 * and assigns it to a Group.
170 *
171 * @param field a <code>XmlField</code> value
172 * @param group a <code>Group</code> value
173 * @throws IntakeException indicates the validator was not valid or
174 * could not be loaded.
175 * @throws SystemError only occurs is the Validation object does not
176 * extend InitableByConstraintMap
177 */
178 public Field(XmlField field, Group group) throws IntakeException
179 {
180 isDebugEnabled = log.isDebugEnabled();
181
182 this.group = group;
183 key = field.getKey();
184 name = field.getName();
185 displayName = field.getDisplayName();
186 displaySize = field.getDisplaySize();
187 isMultiValued = field.isMultiValued();
188
189 try
190 {
191 setDefaultValue(field.getDefaultValue());
192 }
193 catch (RuntimeException e)
194 {
195 log.error("Could not set default value of " +
196 this.getDisplayName() + " to "
197 + field.getDefaultValue(), e);
198 }
199
200 try
201 {
202 setEmptyValue(field.getEmptyValue());
203 }
204 catch (RuntimeException e)
205 {
206 log.error("Could not set empty value of " +
207 this.getDisplayName() + " to "
208 + field.getEmptyValue(), e);
209 }
210
211 String validatorClassName = field.getValidator();
212 if (validatorClassName == null)
213 {
214 validatorClassName = getDefaultValidator();
215 }
216 else if (validatorClassName != null
217 && validatorClassName.indexOf('.') == -1)
218 {
219 validatorClassName = defaultValidatorPackage + validatorClassName;
220 }
221
222 if (validatorClassName != null)
223 {
224 try
225 {
226 validator = (Validator)
227 Class.forName(validatorClassName).newInstance();
228 }
229 catch (InstantiationException e)
230 {
231 throw new IntakeException(
232 "Could not create new instance of Validator("
233 + validatorClassName + ")", e);
234 }
235 catch (IllegalAccessException e)
236 {
237 throw new IntakeException(
238 "Could not create new instance of Validator("
239 + validatorClassName + ")", e);
240 }
241 catch (ClassNotFoundException e)
242 {
243 throw new IntakeException(
244 "Could not load Validator class("
245 + validatorClassName + ")", e);
246 }
247
248
249 if (validator instanceof InitableByConstraintMap)
250 {
251 ((InitableByConstraintMap) validator).init(field.getRuleMap());
252 }
253 else
254 {
255 throw new SystemError(
256 "All Validation objects must be subclasses of "
257 + "InitableByConstraintMap");
258 }
259 }
260
261
262 Rule reqRule = (Rule) field.getRuleMap().get("required");
263 if (reqRule != null)
264 {
265 alwaysRequired = Boolean.valueOf(reqRule.getValue()).booleanValue();
266 ifRequiredMessage = reqRule.getMessage();
267 }
268
269 Rule maxLengthRule = (Rule) field.getRuleMap().get("maxLength");
270 if (maxLengthRule != null)
271 {
272 maxSize = maxLengthRule.getValue();
273 }
274
275
276 mapToObject = field.getMapToObject();
277 String propName = field.getMapToProperty();
278 Method tmpGetter = null;
279 Method tmpSetter = null;
280 if (StringUtils.isNotEmpty(mapToObject)
281 && StringUtils.isNotEmpty(propName))
282 {
283 try
284 {
285 tmpGetter = TurbineIntake.getFieldGetter(mapToObject, propName);
286 }
287 catch (Exception e)
288 {
289 log.error("IntakeService could not map the getter for field "
290 + this.getDisplayName() + " in group "
291 + this.group.getIntakeGroupName()
292 + " to the property " + propName + " in object "
293 + mapToObject, e);
294 }
295 try
296 {
297 tmpSetter = TurbineIntake.getFieldSetter(mapToObject, propName);
298 }
299 catch (Exception e)
300 {
301 log.error("IntakeService could not map the setter for field "
302 + this.getDisplayName() + " in group "
303 + this.group.getIntakeGroupName()
304 + " to the property " + propName + " in object "
305 + mapToObject, e);
306 }
307 }
308 getter = tmpGetter;
309 setter = tmpSetter;
310
311 valArray = new Object[1];
312 }
313
314 /***
315 * Method called when this field (the group it belongs to) is
316 * pulled from the pool. The request data is searched to determine
317 * if a value has been supplied for this field. If so, the value
318 * is validated.
319 *
320 * @param pp a <code>ValueParser</code> value
321 * @return a <code>Field</code> value
322 * @throws IntakeException this exception is only thrown by subclasses
323 * overriding this implementation.
324 */
325 public Field init(ValueParser pp)
326 throws IntakeException
327 {
328 this.parser = pp;
329 validFlag = true;
330 validated = false;
331
332
333
334 if (TurbineServices.getInstance()
335 .isRegistered(LocalizationService.SERVICE_NAME))
336 {
337 if (pp instanceof ParameterParser)
338 {
339 this.locale = Localization.getLocale
340 (((ParameterParser) pp).getRequest());
341 }
342 else
343 {
344 this.locale = Localization.getLocale((String) null);
345 }
346 }
347
348 if (pp.containsKey(getKey()))
349 {
350 if (isDebugEnabled)
351 {
352 log.debug(name + ": Found our Key in the request, setting Value");
353 }
354 if (pp.getString(getKey()) != null)
355 {
356 setFlag = true;
357 }
358
359 }
360 else if (pp.containsKey(getValueIfAbsent()) &&
361 pp.getString(getValueIfAbsent()) != null)
362 {
363 pp.add(getKey(), pp.getString(getValueIfAbsent()));
364 setFlag = true;
365
366 }
367
368 initialized = true;
369 return this;
370 }
371
372 /***
373 * Method called when this field or the group it belongs to is
374 * pulled from the pool. The retrievable object can provide
375 * a default value for the field, or using setProperty the field's
376 * value can be transferred to the retrievable.
377 *
378 * @param obj a <code>Retrievable</code> value
379 * @return a <code>Field</code> value
380 */
381 public Field init(Retrievable obj)
382 {
383 if (!initialized)
384 {
385 validFlag = true;
386 validated = false;
387 }
388 retrievable = obj;
389 return this;
390 }
391
392 /***
393 * Returns the <code>Group</code> this field belongs to
394 * or <code>null</code> if unknown.
395 *
396 * @return The group this field belongs to.
397 */
398 public Group getGroup()
399 {
400 return group;
401 }
402
403 /***
404 * Returns the <code>Locale</code> used when localizing data for
405 * this field, or <code>null</code> if unknown.
406 *
407 * @return Where to localize for.
408 */
409 public Locale getLocale()
410 {
411 return locale;
412 }
413
414 /***
415 * Produces the fully qualified class name of the default validator.
416 *
417 * @return class name of the default validator
418 */
419 protected String getDefaultValidator()
420 {
421 return DefaultValidator.class.getName();
422 }
423
424 /***
425 * Gets the Validator object for this field.
426 * @return a <code>Validator</code> object
427 */
428 public Validator getValidator()
429 {
430 return validator;
431 }
432
433 /***
434 * Flag to determine whether the field has been declared as multi-valued.
435 *
436 * @return value of isMultiValued.
437 */
438 public boolean isMultiValued()
439 {
440 return isMultiValued;
441 }
442
443 /***
444 * Flag to determine whether the field has been declared as required.
445 *
446 * @return value of required.
447 */
448 public boolean isRequired()
449 {
450 return alwaysRequired || required;
451 }
452
453 /***
454 * Set whether this field is required to have a value. If the field
455 * is already required due to a setting in the XML file, this method
456 * can not set it to false.
457 *
458 * @param v Value to assign to required.
459 */
460 public void setRequired(boolean v)
461 {
462 setRequired(v, ifRequiredMessage);
463 }
464
465 /***
466 * Set the value of required.
467 *
468 * @param v a <code>boolean</code> value
469 * @param message override the value from intake.xml
470 */
471 public void setRequired(boolean v, String message)
472 {
473 this.required = v;
474 if (v && (!setFlag || null == getTestValue()))
475 {
476 validFlag = false;
477 this.message = message;
478 }
479 }
480
481 /***
482 * Removes references to this group and its fields from the
483 * query parameters
484 */
485 public void removeFromRequest()
486 {
487 parser.remove(getKey());
488 parser.remove(getKey()+ VALUE_IF_ABSENT_KEY);
489 }
490
491 /***
492 * Disposes the object after use. The method is called
493 * when the Group is returned to its pool.
494 * if overridden, super.dispose() should be called.
495 */
496 public void dispose()
497 {
498 parser = null;
499 initialized = false;
500 setFlag = false;
501 validFlag = false;
502 validated = false;
503 required = false;
504 message = null;
505 retrievable = null;
506
507 locale = null;
508 stringValue = null;
509 stringValues = null;
510 validValue = null;
511 testValue = null;
512 valArray[0] = null;
513 }
514
515 /***
516 * Get the key used to identify the field.
517 *
518 * @return the query data key.
519 */
520 public String getKey()
521 {
522 return (group == null) ? key : group.getObjectKey() + key;
523 }
524
525 /***
526 * Use in a hidden field assign a default value in the event the
527 * field is absent from the query parameters. Used to track checkboxes,
528 * since they only show up if checked.
529 */
530 public String getValueIfAbsent()
531 {
532 return getKey() + VALUE_IF_ABSENT_KEY;
533 }
534
535 /***
536 * Flag set to true, if the test value met the constraints.
537 * Is also true, in the case the test value was not set,
538 * unless this field has been marked as required.
539 *
540 * @return a <code>boolean</code> value
541 */
542 public boolean isValid()
543 {
544 return validFlag;
545 }
546
547 /***
548 * Flag to determine whether the field has been validated.
549 *
550 * @return value of validated.
551 */
552 public boolean isValidated()
553 {
554 return validated;
555 }
556
557 /***
558 * Flag set to true, if the test value has been set by the parser (even to
559 * an empty value, so don't used this to determine if the field contains a
560 * non-empty value). Validation will only be executed for fields that have
561 * been set in this manner.
562 *
563 * @return a <code>boolean</code> value
564 */
565 public boolean isSet()
566 {
567 return setFlag;
568 }
569
570 /***
571 * Get the display name of the field. Useful for building
572 * data entry forms. Returns name of field if no display
573 * name has been assigned to the field by xml input file.
574 *
575 * @return a <code>String</code> value
576 */
577 public String getDisplayName()
578 {
579 return (displayName == null) ? name : displayName;
580 }
581
582 /***
583 * Set the display name of the field. Display names are
584 * used in building data entry forms and serve as a
585 * user friendly description of the data contained in
586 * the field.
587 */
588 public void setDisplayName(String newDisplayName)
589 {
590 displayName = newDisplayName;
591 }
592
593 /***
594 * Get any error message resulting from invalid input.
595 *
596 * @return a <code>String</code> value
597 */
598 public String getMessage()
599 {
600 return (message == null) ? EMPTY : message;
601 }
602
603 /***
604 * Sets an error message. The field is also marked as invalid.
605 */
606 public void setMessage(String message)
607 {
608 this.message = message;
609 validFlag = false;
610 }
611
612 /***
613 * @deprecated Call validate() instead (with no parameters).
614 */
615 protected boolean validate(ValueParser pp)
616 {
617 return validate();
618 }
619
620 /***
621 * Compares request data with constraints and sets the valid flag.
622 */
623 public boolean validate()
624 {
625 log.debug(name + ": validate()");
626
627 if (isMultiValued)
628 {
629 stringValues = parser.getStrings(getKey());
630
631 if (isDebugEnabled)
632 {
633 log.debug(name + ": Multi-Valued, Value is " + stringValue);
634 if (stringValues != null)
635 {
636 for (int i = 0; i < stringValues.length; i++)
637 {
638 log.debug(name + ": " + i + ". Value: " + stringValues[i]);
639 }
640 }
641 }
642
643 if (validator != null)
644 {
645
646
647 setTestValue(stringValues);
648
649 try
650 {
651 validator.assertValidity(this);
652 }
653 catch (ValidationException ve)
654 {
655 setMessage(ve.getMessage());
656 }
657 }
658
659 if (validFlag)
660 {
661 doSetValue();
662 }
663 }
664 else
665 {
666 stringValue = parser.getString(getKey());
667
668 if (isDebugEnabled)
669 {
670 log.debug(name + ": Single Valued, Value is " + stringValue);
671 }
672
673 if (validator != null)
674 {
675
676
677 setTestValue(parser.getString(getKey()));
678
679 try
680 {
681 validator.assertValidity(this);
682 log.debug(name + ": Value is ok");
683 doSetValue();
684 }
685 catch (ValidationException ve)
686 {
687 log.debug(name + ": Value failed validation!");
688 setMessage(ve.getMessage());
689 }
690 }
691 else
692 {
693 doSetValue();
694 }
695 }
696
697 validated = true;
698
699 return validFlag;
700 }
701
702 /***
703 * Set the default Value. This value is used if
704 * Intake should map this field to a new object.
705 *
706 * @param prop The value to use if the field is mapped to a new object.
707 */
708 public abstract void setDefaultValue(String prop);
709
710 /***
711 * Set the empty Value. This value is used if Intake
712 * maps a field to a parameter returned by the user and
713 * the corresponding field is either empty (empty string)
714 * or non-existant.
715 *
716 * @param prop The value to use if the field is empty.
717 */
718 public abstract void setEmptyValue(String prop);
719
720 /***
721 * @deprecated Use doSetValue() instead (with no parameters).
722 */
723 protected void doSetValue(ValueParser pp)
724 {
725 doSetValue();
726 }
727
728 /***
729 * Sets the value of the field from data in the parser.
730 */
731 protected abstract void doSetValue();
732
733 /***
734 * Set the value used as a default, in the event the field
735 * has not been set yet.
736 *
737 * @param obj an <code>Object</code> value
738 */
739 void setInitialValue(Object obj)
740 {
741 validValue = obj;
742 }
743
744 /***
745 * Get the value used as a default. If the initial value has
746 * not been set and a <code>Retrievable</code> object has
747 * been associated with this field, the objects property will
748 * be used as the initial value.
749 *
750 * @return an <code>Object</code> value
751 * @exception IntakeException indicates the value could not be
752 * returned from the mapped object
753 */
754 public Object getInitialValue() throws IntakeException
755 {
756 if (validValue == null)
757 {
758 if (retrievable != null)
759 {
760 getProperty(retrievable);
761 }
762 else
763 {
764 getDefault();
765 }
766 }
767 return validValue;
768 }
769
770 /***
771 * Set the value input by a user that will be validated.
772 *
773 * @param obj an <code>Object</code> value
774 */
775 void setTestValue(Object obj)
776 {
777 testValue = obj;
778 }
779
780 /***
781 * Get the value input by a user that will be validated.
782 *
783 * @return an <code>Object</code> value
784 */
785 public Object getTestValue()
786 {
787 return testValue;
788 }
789
790 /***
791 * Get the value of the field. if a test value has been set, it
792 * will be returned as is, unless it is so badly formed that the
793 * validation could not parse it. In most cases the test value
794 * is returned even though invalid, so that it can be returned to
795 * the user to make modifications. If the test value is not set
796 * the initial value is returned.
797 *
798 * @return an <code>Object</code> value
799 */
800 public Object getValue()
801 {
802 Object val = null;
803 try
804 {
805 val = getInitialValue();
806 }
807 catch (IntakeException e)
808 {
809 log.error("Could not get intial value of " + this.getDisplayName() +
810 " in group " + this.group.getIntakeGroupName(), e);
811 }
812
813 if (getTestValue() != null)
814 {
815 val = getTestValue();
816 }
817
818 if (val == null)
819 {
820 val = onError;
821 }
822 return val;
823 }
824
825 /***
826 * Calls toString() on the object returned by getValue(),
827 * unless null; and then it returns "", the empty String.
828 *
829 * @return a <code>String</code> value
830 */
831 public String toString()
832 {
833 String res = EMPTY;
834
835 if (stringValue != null)
836 {
837 res = stringValue;
838 }
839 else if (getValue() != null)
840 {
841 res = getValue().toString();
842 }
843 return res;
844 }
845
846 /***
847 * Calls toString() on the object returned by getValue(),
848 * unless null; and then it returns "", the empty String.
849 * Escapes " characters to be able to display these
850 * in HTML form fields.
851 *
852 * @return a <code>String</code> value
853 */
854 public String getHTMLString()
855 {
856 String res = toString();
857 return StringUtils.replace(res, "\"", """);
858 }
859
860 /***
861 * Loads the valid value from a bean
862 *
863 * @throws IntakeException indicates a problem during the execution of the
864 * object's getter method
865 */
866 public void getProperty(Object obj)
867 throws IntakeException
868 {
869 try
870 {
871 validValue = getter.invoke(obj, (Object[])null);
872 }
873 catch (IllegalAccessException e)
874 {
875 throwSetGetException("getter", obj, this.getDisplayName(),
876 this.group.getIntakeGroupName(), e);
877 }
878 catch (IllegalArgumentException e)
879 {
880 throwSetGetException("getter", obj, this.getDisplayName(),
881 this.group.getIntakeGroupName(), e);
882 }
883 catch (InvocationTargetException e)
884 {
885 throwSetGetException("getter", obj, this.getDisplayName(),
886 this.group.getIntakeGroupName(), e);
887 }
888 }
889
890 /***
891 * Loads the default value from the object
892 */
893
894 public void getDefault()
895 {
896 validValue = getDefaultValue();
897 }
898
899 /***
900 * Calls a setter method on obj, if this field has been set.
901 *
902 * @throws IntakeException indicates a problem during the execution of the
903 * object's setter method
904 */
905 public void setProperty(Object obj) throws IntakeException
906 {
907 if (isDebugEnabled)
908 {
909 log.debug(name + ".setProperty(" + obj.getClass().getName() + ")");
910 }
911
912 if (!isValid())
913 {
914 throw new IntakeException(
915 "Attempted to assign an invalid input.");
916 }
917 if (isSet() && null != getTestValue())
918 {
919 valArray[0] = getTestValue();
920 if (isDebugEnabled)
921 {
922 log.debug(name + ": Property is set, value is " + valArray[0]);
923 }
924 }
925 else
926 {
927 valArray[0] = getSafeEmptyValue();
928 if (isDebugEnabled)
929 {
930 log.debug(name + ": Property is not set, using emptyValue " + valArray[0]);
931 }
932 }
933
934 try
935 {
936
937
938
939
940
941
942 if(setter != null)
943 {
944 setter.invoke(obj, valArray);
945 }
946 else if (isDebugEnabled)
947 {
948 log.debug(name + ": has a null setter for the mapToProperty"
949 + " Attribute, although all Fields should be mapped"
950 + " to " + mapToObject + ". If this is unwanted, you"
951 + " should double check the mapToProperty Attribute, and"
952 + " consult the logs. The Turbine Intake Service will"
953 + " have logged a detailed Message with the error.");
954 }
955 }
956 catch (IllegalAccessException e)
957 {
958 throwSetGetException("setter", obj, this.getDisplayName(),
959 this.group.getIntakeGroupName(), e);
960 }
961 catch (IllegalArgumentException e)
962 {
963 throwSetGetException("setter", obj, this.getDisplayName(),
964 this.group.getIntakeGroupName(), e);
965 }
966 catch (InvocationTargetException e)
967 {
968 throwSetGetException("setter", obj, this.getDisplayName(),
969 this.group.getIntakeGroupName(), e);
970 }
971 }
972
973 /***
974 * Used to throw an IntakeException when an error occurs execuing the
975 * get/set method of the mapped persistent object.
976 *
977 * @param type Type of method. (setter/getter)
978 * @param fieldName Name of the field
979 * @param groupName Name of the group
980 * @param e Exception that was thrown
981 * @throws IntakeException New exception with formatted message
982 */
983 private void throwSetGetException(String type, Object obj,
984 String fieldName, String groupName,
985 Exception e)
986 throws IntakeException
987 {
988 throw new IntakeException("Could not execute " + type
989 + " method for " + fieldName + " in group " + groupName
990 + " on " + obj.getClass().getName(), e);
991
992 }
993
994 /***
995 * Get the default Value
996 *
997 * @return the default value
998 */
999 public Object getDefaultValue()
1000 {
1001 return defaultValue;
1002 }
1003
1004 /***
1005 * Get the Value to use if the field is empty
1006 *
1007 * @return the value to use if the field is empty.
1008 */
1009 public Object getEmptyValue()
1010 {
1011 return emptyValue;
1012 }
1013
1014 /***
1015 * Provides access to emptyValue such that the value returned will be
1016 * acceptable as an argument parameter to Method.invoke. Subclasses
1017 * that deal with primitive types should ensure that they return an
1018 * appropriate value wrapped in the object wrapper class for the
1019 * primitive type.
1020 *
1021 * @return the value to use when the field is empty or an Object that
1022 * wraps the empty value for primitive types.
1023 */
1024 protected Object getSafeEmptyValue()
1025 {
1026 return getEmptyValue();
1027 }
1028
1029 /***
1030 * Gets the name of the field.
1031 *
1032 * @return name of the field as specified in the XML file.
1033 */
1034 public String getName()
1035 {
1036 return name;
1037 }
1038
1039 /***
1040 * Gets the diplay size of the field. This is useful when
1041 * building the HTML input tag. If no displaySize was set,
1042 * an empty string is returned.
1043 */
1044 public String getDisplaySize()
1045 {
1046 return (StringUtils.isEmpty(displaySize) ? "" : displaySize);
1047 }
1048
1049 /***
1050 * Gets the maximum size of the field. This is useful when
1051 * building the HTML input tag. The maxSize is set with the maxLength
1052 * rule. If this rul was not set, an enmpty string is returned.
1053 */
1054 public String getMaxSize()
1055 {
1056 return (StringUtils.isEmpty(maxSize) ? "" : maxSize);
1057 }
1058
1059 /***
1060 * Gets the String representation of the Value. This is basically a wrapper
1061 * method for the toString method which doesn't seem to show anything on
1062 * screen if accessed from Template. Name is also more in line with getValue
1063 * method which returns the actual Object.
1064 * This is useful for displaying correctly formatted data such as dates,
1065 * such as 18/11/1968 instead of the toString dump of a Date Object.
1066 *
1067 * @return the String Value
1068 */
1069 public String getStringValue()
1070 {
1071 return this.toString();
1072 }
1073
1074 }