diff --git a/org.springframework.context/src/main/java/org/springframework/ui/message/DefaultMessageResolver.java b/org.springframework.context/src/main/java/org/springframework/ui/message/DefaultMessageResolver.java index b79f3d3f2d1..7bf1eb11e1e 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/message/DefaultMessageResolver.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/message/DefaultMessageResolver.java @@ -95,7 +95,7 @@ class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable defaultText).toString(); } - static class TextMessage implements Message { + private static class TextMessage implements Message { private Severity severity; @@ -116,7 +116,7 @@ class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable } - static class MessageSourceResolvableAccessor implements PropertyAccessor { + private static class MessageSourceResolvableAccessor implements PropertyAccessor { private MessageSource messageSource; @@ -140,12 +140,11 @@ class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable return false; } - @SuppressWarnings("unchecked") public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { throw new UnsupportedOperationException("Should not be called"); } - public Class[] getSpecificTargetClasses() { + public Class[] getSpecificTargetClasses() { return new Class[] { MessageSourceResolvable.class }; } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/message/Message.java b/org.springframework.context/src/main/java/org/springframework/ui/message/Message.java index 48d5fbb3401..c9edd4aa771 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/message/Message.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/message/Message.java @@ -16,18 +16,16 @@ package org.springframework.ui.message; /** - * Communicates information about an event to the user. - * For example, a validation message may inform a web application user a business rule was violated. - * A message is attached to a receiving element, has text providing the basis for communication, - * and has severity indicating the priority or intensity of the message for its receiver. - * + * Communicates information of interest to the user. + * For example, a error message may inform a user of a web application a business rule was violated. + * TODO - should we introduce summary/detail fields instead of just text * @author Keith Donald */ public interface Message { /** * The severity of this message. - * The severity indicates the intensity or priority of the communication. + * The severity indicates the intensity or priority of the message. * @return the message severity */ public Severity getSeverity(); diff --git a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageBuilder.java b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageBuilder.java index 2394bddcc01..d0c4fbeb2b0 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageBuilder.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageBuilder.java @@ -22,31 +22,33 @@ import java.util.Set; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; -import org.springframework.context.expression.MapAccessor; import org.springframework.core.style.ToStringCreator; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; /** - * A convenient builder for building {@link MessageResolver} objects programmatically. - * Often used by model code such as validation logic to conveniently record validation messages. - * Supports the production of message resolvers that hard-code their message text, - * as well as message resolvers that retrieve their text from a {@link MessageSource}. - * - * Usage example: + * A builder for building {@link MessageResolver} objects. + * Typically used by Controllers to {@link MessageContext#add(MessageResolver, String) add} messages to display in a user interface. + * Supports MessageResolvers that hard-code the message text, as well as MessageResolvers that resolve the message text from a localized {@link MessageSource}. + * Also supports named arguments whose values can be inserted into messages using #{eval expressions}. *

+ * Usage example: *

  * new MessageBuilder().
  *     severity(Severity.ERROR).
- *     code("invalidFormat").
- *     arg("mathForm.decimalField").
- *     arg("#,###.##").
- *     defaultText("The decimal field must be in format #,###.##").
+ *     code("invalidFormat").
+ *     resolvableArg("label", "mathForm.decimalField").
+ *     arg("format", "#,###.##").
+ *     defaultText("The decimal field must be in format #,###.##").
  *     build();
  * 
- *

+ * Example messages.properties loaded by the MessageSource: + *
+ * invalidFormat=The #{label} must be in format #{format}.
+ * mathForm.decimalField=Decimal Field
+ * 
* @author Keith Donald + * @see MessageContext#add(MessageResolver, String) */ public class MessageBuilder { @@ -70,9 +72,9 @@ public class MessageBuilder { } /** - * Add a message code to use to resolve the message text. + * Add a code to use to resolve the template for generating the localized message text. * Successive calls to this method add additional codes. - * Codes are applied in the order they are added. + * Codes are tried in the order they are added. * @param code the message code * @return this, for fluent API usage */ @@ -82,8 +84,10 @@ public class MessageBuilder { } /** - * Add a message argument. - * Successive calls to this method add additional args. + * Add a message argument to insert into the message text. + * Named message arguments are inserted by eval expressions denoted within the resolved message template. + * For example, the value of the 'format' argument would be inserted where a corresponding #{format} expression is defined in the message template. + * Successive calls to this method add additional arguments. * @param name the argument name * @param value the argument value * @return this, for fluent API usage @@ -94,14 +98,14 @@ public class MessageBuilder { } /** - * Add a message argument whose value is a resolvable message code. - * Successive calls to this method add additional resolvable arguements. + * Add a message argument to insert into the message text, where the actual value to be inserted should be resolved by the {@link MessageSource}. + * Successive calls to this method add additional resolvable arguments. * @param name the argument name - * @param value the argument value + * @param code the code to use to resolve the argument value * @return this, for fluent API usage */ - public MessageBuilder resolvableArg(String name, Object value) { - args.put(name, new ResolvableArgumentValue(value)); + public MessageBuilder resolvableArg(String name, Object code) { + args.put(name, new ResolvableArgumentValue(code)); return this; } @@ -135,12 +139,12 @@ public class MessageBuilder { return new DefaultMessageResolver(severity, codesArray, args, defaultText, expressionParser); } - static class ResolvableArgumentValue implements MessageSourceResolvable { + private static class ResolvableArgumentValue implements MessageSourceResolvable { - private Object value; + private Object code; - public ResolvableArgumentValue(Object value) { - this.value = value; + public ResolvableArgumentValue(Object code) { + this.code = code; } public Object[] getArguments() { @@ -148,15 +152,15 @@ public class MessageBuilder { } public String[] getCodes() { - return new String[] { value.toString() }; + return new String[] { code.toString() }; } public String getDefaultMessage() { - return String.valueOf(value); + return String.valueOf(code); } public String toString() { - return new ToStringCreator(this).append("value", value).toString(); + return new ToStringCreator(this).append("code", code).toString(); } } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolutionException.java b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolutionException.java index a8a8d9c0973..39a418575e9 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolutionException.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolutionException.java @@ -1,7 +1,32 @@ +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.ui.message; +/** + * Runtime exception thrown by a {@link MessageResolver} if a message resolution fails. + * @author Keith Donald + */ +@SuppressWarnings("serial") public class MessageResolutionException extends RuntimeException { + /** + * Creates a new message resolution exception. + * @param message a messaging describing the failure + * @param cause the cause of the failure + */ public MessageResolutionException(String message, Throwable cause) { super(message, cause); } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolver.java b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolver.java index b8113562b9e..38bebae2125 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolver.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/message/MessageResolver.java @@ -20,9 +20,7 @@ import java.util.Locale; import org.springframework.context.MessageSource; /** - * A factory for a Message. Allows a Message to be internationalized and to be resolved from a - * {@link MessageSource message resource bundle}. - * + * A factory for a localized Message. * @author Keith Donald * @see Message * @see MessageSource @@ -30,10 +28,11 @@ import org.springframework.context.MessageSource; public interface MessageResolver { /** - * Resolve the message from the message source using the current locale. + * Resolve the message from the message source for the locale. * @param messageSource the message source, an abstraction for a resource bundle - * @param locale the current locale of this request + * @param locale the locale of this request * @return the resolved message + * @throws MessageResolutionException if a resolution failure occurs */ public Message resolveMessage(MessageSource messageSource, Locale locale); }