All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.binding.message.MessageBuilder Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/*
 * Copyright 2004-2012 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.binding.message;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.core.style.ToStringCreator;

/**
 * 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
 * message resource bundle}.
 * 
 * Usage example:
 * 

* * new MessageBuilder().error().source("field").code("mycode").arg(arg1).arg(arg2).defaultText("text").build(); * *

* @author Keith Donald * @author Jeremy Grelle */ public class MessageBuilder { private Object source; private Set codes = new LinkedHashSet(); private Severity severity; private List args = new ArrayList(); private String defaultText; /** * Records that the message being built is an informational message. * @return this, for fluent API usage */ public MessageBuilder info() { severity = Severity.INFO; return this; } /** * Records that the message being built is a warning message. * @return this, for fluent API usage */ public MessageBuilder warning() { severity = Severity.WARNING; return this; } /** * Records that the message being built is an error message. * @return this, for fluent API usage */ public MessageBuilder error() { severity = Severity.ERROR; return this; } /** * Records that the message being built is a fatal message. * @return this, for fluent API usage */ public MessageBuilder fatal() { severity = Severity.FATAL; return this; } /** * Records that the message being built is against the provided source. * @param source the source to associate the message with * @return this, for fluent API usage */ public MessageBuilder source(Object source) { this.source = source; return this; } /** * Records that the message being built should try and resolve its text using the code provided. Adds the code to * the codes list. Successive calls to this method add additional codes. Codes are applied in the order they are * added. * @param code the message code * @return this, for fluent API usage */ public MessageBuilder code(String code) { codes.add(code); return this; } /** * Records that the message being built should try and resolve its text using the codes provided. Adds the codes to * the codes list. Successive calls to this method add additional codes. Codes are applied in the order they are * added. * @param codes the message codes; if null, no changes will be made * @return this, for fluent API usage */ public MessageBuilder codes(String... codes) { if (codes == null) { return this; } this.codes.addAll(Arrays.asList(codes)); return this; } /** * Records that the message being built has a variable argument. Adds the arg to the args list. Successive calls to * this method add additional args. Args are applied in the order they are added. * @param arg the message argument value * @return this, for fluent API usage */ public MessageBuilder arg(Object arg) { args.add(arg); return this; } /** * Records that the message being built has variable arguments. Adds the args to the args list. Successive calls to * this method add additional args. Args are applied in the order they are added. * @param args the message argument values, if null no changes will be made * @return this, for fluent API usage */ public MessageBuilder args(Object... args) { if (args == null) { return this; } this.args.addAll(Arrays.asList(args)); return this; } /** * Records that the message being built has a variable argument, whose display value is also * {@link MessageSourceResolvable}. Adds the arg to the args list. Successive calls to this method add additional * resolvable args. Args are applied in the order they are added. * @param arg the resolvable message argument * @return this, for fluent API usage */ public MessageBuilder resolvableArg(Object arg) { args.add(new ResolvableArgument(arg)); return this; } /** * Records that the message being built has variable arguments, whose display values are also * {@link MessageSourceResolvable} instances. Adds the args to the args list. Successive calls to this method add * additional resolvable args. Args are applied in the order they are added. * @param args the resolvable message arguments * @return this, for fluent API usage */ public MessageBuilder resolvableArgs(Object... args) { if (args == null) { return this; } for (Object arg : args) { this.args.add(new ResolvableArgument(arg)); } return this; } /** * Records the fallback text of the message being built. If the message has no codes, this will always be used as * the text. If the message has codes but none can be resolved, this will always be used as the text. * @param text the default text * @return this, for fluent API usage */ public MessageBuilder defaultText(String text) { defaultText = text; return this; } /** * Builds the message that will be resolved. Called after the end of recording builder instructions. * @return the built message resolver */ public MessageResolver build() { if (severity == null) { severity = Severity.INFO; } if (codes == null && defaultText == null) { throw new IllegalArgumentException( "A message code or the message text is required to build this message resolver"); } String[] codesArray = codes.toArray(new String[codes.size()]); Object[] argsArray = args.toArray(new Object[args.size()]); return new DefaultMessageResolver(source, codesArray, severity, argsArray, defaultText); } private static class ResolvableArgument implements MessageSourceResolvable { private Object arg; public ResolvableArgument(Object arg) { this.arg = arg; } public Object[] getArguments() { return null; } public String[] getCodes() { return new String[] { arg.toString() }; } public String getDefaultMessage() { return arg.toString(); } public String toString() { return new ToStringCreator(this).append("arg", arg).toString(); } } }