2.7 本地化
前面提到过,Bundle的元数据信息中包含一些供人工阅读的信息,如Bundle-Name、Bundle-Vendor等。这些信息可能需要根据用户的语言、国家和其他指定的参数(一般是指定“区域”的参数)翻译成不同的语言。OSGi规范定义了Bundle应该如何自动根据系统语言、国家等参数自动翻译这些信息,即Bundle的本地化能力。
Bundle的本地化信息必须遵循特定的命名规则,存放在Bundle的指定目录下,如果没有通过Bundle-Localization特别指定,那么这个目录默认为“OSGI-INFO/l10n”。为了方便实现框架查找存在的本地化信息,OSGi规范规定了这些信息必是以“bundle”开头,以语言、国家、其他参数为内容,以下划线(‘_’,\u005F)分隔,以“.properties”为扩展名来命名的文本文件,即遵循以下格式命名:
OSGI-INF/l10n/bundle_[语言]_[国家]_[其他参数].properties
文件名中所使用到的语言、国家等会从java.util.Locale获取。例如,以下文件提供了英语、荷兰语(比利时和荷兰)和瑞典语的本地化信息:
OSGI-INF/l10n/bundle_en.properties
OSGI-INF/l10n/bundle_nl_BE.properties
OSGI-INF/l10n/bundle_nl_NL.properties
OSGI-INF/l10n/bundle_sv.properties
实现框架不是通过精确匹配文件名来搜索本地化信息,而是采用一种渐进式的搜索方式。如果最佳匹配的文件没有找到,会先删除参数,然后是国家,最后是语言,直到找到一个包含有效信息的本地化文件。比如,参数为welsh、国家是GB、语言是en的本地化文件将通过以下顺序查找:
OSGI-INF/l10n/bundle_en_GB_welsh.properties
OSGI-INF/l10n/bundle_en_GB.properties
OSGI-INF/l10n/bundle_en.properties
OSGI-INF/l10n/bundle.properties
另外,查找过程也并不是找到某个可用的本地化文件就停止,而是会一直进行下去,这种策略允许在拥有更具体区域、语言信息的本地化文件时覆盖更少信息的本地化文件。
本地化文件中包含了以Key-Value值对表示的本地化信息。Bundle的元数据信息文件中所有信息都可以进行本地化。但是,对于带有程序语义而非人工阅读的信息,OSGi实现框架必须使用非本地化版本,也就是只以MANIFEST.MF文件中的内容为准。
我们可以通过两种方式来使用本地化文件中的信息,第一种是直接覆盖元数据标记,例如:
Bundle-Name : The ACME Bundle
Bundle-Vendor : The ACME Corporation
Bundle-Description : The ACME Bundle provides all of the ACME
第二种是在MANIFEST.MF中使用本地化变量,然后在本地化文件中定义这些变量的值,例如:
#在MANIFEST.MF文件中:
Bundle-Name : %acme_bundle
Bundle-Vendor : %acme_corporation
Bundle-Description : %acme_description
Acme-Defined-Header : %acme_special_header
#在OSGI-INF/l10n/bundle.properties文件中:
acme_bundle=The ACME Bundle
acme_corporation=The ACME Corporation
acme_description=The ACME Bundle provides all of the ACME services
acme_special_header=user-defined Acme Data
本地化文件中定义的变量中间允许空格存在,把上面例子中的“_”替换成空格也是允许的。另外,在MANIFEST.MF文件中由用户自定义的非OSGi的标记也可以被本地化,例如上面的“Acme-Defined-Header”。