I'm trying to localize validation error messages with Wicket and ran into this situation. I use custom converters to convert date values to the desired format (see below). However, when using AbstractValidator
and IValidationError
the values are not converted correctly. Default conversion - probably #toString()
- is used instead.
Desired error message "... 20.12.2012"
Actual error message "... 2012-12-20"
We use Joda-time to handle date and time values in our model. We also want that the dates and times are shown in Finnish locale no matter which language is shown to the user, i.e., dates are shown as d.m.yyyy
and time as hh:mm
.
In my Application class I have specified two type converters, one for LocalDate
and one for LocalTime
. Normally, both converters work fine. I.e., new Label("id", new LocalDate(2013, 5, 7));
shows as "7.5.2013". Furthermore, the conversion works great with message interpolation and StringResourceModel
s. E.g. a property prop=The date was: ${date}
is shown correctly as "The date was 20.12.2012".
The date validation logic is done in the business layer, where exception is thrown for a validation error. The exception might contain variables that need to be shown as feedback to the user. Following is a simplified example of the situation.
The Application class
@Override
protected IConverterLocator newConverterLocator() {
final ConverterLocator locator = new ConverterLocator();
locator.set(LocalDate.class, new LocalDateConverter());
locator.set(LocalTime.class, new LocalTimeConverter());
return locator;
}
The Validator class
public class MyDateValidator extends AbstractValidator<LocalDate> {
...
@Override
protected void onValidate(IValidatable<LocalDate> validatable) {
try {
service.validateDate(validatable.getValue());
} catch (MyValidationException e) {
Map<String, Object> values = new HashMap<String, Object>();
values.put("date", e.getDate());
error(validatable, "DateValidator", values);
}
}
The converted properties
DateValidator=There was an error on ${date}
EDIT:
The culprit seems to be MapVariableInterpolator#getValue(variableName)
which uses Strings.toString
which in turns calls object.toString()
. Still need to find out how it normally works.