Eclipse插件的本地化实现
?
基于Equinox的本地化机制,清单文件中的本地化资源约定以%开头,通过MENIFEST.MF文件指定本地化的资源文件名,如MENIFEST.MF:
?
?
那么对应的多语为$BUNDLE/plugin.properties、$BUNDLE/plugin_语种_国家.properties(如zh_CN、zh_TW)等文件。
?

图1 PDE字符串提取工具按钮
?
Localization为清单文件Bundle-Localization属性;而Substitution Key则为提取的多语资源的Key值,在此处可修改为更易读的名称。

图2? PDE字符串提取工具
?

图3 重构文件一览
基于org.eclipse.osgi.util.NLS搭建的多语方案,通过一个Java类作为多语资源的访问器Messages,该类自动载入多语资源(载入时指定多语资源文件名称)到对应的静态属性中;而需要使用多语资源的类调用Messages.XXX直接获取即可。
?
private static final String BUNDLE_NAME ="xx.xx.plugin.ui.testdialog.messages"; //$NON-NLS-1$ static { NLS.initializeMessages(BUNDLE_NAME, Messages.class);}??NLS中载入资源的基本思想是通过对资源文件的顺序载入,保证高优先级的资源优先被载入到Messages类中。实现如下:
?
按当前语种(如:zh_CN会尝试载入_zh和_zh_CN资源)优先、默认资源(即不添加任何语种资源的文件)最后的原则,顺序载入资源文件。
为保证Messages中的字段只被一次设值,NLS构造了Map<属性名,字段>结构,初始化时,置入所有<FieldName,Field>,如图4所示:

图?4?预置所有可用的字段到Map结构
?
当Properties载入时,将使用一个已赋值的约定标记,记为FLAG与原值交换,若交换出的是字段,那么利用反射进行首次设值,如图5所示;若交换出的是NULL,则表示Messages类中可能缺失了某多语资源的定义,不处理;若交换出的是FLAG,则表示原字段已赋值,不处理,如图6所示:

图5?交换出的是Filed,则进行赋值处理

图6?交换出的是已赋值的标记,则不处理
?
经过多次资源文件的载入并交换设值后,Messages中可能存在未初始化的资源,即值非FLAG的字段,如图7所示,为了避免在运行时由于资源缺失造成的NullPointerException,最后进行一次补偿设置,设置值非FLAG的字段的值为NLS资源缺失提示的文本。

图7?多语资源载入后对缺失资源的字段进行处理

图8 提取字符串功能按钮
?

图9 可提取资源列表窗口
?
其中红色标出的输入框内容为多语资源Key的前缀,默认为”类名_”,不建议修改;而下方列表中的Key值对应为资源文件的Key值,此处请修改为更易读的名称;而Accessor class则指定访问器类和资源文件,可通过configure… 按钮进行编辑。

图10 提取字符串功能对话框
?

图11 代码变更一览
?
?