posts - 1,comments - 1,trackbacks - 0

级别: 中级

徐 亚玲 (xuyal@cn.ibm.com), 软件工程师, IBM 中国开发试验室

2007 年 10 月 18 日

在全球经济一体化的今天,网络让大家可以共享同等的信息。世界是平的,在这个变平的世界里,我们仍然需要克服语言和文化的差异, 如果软件如果能够做到全球化,以不同的语言和文化提供信息,那么无疑这个全球化的软件也是让这个世界变平的力量之一。

Eclipse已经成为大家耳熟能详的开发环境和架构平台。现在IBM越来越多的客户端产品移植到Eclipse RCP平台,本文将介绍基于Eclipse RCP的产品的全球化实现。

Eclipse RCP介绍

Eclipse的文章很多,那么我们就来总结一下关键词:开放的可扩展的IDE -> 可插入插件的开发环境 -> 带标准插件集(Java Development Tool, JDT)的JAVA开发环境 ->可开发插件的开发环境(Plug-in Development Environment, PDE)-> 开放的可扩展的应用平台。

Eclipse的开放和可扩展究其根源是运行时组件模式的架构(runtime component module),我们可以从C++的纯虚基类到COM原理来解释这些动态可加载原理,从他们的似曾相识来认知多年来我们不变的追求。Eclipse 使用 OSGi 作为插件系统的基础,OSGi,Open Services Gateway Initiative是一个基于Java语言的服务(业务)规范,该规范和核心部分是一个框架,Eclipse框架采用Lazy loading,提供了运行时可扩展的扩展点模式。

Eclipse Rich Client Platform, RCP, 在Eclipse platform的基础上增加了GUI的特性,它当然也具备Java的跨平台特性,是由可构建桌面应的最小的一组插件组成的运行平台。这里面的关键词/ SWT, JFace,Workbench。首先,Standard Widget Toolkit,SWT最显著的特点是体现了系统平台即操作系统的UI的特性,是平台相关的套件集合。基于SWT开发的UI体现了操作系统平台的UI特征。 JFace在SWT上提供了更高层的封装,提供了功能强大的界面组建,菜单,工具条,状态条等等。 Workbench: 提供了更高层的可扩展可管理的UI, 包括editors, views 和 perspectives。

Eclipse RCP 结构图片示例

Eclipse RCP 对国际化的支持

您谈到软件的国际化支持,我们通常会从对字符集,文化习惯和对翻译的支持也就是对本地化的支持三个方面来考虑。

对于前两个方面,我们知道现在通过UNICODE字符集来支持全球字符,而文化习惯包括日期,时间,货币,地址等等,尽管不同的国家地区千差万别,但它的实现通常并没有我们想象的那么复杂,可以通过调用支持全球化的组件来实现对字符集和文化特性的支持。例如IBM 中国开发中心的Globalization团队就推出过基于SWT的支持文化特性的套件,这些套件可在基于RCP平台的应用中被重用。所以,在以下的段落中我们会重点来谈如何实现Eclipse RCP 软件对本地化的支持,也就是软件的可翻译性。

我们将从以下几方面探讨软件的可翻译性:

  • 界面布局
  • BIDirection
  • 可翻译资源外部化,即资源与代码分离及资源文件的管理

Layout manager 对布局的支持

通常,在传统开发中,界面布局问题一直是困扰本地化开发过程中比较大的问题,由于文本翻译后引起长度的扩展,导致了界面布局的截断,对齐和遮盖问题。如下图,在翻译为Greek语言后,出现了很多截断问题。


图形界面的布局调整是一项工作量非常大的工作,我们知道传统开发是以矩形来定位控件的布局,即通过坐标值和长度及宽度来描述控件的位置和大小,通常在英文产品开发过程中,会通过预留一定的扩展空间来解决这个问题,但是翻译的过程中存在着很多偶然性,经常会有一些翻译过长的字串还会出现截断问题,同时所有语言共享统一的留有扩展的界面布局降低了界面的友好性,在英文和CJKT这些扩展较少的语言上,我们会觉得界面上有太多的空白空间。

SWT中的Layout manager很好的解决了这个问题。layout manager会管理界面的布局,SWT提供了四种layout manager,在这四种layout manager中,功能最强大,最复杂,也最有实用性的是GridLayout。GridLayout用网格来控制布局。关于layout manager 有最经典的介绍文章,大家可以通过这些文章来了解layout manager的工作原理。本文则是要强调一定要用layout manager来解决本地化过程中界面的布局问题,在布局设计时要想到本地化后引起的扩展问题,在这种前提下开发,会将布局问题减少到最小,我们在测试Sametime7.5 等RCP的产品过程中发现,布局这一困扰本地化开发的问题得到了根本的解决。

在SWT的示例程序中,我们可以看到layout manager在本地化过程中是如何自动调整布局的, 在AddressBook这个例子中采用了Fill Layout 布局管理器,当我们扩展这些界面上要翻译的字符串时,我们看到界面的布局也随之自动的扩展变化。




Bidirection

SWT套件允许设置为从右到左RTL,但BiDi的支持与平台有关,BiDi支持正扩展到所有Windows平台和GTK的linux平台。如果产品考虑支持BiDi,需要调研你使用的SWT版本对BiDi的支持。


资源的外部化Externalization

大家都知道在Java程序中使用Resource bundle来处理locale相关的资源文件, 所有要翻译的资源保存到按照locale命名的properties文件中,通过resource bundle来调用。Locale这个词一直没有很好的翻译,我们可以理解为语言+地区,我们命名properties文件也会以locale作为扩展,例如中国的简体中文文件,我们会命名为address_zh_CN.properties, 而台湾的繁体中文文件会命名为address_zh_TW.properties, 当在中文中国locale下时,程序设计会依顺序查找address_zh_CN.properties,然后是 address_zh.properties,最后fall back到address.properties,而在中文台湾locale下则会查找address_zh_TW.properties,找不到会是地域不同但语言相近的address_zh.properties,最后是英文的address.properties。

如果你在编程时没有这样的远虑,可以使用Eclipse提供的wizard来完成这项工作,这部分也有很多技术资料可参考。同时我们更应该从程序设计开始就做好资源文件的规划,下面我们来介绍一下资源文件的管理,注释,翻译和检查工作。


资源文件的管理

在一个项目中如何有效的定义,创建和管理资源文件?首先我们会对资源进行分类,按照资源的类型我们会分为User Interface,UI界面资源和User Assisant, UA帮助资源,从最终使用者的角度,资源可分为普通用户资源和IT用户的资源。

我们把用户分为普通用户和IT用户,普通用户是指用户的领域并非IT领域,例如银行柜员,尽管他熟悉他所使用的业务系统,但他并非IT专职人员,而IT用户则特指如程序员,网络管理员等IT从业者。从最终用户来区分资源,我们可以根据资源的使用者来确定是否要翻译这部分资源。通常普通用户的资源翻译级别较高,而IT用户的资源翻译级别较低,例如一些专业的调试出错信息,IT用户可能更倾向于使用英文原文信息。

在JAVA项目中,通常UA帮助文件会以html的形式存在,所以我们通常以不同语言命名的文件夹下面。而对于UI文件,正如我们前面介绍的,通常存为filename_{locale}.properties 的文件。

在这里,我们在创建资源文件时要同时创建filenames.properties和filenames_en.properties文件,在filenames_en.properties中存放要翻译的字串而在filenames.properties中存放版权信息和不需要翻译的资源。通过这个简单的拆分法,我们可以得到很多开发的方便之处:

  • 首先可以保证只有要翻译的资源被送出去翻译,而不需翻译的资源保留在本地不会被改变;
  • 当需要翻译的资源开始翻译,因而不可以继续修改时,不需翻译的资源文件filenames.properties还可以继续更新;
  • 首先可以保证只有要翻译的资源被送出去翻译,而不需翻译的资源保留在本地不会被改变;
  • 当需要翻译的资源开始翻译,因而不可以继续修改时,不需翻译的资源文件filenames.properties还可以继续更新;
  • 同时我们作伪翻译测试和资源文件检查时,也可以有效的判断哪些是语言相关的资源和文件。
  • 在生成安装包时,我们可以动态的将filenames.properties 文件加到filename_{locale}.properties中,而将filenames_en.properties加到filenames.properties中,形成最终的properties文件组。

伪翻译及伪翻译测试

伪翻译测试是测试软件可翻译性的最有效的手段,通常我们测试软件的可翻译性可通过伪翻译或pilot翻译来测试。伪翻译的过程是利用工具将产品中需要翻译的部分随机或按照一定规则进行转换,以这种转换来模仿翻译的过程,而pilot翻译则是在英文产品开发的同时,选择某种语言例如德文进行同步翻译。通过产品开发过程中的伪翻译或pilot翻译,测试下面几类问题:

1.是否有需要翻译的字符串被硬编码。当所有的资源文件中的资源被伪翻译为某种字符,例如全部被转换为圆点符号,那么界面上仍旧显示为英文ASCII原文的字符串就有可能是硬编码在代码中,没有被伪翻译的字符串。这些字符串需要被resource out, 才会被正确的翻译和显示。

2.对字符集的支持在伪翻译过程中,我们会把原ASCII字符伪翻译为风险字符来测试产品对这些特殊字符的支持。关于风险字符,如果大家感兴趣,我会单独写一篇介绍文章,每个语言的风险字符不同,另外比如欧元,GB18030字符都是容易出现问题的风险字符。如下给出了一段将ASCII码转化为重音字符的脚本代码,基于这种转换,不但可以测试对西欧中欧重音字符的支持,同时保证了程序的可读性。


ASCII码转化为重音字符的脚本代码示例
 1Select Case temp
 2        Case "a"
 3            tempstr = tempstr + "ã"
 4        Case "A"
 5            tempstr = tempstr + "À"
 6        Case "B"
 7            tempstr = tempstr + "ß"
 8        Case "c"
 9            tempstr = tempstr + "ç"
10        Case "C"
11            tempstr = tempstr + "Ç"
12        Case "d"
13            tempstr = tempstr + "ð"
14        Case "D"
15            tempstr = tempstr + "Ð"
16        Case "e"
17            tempstr = tempstr + "é"   
18        Case "E"
19            tempstr = tempstr + "É"
20        Case "n"
21            tempstr = tempstr + "ñ"     
22        Case "N"
23            tempstr = tempstr + "Ñ"
24        Case "o"
25            tempstr = tempstr + "ö"     
26        Case "O"
27            tempstr = tempstr + "Ô"
28        Case "i"
29            tempstr = tempstr + "ï"   
30        Case "I"     
31            tempstr = tempstr + "Ï"     
32        Case "p"
33            tempstr = tempstr + "þ"
34        Case  temp = "P"
35            tempstr = tempstr + "Þ"
36        Case "u"
37            tempstr = tempstr + "û"
38        Case  temp = "U"
39            tempstr = tempstr + "Ü"
40        Case "y"
41            tempstr = tempstr + "ý"
42        Case  temp = "Y"
43            tempstr = tempstr + "Ý"
44        Case Else
45            tempstr = tempstr + temp
46        End Select
47

3.界面布局的可翻译性我们可以选择按一定比例,例如30%,扩展原文的伪翻译方式,如果伪翻译后界面出现截断,不对齐等问题,说明界面的设计不具备可翻译性。由于语言的翻译有很多偶然性,可以随机的把一些字符串加长,来测试界面对可翻译性的支持。

4.串联字符串在伪翻译的过程中,我们会通过给每句要翻译的文本在首尾加上分割符例如[]来发现这类问题。当一个完整的句子是由几个片断拼凑起来的话会为翻译带来很大的困扰,例如:

Strings_OutOfOffice = I will be out of the office

Strings_StartTime= starting {0}.

在实际运行环境中的显示为:I will be out of the office starting 2007-8-17.

我们可以通过定义在句首加“[”,句末加“]”的伪翻译规则,这样在伪翻译后:

Strings_OutOfOffice=[I will be out of the office]

Strings_StartTime=[starting{0}]

在实际运行环境中的显示为:[I will be out of the office][ starting 2007-8-17.] 如果在一个整句中发现“][”,则是有串联情况出现。

这句话整句翻译成中文:我从2007-8-17日起不在办公室。

Strings_OutOfOffice=我不在办公室

Strings_StartTime=从{0}.

当在资源文件中被分为两个断句分别翻译在进行组合时,翻译变为“我不在办公室从2007-8-17日”,显然,这不符合中文的翻译习惯。所以,在翻译的过程中,由于不同语言间的文化特性有很大的不同,语序经常会出现变化,只有保持句子的完整性,才能保证翻译的准确性。

小结

以上从开发和全球化测试的角度介绍了 Eclipse RCP 上的国际化,软件的本地化是一个比较复杂的工程,在开发中充分考虑对本地化的支持,使用自动化工具来进行管理会使这个工程更加更加规范有序



posted on 2009-10-27 11:03 FINDER 阅读(486) 评论(0)  编辑  收藏 所属分类: Eclipse RCP

只有注册用户登录后才能发表评论。


网站导航: