gettextmodule.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 545 行

JAVA
545
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Nam Nguyen */package com.caucho.quercus.lib.gettext;import com.caucho.quercus.QuercusModuleException;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.env.*;import com.caucho.quercus.lib.string.StringModule;import com.caucho.quercus.module.AbstractQuercusModule;import com.caucho.util.L10N;import com.caucho.util.LruCache;import com.caucho.vfs.Path;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.HashMap;import java.util.Locale;import java.util.logging.Logger;/** * Module to find translated strings and return them in desired charset. * Translations are LRU cached. */public class GettextModule  extends AbstractQuercusModule{  private LruCache<Object,GettextResource> _cache    = new LruCache<Object,GettextResource>(16);  private final Logger log    = Logger.getLogger(GettextModule.class.getName());  private final L10N L = new L10N(GettextModule.class);  public String []getLoadedExtensions()  {    return new String[] { "gettext" };  }  /**   * Sets charset of translated strings that are returned from this domain.   *   * @param env   * @param domain   * @param codeset   * @return codeset   */  public String bind_textdomain_codeset(Env env,                                             String domainName,                                             String charset)  {    getDomain(env, domainName).setCharset(charset);        return charset;  }  /**   * Changes root directory of domain.   *   * @param env   * @param domain   * @param directory   * @return directory   */  public Value bindtextdomain(Env env,                              String domainName,                              StringValue directory)  {    GettextDomain domain = getDomain(env, domainName);        domain.setPath(env, directory);        if (domain.getPath() == null)      return BooleanValue.FALSE;    else      return directory;  }  /**   * Same as gettext, but allows overriding of domain and category.   *   * @param env   * @param domain   * @param message   * @param category   */  public StringValue dcgettext(Env env,                              String domainName,                              StringValue message,                              int category,                              Value args[])  {    return translate(env,                     getDomain(env, domainName),                     getCategory(env, category),                     message,                     args);  }  /**   * Same as ngettext, but allows overriding of domain and category.   *   * @param env   * @param domain   * @param msgid1   * @param msgid2   * @param n   * @param category   */  public StringValue dcngettext(Env env,                                String domainName,                                StringValue msgid1,                                StringValue msgid2,                                int n,                                int category,                                Value args[])  {    return translate(env,                     getDomain(env, domainName),                     getCategory(env, category),                     msgid1,                     msgid2,                     n,                     args);  }  /**   * Same as gettext, but allows overriding of current domain.   *   * @param env   * @param domain   * @param message   */  public StringValue dgettext(Env env,                              String domainName,                              StringValue message,                              Value args[])  {    return translate(env,                     getDomain(env, domainName),                     "LC_MESSAGES",                     message,                     args);  }  /**   * Same as ngettext, but allows overriding of current domain.   *   * @param env   * @param domain   * @param msgid1   * @param msgid2   * @param n   */  public StringValue dngettext(Env env,                               String domainName,                               StringValue msgid1,                               StringValue msgid2,                               int n,                               Value args[])  {    return translate(env,                     getDomain(env, domainName),                     "LC_MESSAGES",                     msgid1,                     msgid2,                     n,                     args);  }  /**   * Alias of gettext().   *   * @param env   * @param message   */  public StringValue _(Env env, StringValue message, Value []args)  {    return gettext(env, message, args);  }  /**   * Returns translated string from current domain and default category.   *   * @param env   * @param message   */  public StringValue gettext(Env env, StringValue message, Value []args)  {    return translate(env,                     getCurrentDomain(env),                     "LC_MESSAGES",                     message,                     args);  }  /**   * Returns translated plural string form from current domain and default   * category.   *   * @param env   * @param msgid1   * @param msgid2   * @param n   * @return translated string, or original plural string if n == 1,   *     else return original singular string   */  public StringValue ngettext(Env env,                              StringValue msgid1,                              StringValue msgid2,                              int n,                              Value args[])  {    return translate(env,                     getCurrentDomain(env),                     "LC_MESSAGES",                     msgid1,                     msgid2,                     n,                     args);  }  /**   * Changes the current domain.   *   * @param env   * @param domain   * @return name of current domain after change.   */  public String textdomain(Env env,                                @Optional Value domain)  {    if (! domain.isNull()) {      String name = domain.toString();            setCurrentDomain(env, name);            return name;    }        return getCurrentDomain(env).getName();  }  /**   * Retrieves the translation for message.   *    * @param env   * @param domain   * @param category   * @param message   *   * @return translation found, else message   */  private StringValue translate(Env env,                                GettextDomain domain,                                CharSequence category,                                StringValue message,                                Value []args)  {    Locale locale = env.getLocaleInfo().getMessages().getLocale();    GettextResource resource = getResource(env,                                           domain.getPath(),                                           locale,                                           category,                                           domain.getName());    StringValue unicodeTranslation = resource.getTranslation(message);    if (unicodeTranslation == null)      unicodeTranslation = message;    StringValue translation      = message.create(env, unicodeTranslation, domain.getCharset());        return format(env, translation, args);  }  /**   * Retrieves the plural translation for msgid1.   *    * @param env   * @param domain   * @param category   * @param msgid1   * @param msgid2   *   * @return translation found, else msgid1 if n == 1, else msgid2   */  private StringValue translate(Env env,                                GettextDomain domain,                                CharSequence category,                                StringValue msgid1,                                StringValue msgid2,                                int quantity,                                Value []args)  {    Locale locale = env.getLocaleInfo().getMessages().getLocale();    GettextResource resource = getResource(env,                                           domain.getPath(),                                           locale,                                           category,                                           domain.getName());    StringValue unicodeTranslation      = resource.getTranslation(msgid1, quantity);    if (unicodeTranslation == null)      unicodeTranslation = errorReturn(msgid1, msgid2, quantity);    StringValue translation = msgid1.create(env, unicodeTranslation, domain.getCharset());        return format(env, translation, args);  }  private GettextResource getResource(Env env,                              Path path,                              Locale locale,                              CharSequence category,                              String domain)  {    ArrayList<Object> key = new ArrayList<Object>();    key.add(path.getFullPath());    key.add(locale);    key.add(category);    key.add(domain);    GettextResource resource = _cache.get(key);    if (resource == null) {      resource = new GettextResource(env, path, locale, category, domain);      _cache.put(key, resource);    }    return resource;  }  private GettextDomainMap getDomains(Env env)  {    Object val = env.getSpecialValue("caucho.gettext_domains");    if (val == null) {      val = new GettextDomainMap();      env.setSpecialValue("caucho.gettext_domains", val);    }        return (GettextDomainMap) val;  }    private GettextDomain getDomain(Env env, String name)  {    return getDomains(env).getDomain(env, name);  }    private GettextDomain getCurrentDomain(Env env)  {    return getDomains(env).getCurrent(env);  }  private void setCurrentDomain(Env env, String name)  {    getDomains(env).setCurrent(name);  }  /**   * Gets the name for this category.   */  private String getCategory(Env env, int category)  {    switch (category) {      case StringModule.LC_MESSAGES:        return "LC_MESSAGES";      case StringModule.LC_ALL:        return "LC_ALL";      case StringModule.LC_CTYPE:        return "LC_CTYPE";      case StringModule.LC_NUMERIC:        return "LC_NUMERIC";      case StringModule.LC_TIME:        return "LC_TIME";      case StringModule.LC_COLLATE:        return "LC_COLLATE";      case StringModule.LC_MONETARY:        return "LC_MONETARY";      default:        env.warning(L.l("Invalid category. Please use named constants"));        return "LC_MESSAGES";    }  }  private static StringValue errorReturn(StringValue msgid1,                              StringValue msgid2,                              int n)  {    if (n == 1)      return msgid1;    else      return msgid2;  }  private static StringValue format(Env env,                              StringValue msg,                              Value []args)  {    if (args.length == 0)      return msg;        StringValue sb;        if (msg.isUnicode())      sb = env.createUnicodeBuilder();    else      sb = env.createBinaryBuilder();        return formatImpl(env, msg, args, sb);  }  /*  private static StringValue formatBinary(Env env,					  StringValue msg,					  Value []args,					  String charset)  {    StringValue sb = env.createBinaryBuilder();    byte []bytes = null;        try {      bytes = msg.toString().getBytes(charset);    }    catch (UnsupportedEncodingException e) {      throw new QuercusModuleException(e);    }        int i = 0;    int len = bytes.length;            while (i < len) {      byte ch = bytes[i];      if (ch != '[' || i + 4 > len) {        sb.appendByte(ch);        i++;      }      else if (bytes[i + 1] != '_') {        sb.appendByte('[');        i++;      }      else if (bytes[i + 3] != ']') {        sb.appendByte('[');        sb.appendByte('_');        i += 2;      }      else {        ch = bytes[i + 2];        int argIndex = ch - '0';        if (0 <= argIndex && argIndex < args.length) {          sb.append(args[argIndex]);          i += 4;        }        else {          sb.appendByte('[');          i++;        }      }    }    return sb;  }  */  private static StringValue formatImpl(Env env,                                        StringValue msg,                                        Value []args,                                        StringValue sb)  {    int i = 0;    int length = msg.length();    while (i < length) {      char ch = msg.charAt(i);      if (ch != '[' || i + 4 > length) {        sb.append(ch);        i++;      }      else if (msg.charAt(i + 1) != '_') {        sb.append(ch);        i++;      }      else if (msg.charAt(i + 3) != ']') {        sb.append(ch);        i++;      }      else {        ch = msg.charAt(i + 2);        int argIndex = ch - '0';        if (0 <= argIndex && argIndex < args.length) {          sb.append(args[argIndex]);          i += 4;        }        else {          sb.append('[');          i++;        }      }    }        return sb;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?