001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 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(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 }