Code I/O

A topnotch WordPress.com site

5 Minutes on Java – A template implementation for configuration files

Leave a comment

Loading properties or configurations for applications is a common task.  The process is generic and repeatable.  The following template implementation should provide an easy way to extend it based on application needs.

The design:

  • Template class: implements the algorithm and automates the process of initialising and loading/saving configuration files.
  • Implementation classes
  • A factory approach to consume all the implementations.

An Implementation

 public class Test{
 public static void main(String[] args) {
 PropertyFilesFactory.init();
 Properties properties = PropertyFilesFactory.getProperties("db");
 System.out.println("Testing: " + properties.getProperty("DB_MAX_CONNECTIONS"));
 }
 public class PropertyFilesFactory {

private static HashMap props = new HashMap();

public static void init(){

if(props.size() == 0){

// Create Configuration
 props.put("app", new AppPropertiesFileLoader());
 props.put("log", new LoggerPropertiesFileLoader());
 props.put("db" new IMDBPropertiesFileLoader());

// initialize configuration
 for(PropertiesFileTypes key : props.keySet()){
 props.get(key).init();

}

// post initialization
 for(PropertiesFileTypes key : props.keySet()){

props.get(key).postinit();

}

}

private static PropertiesFileLoader getConfig(String ct)

return props.get(ct);

}

public static Properties getProperties(String ct){

if(ct == null) return null;
 else return getConfig(ct).getProperties();

}

}

The Algorithm


package ez.cfg;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

import ez.util.Constants;
import ez.util.Utility;

public abstract class PropertiesFileLoader {
 private static final Logger logger = Logger.getLogger(PropertiesFileLoader.class.getName());

 protected boolean justCreated = false;
 protected boolean initialized = false;
 protected Properties properties = new Properties();
 protected String fileName = "";

 public PropertiesFileLoader(String fileName){
 this.fileName = fileName;

 preinit();
 }

 // Mandatory: Client must override;
 abstract public void setup();

 // hook: client may not override unless needed
 public void postinit() {}

 public void preinit() {
 // Create Configdir
 File f = new File(Constants.CONFIG_DIR);
 if(f.exists() == false) {
 f.mkdir();
 }
 }

 // Can't override
 public final void init(){
 if(Utility.exists(fileName) == true){
 load();
 }
 else {
 justCreated = true;
 setup();

 save();

 load();
 }
 }
 synchronized final public void save(){
 File f = new File(fileName);
 FileOutputStream fos = null;

 try {
 fos = new FileOutputStream(f);
 if(properties.size() > 0){
 properties.store(fos, "");
 }
 else {
 logger.debug("Properites not setup, not writing to file!");
 }
 } catch (Exception e) {
 logger.error("Error while loading configuration: " + fileName);
 e.printStackTrace();
 } finally {
 try {
 if(fos != null) fos.close();

 if(justCreated == true){
 System.err.println("Config file " + fileName + " was just created, please fill it up before proceeding!");
 System.exit(1);
 }
 } catch (IOException e) {
 logger.error("Error while closing configuration: " + fileName);
 e.printStackTrace();
 }
 }
 }

 public final void load(){
 FileInputStream fis = null;

 try {
 File f = new File(fileName);
 fis = new FileInputStream(f);
 properties.load(fis);

 initialized = true;
 } catch (Exception e) {
 logger.error("Error while loading configuration: " + fileName);
 e.printStackTrace();
 } finally {
 try {
 if(fis != null) fis.close();
 } catch (IOException e) {
 logger.error("Error while closing configuration: " + fileName);
 e.printStackTrace();
 }
 }
 }

 public final Properties getProperties() {
 return properties;
 }

 public final boolean isInitialized(){
 return initialized;
 }

 public final boolean wasJustCreated() {
 return justCreated;
 }
}

Specialization for DataBase Configuration


package ez.cfg;

import java.io.File;

import ez.util.Constants;

public class IMDBPropertiesFileLoader extends PropertiesFileLoader {
 private static final String IMDB_CONFIG_FILE = Constants.CONFIG_DIR + File.separatorChar + "db.properties";

 public IMDBPropertiesFileLoader(){
 super(IMDB_CONFIG_FILE);
 }

 @Override
 public void setup(){
 properties.setProperty(Constants.DB_DRIVER_CLASS, "org.hsqldb.jdbcDriver");
 properties.setProperty(Constants.DB_URL, "jdbc:hsqldb:mem:feed_content_db");
 properties.setProperty(Constants.DB_USER, "sa");
 properties.setProperty(Constants.DB_PASSWORD, "");
 properties.setProperty(Constants.DB_MAX_CONNECTIONS, "2");
 }
}

Specialization for Logger Configuration


package ez.cfg;

import java.io.File;

import org.apache.log4j.PropertyConfigurator;

import ez.util.Constants;

public class LoggerPropertiesFileLoader extends PropertiesFileLoader {
 private static final String LOGGER_CONFIG_FILE = Constants.CONFIG_DIR + File.separatorChar + "logger-config.properties";

 public LoggerPropertiesFileLoader(){
 super(LOGGER_CONFIG_FILE);
 }

 @Override
 public void setup(){
 properties.setProperty("log4j.rootLogger", "debug, FILE");
 properties.setProperty("log4j.appender.FILE", "org.apache.log4j.FileAppender");
 properties.setProperty("log4j.appender.FILE.layout", "org.apache.log4j.PatternLayout");
 properties.setProperty("log4j.appender.FILE.File", "logs/diagnostic.log");
 properties.setProperty("log4j.appender.FILE.layout.ConversionPattern", "%d{ABSOLUTE} %5p %c{1}:%L - %m%n");
 }

 @Override
 public void postinit(){
 PropertyConfigurator.configure(properties);
 }
}

Constants used


package ez.util;

import java.io.File;

public interface Constants {
 public static final String CONFIG_DIR = "config";
 public static final String DATA_DIR = "data";
 
 public static final String HTTP_TIMEOUT = "HTTP_TIMEOUT";
 public static final String OUTPUT_FILE_STORE = "OutputFileStore";
 

 public static final String DB_DRIVER_CLASS = "JDBC.DRIVER";
 public static final String DB_USER = "USER";
 public static final String DB_PASSWORD = "PASSWORD";
 public static final String DB_MAX_CONNECTIONS = "CONNECTIONS";
 public static final String DB_URL = "JDBC.URL";
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s