message argument accessor - thanks andy

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1392 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Keith Donald 2009-06-17 03:12:44 +00:00
parent 7d3fae6640
commit 86abbc2b59
4 changed files with 35 additions and 29 deletions

View File

@ -56,15 +56,20 @@ public class WebBindAndValidateLifecycle {
// TODO get validation results // TODO get validation results
validator.validate(binder.getModel(), bindingResults.successes().properties()); validator.validate(binder.getModel(), bindingResults.successes().properties());
} }
// TODO make message translation pluggable
MessageBuilder builder = new MessageBuilder(); MessageBuilder builder = new MessageBuilder();
for (BindingResult result : bindingResults.failures()) { for (BindingResult result : bindingResults.failures()) {
MessageResolver message = builder.code(modelPropertyError(result)).code(propertyError(result)).code( MessageResolver message = builder.
typeError(result)).code(error(result)).resolvableArg("label", getModelProperty(result)).arg( code(modelPropertyError(result)).
"value", result.getUserValue()). code(propertyError(result)).
// TODO add binding el resolver allowing binding.format to be called code(typeError(result)).
arg("binding", binder.getBinding(result.getProperty())). code(error(result)).
// TODO allow binding result to contribute additional arguments resolvableArg("label", getModelProperty(result)).
build(); arg("value", result.getUserValue()).
// TODO add binding el resolver allowing binding.format to be called
arg("binding", binder.getBinding(result.getProperty())).
// TODO allow binding result to contribute additional arguments
build();
// TODO should model name be part of element id? // TODO should model name be part of element id?
messageContext.add(message, result.getProperty()); messageContext.add(message, result.getProperty());
} }

View File

@ -20,7 +20,6 @@ import java.util.Map;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable; import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.style.ToStringCreator; import org.springframework.core.style.ToStringCreator;
import org.springframework.expression.AccessException; import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
@ -40,13 +39,13 @@ final class DefaultMessageResolver implements MessageResolver, MessageSourceReso
private String[] codes; private String[] codes;
private Map<String, Object> args; private Map<String, Object> args;
private String defaultText; private String defaultText;
private ExpressionParser expressionParser; private ExpressionParser expressionParser;
public DefaultMessageResolver(Severity severity, String[] codes, Map<String, Object> args, public DefaultMessageResolver(Severity severity, String[] codes, Map<String, Object> args, String defaultText,
String defaultText, ExpressionParser expressionParser) { ExpressionParser expressionParser) {
this.severity = severity; this.severity = severity;
this.codes = codes; this.codes = codes;
this.args = args; this.args = args;
@ -67,8 +66,7 @@ final class DefaultMessageResolver implements MessageResolver, MessageSourceReso
try { try {
StandardEvaluationContext context = new StandardEvaluationContext(); StandardEvaluationContext context = new StandardEvaluationContext();
context.setRootObject(args); context.setRootObject(args);
context.addPropertyAccessor(new MapAccessor()); context.addPropertyAccessor(new MessageArgumentAccessor(messageSource, locale));
context.addPropertyAccessor(new MessageSourceResolvableAccessor(messageSource, locale));
String text = (String) message.getValue(context); String text = (String) message.getValue(context);
return new TextMessage(severity, text); return new TextMessage(severity, text);
} catch (EvaluationException e) { } catch (EvaluationException e) {
@ -116,37 +114,44 @@ final class DefaultMessageResolver implements MessageResolver, MessageSourceReso
} }
private static class MessageSourceResolvableAccessor implements PropertyAccessor { static class MessageArgumentAccessor implements PropertyAccessor {
private MessageSource messageSource; private MessageSource messageSource;
private Locale locale; private Locale locale;
public MessageSourceResolvableAccessor(MessageSource messageSource, Locale locale) { public MessageArgumentAccessor(MessageSource messageSource, Locale locale) {
this.messageSource = messageSource; this.messageSource = messageSource;
this.locale = locale; this.locale = locale;
} }
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return true; return (((Map) target).containsKey(name));
} }
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
// TODO this does not get called when resolving MessageSourceResolvable variables; only when accessing properties on MessageSourceResolvable targets. Object o = ((Map) target).get(name);
return new TypedValue(messageSource.getMessage((MessageSourceResolvable)target, locale)); if (o instanceof MessageSourceResolvable) {
String message = messageSource.getMessage((MessageSourceResolvable) o, locale);
return new TypedValue(message);
} else {
return new TypedValue(o);
}
} }
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return false; return false;
} }
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { public void write(EvaluationContext context, Object target, String name, Object newValue)
throws AccessException {
throw new UnsupportedOperationException("Should not be called"); throw new UnsupportedOperationException("Should not be called");
} }
public Class<?>[] getSpecificTargetClasses() {
return new Class[] { MessageSourceResolvable.class };
}
public Class[] getSpecificTargetClasses() {
return new Class[] { Map.class };
}
} }
} }

View File

@ -4,7 +4,6 @@ import static org.junit.Assert.assertEquals;
import java.util.Locale; import java.util.Locale;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
public class MessageBuilderTests { public class MessageBuilderTests {
@ -12,7 +11,6 @@ public class MessageBuilderTests {
private MessageBuilder builder = new MessageBuilder(); private MessageBuilder builder = new MessageBuilder();
@Test @Test
@Ignore
public void buildMessage() { public void buildMessage() {
MessageResolver resolver = builder.severity(Severity.ERROR).code("invalidFormat").resolvableArg("label", "mathForm.decimalField") MessageResolver resolver = builder.severity(Severity.ERROR).code("invalidFormat").resolvableArg("label", "mathForm.decimalField")
.arg("format", "#,###.##").defaultText("Field must be in format #,###.##").build(); .arg("format", "#,###.##").defaultText("Field must be in format #,###.##").build();

View File

@ -8,7 +8,6 @@ import java.util.Map;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.ui.message.Message; import org.springframework.ui.message.Message;
@ -36,7 +35,6 @@ public class DefaultMessageContextTests {
} }
@Test @Test
@Ignore
public void addMessage() { public void addMessage() {
MessageBuilder builder = new MessageBuilder(); MessageBuilder builder = new MessageBuilder();
MessageResolver message = builder.severity(Severity.ERROR).code("invalidFormat").resolvableArg("label", MessageResolver message = builder.severity(Severity.ERROR).code("invalidFormat").resolvableArg("label",