package org.sigmah.server.i18n;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program 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 3 of the
* License, or (at your option) any later version.
*
* This program 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.sigmah.server.conf.Properties;
import org.sigmah.server.conf.ReloadableProperties;
import org.sigmah.server.util.Languages;
import org.sigmah.shared.Language;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Implementation for {@link I18nServer}
*
* @author Maxime Lombard (mlombard@ideia.fr)
* @author Denis Colliot (dcolliot@ideia.fr)
*/
public class I18nServerImpl implements I18nServer {
/**
* Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(ReloadableProperties.class);
/**
* Properties files extension.
*/
private static final String PROPERTIES_FILE_EXTENSION = ".properties";
/**
* <p>
* i18n files encoding charset.
* </p>
* See {@code http://www.gwtproject.org/doc/latest/DevGuideI18n.html#DevGuidePropertiesFiles}.
*/
private static final Charset I18N_FILE_ENCODING = StandardCharsets.UTF_8;
/**
* The start tag for I18N message property parameter.
*/
private static final String PARAM_TAG_START = "{";
/**
* The end tag for I18N message property parameter.
*/
private static final String PARAM_TAG_END = "}";
/**
* The list of the properties file to load.
*/
private static final List<String> propertiesFiles = new ArrayList<String>();
/**
* Properties map: one {@code java.util.Properties} for each language.
*/
private static final Map<Language, java.util.Properties> propertiesMap = new EnumMap<Language, java.util.Properties>(Language.class);
public I18nServerImpl() {
// Initialize the properties files list.
propertiesFiles.add("org/sigmah/client/i18n/UIConstants");
propertiesFiles.add("org/sigmah/client/i18n/UIMessages");
propertiesFiles.add("org/sigmah/server/mail/model/MailModels");
}
/**
* {@inheritDoc}
*/
@Override
public String t(final Language language, final String key) {
return t(language, key, (Object[]) null);
}
/**
* {@inheritDoc}
*/
@Override
public String t(final Language language, final String key, final Object... parameters) {
if (StringUtils.isBlank(key)) {
return null;
}
// Loading the properties files for the language if necessary
ensurePropertiesLoaded(language);
String propertyValue = propertiesMap.get(Languages.notNull(language)).getProperty(key);
if(propertyValue == null) {
ensurePropertiesLoaded(Languages.DEFAULT_LANGUAGE);
propertyValue = propertiesMap.get(Languages.DEFAULT_LANGUAGE).getProperty(key);
}
if (propertyValue != null && ArrayUtils.isNotEmpty(parameters)) {
return buildMessage(propertyValue, parameters);
} else {
return propertyValue;
}
}
/**
* Load the properties for the given language if not loaded yet.
*
* @param language Language to load.
*/
private static void ensurePropertiesLoaded(Language language) {
if (propertiesMap.get(Languages.notNull(language)) == null) {
try {
loadProperties(Languages.notNull(language));
} catch (final IOException e) {
// If the properties files cannot be loaded properly, returning null value
}
}
}
/**
* Load the properties files for a given {@code language} code.
*
* @param language
* The language.
* @throws IOException
* If an error occurs while loading the properties files.
*/
private static void loadProperties(final Language language) throws IOException {
final java.util.Properties properties = new java.util.Properties();
// Read properties from the properties files.
for (final String file : propertiesFiles) {
// Determining the properties filename using the language code.
final String fullFilename = file + Languages.getFileSuffix(language, PROPERTIES_FILE_EXTENSION);
try {
if (LOG.isInfoEnabled()) {
LOG.info("Loading properties from file '{}'.", fullFilename);
}
// Loading the properties file.
properties.load(new InputStreamReader(Properties.class.getClassLoader().getResourceAsStream(fullFilename), I18N_FILE_ENCODING));
} catch (final IOException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Properties loading failure with file '" + fullFilename + "'.", e);
}
throw e;
}
}
propertiesMap.put(language, properties);
}
/**
* Builds the property value's message from given parameters.
*
* @param propertyValue
* The value issued of a message property key.
* @param params
* The parameters object values that are supposed to fit the message content.
* @return The built message.
*/
private static String buildMessage(String propertyValue, final Object... params) {
propertyValue = propertyValue.replaceAll(Pattern.quote("''"), "'");
if (params != null) {
for (int index = 0; index < params.length; index++) {
propertyValue = propertyValue.replace(PARAM_TAG_START + index + PARAM_TAG_END, String.valueOf(params[index]));
}
}
return propertyValue;
}
}