package info.ephyra.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Properties class the way it was meant to be; Generics and property filtering
* and manipulation based on the conventional dot-separator property name
* syntax.
*
* @author Andy Schlaikjer, Nico Schlaefer
* @version 2008-02-10
*/
public class Properties extends HashMap<String,String>
{
private static final long serialVersionUID = 1L;
public Properties() {
super();
}
public Properties(Properties properties) {
super(properties);
}
public String getProperty(String name) {
return get(name)!=null?get(name).trim():null;
}
public void setProperty(String name, String value) {
put(name, value);
}
public String getProperty(String name, String defaultValue) {
String value = get(name);
if (value == null)
return defaultValue;
return value;
}
public Set<String> getPropertyNames() {
return keySet();
}
/**
* @see java.util.Properties#load(InputStream)
* @param is
* @throws IOException
*/
public void load(InputStream is) throws IOException {
java.util.Properties properties = new java.util.Properties();
properties.load(is);
for (Map.Entry entry : properties.entrySet())
put((String) entry.getKey(), (String) entry.getValue());
}
/**
* @see java.util.Properties#loadFromXML(InputStream)
* @param is
* @throws IOException
*/
public void loadFromXML(InputStream is) throws IOException {
java.util.Properties properties = new java.util.Properties();
properties.loadFromXML(is);
for (Map.Entry entry : properties.entrySet())
put((String) entry.getKey(), (String) entry.getValue());
}
/**
* Filters the entries in this Properties object and returns a new object
* containing only those entries whose keys match the given string prefix.
* Optionally, you may have the prefix removed from the keys in the returned
* Properties object.
*
* @param prefix the prefix string to use as a filter on existing entry keys
* @param remove_prefix if true, strips the prefix off of all key values in
* the returned Properties object
* @return a new Properties object containing only those entries from this
* Properties object whose keys match the given prefix
*/
public Properties filterProperties(String prefix, boolean remove_prefix) {
Properties properties = new Properties();
for (Map.Entry<String,String> property : entrySet()) {
String key = property.getKey();
if (key.startsWith(prefix)) {
if (remove_prefix)
key = key.substring(prefix.length());
properties.put(key, property.getValue());
}
}
return properties;
}
/**
* For each key in this Properties object a prefix string is created from
* all leading characters before the first '.' (period) character. This
* prefix string is used as a new key which will reference a new Properties
* object containing the original key stripped of the prefix and the
* original value. For example, if this Properties object contains the
* following entries:
*
* <pre>
* one = yes
* one.a = 1
* one.b = 2
* two.a = 3
* two.b = 4
* </pre>
*
* then the returned Map<String,Properties> would look like this (Perl
* notation):
*
* <pre>
* {
* one => {
* a => '1',
* b => '2'
* },
* two => {
* a => '3',
* b => '4'
* }
* }
* </pre>
*/
public Map<String,Properties> mapProperties() {
Map<String,Properties> properties_map = new HashMap<String,Properties>();
for (Map.Entry<String, String> property: entrySet()) {
String key = property.getKey();
int i = key.indexOf('.');
if (i == -1) {
Properties properties = properties_map.get(key);
if (properties == null) {
properties = new Properties();
properties_map.put(key, properties);
}
properties.put(key, property.getValue());
continue;
}
String name = key.substring(0, i);
String property_name = key.substring(i+1);
Properties properties = properties_map.get(name);
if (properties == null) {
properties = new Properties();
properties_map.put(name, properties);
}
properties.put(property_name, property.getValue());
}
return properties_map;
}
/**
* @return a java.util.Properties object containing equivalent key-value
* entries
*/
public java.util.Properties toJavaProperties() {
java.util.Properties properties = new java.util.Properties();
properties.putAll(this);
return properties;
}
/**
* Loads properties from a file given a class name.
*
* Sample usage:
* <code>
* Properties p =
* Properties.loadPropertiesFromClassName(getClass().getName());
* </code>
*
* @return a Properties object containing the content of the properties file
*/
public static Properties loadFromClassName(String className) {
Properties p = new Properties();
File userProperties;
String conf_dir = "conf";
try {
userProperties = new File(conf_dir, className + ".properties");
if (!userProperties.exists()) {
// if properties file not in conf_dir then search classpath
URL url = (new Properties()).getClass().getClassLoader()
.getResource(className + ".properties");
if (url != null) userProperties = new File(url.getFile());
}
if (!userProperties.exists())
throw new IOException("Missing properties file for " +
className + "\n" + "Make sure that " + className +
".properties" + " is in the folder \"" + conf_dir +
"\" or on the classpath.");
p.load(new FileInputStream(userProperties));
} catch (Exception e) {
System.err.println("Caught exception while loading properties: "
+ e.getMessage());
}
return p;
}
}