You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by df...@apache.org on 2004/12/18 16:08:50 UTC
cvs commit: jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n XMLMessageProvider.java MessageProvider.java ResourceBundleMessageProvider.java LocalizedBundle.java MessageManager.java
dflorey 2004/12/18 07:08:50
Modified: i18n/src/java/org/apache/commons/i18n LocalizedBundle.java
MessageManager.java
Added: i18n/src/java/org/apache/commons/i18n
XMLMessageProvider.java MessageProvider.java
ResourceBundleMessageProvider.java
Log:
Added support for pluggable MessageProviders and added ResourceBundleMessageProvider
to enable migration from resource bundle based applications to i18n.
Revision Changes Path
1.2 +41 -3 jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/LocalizedBundle.java
Index: LocalizedBundle.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/LocalizedBundle.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- LocalizedBundle.java 4 Oct 2004 13:41:09 -0000 1.1
+++ LocalizedBundle.java 18 Dec 2004 15:08:49 -0000 1.2
@@ -25,6 +25,13 @@
import java.util.Locale;
+/**
+ * @author Daniel Florey
+ *
+ * The LocalizedBundle class represents a bundle of localized messages that
+ * belong together.
+ *
+ */
public class LocalizedBundle {
public final static String ID = "id";
public final static String ARGUMENTS = "arguments";
@@ -32,28 +39,59 @@
protected String id;
protected Object[] arguments;
+ /**
+ * @param messageId The messageId refers the corresponding bundle in the file containing
+ * the localized messages. The format of the message file depends on the implementation of the
+ * MessageManager.
+ */
public LocalizedBundle(String messageId) {
this.id = messageId;
this.arguments = new Object[0];
}
+ /**
+ * @param messageId The messageId refers the corresponding bundle in the file containing
+ * the localized messages. The format of the message file depends on the implementation of the
+ * MessageManager.
+ * @param arguments An array of objects containing argument for the messages. These arguments
+ * are used to insert dynamic values into the localized messages.
+ */
public LocalizedBundle(String messageId, Object[] arguments) {
this.id = messageId;
this.arguments = arguments;
}
+ /**
+ * @return returns the id of this bundle
+ */
public String getId() {
return id;
}
+ /**
+ * @return returns the arguments associated with this message bundle
+ */
public Object[] getArguments() {
return arguments;
}
+ /**
+ * @param key the key of the specific message entry in the message bundle
+ * @param locale the locale for that this message should be rendered
+ * @return returns the localized text
+ * @throws MessageNotFoundException if an entry with the given key can not be found
+ * in this bundle
+ */
public String getText(String key, Locale locale) throws MessageNotFoundException {
return MessageManager.getText(id, key, arguments, locale);
}
+ /**
+ * @param key the key of the specific message entry in the message bundle
+ * @param locale the locale for that this message should be rendered
+ * @param defaultText the text to be returned if no entry was found for the given key
+ * @return returns the localized text
+ */
public String getText(String key, String defaultText, Locale locale) {
return MessageManager.getText(id, key, arguments, locale, defaultText);
}
1.3 +45 -184 jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/MessageManager.java
Index: MessageManager.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/MessageManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MessageManager.java 16 Oct 2004 17:41:16 -0000 1.2
+++ MessageManager.java 18 Dec 2004 15:08:49 -0000 1.3
@@ -1,201 +1,62 @@
/*
- * $Header$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- *
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed 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.
- *
- */
+*
+* ====================================================================
+*
+* Copyright 2004 The Apache Software Foundation
+*
+* Licensed 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.commons.i18n;
-import java.io.InputStream;
-import java.text.MessageFormat;
-import java.util.Collection;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.commons.i18n.MessageNotFoundException;
-import org.apache.commons.xmlio.in.DefaultSimpleImportHandler;
-import org.apache.commons.xmlio.in.SimpleImporter;
-import org.apache.commons.xmlio.in.SimplePath;
-import org.xml.sax.InputSource;
-import org.xml.sax.helpers.AttributesImpl;
+/**
+ * @author Daniel Florey
+ *
+ */
public class MessageManager {
- private static Logger logger = Logger.getLogger(MessageManager.class.getName());
-
- private static Map installedMessages = new HashMap();
- private static Map messages = new HashMap();
-
- public static String getText(String id, String entry, Object[] arguments, Locale locale, String defaultText) {
- Message message = findMessage(id, locale);
- try {
- return format(message.getEntry(entry), arguments);
- } catch ( MessageNotFoundException exception ) {
- return defaultText;
- }
- }
-
- public static String getText(String id, String entry, Object[] arguments, Locale locale) throws MessageNotFoundException {
- Message message = findMessage(id, locale);
- return format(message.getEntry(entry), arguments);
- }
-
- public static Map getEntries(String id, Locale locale) throws MessageNotFoundException {
- Message message = findMessage(id, locale);
- return message.getEntries();
- }
-
- public static void install(String id, InputStream inputStream) {
- logger.log(Level.FINE, "Installing messages '"+id+"'");
- try {
- Map applicationMessages = new HashMap();
- SimpleImporter importer = new SimpleImporter();
- importer.setIncludeLeadingCDataIntoStartElementCallback(true);
- ConfigurationHandler handler = new ConfigurationHandler();
- importer.addSimpleImportHandler(handler);
- importer.parse(new InputSource(inputStream));
- Map parsedMessages = handler.getMessages();
- applicationMessages.putAll(parsedMessages);
- messages.putAll(applicationMessages);
- installedMessages.put(id, applicationMessages.keySet());
- } catch (Exception exception) {
- logger.log(Level.SEVERE, "Error while parsing messages", exception);
- }
- }
-
- public static void uninstall(String id) {
- logger.log(Level.FINE, "Uninstalling messages '"+id+"'");
- Collection messageKeys = (Collection)installedMessages.get(id);
- for ( Iterator i = messageKeys.iterator(); i.hasNext(); ) {
- String messageKey = (String)i.next();
- messages.remove(messageKey);
- logger.log(Level.FINE, "Removing message with key '"+messageKey+"'");
- }
- installedMessages.remove(id);
- }
+ private static List messageProviders = new ArrayList();
- public static void update(String id, InputStream inputStream) {
- uninstall(id);
- install(id, inputStream);
+ static {
+ messageProviders.add(new XMLMessageProvider());
+ messageProviders.add(new ResourceBundleMessageProvider());
}
-
- private static String format(String formatString, Object[] arguments) {
- if (formatString == null) return null;
- return MessageFormat.format(formatString, arguments);
- }
-
- private static Message findMessage(String id, Locale locale) {
- Message message = lookupMessage(id, locale);
- if (message == null) {
- message = lookupMessage(id, Locale.getDefault());
- }
- if (message == null ) throw new MessageNotFoundException("Message with id "+id+" not found");
- return message;
- }
-
- private static Message lookupMessage(String id, Locale locale) {
- StringBuffer keyBuffer = new StringBuffer(64);
- keyBuffer.append(id);
- if (locale.getLanguage() != null) keyBuffer.append("_" + locale.getLanguage());
- if (locale.getCountry() != null) keyBuffer.append("_" + locale.getCountry());
- if (locale.getVariant() != null) keyBuffer.append("_" + locale.getVariant());
- String key = keyBuffer.toString();
- if (messages.containsKey(key)) return (Message)messages.get(key);
- while (key.lastIndexOf('_') > 0) {
- key = key.substring(0, key.lastIndexOf('_'));
- if (messages.containsKey(key)) return (Message)messages.get(key);
- }
- return null;
+
+ public static void addMessageProvider(MessageProvider messageProvider) {
+ messageProviders.add(messageProvider);
}
-
- static class ConfigurationHandler extends DefaultSimpleImportHandler {
- private Map messages = new HashMap();
- private String id;
- private Message message;
-
- public void startElement(SimplePath path, String name, AttributesImpl attributes, String leadingCDdata) {
- if (path.matches("message")) {
- id = attributes.getValue("id");
- } else if (path.matches("message/locale")) {
- message = new Message(id);
- message.setLanguage(attributes.getValue("language"));
- message.setCountry(attributes.getValue("country"));
- message.setVariant(attributes.getValue("variant"));
- } else if (path.matches("message/locale/entry")) {
- String key = attributes.getValue("key");
- message.addEntry(key, leadingCDdata);
- }
- }
-
- public void endElement(SimplePath path, String name) {
- if (path.matches("message/locale")) {
- messages.put(message.getKey(), message);
+
+ public static String getText(String id, String entry, Object[] arguments, Locale locale) throws MessageNotFoundException {
+ MessageNotFoundException exception = null;
+ for ( Iterator i = messageProviders.iterator(); i.hasNext(); ) {
+ try {
+ return ((MessageProvider)i.next()).getText(id, entry, arguments, locale);
+ } catch ( MessageNotFoundException e ) {
+ exception = e;
}
}
-
- Map getMessages() {
- return messages;
- }
+ throw exception;
}
- static class Message {
- private String id, language, country, variant;
- private Map entries = new HashMap();
-
- public Message(String id) {
- this.id = id;
- }
-
- public void addEntry(String key, String value) {
- entries.put(key, value);
- }
-
- public String getEntry(String key) {
- return (String)entries.get(key);
- }
-
- public Map getEntries() {
- return entries;
- }
-
- public void setLanguage(String language) {
- this.language = language;
- }
-
- public void setCountry(String country) {
- this.country = country;
- }
-
- public void setVariant(String variant) {
- this.variant = variant;
- }
-
- public String getKey() {
- StringBuffer key = new StringBuffer(64);
- key.append(id);
- if (language != null) key.append("_" + language);
- if (country != null) key.append("_" + country);
- if (variant != null) key.append("_" + variant);
- return key.toString();
+ public static String getText(String id, String entry, Object[] arguments, Locale locale, String defaultText) {
+ try {
+ return getText(id, entry, arguments, locale);
+ } catch ( MessageNotFoundException e ) {
+ return defaultText;
}
}
}
1.1 jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/XMLMessageProvider.java
Index: XMLMessageProvider.java
===================================================================
/*
*
* ====================================================================
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.commons.i18n;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.xmlio.in.DefaultSimpleImportHandler;
import org.apache.commons.xmlio.in.SimpleImporter;
import org.apache.commons.xmlio.in.SimplePath;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.AttributesImpl;
/**
* @author Daniel Florey
*
*/
public class XMLMessageProvider implements MessageProvider {
private static Logger logger = Logger.getLogger(XMLMessageProvider.class.getName());
private static Map installedMessages = new HashMap();
private static Map messages = new HashMap();
public String getText(String id, String entry, Object[] arguments, Locale locale) throws MessageNotFoundException {
Message message = findMessage(id, locale);
return MessageFormat.format(message.getEntry(entry), arguments);
}
public Map getEntries(String id, Locale locale) throws MessageNotFoundException {
Message message = findMessage(id, locale);
return message.getEntries();
}
public static void install(String id, InputStream inputStream) {
logger.log(Level.FINE, "Installing messages '"+id+"'");
try {
Map applicationMessages = new HashMap();
SimpleImporter importer = new SimpleImporter();
importer.setIncludeLeadingCDataIntoStartElementCallback(true);
ConfigurationHandler handler = new ConfigurationHandler();
importer.addSimpleImportHandler(handler);
importer.parse(new InputSource(inputStream));
Map parsedMessages = handler.getMessages();
applicationMessages.putAll(parsedMessages);
messages.putAll(applicationMessages);
installedMessages.put(id, applicationMessages.keySet());
} catch (Exception exception) {
logger.log(Level.SEVERE, "Error while parsing messages", exception);
}
}
public static void uninstall(String id) {
logger.log(Level.FINE, "Uninstalling messages '"+id+"'");
Collection messageKeys = (Collection)installedMessages.get(id);
for ( Iterator i = messageKeys.iterator(); i.hasNext(); ) {
String messageKey = (String)i.next();
messages.remove(messageKey);
logger.log(Level.FINE, "Removing message with key '"+messageKey+"'");
}
installedMessages.remove(id);
}
public static void update(String id, InputStream inputStream) {
uninstall(id);
install(id, inputStream);
}
private static Message findMessage(String id, Locale locale) {
Message message = lookupMessage(id, locale);
if (message == null) {
message = lookupMessage(id, Locale.getDefault());
}
if (message == null ) throw new MessageNotFoundException("Message with id "+id+" not found");
return message;
}
private static Message lookupMessage(String id, Locale locale) {
StringBuffer keyBuffer = new StringBuffer(64);
keyBuffer.append(id);
if (locale.getLanguage() != null) keyBuffer.append("_" + locale.getLanguage());
if (locale.getCountry() != null) keyBuffer.append("_" + locale.getCountry());
if (locale.getVariant() != null) keyBuffer.append("_" + locale.getVariant());
String key = keyBuffer.toString();
if (messages.containsKey(key)) return (Message)messages.get(key);
while (key.lastIndexOf('_') > 0) {
key = key.substring(0, key.lastIndexOf('_'));
if (messages.containsKey(key)) return (Message)messages.get(key);
}
return null;
}
static class ConfigurationHandler extends DefaultSimpleImportHandler {
private Map messages = new HashMap();
private String id;
private Message message;
public void startElement(SimplePath path, String name, AttributesImpl attributes, String leadingCDdata) {
if (path.matches("message")) {
id = attributes.getValue("id");
} else if (path.matches("message/locale")) {
message = new Message(id);
message.setLanguage(attributes.getValue("language"));
message.setCountry(attributes.getValue("country"));
message.setVariant(attributes.getValue("variant"));
} else if (path.matches("message/locale/entry")) {
String key = attributes.getValue("key");
message.addEntry(key, leadingCDdata);
}
}
public void endElement(SimplePath path, String name) {
if (path.matches("message/locale")) {
messages.put(message.getKey(), message);
}
}
Map getMessages() {
return messages;
}
}
static class Message {
private String id, language, country, variant;
private Map entries = new HashMap();
public Message(String id) {
this.id = id;
}
public void addEntry(String key, String value) {
entries.put(key, value);
}
public String getEntry(String key) {
return (String)entries.get(key);
}
public Map getEntries() {
return entries;
}
public void setLanguage(String language) {
this.language = language;
}
public void setCountry(String country) {
this.country = country;
}
public void setVariant(String variant) {
this.variant = variant;
}
public String getKey() {
StringBuffer key = new StringBuffer(64);
key.append(id);
if (language != null) key.append("_" + language);
if (country != null) key.append("_" + country);
if (variant != null) key.append("_" + variant);
return key.toString();
}
}
}
1.1 jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/MessageProvider.java
Index: MessageProvider.java
===================================================================
/*
* $Header: /home/cvs/jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/MessageProvider.java,v 1.1 2004/12/18 15:08:49 dflorey Exp $
* $Revision: 1.1 $
* $Date: 2004/12/18 15:08:49 $
*
* ====================================================================
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.commons.i18n;
import java.util.Locale;
public interface MessageProvider {
public String getText(String id, String entry, Object[] arguments, Locale locale) throws MessageNotFoundException;
}
1.1 jakarta-commons-sandbox/i18n/src/java/org/apache/commons/i18n/ResourceBundleMessageProvider.java
Index: ResourceBundleMessageProvider.java
===================================================================
/*
*
* ====================================================================
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed 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.commons.i18n;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Daniel Florey
*
*/
public class ResourceBundleMessageProvider implements MessageProvider {
private static Logger logger = Logger.getLogger(ResourceBundleMessageProvider.class.getName());
private static List installedResourceBundles = new ArrayList();
public String getText(String id, String entry, Object[] arguments, Locale locale) throws MessageNotFoundException {
String text = null;
for ( Iterator i = installedResourceBundles.iterator(); i.hasNext(); ) {
String baseName = (String)i.next();
try {
ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName, locale);
try {
text = resourceBundle.getString(id+"."+entry);
return MessageFormat.format(text, arguments);
} catch ( ClassCastException e ) {
// ignore all entries that are not of type String
} catch ( MissingResourceException e ) {
// skip resource bundle if it is not containing the desired entry
}
} catch ( MissingResourceException e ) {
logger.log(Level.WARNING, "Could not find resource bundle with base name '"+baseName+"', uninstalling it...");
uninstall(baseName);
}
}
throw new MessageNotFoundException("Message with id "+id+" not found");
}
public static void install(String baseName) {
logger.log(Level.FINE, "Installing bundle with base name '"+baseName+"'");
installedResourceBundles.add(baseName);
}
public static void uninstall(String baseName) {
logger.log(Level.FINE, "Uninstalling bundle with base name '"+baseName+"'");
installedResourceBundles.remove(baseName);
}
public static void update(String baseName) {
uninstall(baseName);
install(baseName);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org