You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

MessageContext

The MessageContext allows using a fluent API for

  • Creating messages
  • Creating message text
  • Processing messages
  • Changing the configuration of the current context
  • Using the current context as template for a new context

Furthermore, the context provides the current locale.

Message

The default implementation provides

  • Descriptor (Key or inline-message)
  • Arguments
    • Numbered arguments
    • Named arguments
  • Payload

The Message interface extends Localizable . Therefore it's possible to use a MessageContext to create the final message text based on the message and the current configuration of the MessageContext .

Creating messages

Instead of instantiating messages manually, the fluent API allows to create messages with (named-)arguments and message payload.

Example 1

Creating messages with inline-text
Message message = messageContext.message().text("Hello MyFaces").create();

... creates a message with the hardcoded text 'Hello MyFaces' as message descriptor.

Example 2

Creating messages with a key
Message message = messageContext.message().text("msgKey").create();

... creates a message with the key 'msgKey' as message descriptor.
(The concrete syntax of a key depends on the used MessageResolver. Further details are available in the DevDoc.)

Example 3

Creating messages with arguments
Message message = messageContext.message().text("Hello {0}").argument("MyFaces").create();

... creates a message with 'Hello {0}' as message descriptor and 'MyFaces' as argument.
An argument has to be Serializable .
(By default numbered arguments are formatted by MessageFormat based on the current locale.)

Example 4

Creating messages with named arguments
Message message = messageContext.message().text("Hello {name}").namedArgument("name", "MyFaces").create();

... creates a message with 'Hello {name}' as message descriptor and 'MyFaces' as argument.
Values of named arguments are formatted by Formatter s created by the FormatterFactory

Example 5

Creating messages with payload
Message message = messageContext.message().text("Hello CODI").payload(MessageSeverity.Error.class).create();

... creates a message with 'Hello CODI' as message descriptor and error as message-severity.
Payload is based on the validation payload of Bean-Validation. Via payload it's possible to provide additional information via a typesafe mechanism. It's possible to use the provided types of payload (MessageSeverity or InternalMessage) or to create custom payload like Label . It's possible to handle messages depending on the payload of the message. By default a message is created with MessageSeverity.Info .

Creating message text

Example 1

Creating the message-text (immediately)
String messageText = messageContext.message().text("msgKey").toText();

... creates the message-text based on the constructed message.

Example 2

Creating the message-text of a given message
//Message message = messageContext.message().text("Hello {name}").namedArgument("name", "MyFaces").create();
String messageText = message.toString(messageContext);

... creates the message-text based on the given message and MessageContext .

Processing messages

It's possible to register MessageHandler s which process or forward messages added to the MessageContext .

E.g. a MessageHandler for JSF would convert messages to FacesMessage s and add them to the current FacesContext .

Example 1

Creating the message-text (immediately)
messageContext.message().text("Hello MyFaces").add();

... adds the constructed message to the MessageHandler (s) of the current MessageContext .

Example 2

Creating the message-text of a given message
//Message message = messageContext.message().text("Hello {name}").namedArgument("name", "MyFaces").create();
messageContext.addMessage(message);

... adds the given message to the MessageHandler (s) of the current MessageContext .

Message Builder

The MessageContext uses a (default) MessageBuilder to create Message s via a fluent API.
If you don't have access to the MessageContext it's possible to use a stand-alone MessageBuilder (SimpleMessageBuilder ).

Attention!

Keep in mind that a stand-alone MessageBuilder is able to create Message objects, but it needs a MessageContext to create the final text or to add the message to the context.

Without direct access to the MessageContext you can use a MessageBuilder to create a message via:
Message message = SimpleMessageBuilder.message().text("msgKey").create();
As soon as you have a MessageContext you have access to the final message-text via:
message.toString(messageContext));
And/or you can add it to the context via:
messageContext.addMessage(message);

Custom Message Types

A custom MessageBuilder also allows to introduce custom message types easily:

Creating custom message types via a custom message-builder
Message label = CustomMessageBuilder.label().text("myMsgKey").create();
Message technicalMessage = CustomMessageBuilder.technicalMessage().text("myMsgKey").create();

//the context needs a message-resolver which knows how to handle the different message types.
label.toString(messageContext));
technicalMessage.toString(messageContext));
Implementation of a custom message-builder
public class CustomMessageBuilder extends SimpleMessageBuilder
{
    private CustomMessageBuilder ()
    {
    }

    public static MessageBuilder message()
    {
        return new CustomMessageBuilder();
    }

    public static MessageBuilder technicalMessage()
    {
        return new CustomMessageBuilder().payload(TechnicalMessage.class);
    }

    public static MessageBuilder label()
    {
        return new CustomMessageBuilder().payload(Label.class);
    }
}

A custom MessageResolver has to know how to handle the different message types.

Handling different message types
public class TestMessageResolver implements MessageResolver
{
    public String getMessage(String key, Locale locale, Map<Class, Class<? extends MessagePayload>> messagePayload)
    {
        if (!isKey(key))
        {
            return key;
        }

        try
        {
            key = extractKey(key);

            if(messagePayload.containsKey(Label.class))
            {
                return ResourceBundle.getBundle(TEST_LABELS, locale, getClassLoader()).getString(key);
            }
            else if(messagePayload.containsKey(TechnicalMessage.class))
            {
                return ResourceBundle.getBundle(TEST_TECHNICAL_MESSAGES, locale, getClassLoader()).getString(key);
            }
            return ResourceBundle.getBundle(TEST_MESSAGES, locale, getClassLoader()).getString(key);
        }
        catch (MissingResourceException e)
        {
            return key;
        }
    }
    //The full example is available in the code-base (see: TestMessageResolver)
}

Manual Usage

If you don't like the fluent API you can create your own message (e.g. based on DefaultMessage) or you can just instantiate DefaultMessage.

Creating a message manually
Message message = new DefaultMessage("inline message");
  • No labels