Thanks, each plugin/module will have its own resource file in the plugin/module jar now.

The MessageFormat and varargs were very helpful. The code is much simpler now.

For the message keys, I'm just looking for some way to have a unique naming scheme and the group id/module/abbreviations should do that (for now at least). With a scheme not based on the module name, I'm afraid of the following: since each module has its own resource bundle, keys in different modules could have the same name and everything would work fine, but if users reference a key and it's not unique.....what else can we use to help make these keys unique across modules?

--B.J. Reed


Jarek Gawor wrote:
Some thoughts:

1) Each module or plugin should have its own resource file.

2) Messages should be formatted using java.text.MessageFormat. The
substitution arguments should be arbitrary objects (not just strings)
and should be passed using varargs.

3) As soon as we encode the module or group id into the key or
whatever, it will become invalid or inaccurate. It's a maintenance
mess in my opinion. I think the key should just be a simple string
without any additional encoded information. We can inject some extra
info as the message is displayed but the key should be very simple.

Jarek

On Tue, Feb 26, 2008 at 10:30 AM, B.J. Reed <[EMAIL PROTECTED]> wrote:
I have written a patch to get Geronimo messages from a common set of
 resource bundles.  Included in the patch is the
 GeronimoMessageBundle.java, GeronimoMessageBundleTest.java, and the
 start of the  geronimo-messages.properties file.

 The patch should be unzipped into the
 trunk/framework/modules/geronimo-common directory.  Please take a look
 and provide suggestions/comments/etc.  I would like to really begin
 moving messages into this common file - probably a module at a time.

 Questions/Answers

 1) How do I use the new class in the Geronimo code?  So that we don't
 load the list of messages and keys multiple times, the
 GeronimoMessageBundle is a singleton.  Simply make a call to
 GeronimoMessageBundle.getInstance() and then make the appropriate
 getMessage call.  For starters, I have made the message key the message
 number that will show up as part of the message.  Also provided is a way
 to substitute parts of the message with substitution strings.

 2) Is there a numbering standard for the key?  The standard that I have
 started for the message key is as follows:
 mmmmlxxxx
    mmmm - 4 char module name abbreviation
    l - one char level (E - error, W - warning, I - information
    xxxx - 4 digit error number
 Since I haven't gotten very far...if there is a better suggestion, then
 it will be easier to change this sooner rather than later.

 3)  Tell me more about the string substitutions.  To make messages more
 flexible, placeholders can be put in the messages that look like {0} {1}
 etc.  An ArrayList can be passed in to the getMessage method that will
 be used to replace the placeholders.  This way, if a language needs the
 replacements in a different order, the code will not need to be changed.

 4)  How do I add a language?  At this time, the
 geronimo-messages.properties is included in the geronimo-common.jar.
 The easiest thing that I have found is to copy the .properties file to
 an apprpriate locale named file  (geronimo-messages_de.properties (for
 German) or geronimo-messages_de_CH.properties for German in
 Switzerland).  Re-create the geronimo-common.jar file.  Right now, the
 machine locale is used.  After we have several translations, we may want
 to add something to the Admin Console to allow an administrator to set
 the locale.

 5)  Is there a way to have the .properties file(s) outside of the jar?
 I'm sure there is, but I haven't stumbled across it yet.  That's
 actually where I've been banging my head the last few days.

 6)  I also envision that when we have all the messages in the common
 file, that it will be very easy to have a troubleshooting section on our
 website that gives more in depth knowledge about each message.

 I will begin writing 2.2 documentation from the above questions.

 This is just for message translation, so I believe that we'll need to
 come up with other methods for the Admin Console and possibly the
 Eclipse plugin if we want to have everything translatable.

 -- B.J. Reed



/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.apache.geronimo.common;

import java.util.ResourceBundle;
import java.util.PropertyResourceBundle;
//import java.util.ArrayList;
import java.util.MissingResourceException;
import java.text.MessageFormat;

/**
 * Resource Bundle for reading messages.  All messages should be held
 * in the geronimo-messages.properties file found in geronimo-common.jar.
 * Several methods are provided for getting the messages.  The first gets
 * a String as is.  The others allow substitutions for flexibility.
 */
public class GeronimoMessageBundle  {

    // MessageBundle that we are working with
    private ResourceBundle messageBundle = null;
    private String messageBundleName = null;
    private boolean validString = true;
    

    /**
     * Get the Message Resource Bundle from geronimo-messages.properties
     * If it is not found, a MissingResourceException will be thrown.
     */
    public GeronimoMessageBundle (String bundleName) {
        messageBundleName = bundleName;
        messageBundle = PropertyResourceBundle.getBundle (bundleName);
    }
    
    /*
     * Get a String from the message resource bundle.
     * No substitutions needed, simple method.
     */
    public String getString (String key) {
        try {
            String aString = messageBundle.getString(key);
            validString = true;
            return aString;
        } catch (MissingResourceException e) {
            // don't want to throw the exception, just return that the key was 
not found
            GeronimoMessageBundle commonMB = new GeronimoMessageBundle 
("geronimo-common");
            validString = false;
            return commonMB.getMessage ("GFMCMN001E", key, messageBundleName);
        }
    }

    /*
     * Get a message from the message resource bundle.
     * Replace all {x} in the message with values from the ArrayList.
     * 
     */
    public String getMessage (String key, Object ... replacements) {
        MessageFormat messageFormat = new MessageFormat (getString(key));
        String message = messageFormat.format (replacements);
        if (validString == true)
            message = key + "  " + message;

        return message;
    }
}

Reply via email to