chris@3: /*
chris@3:  *   SONEWS News Server
chris@3:  *   see AUTHORS for the list of contributors
chris@3:  *
chris@3:  *   This program is free software: you can redistribute it and/or modify
chris@3:  *   it under the terms of the GNU General Public License as published by
chris@3:  *   the Free Software Foundation, either version 3 of the License, or
chris@3:  *   (at your option) any later version.
chris@3:  *
chris@3:  *   This program is distributed in the hope that it will be useful,
chris@3:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
chris@3:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
chris@3:  *   GNU General Public License for more details.
chris@3:  *
chris@3:  *   You should have received a copy of the GNU General Public License
chris@3:  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
chris@3:  */
chris@3: 
chris@3: package org.sonews.config;
chris@3: 
chris@3: import java.io.FileInputStream;
chris@3: import java.io.FileNotFoundException;
chris@3: import java.io.FileOutputStream;
chris@3: import java.io.IOException;
chris@3: import java.util.Properties;
chris@3: 
chris@3: /**
chris@3:  * Manages the bootstrap configuration. It MUST contain all config values
chris@3:  * that are needed to establish a database connection.
chris@3:  * For further configuration values use the Config class instead as that class
chris@3:  * stores its values within the database.
chris@3:  * @author Christian Lins
chris@3:  * @since sonews/0.5.0
chris@3:  */
chris@3: class FileConfig extends AbstractConfig
chris@3: {
chris@3: 
cli@37: 	private static final Properties defaultConfig = new Properties();
cli@37: 	private static FileConfig instance = null;
chris@3: 
cli@37: 	static {
cli@37: 		// Set some default values
cli@37: 		defaultConfig.setProperty(Config.STORAGE_DATABASE, "jdbc:mysql://localhost/sonews");
cli@37: 		defaultConfig.setProperty(Config.STORAGE_DBMSDRIVER, "com.mysql.jdbc.Driver");
cli@37: 		defaultConfig.setProperty(Config.STORAGE_USER, "sonews_user");
cli@37: 		defaultConfig.setProperty(Config.STORAGE_PASSWORD, "mysecret");
cli@37: 		defaultConfig.setProperty(Config.DEBUG, "false");
cli@37: 	}
chris@3: 
cli@37: 	/**
cli@37: 	 * Note: this method is not thread-safe
cli@37: 	 * @return A Config instance
cli@37: 	 */
cli@37: 	public static synchronized FileConfig getInstance()
cli@37: 	{
cli@37: 		if (instance == null) {
cli@37: 			instance = new FileConfig();
cli@37: 		}
cli@37: 		return instance;
cli@37: 	}
cli@37: 	// Every config instance is initialized with the default values.
cli@37: 	private final Properties settings = (Properties) defaultConfig.clone();
chris@3: 
cli@37: 	/**
cli@37: 	 * Config is a singelton class with only one instance at time.
cli@37: 	 * So the constructor is private to prevent the creation of more
cli@37: 	 * then one Config instance.
cli@37: 	 * @see Config.getInstance() to retrieve an instance of Config
cli@37: 	 */
cli@37: 	private FileConfig()
cli@37: 	{
cli@37: 		try {
cli@37: 			// Load settings from file
cli@37: 			load();
cli@37: 		} catch (IOException ex) {
cli@37: 			ex.printStackTrace();
cli@37: 		}
cli@37: 	}
chris@3: 
cli@37: 	/**
cli@37: 	 * Loads the configuration from the config file. By default this is done
cli@37: 	 * by the (private) constructor but it can be useful to reload the config
cli@37: 	 * by invoking this method.
cli@37: 	 * @throws IOException
cli@37: 	 */
cli@37: 	public void load()
cli@37: 		throws IOException
cli@37: 	{
cli@37: 		FileInputStream in = null;
chris@3: 
cli@37: 		try {
cli@37: 			in = new FileInputStream(
cli@37: 				Config.inst().get(Config.LEVEL_CLI, Config.CONFIGFILE, "sonews.conf"));
cli@37: 			settings.load(in);
cli@37: 		} catch (FileNotFoundException e) {
cli@37: 			// MUST NOT use Log otherwise endless loop
cli@37: 			System.err.println(e.getMessage());
cli@37: 			save();
cli@37: 		} finally {
cli@37: 			if (in != null) {
cli@37: 				in.close();
cli@37: 			}
cli@37: 		}
cli@37: 	}
chris@3: 
cli@37: 	/**
cli@37: 	 * Saves this Config to the config file. By default this is done
cli@37: 	 * at program end.
cli@37: 	 * @throws FileNotFoundException
cli@37: 	 * @throws IOException
cli@37: 	 */
cli@37: 	public void save() throws FileNotFoundException, IOException
cli@37: 	{
cli@37: 		FileOutputStream out = null;
cli@37: 		try {
cli@37: 			out = new FileOutputStream(
cli@37: 				Config.inst().get(Config.LEVEL_CLI, Config.CONFIGFILE, "sonews.conf"));
cli@37: 			settings.store(out, "SONEWS Config File");
cli@37: 			out.flush();
cli@37: 		} catch (IOException ex) {
cli@37: 			throw ex;
cli@37: 		} finally {
cli@37: 			if (out != null) {
cli@37: 				out.close();
cli@37: 			}
cli@37: 		}
cli@37: 	}
cli@37: 
cli@37: 	/**
cli@37: 	 * Returns the value that is stored within this config
cli@37: 	 * identified by the given key. If the key cannot be found
cli@37: 	 * the default value is returned.
cli@37: 	 * @param key Key to identify the value.
cli@37: 	 * @param def The default value that is returned if the key
cli@37: 	 * is not found in this Config.
cli@37: 	 * @return
cli@37: 	 */
cli@37: 	@Override
cli@37: 	public String get(String key, String def)
cli@37: 	{
cli@37: 		return settings.getProperty(key, def);
cli@37: 	}
cli@37: 
cli@37: 	/**
cli@37: 	 * Sets the value for a given key.
cli@37: 	 * @param key
cli@37: 	 * @param value
cli@37: 	 */
cli@37: 	@Override
cli@37: 	public void set(final String key, final String value)
cli@37: 	{
cli@37: 		settings.setProperty(key, value);
cli@37: 	}
chris@3: }