/*
* Copyright (c) JForum Team. All rights reserved.
*
* The software in this package is published under the terms of the LGPL
* license a copy of which has been included with this distribution in the
* license.txt file.
*
* The JForum Project
* http://www.jforum.net
*/
package net.jforum.util;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import net.jforum.core.exceptions.ForumException;
import br.com.caelum.vraptor.ioc.Component;
/**
* @author Rafael Steil
* @author James Yong
*/
@Component
public class I18n {
private Map<String, Properties> messages = new HashMap<String, Properties>();
private Properties localeNames = new Properties();
private String defaultLocaleName;
private JForumConfig config;
public I18n(JForumConfig config) {
this.config = config;
this.loadConfiguration();
}
/**
* Changes the deafult language for the entire board
* @param newDefaultLanguage
*/
public void changeBoardDefaultLanguage(String newDefaultLanguage) {
if (!this.isLanguageLoaded(newDefaultLanguage)) {
this.loadLanguage(newDefaultLanguage, this.config.getValue(ConfigKeys.I18N_DEFAULT_ADMIN));
}
this.defaultLocaleName = newDefaultLanguage;
}
/**
* Loads a new Language. If <code>language</code> is either null or empty, or if it is already loaded, the
* method will return without executing any code.
* The language file will be merged with the default board language
* @param language The language to load
*/
public void load(String language) {
this.loadLanguage(language, this.defaultLocaleName);
}
/**
* Gets a I18N message.
* @param key The message name to retrieve. Must be a valid entry into the file specified by
* <code>i18n.file</code> property.
* @param language The locale name to retrieve the messages from
* @param args Parameters needed by some messages. The messages with extra parameters are formated according to
* {@link java.text.MessageFormat}specification
*
* @return String With the message
*/
public String getFormattedMessage(String key, String language, Object[] args) {
return MessageFormat.format(this.messages.get(language).getProperty(key), args);
}
/**
* @see #getMessage(String, String, Object[])
* @param key String
* @param args Object
* @return String
*/
public String getFormattedMessage(String key, Object... args) {
return this.getFormattedMessage(key, this.defaultLocaleName, args);
}
public Object[] params(Object... args) {
return args;
}
/**
* Gets an I18n message.
* @param key The message name to retrieve. Must be a valid entry into the file specified by <code>i18n.file</code> property.
* @param language The locale name to load the message from. If it is not loaded yet,
* a load operation will be automatically called. In case of failure to find the
* requested message in such locale, the default board locale will be used.
* @return String With the localized message
*/
public String getMessage(String key, String language) {
Properties p = this.messages.get(language);
if (p == null) {
this.load(language);
p = this.messages.get(language);
}
return p.getProperty(key);
}
/**
* Gets an I18n message from the default board locale.
* @param key the message key
* @return string with the localized message
*/
public String getMessage(String key) {
return this.getMessage(key, this.defaultLocaleName);
}
/**
* Check whether the language file is loaded
*
* @param language String
* @return boolean
*/
public boolean isLanguageLoaded(String language) {
return this.messages.containsKey(language);
}
/**
* Check if the given language exist.
*
* @param language The language to check
* @return <code>true</code> if the language is a valid and registered translation.
*/
public boolean languageExists(String language) {
return (this.localeNames.getProperty(language) != null);
}
/**
* Start I18n, loading the locales list and default language boards
*/
private void loadConfiguration() {
this.loadLocales();
this.defaultLocaleName = this.config.getValue(ConfigKeys.I18N_DEFAULT_ADMIN);
this.loadLanguage(defaultLocaleName, null);
String custom = this.config.getValue(ConfigKeys.I18N_DEFAULT);
if (!custom.equals(defaultLocaleName)) {
this.loadLanguage(custom, defaultLocaleName);
this.defaultLocaleName = custom;
}
}
/**
* Load all configured locale names
*/
private void loadLocales() {
try {
this.localeNames.load(this.getClass().getResourceAsStream("/jforumConfig/languages/locales.properties"));
}
catch (IOException e) {
throw new ForumException(e);
}
}
/**
* Load a language file
* @param language the language name to load
* @param mergeWith if not null, merge the language file with the language
* specified in this parameter
*/
private void loadLanguage(String language, String mergeWith) {
Properties p = new Properties();
if (mergeWith != null) {
if (!this.isLanguageLoaded(mergeWith)) {
this.loadLanguage(mergeWith, null);
}
p.putAll(this.messages.get(mergeWith));
}
try {
p.load(this.getClass().getResourceAsStream("/jforumConfig/languages/" + this.localeNames.getProperty(language)));
}
catch (IOException e) {
throw new ForumException(e);
}
this.messages.put(language, p);
}
}