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