/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
Cyclos 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.
Cyclos 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 Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package nl.strohalm.cyclos.utils;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.lang.StringUtils;
/**
* Helper class for java.util.Properties
* @author luis
*/
public class PropertiesHelper {
private static class PropertiesResourceBundle extends ResourceBundle {
private Map<String, String> properties;
@SuppressWarnings({ "unchecked", "rawtypes" })
private PropertiesResourceBundle(final Properties properties, final PropertiesResourceBundle parent) {
this.properties = (Map) properties;
if (parent != null) {
setParent(parent);
}
}
@Override
@SuppressWarnings("unchecked")
public Enumeration<String> getKeys() {
return IteratorUtils.asEnumeration(properties.keySet().iterator());
}
@Override
protected Object handleGetObject(final String key) {
final String value = properties.get(key);
return StringUtils.trimToNull(value);
}
}
/**
* Loads a property file from a base name, like "package.File", which would be translated into a classpath resource "package/File.properties".
* Returns null if no such file exists
*/
public static Properties loadFromResource(final String baseName) {
final String path = baseName.replace('.', '/');
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final InputStream in = loader.getResourceAsStream(path + ".properties");
if (in == null) {
return null;
}
return loadFromStream(in);
}
/**
* Loads the properties from the input stream using the UTF-8 charset. Since the option to load properties using a specified charset is only
* available in java 6+, running on older versions will result in ignoring the charset. For that reason, it is recommended that the resource
* bundle itself be encoded using ascii in production
*/
public static Properties loadFromStream(final InputStream in) {
final Properties properties = new Properties();
try {
try {
// The Properties.load(Reader) only exists on Java 6
final Reader reader = new InputStreamReader(in, "UTF-8");
MethodUtils.invokeMethod(properties, "load", reader);
} catch (final NoSuchMethodException e) {
// Fallback to Properties.load(InputStream)
properties.load(in);
}
} catch (final Exception e) {
throw new IllegalStateException("Error reading resource bundle", e);
}
return properties;
}
public static void main(final String[] args) {
final ResourceBundle bundle = readBundle("nl.strohalm.cyclos.setup.CyclosSetup", new Locale("pt", "BR", "RS"));
System.out.println(bundle);
}
/**
* Reads a resource bundle from a properties file encoded as utf-8
*/
public static ResourceBundle readBundle(final String baseName, Locale locale) {
if (locale == null) {
locale = Locale.getDefault();
}
final List<String> suffixes = new ArrayList<String>();
if (locale != null) {
suffixes.add("");
if (StringUtils.isNotEmpty(locale.getLanguage())) {
suffixes.add("_" + locale.getLanguage());
}
if (StringUtils.isNotEmpty(locale.getCountry()) && StringUtils.isNotEmpty(locale.getLanguage())) {
suffixes.add("_" + locale.getLanguage() + "_" + locale.getCountry());
}
if (StringUtils.isNotEmpty(locale.getVariant()) && StringUtils.isNotEmpty(locale.getCountry()) && StringUtils.isNotEmpty(locale.getLanguage())) {
suffixes.add("_" + locale.getLanguage() + "_" + locale.getCountry() + "_" + locale.getVariant());
}
}
PropertiesResourceBundle bundle = null;
for (final String suffix : suffixes) {
final Properties properties = loadFromResource(baseName + suffix);
if (properties != null) {
final PropertiesResourceBundle current = new PropertiesResourceBundle(properties, bundle);
bundle = current;
}
}
if (bundle == null) {
throw new IllegalArgumentException("Error loading properties resource bundle for baseName=" + baseName + " and locale=" + locale);
}
return bundle;
}
}