- Add class-level documentation for all mapper and multilingual classes - Add complete javadoc for all public methods with @param and @return tags - Add field-level comments for better code readability - Improve documentation for initialization blocks and constructors Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
155 lines
3.4 KiB
Java
155 lines
3.4 KiB
Java
package com.imyeyu.lang.mapper;
|
|
|
|
import com.imyeyu.java.TimiJava;
|
|
import com.imyeyu.java.bean.CallbackArgReturn;
|
|
import com.imyeyu.java.bean.Language;
|
|
import com.imyeyu.utils.Text;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* 基于内存的语言映射实现
|
|
* <p>
|
|
* 使用 HashMap 存储语言映射关系,支持二次映射、模糊匹配等功能
|
|
* </p>
|
|
*
|
|
* @author 夜雨
|
|
* @version 2024-04-03 10:11
|
|
*/
|
|
public class LanguageMap extends AbstractLanguageMapper {
|
|
|
|
/** 语言键值映射表 */
|
|
protected final Map<String, String> map;
|
|
|
|
// 初始化字符串插值器过滤器,支持 @key 格式的语言映射引用
|
|
{
|
|
INTERPOLATOR.putFilter("lang", value -> {
|
|
if (value.startsWith("@")) {
|
|
value = text(value.substring(1));
|
|
}
|
|
return value;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 默认构造
|
|
*
|
|
* @param language 所属语言
|
|
*/
|
|
public LanguageMap(Language.Enum language) {
|
|
super(language);
|
|
this.map = new HashMap<>();
|
|
}
|
|
|
|
/**
|
|
* 合并另一个语言映射表
|
|
* <p>
|
|
* 将另一个映射表的所有键值对合并到当前映射表中,如果存在相同键则覆盖
|
|
* </p>
|
|
*
|
|
* @param map 要合并的语言映射表
|
|
*/
|
|
public void union(LanguageMap map) {
|
|
this.map.putAll(map.map);
|
|
}
|
|
|
|
/**
|
|
* 添加语言映射
|
|
*
|
|
* @param key 键
|
|
* @param value 值
|
|
*/
|
|
@Override
|
|
public void add(String key, String value) {
|
|
map.put(key, value);
|
|
}
|
|
|
|
/**
|
|
* 检查是否存在指定键的映射
|
|
*
|
|
* @param key 键
|
|
* @return true 为存在
|
|
*/
|
|
@Override
|
|
public boolean has(String key) {
|
|
return map.containsKey(key);
|
|
}
|
|
|
|
/**
|
|
* 获取文本,支持二次映射,没有找到映射时返回入参键
|
|
* <pre>
|
|
* test.msg=Hello world
|
|
* mapping=@test.msg
|
|
* no_mapping=\@test.msg
|
|
*
|
|
* Multilingual.text("mapping"); // Hello world
|
|
* Multilingual.text("no_mapping"); // @test.msg
|
|
* </pre>
|
|
*
|
|
* @param key 键
|
|
* @return 文本值
|
|
*/
|
|
@Override
|
|
public String text(String key) {
|
|
if (map.containsKey(key)) {
|
|
String result = map.get(key);
|
|
if (result.startsWith("@")) {
|
|
// 递归映射
|
|
return text(result.substring(1));
|
|
} else {
|
|
if (result.startsWith("\\@")) {
|
|
return result.substring(1);
|
|
} else {
|
|
return result;
|
|
}
|
|
}
|
|
} else {
|
|
if (TimiJava.isNotEmpty(key)) {
|
|
// 推测
|
|
String guessKey = key;
|
|
LinkedHashMap<String, Number> keySRL = Text.similarityRatioList(map.keySet(), key);
|
|
if (keySRL.keySet().iterator().hasNext()) {
|
|
String k = keySRL.keySet().iterator().next();
|
|
Number ratio = keySRL.get(k);
|
|
if (.7 < ratio.doubleValue()) {
|
|
guessKey = k;
|
|
}
|
|
}
|
|
System.err.printf("not found language mapping for key: [%s], it is [%s]?%n", key, guessKey);
|
|
if (isDebugging) {
|
|
throw new RuntimeException("not found language mapping key: " + key);
|
|
}
|
|
}
|
|
}
|
|
// 找不到映射,直接返回键
|
|
return key;
|
|
}
|
|
|
|
/**
|
|
* 获取文本
|
|
*
|
|
* @param key 键
|
|
* @param def 默认值(没有找到映射值时)
|
|
* @return 获取结果
|
|
*/
|
|
@Override
|
|
public String text(String key, String def) {
|
|
String result = text(key);
|
|
return key.equals(result) ? def : result;
|
|
}
|
|
|
|
/**
|
|
* 插入参数获取文本
|
|
*
|
|
* @param key 键
|
|
* @param argsMap 参数
|
|
* @return 结果
|
|
*/
|
|
@Override
|
|
public String textArgs(String key, Map<String, Object> argsMap) {
|
|
return INTERPOLATOR.inject(text(key), argsMap);
|
|
}
|
|
}
|