📄 cblocalization.java
字号:
package com.ca.commons.cbutil;
import java.io.File;
import java.io.FileInputStream;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;
/**
* Reads a language translation file into a hashtable.
* Figures out the name of the translation file by
* the most specific description of the Locale. For example, <br>
* [language]_[country]_[variant].properties would be loaded before:<br>
* [language]_[country].properties would be loaded before:<br>
* [language].properties<br><br>
* Use the 'get' method to return the tranlated text.
*
* @author erstr01
*/
public class CBLocalization
{
private final static Logger log = Logger.getLogger(CBLocalization.class.getName());
Locale locale = null;
MessageFormat messageFormatter = null;
Hashtable translations = null;
private boolean errorGiven = false; // This is a 'complain once' class - usually it's either working or it's not...
/*
* If the local language is english, don't print warning messages
* about missing translation files (it confuses soooo many people)
*/
private boolean english = true;
/**
* This initialises the international text class.
*
* @param locale the locale to use.
* @param path the path where the language files are stored.
*/
public CBLocalization(Locale locale, String path)
{
this.locale = locale;
translations = new Hashtable(500);
loadLanguageFile(path, locale);
if (!locale.getLanguage().equals("en"))
english = false;
messageFormatter = new MessageFormat("");
messageFormatter.setLocale(locale);
}
/**
* This attempts to get the localised version of a string.
* If anything goes wrong, it attempts to return the key
* string it was given - hence using a meaningfull key is
* a good harm minimization strategy.
*/
public String get(String key)
{
if (key == null) // sanity check that a valid key has been passed.
{
return "null key";
}
if (translations == null || translations.size() == 0) // we never opened a file...
{
if (errorGiven == false) // only print error message once! (otherwise we'd print an
{ // error for every string in the program!)
if (!english) log.warning("Unable to translate (" + key + ") - can't find language file.");
errorGiven = true;
}
return key; // try to keep on trucking using the (english) key phrase
}
try
{
String val = (String) translations.get(key); // return the translated word!
if (val == null) // this shouldn't happen, but can occur with an out-of-date (=incomplete) translation file.
{
if (!english) log.warning("Can't find translation for '" + key + "' - returning '" + key + "' unchanged.");
return key;
}
return val;
}
catch (MissingResourceException e)
{
return key; // couldn't find a translation, so return the keyword instead.
}
}
/**
* This attempts to get the localised version of a formatted string,
* inserting arguments as appropriate (see MessageFormat class
* for more details).
* If anything goes wrong, it attempts to return the key
* string it was given - hence using a meaningfull key is
* a good harm minimization strategy.
*
* @param key the format pattern; e.g. 'JXplorer has saved {0} ldif entries'.
* @param args the list of parameters to insert into the format pattern.
*/
public String get(String key, ArrayList args)
{
return get(key, args.toArray());
}
/**
* This attempts to get the localised version of a formatted string,
* inserting arguments as appropriate (see MessageFormat class
* for more details).
* If anything goes wrong, it attempts to return the key
* string it was given - hence using a meaningfull key is
* a good harm minimization strategy.
*
* @param key the format pattern; e.g. 'JXplorer has saved {0} ldif entries'.
* @param args the list of parameters to insert into the format pattern.
*/
public String get(String key, Object[] args)
{
if (key == null) // sanity check that a valid key has been passed.
{
return "null key";
}
String val = key;
if (translations == null || translations.size() == 0) // we never opened a file...
{
if (errorGiven == false) // only print error message once! (otherwise we'd print an
{ // error for every string in the program!)
if (!english) log.warning("Unable to translate (" + key + ") - can't find language file.");
errorGiven = true;
}
}
else
{
try
{
val = (String) translations.get(key); // return the translated word!
if (val == null) // this shouldn't happen, but can occur with an out-of-date (=incomplete) translation file.
{
if (!english) log.warning("Can't find translation for (" + key + ") - returning unchanged.");
val = key; // revert to english
}
}
catch (MissingResourceException e)
{
val = key; // couldn't find a translation, so return the keyword instead.
}
}
return MessageFormat.format(val, args);
}
/**
* This method searches through all the valid permutations of the language
* files that are found under the path. It choses the file which is the
* most specific for the given locale. Then it loads the data (the translation
* strings) into a local data store (Hashtable).
*
* @param path the path where the language files are stored.
* @param locale a specific locale to use.
*/
private void loadLanguageFile(String path, Locale locale)
{
Vector names = getLanguageFileNames(path, locale);
if (names == null)
{
log.warning("Names are null");
return;
}
//TE: the most specific language file is added to the Vector last, so start at the end and work backwards...
for (int i = names.size() - 1; i >= 0; i--)
{
// once a single file has been loaded, we're done...
if (loadData(new File(names.get(i).toString())) == true)
return;
}
// couldn't succesfully load anything...
log.warning("Unable to load language file '" + path + "'");
return;
}
/**
* A file might be named 'en_AU.properties'. This method tries to figure out
* from the locale what the language file names are. The least specific file
* name is added to the list first and the most specific last. For example,
* the least specific file name would be...<br><br>
* [language].properties followed by<br>
* [language]_[country].properties followed by<br>
* [language]_[country]_[variant].properties<br><br>
* This method adds the file names to the list with and without the extension '.properties'
*
* @param path the path to the language files.
* @param locale the locale.
* @return a list of possible language file names.
*/
private static Vector getLanguageFileNames(String path, Locale locale)
{
if (locale == null)
{
log.warning("Locale is null");
return null;
}
final Vector result = new Vector(8);
final String language = locale.getLanguage();
final int languageLength = language.length();
final String country = locale.getCountry();
final int countryLength = country.length();
final String variant = locale.getVariant();
final int variantLength = variant.length();
final StringBuffer temp = new StringBuffer(path);
if (languageLength + countryLength + variantLength == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -