Fixed up xlate() to support recursive composed translations by providing a
method for composing a translation key and arguments into a single string which is later decoded by the call to xlate(). This also requires that unsafe strings (those entered by the user which should not be translated) be marked with the new taint() method so that xlate() knows not to try to translate those when it is recursively translating everything in sight. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1079 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MessageBundle.java,v 1.2 2002/02/09 01:35:26 mdb Exp $
|
||||
// $Id: MessageBundle.java,v 1.3 2002/02/28 23:13:54 mdb Exp $
|
||||
|
||||
package com.threerings.util;
|
||||
|
||||
@@ -38,6 +38,12 @@ public class MessageBundle
|
||||
*/
|
||||
public String get (String key)
|
||||
{
|
||||
// if this string is tainted, we don't translate it, instead we
|
||||
// simply remove the taint character and return it to the caller
|
||||
if (key.startsWith(TAINT_CHAR)) {
|
||||
return key.substring(1);
|
||||
}
|
||||
|
||||
try {
|
||||
return _bundle.getString(key);
|
||||
|
||||
@@ -132,22 +138,128 @@ public class MessageBundle
|
||||
{
|
||||
// to be more efficient about creating unnecessary objects, we
|
||||
// do some checking before splitting
|
||||
int tidx = compoundKey.indexOf("\t");
|
||||
int tidx = compoundKey.indexOf('|');
|
||||
if (tidx == -1) {
|
||||
return get(compoundKey);
|
||||
|
||||
} else {
|
||||
String key = compoundKey.substring(0, tidx);
|
||||
String argstr = compoundKey.substring(tidx+1);
|
||||
String[] args = StringUtil.split(argstr, "\t");
|
||||
String[] args = StringUtil.split(argstr, "|");
|
||||
// unescape and translate the arguments
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = xlate(unescape(args[i]));
|
||||
}
|
||||
return get(key, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to "taint" any string that has been entered by an entity
|
||||
* outside the application so that the translation code knows not to
|
||||
* attempt to translate this string when doing recursive translations
|
||||
* ({@see #xlate}).
|
||||
*/
|
||||
public static String taint (String text)
|
||||
{
|
||||
return TAINT_CHAR + text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes a message key with an array of arguments. The message can
|
||||
* subsequently be translated in a single call using {@link #xlate}.
|
||||
*/
|
||||
public static String compose (String key, String[] args)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(key);
|
||||
buf.append('|');
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (i > 0) {
|
||||
buf.append('|');
|
||||
}
|
||||
// escape the string while adding to the buffer
|
||||
String arg = args[i];
|
||||
int alength = arg.length();
|
||||
for (int p = 0; p < alength; p++) {
|
||||
char ch = arg.charAt(p);
|
||||
if (ch == '|') {
|
||||
buf.append("\\!");
|
||||
} else if (ch == '\\') {
|
||||
buf.append("\\\\");
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unescapes characters that are escaped in a call to compose.
|
||||
*/
|
||||
protected static String unescape (String value)
|
||||
{
|
||||
int bsidx = value.indexOf('\\');
|
||||
if (bsidx == -1) {
|
||||
return value;
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int vlength = value.length();
|
||||
for (int i = 0; i < vlength; i++) {
|
||||
char ch = value.charAt(i);
|
||||
if (ch != '\\') {
|
||||
buf.append(ch);
|
||||
} else if (i < vlength-1) {
|
||||
// look at the next character
|
||||
ch = value.charAt(++i);
|
||||
buf.append((ch == '!') ? '|' : ch);
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for calling {@link #compose(String,String[])}
|
||||
* with a single argument.
|
||||
*/
|
||||
public static String compose (String key, String arg)
|
||||
{
|
||||
return compose(key, new String[] { arg });
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for calling {@link #compose(String,String[])}
|
||||
* with two arguments.
|
||||
*/
|
||||
public static String compose (String key, String arg1, String arg2)
|
||||
{
|
||||
return compose(key, new String[] { arg1, arg2 });
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for calling {@link #compose(String,String[])}
|
||||
* with three arguments.
|
||||
*/
|
||||
public static String compose (
|
||||
String key, String arg1, String arg2, String arg3)
|
||||
{
|
||||
return compose(key, new String[] { arg1, arg2, arg3 });
|
||||
}
|
||||
|
||||
/** The path that identifies the resource bundle we are using to
|
||||
* obtain our messages. */
|
||||
protected String _path;
|
||||
|
||||
/** The resource bundle from which we obtain our messages. */
|
||||
protected ResourceBundle _bundle;
|
||||
|
||||
/** Text prefixed by this character will be considered tainted when
|
||||
* doing recursive translations and won't be translated. */
|
||||
protected static final String TAINT_CHAR = "~";
|
||||
// protected static final String TAINT_CHAR = '~';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user