Hi

I have recently wondered about the same, and have now built something that after much trial and error now works.

Basically, I have created a Messages implementation that wraps both a tapestry Messages object and our own database messages. If a message is not found in our database, the default Messages object is queried.

To get Tapestry to use my Messages implementation i had to decorate the ComponentMessagesSource (and ValidationMessagesSource), since it is not possible to replace the one in Tapestry. I think I read about decorating services here: http://tapestry.apache.org/tapestry5/tapestry-ioc/decorator.html and on the mailing list.

My messages source service doesn't implement the ComponentMessagesSource interface. I use an interception object for that. Hopefully you can understand how it works from my example code below:

public class CommonsMessages extends AbstractMessages {

    private Messages fallbackMessages;

    protected String valueForKey(final key) {
        ... logic to get key from db, use fallbackMessages as fallback...
    }

}

-----

public class CommonsMessagesSource {

    public Messages getMessages(Locale locale, Messages fallbackMessages) {
... code that creates a CommonsMessages object, with fallbackMessages ...
    }   
}

----

// This is the decorating class
public class CommonsComponentMessagesSourceInterceptor implements
    ComponentMessagesSource {

    private final CommonsMessagesSource service;
    private final ComponentMessagesSource delegate;

    public CommonsComponentMessagesSourceInterceptor
        (CommonsMessagesSource service, ComponentMessagesSource delegate)
    {
        this.service = service;
        this.delegate = delegate;
    }

public Messages getMessages(ComponentModel componentModel, Locale locale) {

        return service.getMessages(locale,
            delegate.getMessages(componentModel, locale));
    }

    // Not sure about how I should handle this one
    public void addInvalidationListener(
        InvalidationListener invalidationlistener) {
        delegate.addInvalidationListener(invalidationlistener);
    }
}

---

In AppModule.java:

    // Method for instantiating and configuring the custom messages source
    public static CommonsMessagesSource buildCommonsMessagesSource()
    {
        CommonsMessagesSource messagesSource = new CommonsMessagesSource();
        return messagesSource;
    }

// Method that decorates the default MessagesSource using the interceptor class
    @Match("ComponentMessagesSource")
    public static ComponentMessagesSource decorateComponentMessagesSource
         (Object delegate, CommonsMessagesSource service)
     {
return new CommonsComponentMessagesSourceInterceptor(service, (ComponentMessagesSource)delegate);
     }

This is how I got it to work, there may be other ways ofcourse. There might even be better ways :-)

Cheers,
/Hannes

Michael Capper skrev:
Summary: How do I include additional localization-key/values-pairs in my
global messages-catalog, originating from some app_<lang>.properties or from
a database?

Hi,
I'd like to extend the Hash-Table containing the message-keys and
message-values used in my app. The app_en.properties provides the basic
global localization data, but I need even more data, which is spead about in
other .properties-files or even in a Database. What I'd like to do would be
to read in the data somewhere, and pass it on to the Messages(or
ResourceBundle) somehow, so when I @Inject the Messages into a
page/component or use the 'message:' binding, the extra localization is
available at a root level.

Thanks for any help or pointers,
Mike


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to