001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.utils;
021
022 import com.google.common.collect.Iterators;
023 import com.google.common.collect.Lists;
024 import org.slf4j.Logger;
025 import org.slf4j.LoggerFactory;
026
027 import java.util.*;
028
029 public class LocalizedMessages extends ResourceBundle {
030
031 private static final Logger LOG = LoggerFactory.getLogger(LocalizedMessages.class);
032
033 private Locale locale;
034 private List<ResourceBundle> bundles;
035
036 /**
037 * Constructs a resource bundle from a list of other resource bundles. If
038 * there are duplicate keys, the key from the resource bundle with the
039 * smallest index takes precedence.
040 */
041 public LocalizedMessages(Locale locale, String... basenames) {
042 this.locale = locale;
043 bundles = new ArrayList<ResourceBundle>(basenames.length);
044 for (String basename : basenames) {
045 bundles.add(ResourceBundle.getBundle("sonar.bundles." + basename, locale));
046 }
047 }
048
049 public Locale getLocale() {
050 return locale;
051 }
052
053 public String format(String key, Object... args) {
054 return format(true, key, args);
055 }
056
057 public String formatQuietly(String key, Object... args) {
058 return format(false, key, args);
059 }
060
061 private String format(boolean logIfMissing, String key, Object... args) {
062 try {
063 String message = getString(key);
064 return String.format(locale, message, args);
065
066 } catch (MissingResourceException e) {
067 if (logIfMissing) {
068 LOG.warn("Missing translation: key==" + key + ",locale=" + locale);
069 }
070 return key;
071 }
072 }
073
074 /*
075 * (non-Javadoc)
076 *
077 * @see java.util.ResourceBundle#getKeys()
078 */
079
080 @Override
081 public Enumeration<String> getKeys() {
082 return new Enumeration<String>() {
083 private Set<String> keys = new HashSet<String>();
084
085 // Set iterator to simulate enumeration
086 private Iterator<String> i;
087
088 // Constructor
089 {
090 for (ResourceBundle b : bundles) {
091 keys.addAll(Lists.newArrayList(Iterators.forEnumeration(b.getKeys())));
092 }
093 i = keys.iterator();
094 }
095
096 public boolean hasMoreElements() {
097 return i.hasNext();
098 }
099
100 public String nextElement() {
101 return i.next();
102 }
103 };
104 }
105
106 /*
107 * (non-Javadoc)
108 *
109 * @see java.util.ResourceBundle#handleGetObject(java.lang.String)
110 */
111
112 @Override
113 protected Object handleGetObject(String key) {
114 for (ResourceBundle b : bundles) {
115 try {
116 return b.getObject(key);
117 } catch (MissingResourceException mre) {
118 // iterate
119 }
120 }
121 throw new MissingResourceException(null, null, key);
122 }
123 }