前言

在实现中文的提取和过滤之后,咱们须要对中文节点进行转换、翻译、替换。

文案转换

文案转换通常有一下几个状况

一般文案

比方"保留胜利",间接替换成对应的code即可

拼接的文案

"用户" + user.name + "不能为空",会做占位符转换, 合并成"用户{0}不能为空", 而后替换成对应的code

注解中的文案

比方"用户不能为空",须要替换成成对应的{code},code两边须要退出{},以符合要求。

节点替换

一般文案

"保留胜利"
替换为
I18nUtils.getMessage("save_succeeded")

拼接文案

"用户名" + user.name + "不能为空"
替换为
I18nUtils.getMessage("user_name_not_empty", new Object[]{ user.name })

注解中的文案

@NotNull(message = "'type'不能为空")
替换为
@NotNull(message = "{type_cannot_be_empty}")

字段中的字符串

private static String abc = "你好"
替换为

private String getAbc(){  return I18nUtils.getMessage("hello")}

MessageFormat.format中的文案

MessageFormat.format("用户名{0}不能为空", user.name)
替换为
I18nUtils.getMessage("user_name_not_empty", new Object[]{ user.name })

替换原理

所谓替换,就是解析相应的AST树并转为指标树

一般文案AST树结构

MethodInvocation getI18nCall(List<ASTNode> args){    def methodInvocation = ast.newMethodInvocation()    methodInvocation.setExpression(ast.newSimpleName(Config.getI18nClass()))    methodInvocation.name = ast.newSimpleName("getMessage")    methodInvocation.arguments().addAll(args)    methodInvocation}

简单文案节点结构

源AST树(MessageFormat.format(“{0}”, row))

指标AST树(I18nUtils.getMessage(“{0}”, new Object[]{ row }))
void replaceMessageFormatWithI18n(MethodInvocation methodInvocation, StringLiteral stringLiteral){  def args = []  // 提取MessageFormat.format中的第一个中文  StringLiteral code = ASTNode.copySubtree(methodInvocation.getAST(), stringLiteral)  // 翻译并替换code  translateKey(code)  // 获取MessageFormat.format残余的参数  List<ASTNode> retainExp = methodInvocation.arguments().subList(1, methodInvocation.arguments().size())      .collect({ ASTNode.copySubtree(methodInvocation.getAST(), (ASTNode)it) })  args.add(code)  def array = ast.newArrayCreation()  args.add(array)  // 结构new Object节点  array.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("Object"))))  def arrayInitializer = ast.newArrayInitializer()  // 将残余的参数全副退出到new Object节点  arrayInitializer.expressions().addAll(retainExp)  array.setInitializer(arrayInitializer)  // 转换为I18nUtils.getMessage模式  convertStringLiteral(args, methodInvocation)}