* Translation: Move code from routerconsole to core,
to support translation of other webapps
This commit is contained in:
@ -1,65 +1,17 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Translate strings efficiently.
|
||||
* We don't include an English or default ResourceBundle, we simply check
|
||||
* for "en" and return the original string.
|
||||
* Support real-time language changing with the routerconsole.lang property.
|
||||
*
|
||||
* @author zzz, from a base generated by eclipse.
|
||||
* Translate strings for this package.
|
||||
*/
|
||||
public class Messages {
|
||||
public static final String PROP_LANG = "routerconsole.lang";
|
||||
public class Messages extends Translate {
|
||||
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
||||
private static final String _localeLang = Locale.getDefault().getLanguage();
|
||||
private static final Map<String, ResourceBundle> _bundles = new ConcurrentHashMap(2);
|
||||
private static final Set<String> _missing = new ConcurrentHashSet(2);
|
||||
/** use to look for untagged strings */
|
||||
private static final String TEST_LANG = "xx";
|
||||
private static final String TEST_STRING = "XXXX";
|
||||
|
||||
/** current locale **/
|
||||
/* unused
|
||||
public static String getString(String key) {
|
||||
if (_localeLang.equals("en"))
|
||||
return key;
|
||||
ResourceBundle bundle = findBundle(_localeLang);
|
||||
if (bundle == null)
|
||||
return key;
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
public static String getString(String key, I2PAppContext ctx) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals("en"))
|
||||
return key;
|
||||
else if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING;
|
||||
ResourceBundle bundle = findBundle(lang);
|
||||
if (bundle == null)
|
||||
return key;
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
return Translate.getString(key, ctx, BUNDLE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,45 +27,6 @@ public class Messages {
|
||||
* Use autoboxing to call with ints, longs, floats, etc.
|
||||
*/
|
||||
public static String getString(String s, Object o, I2PAppContext ctx) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING + '(' + o + ')' + TEST_STRING;
|
||||
String x = getString(s, ctx);
|
||||
Object[] oArray = new Object[1];
|
||||
oArray[0] = o;
|
||||
try {
|
||||
MessageFormat fmt = new MessageFormat(x, new Locale(lang));
|
||||
return fmt.format(oArray, new StringBuffer(), null).toString();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
System.err.println("Bad format: orig: \"" + s +
|
||||
"\" trans: \"" + x +
|
||||
"\" param: \"" + o +
|
||||
"\" lang: " + lang);
|
||||
return "FIXME: " + x + ' ' + o;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLanguage(I2PAppContext ctx) {
|
||||
String lang = ctx.getProperty(PROP_LANG);
|
||||
if (lang == null || lang.length() <= 0)
|
||||
lang = _localeLang;
|
||||
return lang;
|
||||
}
|
||||
|
||||
/** cache both found and not found for speed */
|
||||
private static ResourceBundle findBundle(String lang) {
|
||||
ResourceBundle rv = _bundles.get(lang);
|
||||
if (rv == null && !_missing.contains(lang)) {
|
||||
try {
|
||||
// Would it be faster to specify a class loader?
|
||||
// No matter we only do this once per lang.
|
||||
rv = ResourceBundle.getBundle(BUNDLE_NAME, new Locale(lang));
|
||||
if (rv != null)
|
||||
_bundles.put(lang, rv);
|
||||
} catch (MissingResourceException e) {
|
||||
_missing.add(lang);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
return Translate.getString(s, o, ctx, BUNDLE_NAME);
|
||||
}
|
||||
}
|
||||
|
104
core/java/src/net/i2p/util/Translate.java
Normal file
104
core/java/src/net/i2p/util/Translate.java
Normal file
@ -0,0 +1,104 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
|
||||
/**
|
||||
* Translate strings efficiently.
|
||||
* We don't include an English or default ResourceBundle, we simply check
|
||||
* for "en" and return the original string.
|
||||
* Support real-time language changing with the routerconsole.lang property.
|
||||
*
|
||||
* @author zzz, from a base generated by eclipse.
|
||||
*/
|
||||
public abstract class Translate {
|
||||
public static final String PROP_LANG = "routerconsole.lang";
|
||||
private static final String _localeLang = Locale.getDefault().getLanguage();
|
||||
private static final Map<String, ResourceBundle> _bundles = new ConcurrentHashMap(2);
|
||||
private static final Set<String> _missing = new ConcurrentHashSet(2);
|
||||
/** use to look for untagged strings */
|
||||
private static final String TEST_LANG = "xx";
|
||||
private static final String TEST_STRING = "XXXX";
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
public static String getString(String key, I2PAppContext ctx, String bun) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals("en"))
|
||||
return key;
|
||||
else if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING;
|
||||
ResourceBundle bundle = findBundle(bun, lang);
|
||||
if (bundle == null)
|
||||
return key;
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* translate a string with a parameter
|
||||
* This is a lot more expensive than getString(s, ctx), so use sparingly.
|
||||
*
|
||||
* @param s string to be translated containing {0}
|
||||
* The {0} will be replaced by the parameter.
|
||||
* Single quotes must be doubled, i.e. ' -> '' in the string.
|
||||
* @param o parameter, not translated.
|
||||
* To tranlslate parameter also, use _("foo {0} bar", _("baz"))
|
||||
* Do not double the single quotes in the parameter.
|
||||
* Use autoboxing to call with ints, longs, floats, etc.
|
||||
*/
|
||||
public static String getString(String s, Object o, I2PAppContext ctx, String bun) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING + '(' + o + ')' + TEST_STRING;
|
||||
String x = getString(s, ctx, bun);
|
||||
Object[] oArray = new Object[1];
|
||||
oArray[0] = o;
|
||||
try {
|
||||
MessageFormat fmt = new MessageFormat(x, new Locale(lang));
|
||||
return fmt.format(oArray, new StringBuffer(), null).toString();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
System.err.println("Bad format: orig: \"" + s +
|
||||
"\" trans: \"" + x +
|
||||
"\" param: \"" + o +
|
||||
"\" lang: " + lang);
|
||||
return "FIXME: " + x + ' ' + o;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return lang in routerconsole.lang property, else current locale */
|
||||
public static String getLanguage(I2PAppContext ctx) {
|
||||
String lang = ctx.getProperty(PROP_LANG);
|
||||
if (lang == null || lang.length() <= 0)
|
||||
lang = _localeLang;
|
||||
return lang;
|
||||
}
|
||||
|
||||
/** cache both found and not found for speed */
|
||||
private static ResourceBundle findBundle(String bun, String lang) {
|
||||
String key = bun + '-' + lang;
|
||||
ResourceBundle rv = _bundles.get(key);
|
||||
if (rv == null && !_missing.contains(key)) {
|
||||
try {
|
||||
// Would it be faster to specify a class loader?
|
||||
// No matter we only do this once per lang.
|
||||
rv = ResourceBundle.getBundle(bun, new Locale(lang));
|
||||
if (rv != null)
|
||||
_bundles.put(key, rv);
|
||||
} catch (MissingResourceException e) {
|
||||
_missing.add(key);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user