public interface StateManageableMessageContext extends MessageContext {
/** * Create a serializable memento, or token representing a snapshot of the internal state of this message context. * @return the messages memento */ public Serializable createMessagesMemento();
/** * Set the state of this context from the memento provided. After this call, the messages in this context will match * what is encapsulated inside the memento. Any previous state will be overridden. * @param messagesMemento the messages memento */ public void restoreMessages(Serializable messagesMemento);
/** * Configure the message source used to resolve messages added to this context. May be set at any time to change how * coded messages are resolved. * @param messageSource the message source * @see MessageContext#addMessage(MessageResolver) */ public void setMessageSource(MessageSource messageSource); }
public class DefaultMessageContext implements StateManageableMessageContext {
private static final Log logger = LogFactory.getLog(DefaultMessageContext.class);
private MessageSource messageSource;
@SuppressWarnings("serial") private Map<Object, List<Message>> sourceMessages = new AbstractCachingMapDecorator<Object, List<Message>>( new LinkedHashMap<Object, List<Message>>()) {
protected List<Message> create(Object source) { return new ArrayList<Message>(); } };
/** * Creates a new default message context. Defaults to a message source that simply resolves default text and cannot * resolve localized message codes. */ public DefaultMessageContext() { init(null); }
/** * Creates a new default message context. * @param messageSource the message source to resolve messages added to this context */ public DefaultMessageContext(MessageSource messageSource) { init(messageSource); }
public MessageSource getMessageSource() { return messageSource; }
// implementing message context
public Message[] getAllMessages() { List<Message> messages = new ArrayList<Message>(); for (List<Message> list : sourceMessages.values()) { messages.addAll(list); } return messages.toArray(new Message[messages.size()]); }
public Message[] getMessagesByCriteria(MessageCriteria criteria) { List<Message> messages = new ArrayList<Message>(); for (List<Message> sourceMessages : this.sourceMessages.values()) { for (Message message : sourceMessages) { if (criteria.test(message)) { messages.add(message); } } } return messages.toArray(new Message[messages.size()]); }
public boolean hasErrorMessages() { for (List<Message> sourceMessages : this.sourceMessages.values()) { for (Message message : sourceMessages) { if (message.getSeverity() == Severity.ERROR) { return true; } } } return false; }
public void addMessage(MessageResolver messageResolver) { Locale currentLocale = LocaleContextHolder.getLocale(); if (logger.isDebugEnabled()) { logger.debug("Resolving message using " + messageResolver); } Message message = messageResolver.resolveMessage(messageSource, currentLocale); List<Message> messages = sourceMessages.get(message.getSource()); if (logger.isDebugEnabled()) { logger.debug("Adding resolved message " + message); } messages.add(message); }
public void clearMessages() { sourceMessages.clear(); }
// implementing state manageable message context
public Serializable createMessagesMemento() { return new LinkedHashMap<Object, List<Message>>(sourceMessages); }
@SuppressWarnings("unchecked") public void restoreMessages(Serializable messagesMemento) { sourceMessages.putAll((Map<Object, List<Message>>) messagesMemento); }
public void setMessageSource(MessageSource messageSource) { if (messageSource == null) { messageSource = new DefaultTextFallbackMessageSource(); } this.messageSource = messageSource; }
// internal helpers
private void init(MessageSource messageSource) { setMessageSource(messageSource); // create the 'null' source message list eagerly to ensure global messages are indexed first this.sourceMessages.get(null); }
public String toString() { return new ToStringCreator(this).append("sourceMessages", sourceMessages).toString(); }