Overview
Other MyFaces Extensions
- ExtVal
- Ext-Script
- [Orchestra]
- [Portlet Bridge]
Community
Development
Sponsorship
Your browser does not support iframes
Table of Contents | ||||||
---|---|---|---|---|---|---|
|
The MessageContext
allows using a fluent API for
Furthermore, the context provides the current locale.
...
The default implementation provides
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
.
...
... 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.)
Code Block | ||||
---|---|---|---|---|
| ||||
Message message = messageContext.message().text("Hello {0}").argument("MyFaces").create(); |
...
Code Block | ||||
---|---|---|---|---|
| ||||
Message message = messageContext.message().text("Hello CODI").payload(MessageSeverity.Error.classERROR).create(); |
... creates a message with 'Hello CODI' as message descriptor and error as message-severity.
Payload is based on similar to 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
or to create something like serializable attatchments. It's possible to handle messages depending on the payload of the message. By default a message is created with MessageSeverity.InfoINFO
.
...
... creates the message-text based on the constructed message.
To avoid side-effects with other libs as well as IDEs there is no #toString().
Code Block | ||||
---|---|---|---|---|
| ||||
//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
. That's essential if you would like to create the final text with a different/new MessageContext
e.g. with a different configuration or with the current MessageContext
if you receive a de-serialized message instance.
It's possible to register MessageHandler
s which process or forward messages added to the MessageContext
.
...
Note | ||
---|---|---|
| ||
Keep in mind that a stand-alone Without direct access to the |
A custom MessageBuilder
also allows to introduce custom message types easily:
...
Code Block | ||||
---|---|---|---|---|
| ||||
public class CustomMessageBuilder extends SimpleMessageBuilder { private CustomMessageBuilder () { } public static MessageBuilder message() { return new CustomMessageBuilder(); } public static MessageBuilder technicalMessage() { return new CustomMessageBuilder().payload(TechnicalMessage.classPAYLOAD); } public static MessageBuilder label() { return new CustomMessageBuilder().payload(Label.classPAYLOAD); } } |
A custom MessageResolver
has to know how to handle the different message types. If a payload type just allows one possible value (as marker), we can use the class of the payload to check if the payload-map contains such a marker entry.
Code Block | ||||
---|---|---|---|---|
| ||||
public class TestMessageResolver implements MessageResolver { public String getMessage(String key, Locale locale, Map<Class, Class<? extends MessagePayload>> 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) } |
As soon as an application has to support different business clients, it's required to display messages which are specific to each business client. The message module allows to use one MessageResolver
per client. So it's possible to use the same message-keys for all clients and the concrete MessageResolver
provides the correct message.
In combination with CDI a possible implementation is illustrated in the following listings.
Code Block | ||||
---|---|---|---|---|
| ||||
@Produces
@RequestScoped
public Client getCurrentClient(ClientService clientService)
{
return clientService.loadClient(this.currentClientId);
}
|
Code Block | ||||
---|---|---|---|---|
| ||||
@Produces
@RequestScoped
@ClientQualifier
public MessageContext createClientAwareContext(@Jsf MessageContext messageContext,
Client client)
{
MessageResolver clientAwareMessageResolver = createMessageResolverForClient(client.getId());
return messageContext.config().use().messageResolver(clientAwareMessageResolver).create();
}
private MessageResolver createMessageResolverForClient(final String currentClientId)
{
return new MessageResolver()
{
public String getMessage(String messageDescriptor,
Locale locale,
Map<Class, MessagePayload> messagePayload)
{
FacesContext facesContext = FacesContext.getCurrentInstance();
try
{
return facesContext.getApplication()
.getResourceBundle(facesContext, currentClientId).getString(messageDescriptor);
}
catch (MissingResourceException e)
{
return "???" + messageDescriptor + "???";
}
}
};
}
|
This example uses the existing message-context as template and creates a new context with a different message resolver.
In this example the client-id is used as resource-bundle name.
Code Block | ||||
---|---|---|---|---|
| ||||
@Inject
@ClientQualifier
private MessageContext clientAwareMessageContext;
|
To use such messages in a XHTML page, it's required to provide a bean which in-/directly implements the Map interface.
Code Block | ||||
---|---|---|---|---|
| ||||
@Named("clientMessages")
@Singleton
public class ClientAwareMessages extends MapHelper<String, String>
{
@Inject
@ClientQualifier
private MessageContext clientAwareMessageContext;
protected String getValue(String key)
{
return this.clientAwareMessageContext.message().text(key).toText();
}
}
|
Code Block | ||||
---|---|---|---|---|
| ||||
#{clientMessages.sample_message}
|
The full example is available in the current MyFaces CODI example application.
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
.
...