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