/**
*
*/
package net.frontlinesms.resources;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
/**
* @author aga
*/
public class FilePropertySet extends BasePropertySet {
/** The file the properties are loaded from and saved to. */
private File file;
/**
* Create a new instance of this class pointing to the supplied file.
* @param file
*/
protected FilePropertySet(File file) {
this.file = file;
}
//> INSTANCE METHODS
/**
* Save this {@link UserHomeFilePropertySet} to disk.
* @return <code>true</code> if the properties file was successfully saved; <code>false</code> otherwise.
*/
public synchronized boolean saveToDisk() {
LOG.trace("ENTER");
File propFile = this.file;
BufferedWriter out = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(propFile);
out = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
for(String propertyKey : this.getProperties().keySet()) {
out.write(propertyKey + "=" + this.getProperties().get(propertyKey) + "\n");
}
out.flush();
LOG.trace("EXIT");
return true;
} catch(IOException ex) {
LOG.debug("Exception thrown while saving properties file: " + propFile.getAbsolutePath(), ex);
LOG.trace("EXIT");
return false;
} finally {
if(fos != null) { try { fos.close(); } catch(IOException ex) {} }
if(out != null) { try { out.close(); } catch(IOException ex) {} }
}
}
//> ACCESSOR METHODS
/**
* Set a property in this property set.
* @param propertyName
* @param value
*/
protected synchronized void setProperty(String propertyName, String value) {
this.getProperties().put(propertyName, value);
}
/**
* Gets the {@link String} value of a property.
* @param propertyName
* @return The value of the property as a {@link String} or <code>null</code> if it is not set.
*/
protected synchronized String getProperty(String propertyName) {
return this.getProperties().get(propertyName);
}
/**
* Gets the <code>boolean</code> value of a property.
* @param propertyName the name of the property
* @param defaultValue the default value for the property, returned if the property is not set
* @return The value of the property or <code>defaultValue</code> if it is not set.
*/
protected boolean getPropertyAsBoolean(String propertyName, boolean defaultValue) {
String value = getProperty(propertyName);
if (value == null) return defaultValue;
else return Boolean.parseBoolean(value);
}
/**
* Sets the {@link Boolean} value of a property.
* @param propertyName
* @param value
*/
protected void setPropertyAsBoolean(String propertyName, Boolean value) {
if(value == null) setProperty(propertyName, null);
else setProperty(propertyName, Boolean.toString(value));
}
/**
* Gets the <code>int</code> value of a property.
* @param propertyName the name of the property
* @param defaultValue the default value for the property
* @return The value of the property, or <code>defaultValue</code> if it is not set.
*/
protected int getPropertyAsInt(String propertyName, int defaultValue) {
String value = getProperty(propertyName);
try {
return Integer.parseInt(value);
} catch(NumberFormatException ex) {
return defaultValue;
}
}
protected String[] getPropertyValues(String propertyName, String... defaultValues) {
LinkedList<String> values = new LinkedList<String>();
for(int i=0; i>=0; ++i) {
String val = getProperty(propertyName + "." + i);
if(val == null) break;
else values.add(val);
}
if(values.isEmpty()) {
return defaultValues;
} else {
return values.toArray(new String[0]);
}
}
/** Sets the {@link Integer} value of a property. */
protected void setPropertyAsInteger(String propertyName, Integer value) {
if(value == null) setProperty(propertyName, null);
else setProperty(propertyName, Integer.toString(value));
}
/** @return the property keys in {@link #properties} */
protected Set<String> getPropertyKeys() {
return this.getProperties().keySet();
}
/** @return {@link #file} */
protected File getFile() {
return file;
}
/** @return {@link BasePropertySet#getProperties()} */
public Map<String, String> getProperties() {
return super.getProperties();
}
//> GETTERS WITH DEFAULT VALUES
/**
* Gets the {@link String} value of a property. If no value is set, the default value is set and then returned.
* @param propertyName The name of this property
* @param defaultValue The value to use for this property if none is yet set
* @return The value to be used for this property
*/
protected synchronized String getProperty(String propertyName, String defaultValue) {
if(!this.getProperties().containsKey(propertyName)) {
this.getProperties().put(propertyName, defaultValue);
}
return this.getProperties().get(propertyName);
}
//> STATIC FACTORIES
public static FilePropertySet load(String filePath) {
File file = new File(filePath);
return load(file);
}
public static FilePropertySet load(File file) {
FilePropertySet properties = new FilePropertySet(file);
properties.setProperties(loadPropertyMap(file));
return properties;
}
/**
* Loads a {@link UserHomeFilePropertySet} from the supplied file
* @param propFile The file to load the {@link UserHomeFilePropertySet} from
* @return new map of properties loaded from the requested file, or an empty map if no properties could be loaded.
*/
protected static HashMap<String, String> loadPropertyMap(File propFile) {
HashMap<String, String> properties = new HashMap<String, String>();
loadPropertyMap(properties, propFile);
return properties;
}
/**
* Loads a {@link UserHomeFilePropertySet} from the supplied file
* @param propFile The file to load the {@link UserHomeFilePropertySet} from
* @return new map of properties loaded from the requested file, or an empty map if no properties could be loaded.
*/
protected static void loadPropertyMap(Map<String, String> map, File propFile) {
LOG.debug("File [" + propFile.getAbsolutePath() + "]");
FileInputStream fis = null;
BufferedReader in = null;
try {
fis = new FileInputStream(propFile);
BasePropertySet.load(map, fis);
} catch(FileNotFoundException ex) {
LOG.debug("Properties file not found [" + propFile.getAbsolutePath() + "]", ex);
} catch(IOException ex) {
LOG.debug("Exception thrown while loading properties file:" + propFile.getAbsolutePath(), ex);
} finally {
// Close all streams
if(fis != null) try { fis.close(); } catch(Exception ex) {
// nothing we can do except log the exception
LOG.warn("Exception thrown while closing stream 'fis'.", ex);
}
if(in != null) try { in.close(); } catch(IOException ex) {
// nothing we can do except log the exception
LOG.warn("Exception thrown while closing stream 'fis'.", ex);
}
}
LOG.trace("EXIT");
}
}