繁体   English   中英

没有 RessourceBundle 的 Java i18n

[英]Java i18n without RessourceBundle

我正在尝试从我的BuildPath获取i18n属性文件。 如果您尝试获取PropertiesFile ResourceBundle.getBundle将抛出java.util.MissingResourceException 有没有一种方法可以从BuildPath外部加载i18n文件,但仍然可以BuildPath检测您的语言环境?

编辑:

这是我在Paweł Dyda的帮助下能够创建的解决方案。 也许有人会需要它。 可能会有一些改进,但它有效;)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle.Control;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;

public class GlobalConfigurationProvider {

    Logger logger = Logger.getLogger(GlobalConfigurationProvider.class);

    private static GlobalConfigurationProvider instance;

    PropertiesConfiguration i18n;


    private GlobalConfigurationProvider() {
        String path = GlobalConfigurationProvider.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        String decodedPath = "";
        try {
            decodedPath = URLDecoder.decode(path, "UTF-8");
            // This ugly thing is needed to get the correct
            // Path
            File f = new File(decodedPath);
            f = f.getParentFile().getParentFile();
            decodedPath = f.getAbsolutePath();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            this.logger.error("Failed to decode the Jar path", e);
        }
        this.logger.debug("The Path of the jar is: " + decodedPath);

        String configFolder = FilenameUtils.concat(decodedPath, "cfg");
        String i18nFolder = FilenameUtils.concat(configFolder, "i18n");
        File i18nFile = null;
        try {
            i18nFile = this.getFileForLocation(new File(i18nFolder), Locale.getDefault());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            this.logger.error("Can't find the LocaleFile", e);
        }
        if (!i18nFile.exists()) {
            // If this can't be found something is wrong
            i18nFile = new File(i18nFolder, "eng.i18n");
            if (!i18nFile.exists()) {
                this.logger.error("Can't find the i18n File at the Location: " + i18nFile.getAbsolutePath());
            }
        }

        this.logger.debug("The Path to the i18n File is: " + i18nFile);

        try {
            this.i18n = new PropertiesConfiguration(i18nFile);
        } catch (ConfigurationException e) {
            this.logger.error("Couldn't Initialize the i18nPropertiesFile", e);
        }
    }

    private File getFileForLocation(File i18nFolder, Locale locale) throws FileNotFoundException {
        Control control = Control.getControl(Control.FORMAT_DEFAULT);
        List<Locale> locales = control.getCandidateLocales(this.getBaseName(), locale);
        File f = null;
        for (Locale l : locales) {
            String i18nBundleName = control.toBundleName(this.getBaseName(), l);
            String i18nFileName = control.toResourceName(i18nBundleName, "properties");
            f = new File(i18nFolder, i18nFileName);
            this.logger.debug("Looking for the i18n File at: " + f);
            if (f.exists()) {
                return f;
            }
        }
        // Last try for a File that should exist
        if (!locale.equals(Locale.US)) {
            return this.getFileForLocation(i18nFolder, Locale.US);
        }
        throw new FileNotFoundException("Can't find any i18n Files in the Folder " + i18nFolder.getAbsolutePath());
    }

    private String getBaseName() {
        // TODO: Get this from the Settings later
        return "messages";
    }

    public static GlobalConfigurationProvider getInstance() {
        if (GlobalConfigurationProvider.instance == null) {
            GlobalConfigurationProvider.instance = new GlobalConfigurationProvider();
        }
        return GlobalConfigurationProvider.instance;
    }

    public String getI18nString(String key) {
        try {
            return this.i18n.getString(key);
        } catch (MissingResourceException e) {
            return '!' + key + '!';
        }
    }

}

当然,有一些方法可以做到这一点。 无论如何,我相信您的问题是您尝试加载的资源的错误路径。

尽管如此,您肯定正在寻找使用区域设置回退机制来加载非常具体的资源的方法。 可以办到。 您可能想看看ResourceBundle.Control类。 例如,您可以获得后备语言环境列表:

Control control = Control.getControl(Control.FORMAT_DEFAULT);
List<Locale> locales = control.getCandidateLocales("messages",
           Locale.forLanguageTag("zh-TW"));

从那里,您实际上可以创建您要查找的资源文件的名称:

for (Locale locale : locales) {
      String bundleName = control.toBundleName("messages", locale);
      String resourceName = control.toResourceName(bundleName, "properties");
      // break if resource under given name exist
}

然后,您需要以某种方式加载资源 - 您可能希望使用ClassLoader 的getResourceAsStream(String)为您打开InputStream 最后一步实际上可以使用流作为PropertyResourceBundle的输入:

ResourceBundle bundle = new PropertyResourceBundle(inputStream);

您也可以传递Reader而不是InputStream ,这至少有一个优势 - 您实际上可以允许属性文件以 UTF-8 编码,而不是常规的 ISO8859-1。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM