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;
}
}