2021SC@SDUSC山东大学软件学院软件工程应用与实践 COCOON 第六篇

2021SC@SDUSC

目录

I18nTransformer.java

1.总结

1.概述

2.信息目录

3.用法

4.站点地图配置

5.管道使用

6.i18n标记

2.属性

3.方法


I18nTransformer.java

1.总结

1.概述

i18n transformer通过在配置的目录中查找用户区域设置的翻译来工作。Locale作为参数传递给transformer,它可以由LocaleAction根据请求、会话或cookie数据确定。

然后,对于传递的本地消息,它尝试查找满足本地语言环境的消息目录,并使用它来处理i18n标记指示的文本替换。

消息目录保存在单独的文件中,命名约定与ResourceBundle类似。即basename_locale,其中basename可以是任何名称,locale可以是使用ISO 639/3166字符指定的任何语言环境(例如en_AU、de_AT、es)。

2.信息目录

目录的格式如下:

<?xml version="1.0"?>
 <!-- message catalogue file for locale ... -->
 <catalogue xml:lang="locale">
   <message key="key">text <i>or</i> markup</message>
   ....
 </catalogue>

其中key指定该语言的特定消息。

3.用法

要翻译的文件包含以下标记:

<?xml version="1.0"?>
 ... some text, translate <i18n:text>key</i18n:text>

在运行时,i18n transformer将查找用户区域设置的消息目录,并使用标记之间的值作为查找键,适当地替换<i18n:text>标记之间的文本。

如果i18n transformer无法为用户给定的语言环境找到合适的消息目录,它将递归地尝试查找父消息目录,直到找到有效的目录。即:

  • catalogue_language_country_variant.xml
  • catalogue_language_country.xml
  • catalogue_language.xml
  • catalogue.xml

这允许开发人员编写消息目录的层次结构,在每个层次上定义具有不断增加的变化深度的消息。

此外,目录可以跨多个位置拆分。例如,一个目录中可能有一个默认目录,而另一个目录中有一个用户或客户机特定目录。目录将按照指定的位置顺序进行搜索,但仍遵循上述指定的区域设置顺序。例如:假设消息的基本名称和en_AU(无变体)的区域设置以及翻译/客户端和翻译的位置,将进行以下搜索:

翻译/client/messages_en_AU.xml

翻译/消息_en_.xml

翻译/client/messages_en.xml

翻译/messages\u entransations/client/messages.xml

translations/messages.xml

i18n:text元素可以选择使用属性i18n:catalog来指示要使用的特定目录。此属性的值应该是要使用的目录的id(请参见站点地图配置)。

4.站点地图配置

 <map:transformer name="i18n"
     src="org.apache.cocoon.transformation.I18nTransformer">

     <catalogues default="someId">
       <catalogue id="someId" name="messages" [location="translations"]>
         [<location>translations/client</location>]
         [<location>translations</location>]
       </catalogue>
       ...
     </catalogues>
     <untranslated-text>untranslated</untranslated-text>
     <preload>en_US</preload>
     <preload catalogue="someId">fr_CA</preload>
 </map:transformer>

目录:定义目录的容器元素。它必须有一个属性“default”,其值是目录元素的id之一。(强制性)。

目录:指定目录。它需要两个必需的属性:id(可以是您喜欢的任何一个)和name(目录的基本名称)。位置(邮件目录的位置)也是必需的,但可以指定为属性或一个或多个子元素,但不能同时指定两者。如果指定了多个位置,则目录将按照它们在配置中出现的顺序进行搜索。名称和位置可以包含对InputModule的引用(与站点地图中其他位置的语法相同)。它们在变压器的每次使用中都会得到解决,因此它们可以参考例如请求参数。(至少需要一个目录元素)。解析输入模块引用后,位置字符串可以是URI的根。例如,使用消息名称和en_GB语言环境指定cocoon:/test的位置将导致站点地图尝试处理cocoon:/test/messages\u en_GB.xml、cocoon:/test/messages\u en.xml和cocoon:/test/messages.xml。

未翻译文本:用于未翻译键的文本(默认为输出键名)。

预加载:要预加载的目录的区域设置。将尝试解析指定区域设置的所有配置目录。如果存在可选目录属性,将仅预加载指定目录。可以指定多个预加载元素。

5.管道使用

要在管道中使用转换器,只需在特定转换中指定它,然后传递locale参数:

<map:match pattern="file">
   <map:generate src="file.xml"/>
   <map:transform type="i18n">
     <map:parameter name="locale" value="..."/>
   </map:transform>
   <map:serialize/>
 </map:match>

您可以使用LocaleAction或任何其他方式为transformer提供区域设置。

如果在某些管道中,希望使用不同的目录作为默认目录,可以通过指定名为default-catalog-id的参数来实现。

通过将未翻译文本指定为参数,还可以在管道级别覆盖该文本。

6.i18n标记

  • <i18n:date/>提供本地化日期。
  • <i18n:date-time/>提供本地化的日期和时间。
  • <i18n:time/> 给出本地时间。
  • <i18n:number/> 给出了本地化的数字。
  • <i18n:currency/>提供本地化货币。
  • <i18n:percent/> 给出本地化的百分比。

2.属性

static String	CURRENCY_LOCALE_ATTRIBUTE
         // 此属性用于指定不同的语言环境。
protected  BundleFactory	factory
         // 消息包加载器工厂组件(服务)
static String	I18N_ATTR_ATTRIBUTE
        //  此属性与任何元素(甚至不是 i18n)一起使用以转换属性值。
static String	I18N_CATALOGUE_ATTRIBUTE
        //  此属性可用于i18n:text指示应从中检索密钥的目录。
static String	I18N_CHOOSE_ELEMENT
        //  i18n:choose element 用于就地转换元素。
static String	I18N_CURRENCY_ELEMENT
        //  货币要素名称
static String	I18N_CURRENCY_NO_UNIT_ELEMENT
        //  没有单位元素名称的货币
static String	I18N_DATE_ELEMENT
       //   i18n:date 用于提供本地化的日期字符串。
static String	I18N_DATE_TIME_ELEMENT
       //   i18n:date-time 用于提供本地化的日期和时间字符串。
static String	I18N_DEFAULT_CATALOGUE_ID
       //   此配置参数指定要用作默认目录的目录的 id,允许在管道级别重新定义默认目录。
static String	I18N_EXPR_ATTRIBUTE
       //   此属性与任何元素(甚至不是 i18n)一起使用来评估属性值。
static String	I18N_FRACTION_DIGITS_ATTRIBUTE
       //  fraction-digits属性用于 i18:number指示分数后面的位数
static String	I18N_IF_ELEMENT
       //   i18n:if 用于测试语言环境。
static String	I18N_INT_CURRENCY_ELEMENT
       //   整数货币元素名称
static String	I18N_INT_CURRENCY_NO_UNIT_ELEMENT
      //    没有单位元素名称的整数货币
     // 该属性与i18n:text元素一起用于指示相应消息的键。如果此键未找到任何消息,则将使用 
     //元素的字符数据。
static String	I18N_KEY_ATTRIBUTE
       //   此属性与 i18n:text 元素一起使用以指示相应消息的键。
static String	I18N_LOCALE
       //   此配置参数指定要使用的默认语言环境。
static String	I18N_LOCALE_ATTRIBUTE
       //   此属性与日期和数字格式化元素一起使用,以指示应该用于格式化元素值的区域设置。
static String	I18N_NAMESPACE_URI
        //  i18n 的命名空间是“http://apache.org/cocoon/i18n/2.1”。
static String	I18N_NUMBER_ELEMENT
       //   i18n:number 用于提供本地化的数字字符串。
static String	I18N_OLD_NAMESPACE_URI
       //   i18n 的旧命名空间是“http://apache.org/cocoon/i18n/2.0”。
static String	I18N_OTHERWISE_ELEMENT
        //  i18n:otherwise当在i18n:choose 块内找不到匹配的语言环境时,用于匹配任何语言环境。
static String	I18N_PARAM_ELEMENT
       //   i18n:param 与 i18n:translate 一起使用以提供替换参数。
static String	I18N_PARAM_NAME_ATTRIBUTE
       //   此属性会影响可用于替换的参数名称。
static String	I18N_PATTERN_ATTRIBUTE
      //    此属性与日期和数字格式元素一起使用,以指示应用于设置元素值格式的模式。
static String	I18N_PERCENT_ELEMENT
      //    百分比元素名称
static String	I18N_PRELOAD
      //    此配置参数指定应为其预加载目录的语言环境。
static String	I18N_SRC_LOCALE_ATTRIBUTE
      //    此属性与日期和数字格式元素一起使用,以指示应用于解析元素值的区域设置。
static String	I18N_SRC_PATTERN_ATTRIBUTE
       //   此属性与日期和数字格式元素一起使用,以指示应该用于解析元素值的模式。
static String	I18N_TEXT_ELEMENT
      //    i18n:text element 用于翻译任何带有或不带有标记的文本。
static String	I18N_TIME_ELEMENT
       //   i18n:time 用于提供本地化的时间字符串。
static String	I18N_TRANSLATE_ELEMENT
        //  i18n:translate element 用于翻译带有参数替换的文本。
static String	I18N_UNTRANSLATED
       //   此配置参数指定在未翻译文本(未找到消息)的情况下应显示的消息。
static String	I18N_VALUE_ATTRIBUTE
        //  此属性与日期和数字格式化元素一起使用,以指示应解析和格式化的值。
static String	I18N_WHEN_ELEMENT
       //   i18n:when 用于测试语言环境。
protected  Locale	locale
       //   当地的
protected  ServiceManager	manager
       //   组件(服务)经理
protected  Map	objectModel

3.方法

private Attributes translateAttributes(final String element, Attributes attr)
    throws SAXException {
        if (attr == null) {
            return null;
        }

        AttributesImpl tempAttr = null;

        //将i18n:attr=“name1 name2…”中的所有属性的值作为键进行转换。
        int attrIndex = attr.getIndex(I18N_NAMESPACE_URI, I18N_ATTR_ATTRIBUTE);
        if (attrIndex == -1) {
            // 尝试旧名称空间
            attrIndex = attr.getIndex(I18N_OLD_NAMESPACE_URI, I18N_ATTR_ATTRIBUTE);
        }

        if (attrIndex != -1) {
            StringTokenizer st = new StringTokenizer(attr.getValue(attrIndex));

           //制作一份我们将要修改的副本
            tempAttr = new AttributesImpl(attr);
            // 删除I18n:AtTo属性,我们不再需要它了
            tempAttr.removeAttribute(attrIndex);

            // 遍历列出的属性并转换它们
            while (st.hasMoreElements()) {
                final String name = st.nextToken();

                int index = tempAttr.getIndex(name);
                if (index == -1) {
                    getLogger().warn("Attribute " +
                                     name + " not found in element <" + element + ">");
                    continue;
                }

                String value = translateAttribute(element, name, tempAttr.getValue(index));
                if (value != null) {
                    // 设置转换值。如果为null,则不执行任何操作。
                    tempAttr.setValue(index, value);
                }
            }

            attr = tempAttr;
        }

        // 将i18n:expr=“name1 name2…”中的所有属性的值作为键进行转换。
        attrIndex = attr.getIndex(I18N_NAMESPACE_URI, I18N_EXPR_ATTRIBUTE);
        if (attrIndex != -1) {
            StringTokenizer st = new StringTokenizer(attr.getValue(attrIndex));

            if (tempAttr == null) {
                tempAttr = new AttributesImpl(attr);
            }
            tempAttr.removeAttribute(attrIndex);

            // 遍历列出的属性并对其求值
            while (st.hasMoreElements()) {
                final String name = st.nextToken();

                int index = tempAttr.getIndex(name);
                if (index == -1) {
                    getLogger().warn("Attribute " +
                                     name + " not found in element <" + element + ">");
                    continue;
                }

                final StringBuffer translated = new StringBuffer();

                // 计算{..}表达式
                VariableExpressionTokenizer.TokenReciever tr = new VariableExpressionTokenizer.TokenReciever () {
                    private String catalogueName;

                    public void addToken(int type, String value) {
                        if (type == MODULE) {
                            this.catalogueName = value;
                        } else if (type == VARIABLE) {
                            translated.append(translateAttribute(element, name, value));
                        } else if (type == TEXT) {
                            if (this.catalogueName != null) {
                                translated.append(translateAttribute(element,
                                                                     name,
                                                                     this.catalogueName + ":" + value));
                                this.catalogueName = null;
                            } else if (value != null) {
                                translated.append(value);
                            }
                        }
                    }
                };

                try {
                    VariableExpressionTokenizer.tokenize(tempAttr.getValue(index), tr);
                } catch (PatternException e) {
                    throw new SAXException(e);
                }

                // 设置转换值。
                tempAttr.setValue(index, translated.toString());
            }

            attr = tempAttr;
        }

        // 无需翻译,只需返回即可
        return attr;
    }
void	characters(char[] ch, int start, int len)
           
 void	configure(Configuration conf)
        //  可配置接口的实现。
 void	dispose()
           
 void	endElement(String uri, String name, String raw)
           
 Serializable	getKey()
       //   CacheableProcessingComponents 的实现。
 Locale	getLocale()
       //   返回此转换器实例的当前语言环境设置。
protected  ParamSaxBuffer	getMessage(String catalogueID, String key)
        //  从字典中检索消息的辅助方法。
 SourceValidity	getValidity()
        //  CacheableProcessingComponent 的实现。
 void	recycle()
           
 void	service(ServiceManager manager)
        //  查找BundleFactory要使用的。
 void	setup(org.apache.cocoon.environment.SourceResolver resolver, Map objectModel, String source, Parameters parameters)
        //  设置变压器的当前实例。
 void	startElement(String uri, String name, String raw, Attributes attr)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值