Skip to content

Latest commit

 

History

History
272 lines (194 loc) · 8.35 KB

README.md

File metadata and controls

272 lines (194 loc) · 8.35 KB

i18n-message-plugin

gradle and maven plugin for generate i18n message file from java source file written by javadoc.

注意: 请使用最新发布版本1.0.2

示例

examples目录中存放着基于javafxspringboot框架的应用完整示例,前往查看

动机

我们在进行java开发(j2ee、springboot、validation、javafx客户端应用等)时,常常需要支持多语言,i18n多语言消息文件一般配置在resources/message.properties 中,但是直接面临的一个问题就是配置文件和源代码分离,经常是代码中编写了消息的label ,配置文件中却忘记了增加消息的value; 同时,如果更改或删除消息的label,都可能导致与配置文件中的label不对应,最终运行时因找不到对应消息出错。

本插件旨在提供一种将消息的labelvalue均编写在.java源文件中方法,防止出现代码和配置不一致的问题,同时还可以提升开发效率(减少在常量定义文件/枚举文件和配置文件之间的来回切换)。

设计

为了实现i18n消息labelvalue均编写在源代码中,我们基于java文档注释实现。

注释使用javadoc的tag机制,其中:

  • language标签代表当前使用的语言,可省略。

  • message标签用于表示该消息对应的language语言翻译后的message,不可省略。

  • solution标签用于提示用户出现该message消息的解决方案,可省略。

注意: 该插件仅支持生成单个语言的message文件,针对其他多国语言message文件的生成是在该工具生成后,发送给翻译人员,由翻译人员完成编写,最后再统一整合到项目中。

java开发中,一般使用枚举进行消息label管理,但是也可以使用常量进行消息label管理。本插件支持枚举类接口类两种方式。

  • 枚举模式
public enum UserError {

    /**
     * @language zh_CN
     * @message 用户不存在
     * @solution 请检查用户名是否正确或进行用户注册
     */
    USER_NOT_EXIT("0x0001001", "user not exist"),

    /**
     * @language zh_CN
     * @message 用户密码错误
     * @solution 请检查用户密码或重置密码
     */
    USER_PWD_INCORRECT("0x0001002", "user password incorrect");

    UserError(String label, String errorMsg) {
    }
}

枚举模式编码如上,通过java文档注释的方式,每个枚举字段由两个枚举属性组成。

其中label属性用于生成i18n配置文件的label,不可省略;

errorMsg用于后台日志记录等功能,可省略,省略后的模式如下所示:

public enum UserError {

    /**
     * @language zh_CN
     * @message 用户不存在
     * @solution 请检查用户名是否正确或进行用户注册
     */
    USER_NOT_EXIT("user.not.exist"),

    /**
     * @language zh_CN
     * @message 用户密码错误
     * @solution 请检查用户密码或重置密码
     */
    USER_PWD_INCORRECT("user.password.incorrect");

    UserError(String label) {
    }
}
  • 接口模式
public interface OrderError {

    /**
     * @language zh_CN
     * @message 订单不存在
     * @solution 请更换订单号
     */
    String ORDER_NOT_EXIST = "0x0002001";

    /**
     * @language zh_CN
     * @message 订单已失效
     * @solution 超出规定支付时间订单将失效
     */
    String ORDER_EXPIRED = "0x0002002";
}

其中每个属性对应一个消息label的值。

在接口模式中,还支持将label拆分为前缀+后缀的方式编写(仅支持单变量字符串相加),不常用,编码如下所示:

public interface UserError {

    /**
     * 模块label前缀
     */
    String PREFIX = "0x01f";

    /**
     * @message 用户不存在
     */
    String USER_NOT_EXIST = PREFIX + "002";
}

在Gradle中使用

build.gradle配置如下:

plugins {
    id 'java'
    id 'io.github.humbinal.i18n.message.gradle-plugin' version '1.0.2'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

i18nMessageGenerator {
    sourceDirectory = 'src/main/java'
    outputDirectory = 'build/classes/java/main'
    outputFileNamePrefix = "message"
    sourceTypes = ['enum', 'interface']
    language = 'zh_CN'
    defaultLanguage = 'zh_CN'
}

配置完毕执行: ./gradlew generateI18nMessage , 即可在build/classes/java/main目录下生成message文件。

执行: ./gradlew jar ,即可将message文件打进jar包中。

在Maven中使用

在maven模块pom.xml文件中引入插件,并进行如下配置:

<build>
    <plugins>
        <plugin>
            <groupId>io.github.humbinal</groupId>
            <artifactId>i18n-message-maven-plugin</artifactId>
            <version>1.0.2</version>
            <configuration>
                <sourceDirectory>src/main/java</sourceDirectory>
                <sourceFileEndsWith>Error.java</sourceFileEndsWith>
                <outputDirectory>target/classes</outputDirectory>
                <outputFileNamePrefix>message</outputFileNamePrefix>
                <sourceTypes>
                    <sourceType>enum</sourceType>
                    <sourceType>interface</sourceType>
                </sourceTypes>
                <language>zh_CN</language>
                <defaultLanguage>zh_CN</defaultLanguage>
            </configuration>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

配置完毕执行: maven compile, 即可在target/classes下生成message文件,同时该message文件也会打进jar包中。

完整可配置项列表

生成器配置

gradle配置在i18nMessageGenerator中,maven配置在configuration中,配置列表如下:

  • sourceDirectory: 需要扫描的.java源代码目录,必填

  • outputDirectory: 生成的message文件的输出目录,必填

  • outputFileNamePrefix: 输出的i18n文件名前缀, 必填

  • sourceFileEndsWith: 指定仅扫描某种后缀结尾的文件,默认不限制

  • sourceTypes: 需要扫描的源码类型, 支持enuminterface或二者同时

  • language:生成配置文件的语言,当配置的language与源代码中注释的language不一致时将生成失败

  • defaultLanguage: 生成message文件的默认语言,即:

默认语言message文件为: message.properties; 非默认语言的message文件为:message_XXX.properties, XXX为对应语言; 即当language和defaultLanguage配置一致时,输出两个不同名的文件,但内容一致; language和defaultLanguage配置不一致时,仅输出一个文件。

  • solutionLabelSuffix: 当我们使用solution注释时,生成的solution对应label的后缀

执行阶段配置

gradle和maven插件默认执行时机均在compile阶段。

调整在gradle中的执行时机

目前绑定在gradle的任务classesjar之间执行,但是可以单独使用插件手动执行,因此不需要调整依赖顺序。

手动执行也非常方便,借助IDE或者命令行执行:

./gradlew generateI18nMessage

调整在maven中的执行时机

指定在maven生命周期的哪个阶段生成,默认为compile

maven插件中配置executionphase即可,例如可以调整为validate,在校验阶段就生成,可以不进行编译动作,加快执行速度。

maven插件的goal为generate

配置方式如下:

<executions>
    <execution>
        <phase>validate</phase>
        <goals>
            <goal>generate</goal>
        </goals>
    </execution>
</executions>

开发及缺陷

本项目为标准gradle项目,克隆并打开即可进行二次开发。

如使用中有任何问题请及时提交issue,同时欢迎大家参与代码优化及特性贡献。