2019-06-25 13:29:10 +00:00
|
|
|
|
package cn.glycol.t18n;
|
|
|
|
|
|
2019-06-26 09:10:15 +00:00
|
|
|
|
import java.nio.charset.Charset;
|
2019-06-28 04:40:06 +00:00
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
2019-06-26 09:10:15 +00:00
|
|
|
|
|
2019-06-25 13:29:10 +00:00
|
|
|
|
public class I18n {
|
|
|
|
|
|
|
|
|
|
private static LanguageMap map;
|
2019-06-26 09:10:15 +00:00
|
|
|
|
private static Charset charset;
|
|
|
|
|
|
2019-06-30 07:26:41 +00:00
|
|
|
|
public static final int LOOP_MAX_COUNT = 1000;
|
|
|
|
|
|
2019-06-26 09:10:15 +00:00
|
|
|
|
static {
|
|
|
|
|
charset = Charset.forName(System.getProperty("file.encoding"));
|
|
|
|
|
}
|
2019-06-25 13:29:10 +00:00
|
|
|
|
|
|
|
|
|
public static void setLanguageMap(LanguageMap map) {
|
|
|
|
|
I18n.map = map;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-26 09:10:15 +00:00
|
|
|
|
public static void setEncoding(String charset) {
|
|
|
|
|
I18n.charset = Charset.forName(charset);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-30 07:26:41 +00:00
|
|
|
|
/** 自动从语言文件中提取翻译,空翻译时返回原键值 */
|
|
|
|
|
public static String translate(String key) {
|
|
|
|
|
return reEncode(getLanguageMapSafe().get(key), charset);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-28 04:40:06 +00:00
|
|
|
|
/** 自动翻译(translate)后再执行格式化(format) */
|
2019-06-25 13:29:10 +00:00
|
|
|
|
public static String format(String key, Object...format) {
|
2019-06-26 09:10:15 +00:00
|
|
|
|
return tryFormat(
|
2019-06-28 04:40:06 +00:00
|
|
|
|
translate(key),
|
2019-06-26 09:10:15 +00:00
|
|
|
|
format);
|
2019-06-25 13:29:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-30 07:26:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* 连续读取翻译(translate)。
|
|
|
|
|
* @param keyRegular 翻译键值表达式,需要填入一个“%s”用于替换为行数。行数从0开始。例如“welcome.%s”,则程序会依次向列表中添加“welcome.0”,“welcome.1”...的翻译,直到获取到空值。
|
2019-06-28 04:40:06 +00:00
|
|
|
|
*/
|
2019-06-30 07:26:41 +00:00
|
|
|
|
public static List<String> translateList(String keyRegular) {
|
2019-06-28 04:40:06 +00:00
|
|
|
|
|
|
|
|
|
List<String> vlist = new ArrayList<String>();
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
while(true) {
|
2019-06-30 07:26:41 +00:00
|
|
|
|
if(i >= LOOP_MAX_COUNT) break;
|
|
|
|
|
String k = tryFormat(keyRegular, i);
|
2019-06-28 04:40:06 +00:00
|
|
|
|
if(hasKey(k)) {
|
|
|
|
|
vlist.add(translate(k));
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-30 07:26:41 +00:00
|
|
|
|
return vlist;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 使字符串列表扁平化。 */
|
|
|
|
|
public static String flattenList(List<String> vlist) {
|
|
|
|
|
|
2019-06-28 04:40:06 +00:00
|
|
|
|
String v = "";
|
|
|
|
|
for(String o : vlist) {
|
|
|
|
|
v += o + "\n";
|
|
|
|
|
}
|
|
|
|
|
v = v.trim();
|
|
|
|
|
|
|
|
|
|
return v;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-30 07:26:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* 将列表翻译中的内容进行format操作。
|
|
|
|
|
* @see #translateList(String)
|
|
|
|
|
*/
|
|
|
|
|
public static String formatList(String keyRegular, Object...format) {
|
|
|
|
|
|
|
|
|
|
return tryFormat(flattenList(translateList(keyRegular)), format);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 13:29:10 +00:00
|
|
|
|
public static boolean hasKey(String key) {
|
|
|
|
|
return getLanguageMapSafe().containsKey(key);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-28 04:40:06 +00:00
|
|
|
|
public static boolean canTranslate(String key) {
|
|
|
|
|
return hasKey(key);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-26 09:10:15 +00:00
|
|
|
|
private static String reEncode(String bef, Charset charset) {
|
|
|
|
|
byte[] bytes = bef.getBytes();
|
|
|
|
|
return new String(bytes, charset);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 13:29:10 +00:00
|
|
|
|
private static String tryFormat(String context, Object...format) {
|
|
|
|
|
try {
|
|
|
|
|
return String.format(context, format);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static LanguageMap getLanguageMapSafe() {
|
|
|
|
|
return map == null ? new LanguageMap() : map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|