GrailsのValidationMessageでクラス名とかプロパティ名のi18n対応をどこでやっているのか

grails2.1.0での情報。

org.codehaus.groovy.grails.validation.AbstractConstraint#rejectValueWithDefaultMessageで処理している。

...
final Locale locale = LocaleContextHolder.getLocale();
final Class<?> constrainedClass = (Class<?>) args[1];
final String fullClassName = constrainedClass.getName();

String classNameCode = fullClassName + ".label";
String resolvedClassName = messageSource.getMessage(classNameCode, null, fullClassName, locale);
final String classAsPropertyName = GrailsNameUtils.getPropertyName(constrainedClass);

if (resolvedClassName.equals(fullClassName)) {
    // try short version
    classNameCode = classAsPropertyName+".label";
    resolvedClassName = messageSource.getMessage(classNameCode, null, fullClassName, locale);
}

// update passed version
if (!resolvedClassName.equals(fullClassName)) {
    args[1] = resolvedClassName;
}

String propertyName = (String)args[0];
String propertyNameCode = fullClassName + '.' + propertyName + ".label";
String resolvedPropertyName = messageSource.getMessage(propertyNameCode, null, propertyName, locale);
if (resolvedPropertyName.equals(propertyName)) {
    propertyNameCode = classAsPropertyName + '.' + propertyName + ".label";
    resolvedPropertyName = messageSource.getMessage(propertyNameCode, null, propertyName, locale);
}

// update passed version
if (!resolvedPropertyName.equals(propertyName)) {
    args[0] = resolvedPropertyName;
}
...

プロパティ名の例で行くと、 fullClassName + '.' + propertyName + ".label"があればそれ、なければ classAsPropertyName + '.' + propertyName + ".label"でmessageSourceを元に解決を行う。

例えばorg.yamkazu.Book#titleというプロパティがあったらmessages.propertiesに

org.yamkazu.Book.title.label=hogehoge

と書くか

book.title.label=hogehoge

のどちらかで解決できる。