/* Copyright 2005-2006 Tim Fennell * * 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 net.sourceforge.stripes.action; import java.text.MessageFormat; import java.util.Arrays; import java.util.Locale; /** * <p> * A simple non-error message that uses the String supplied to it as the message * (i.e. it does not look up the message in a resource bundle).</p> * * <p> * Messages may contain one or more "replacement parameters". To use * replacement parameters a message must contain the replacement token {#} where * # is the numeric index of the replacement parameter.</p> * * <p> * For example, to construct a message with two replacement parameters you might * supply a message like:</p> * * <pre>Welcome back {0}, your last login was on {1,date,short}.</pre> * * <p> * At runtime this might get replaced out to result in a message for the user * that looks like "Welcome back <em>Johnnie</em>, your last login was on * <em>01/01/2006</em>".</p> * * <p> * {@link java.text.MessageFormat} is used to merge the parameters in to the * message and as a result the parameters can themselves receive formatting * through the various java.text.* formatters.</p> * * @author Tim Fennell * @see java.text.MessageFormat */ public class SimpleMessage implements Message { private static final long serialVersionUID = 1L; private String message; /** * The set of replacement parameters that will be used to create the message * from the message template. Note that position 0 is reserved for the field * name and position 1 is reserved for the field value. */ private Object[] replacementParameters; /** * Constructs a message with the supplied message string and zero or more * parameters to be merged into the message. When constructing a * SimpleMessage a non-null message string must be supplied (though * subclasses may return null if they do not rely upon it). * * @param message the String message to display to the user, optionally with * placeholders for replacement parameters * @param parameters */ public SimpleMessage(String message, Object... parameters) { this.replacementParameters = parameters; this.message = message; } /** * Helper constructor to allow subclasses to provide and manipulate * replacement parameters without having to supply a message String. * * @param parameters zero or more parameters for replacement into the * message */ protected SimpleMessage(Object... parameters) { this.replacementParameters = parameters; } /** * Uses the String message passed in as the message template and combines it * with any replacement parameters provided to construct a message for * display to the user. Although SimpleMessage does not localize its * message string, any formatters invoked as a result of using replacement * parameters will be in the correct locale. * * @param locale the locale of the current request * @return String the message stored under the messageKey supplied */ public String getMessage(Locale locale) { // Now get the message itself String messageTemplate = getMessageTemplate(locale); // For compatibility with JSTL, only apply formatting if there are replacement parameters if (this.replacementParameters != null && this.replacementParameters.length > 0) { MessageFormat format = new MessageFormat(messageTemplate, locale); return format.format(this.replacementParameters, new StringBuffer(), null).toString(); } else { return messageTemplate; } } /** * Simply returns the message passed in at Construction time. Designed to be * overridden by subclasses to lookup messages from resource bundles. * * @param locale the Locale of the message template desired * @return the message (potentially with TextFormat replacement tokens). */ protected String getMessageTemplate(Locale locale) { return this.message; } /** * Returns the exact message that was supplied in the constructor. This * should not be called to render user output, but only when direct access * to the String is needed for some reason. * * @return the exact message String passed in to the constructor */ public String getMessage() { return this.message; } /** * Allows subclasses to access the replacement parameters for this message. * * @return Array of replacement parameters for this message */ public Object[] getReplacementParameters() { return this.replacementParameters; } /** * Checks equality by ensuring that the current instance and the 'other' * instance are instances of the same class (though not necessarily * SimpleMessage!) and that the message String and replacement parameters * provided are the same. * * @param o another object that is a SimpleMessage or subclass thereof * @return true if the two objects will generate the same user message, * false otherwise */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final SimpleMessage that = (SimpleMessage) o; if (message != null ? !message.equals(that.message) : that.message != null) { return false; } if (!Arrays.equals(replacementParameters, that.replacementParameters)) { return false; } return true; } /** * Generated hash code method. */ @Override public int hashCode() { return (message != null ? message.hashCode() : 0); } }