I want to create a class that wraps Properties and specifically hides the file I/O operations. I have come up with the abridged code below. This is intended to read the properties from a file at a fixed location outside of the class path. It also has a method to write the properties to the same file.
//
/* Defines key properties of the iFlag application.
* Methods read and write properties.
*/
public class ClientProperties {
private Properties props;
private static String xPanelSizeStg = "32";
private static int xPanelSize = 32;
private static String configFilename = "/home/myname/config/client_config.properties";
public ClientProperties() {
props = new Properties();
}
/**
* Reads properties from file
* Reads the current properties object from file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public Properties readPropertiesFromFile( ){
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream( configFilename );
//load a properties file from class path, inside static method
props.load(input);
//get the property values and save
xPanelSizeStg = props.getProperty("xPanelsize","32");
yPanelSizeStg = props.getProperty("yPanelsize", "32");
}
catch (IOException ex) {
logger.error("Could not open config file" + configFilename,ex );
}
finally{
if(input!=null){
try {
input.close();
}
catch (IOException e) {
logger.error( "Could not close config file" + configFilename,e );
}
}
}
return props;
}
/**
* Writes properties to file
* Writes the current properties object to file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public void writePropertiesToFile() {
//saves the current properties to file. Overwrites the existing properties.
Properties props = new Properties(); //a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
System.out.println("Panel size x = " + xPanelSizeStg );
try {
outStrm = new FileOutputStream( configFilename );
// set the properties values
props.setProperty("xPanelsize", xPanelSizeStg);
props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error( "The file :{0} could not be opened", configFilename,io);
} finally {
if (outStrm!= null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
}
The read and write methods work. What doesn't work is trying to change the value of a property, and then save it. The demo code below successfully reads the properties file and displays the correct value for XPanelsize. I then change that value and attempt to write the properties to a file. The new value 64 for xPanelsize is not written to the file.
public static void main(String[] args) {
Properties props;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String txt = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + txt );
p.setProperty("xPanelsize","64"); //method not found error
p.writePropertiesToFile();
So I would like to be able to use the Property.setProperty() method to set the value of a property. When I do that, the changed property is not written to the file. I can see that is because I have more than 1 Property instance and one is not visible to the other. I think I need to extend the built-in Properties class to achieve what I want to do, but I am not sure how to make it all work.
I have found plenty of examples of using Properties on the internet. What I haven't found are any examples that hide the related file I/O in a class. How would I do that??
You should probably need to create a getter for your 'props' object.
public Properties getProps()
{
return props;
}
And you will be able to invoke it like this:
p.getProps().setProperty("key", "value");
Or, if you are planning to make your ClientProperties class a children of Properties class, then you will need to use 'extends' and you would be able to invoke it by using
p.setProperty("key", "value");
And in this case you wouldn't need any Properties object in your class' fields.