/** * Copyright (c) 2006 by Know-Center, Graz, Austria * * This software is the confidential and proprietary information of Know-Center, * Graz, Austria. You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Know-Center. * * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. * * $Id: SettingsReader.java,v 1.6 2006/10/31 08:06:36 wprinz Exp $ */ package at.knowcenter.wag.egov.egiz.cfg; import java.io.FileInputStream; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.Vector; import java.util.ArrayList; import java.util.Enumeration; import java.util.Properties; import org.apache.log4j.Level; import org.apache.log4j.Logger; import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; /** * The SettingsReader reads the settings.txt file. The * settings.txt is a simple java property file that collects all * parameters used in different modules. * * The SettingsReader provides methods to get the property keys and the * corresponding values. The keys could be defined as combinations of single * keys. Therefore it is possible to combine differen classes of keys. An * example could be: * *
 *     
 *      
 *       
 *        
 *         
 *          
 *           
 *            
 *             
 *              
 *               
 *                        #SettingNotFoundException
 *                        error.code.100=Interner Fehler
 *                        error.code.101=Die Konfigurationsdatei konnte nicht geladen werden
 *                        
 *                        #PDFDocumentException
 *                        error.code.200=Das Dokument konnte nicht geladen werden
 *                        
 *                        #SignatureException
 *                        error.code.300=Die Signatur ist ungültig
 *                        
 *                        #NormalizeException
 *                        error.code.400=Die angegebene Version ist nicht bekannt
 *                       
 *                        normalizer.version=V01
 *                
 *               
 *              
 *             
 *            
 *           
 *          
 *         
 *        
 *       
 *      
 * 
* * The internal representation of the example above is: * *
 *     
 *      
 *       
 *        
 *         
 *          
 *           
 *            
 *             
 *              
 *               
 *                        .error|
 *                              |.code|
 *                              |     |.200=Das Dokument konnte nicht geladen werden
 *                              |     |.100=Interner Fehler
 *                              |     |.400=Die angegebene Version ist nicht bekannt
 *                              |     |.101=Die Konfigurationsdatei konnte nicht geladen werden
 *                              |     |.300=Die Signatur ist ungültig
 *                       .normalizer|
 *                                  |.version=V01
 *                
 *               
 *              
 *             
 *            
 *           
 *          
 *         
 *        
 *       
 *      
 * 
* * @author wlackner */ public class SettingsReader implements Settings, Serializable { /** * SVUID. */ private static final long serialVersionUID = -8754114172766023454L; /** * The system File separator char */ private static final String FILE_SEP = System.getProperty("file.separator"); // /** // * The system temp file path // */ // private static final String TEMP_FILE_PATH = // System.getProperty("java.io.tmpdir"); /** * The current user path */ private static final String USER_DIR = System.getProperty("user.dir"); // /** // * The home path of the tomcat webaplication // */ // private static final String CATALINA_HOME = System.getProperty("catalina.home"); // /** // * The default application name used in templates, settings, jsp's etc. // */ // private static final String APPL_NAME = "pdf-as"; // private static final String APPL_NAME = "egiz"; /** * The config file path postfix */ private static final String CFG = "cfg"; /** * The file path postfix where certificates are stored */ private static final String CERT = "certificates"; // /** // * The web application path // */ // private static final String WEB_APPL_DIR = "webapps" + FILE_SEP + APPL_NAME + FILE_SEP; /** * The path of the resources repository. * *

* This usually contains sub directories for the templates, the configuration * files, etc. *

*/ public static String RESOURCES_PATH = null; /** * The path of the configuration directory. */ public static String CONFIG_PATH = null; /** * The path of the certificated directory. */ public static String CERT_PATH = null; /** * The name of the directory, where temporary files are stored. */ protected static String TEMP_DIR_NAME = "pdfastmp"; // /** // * The application config path for the command line tool // */ // public static final String APPL_CONFIG_PATH = USER_DIR + FILE_SEP + CFG + // FILE_SEP; // // /** // * The application config path for the web application // */ // public static final String WEB_CONFIG_PATH = CATALINA_HOME + FILE_SEP + // WEB_APPL_DIR + CFG + FILE_SEP; // // /** // * The certificates path for the command line tool // */ // public static final String APPL_CERT_PATH = USER_DIR + FILE_SEP + CERT + // FILE_SEP; // // /** // * The certificates path for the cweb application // */ // public static final String WEB_CERT_PATH = CATALINA_HOME + FILE_SEP + // WEB_APPL_DIR + CERT + FILE_SEP; /** * The name of the default configuration file. The definition syntax is the * java property config syntax. */ public static final String CONFIG_FILE_DEFAULT_NAME = "config.properties"; /** * The name of the help text configuration file. The definition syntax is the * java property config syntax. */ public static final String HELP_TEXT_FILE_DEFAULT_NAME = "help_text.properties"; /** * The java properties from the settings file. */ private Properties properties_ = null; /** * The settings reader instance. Used to make the class singleton. */ private static SettingsReader instance_ = null; /** * The reference to the settings file. */ private static String settingsFile_ = null; /** * The reference to the property representation of the settings file. */ private PropertyTree pTree_ = new PropertyTree(); /** * The logger definition. */ private static final Logger logger_ = ConfigLogger.getLogger(SettingsReader.class); /** * Make this constructor private. Use the method * {@link SettingsReader#getInstance()}to get an instance from this class. * The only cause to do this is that the definition file should only be read * once while getting often this instance. The method throws an IOException if * the settings file could not be read. * * @param settingsFile * load this file, if the settingsFile == null the * default settings ({@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}) * file is used * @throws SettingsException * if the settings file could not be read */ private SettingsReader(String settingsFile) throws SettingsException { try { String cfg_path = CONFIG_PATH; properties_ = new Properties(); if (settingsFile == null) { settingsFile = cfg_path + CONFIG_FILE_DEFAULT_NAME; } settingsFile_ = settingsFile; if (logger_.isInfoEnabled()) { File file = new File(settingsFile_); logger_.info("load Settings:" + file.getAbsolutePath()); // Properties sys_prop = System.getProperties(); // Enumeration prop_keys = sys_prop.propertyNames(); // while (prop_keys.hasMoreElements()) { // String key = (String) prop_keys.nextElement(); // String value = sys_prop.getProperty(key); // logger_.info(key + "=" + value); // } } FileInputStream sfs = new FileInputStream(settingsFile_); properties_.load(sfs); Properties help_prop = new Properties(); FileInputStream hfs = new FileInputStream(cfg_path + HELP_TEXT_FILE_DEFAULT_NAME); help_prop.load(hfs); // load properties from current package! // properties_.load(getClass().getResourceAsStream(settingsFile_)); Enumeration prop_keys = properties_.propertyNames(); while (prop_keys.hasMoreElements()) { String key = (String) prop_keys.nextElement(); String value = properties_.getProperty(key); pTree_.setKeyValue(key, value); } prop_keys = help_prop.propertyNames(); while (prop_keys.hasMoreElements()) { String key = (String) prop_keys.nextElement(); String value = help_prop.getProperty(key); properties_.setProperty(key, value); pTree_.setKeyValue(key, value); } } catch (IOException e) { throw new SettingsException(e); } } /** * This method returns an synchronized instance of this class. The settings * file is read only once using this class. This method returns the instance * holding the definitions of the default settings file. Default file: * {@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}: "settings.txt" * * @return an instance of the SettingsReader * @throws SettingsException * if the default settings file could not be read */ public synchronized static SettingsReader getInstance() throws SettingsException { return getInstance(null); } /** * This method returns an synchronized instance of this class. The settings * file is read only once using this class. This method returns the instance * holding the definitions of the settingsFile. If the input param * settingsFile == null the default settings file will be load. * Default file: {@link SettingsReader#CONFIG_FILE_DEFAULT_NAME}: * "settings.txt" * * If an instance of this class exist, the input param is ignored! The * SettingsReader is singleton and therefore the first * {@link SettingsReader#getInstance()}defines the settings file that has to * be loaded. This means changes between a application lifecyle can not be * done! * * @param settingsFile * the settings file that should be load. * @return an instance of the SettingsReader * @throws SettingsException * if the settings file could not be read */ private synchronized static SettingsReader getInstance(String settingsFile) throws SettingsException { if (instance_ == null) { instance_ = new SettingsReader(settingsFile); } return instance_; } /** * This method returns a property value to the corresponding key. If the key * is not found in the property file a SettingNotFoundException is thrown. * * @param key * get the value for that key in the property file * @return the value of the property key. * @throws SettingNotFoundException * ErrorCode: 100 */ public String getSetting(String key) throws SettingNotFoundException { String result = properties_.getProperty(key); if (result == null) { String log_message = "Configuration key not found: '" + key + "'! Check '" + settingsFile_ + "' file."; if (logger_.isEnabledFor(Level.WARN)) { logger_.warn(log_message); } SettingNotFoundException snf = new SettingNotFoundException(100, log_message); throw snf; } // if (logger_.isDebugEnabled()) // { // logger_.debug("Get Property:" + key + "=" + result); // } return result; } /** * Relocates the relative file. * * @param file * The relative file. * @return Returns the usable file. */ public static String relocateFile(String file) { // if (isWeb()) // { // return CATALINA_HOME + FILE_SEP + WEB_APPL_DIR + file; // } // // return file; return RESOURCES_PATH + file; } /** * This method returns a property value to the corresponding key. If the key * is not found in the property file the input param defaultValue is returned. * * @param key * get the value for that key in the property file * @param defaultValue * the default value if the key is not found * @return the value of the property key */ public String getSetting(String key, String defaultValue) { String result = properties_.getProperty(key); if (result == null) { result = defaultValue; } // if (logger_.isDebugEnabled()) // { // logger_.debug("Get Property:" + key + "=" + result); // } return result; } /** * This method returns a property value to the corresponding key. If the key * is not found in the property file the input param defaultKey is searched. * If the default key is not found the input param defaultValue is returned. * * @param primaryKey * get the value for that key in the property file * @param defaultKey * the default key that should be searched if the primaryKey is not * found * @param defaultValue * the default value if the defaultKey is not found * @return the value of the property key */ public String getSetting(String primaryKey, String defaultKey, String defaultValue) { String key = primaryKey; String result = properties_.getProperty(key); if (result == null) { key = defaultKey; result = properties_.getProperty(key); if (result == null) { result = defaultValue; } } // if (logger_.isDebugEnabled()) // { // logger_.debug("Get Property:" + key + "=" + result); // } return result; } /** * This method returns an array of keys in the same hierarchy of the * keyPrefix. The method search all keys in the property file that has the * keyPrefix as leading substring. The Object[] collects all * sub keys without the keyPrefix. * * @param keyPrefix * to search for sub keys * @return alls keys starting with the keyPrefix */ public Vector getSettingKeys(String keyPrefix) { Vector keys = new Vector(); Enumeration names = properties_.propertyNames(); while (names.hasMoreElements()) { String full_name = (String) names.nextElement(); if (full_name.indexOf(keyPrefix) == 0) { keys.add(full_name.substring(keyPrefix.length() + 1)); } } return keys; } /** * If a property value is number (interger) this method extracts the value and * convert it to an int. If the key ist not found or the conversion fails, the * defaultValue is returned. * * @param key * get the value for that key in the property file * @param defaultValue * the default value if the key is not found * @return the int value of the property key */ public int getIntSetting(String key, int defaultValue) { int int_property = defaultValue; String value = null; try { value = getSetting(key); int_property = Integer.parseInt(value); } catch (NumberFormatException e) { if (logger_.isEnabledFor(Level.WARN)) { logger_.warn("Can not convert " + value + " to int."); } } catch (SettingNotFoundException e) { if (logger_.isEnabledFor(Level.WARN)) { logger_.warn("Setting " + key + " not found, return default value:" + defaultValue); } } return int_property; } /** * This method returns an array of sub keys (children references) of the key. * The method is a wrapper calling the method * {@link PropertyTree#getKeys(String key)}. * * @param key * get all sub keys for that key in the property file * @return an list of sub keys (type String) * @see PropertyTree */ public ArrayList getKeys(String key) { return pTree_.getKeys(key); } /** * This method returns a the first value from a key. This means the method * search in the PropertyTree representation of the config file. The * PropertyTree class can overload key value paires. But the config file can * not overload keys. If a key is defined more than one times the last * definition is stored it the property list. The method is a wrapper calling * the method {@link PropertyTree#getFirstValue(String key)}. * * @param key * get the value for that key in the property file * @return the value of the property key * @see PropertyTree */ public String getValueFromKey(String key) { String value = pTree_.getFirstValue(key); // if (logger_.isDebugEnabled()) // { // logger_.debug("getValueFromKey:" + key + "=" + value); // } return value; } /** * This method returns the PropertyTree representation of the configuration * file. * * @return Returns the pTree. * @see PropertyTree */ public PropertyTree getPTree() { return pTree_; } // /** // * This method checks the application context. // * // * @return true if the application is running in a webinterface, false // * otherwise // */ // public static boolean isWeb() // { // return CATALINA_HOME != null; // } /** * Assembles the File of the temporary directory without checking if it really * exists. */ protected static File assembleTemporaryDirectoryFile() { File temp_dir = new File(RESOURCES_PATH + TEMP_DIR_NAME); return temp_dir; } /** * Returns the directory where temporary files should be stored. * *

* If the directory doesn't exist, it is created. *

* * @return Returns the directory where temporary files should be stored. */ public static File getTemporaryDirectory() { File temp_dir = assembleTemporaryDirectoryFile(); if (!temp_dir.exists()) { temp_dir.mkdirs(); } return temp_dir; } /** * Deletes all files in the temporary directory, if it exists. * *

* This should be used to clear temporary files when the application shuts * down. *

*/ public static void clearTemporaryDirectory() { File temp_dir = assembleTemporaryDirectoryFile(); logger_.info("Clearing temporary directory: " + temp_dir); if (!temp_dir.exists()) { return; } File[] files = temp_dir.listFiles(); for (int i = 0; i < files.length; i++) { logger_.info(" Clearing temporary file: " + files[i]); boolean delete_success = files[i].delete(); if (!delete_success) { logger_.error("Couldn't delete the temporary file: " + files[i]); } } } /** * Initializes the paths of the SettingsReader for web application usage. * * @param base_dir The base directory of this web application. E.g. TOMCAT_HOME/webapps/pdf-as */ public static void initializeForWeb(String base_dir) { RESOURCES_PATH = base_dir + FILE_SEP; //CATALINA_HOME + FILE_SEP + WEB_APPL_DIR; CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP; CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP; } /** * Initializes the paths of the SettingsReader for commanline usage. */ public static void initializeForCommandLine() { RESOURCES_PATH = USER_DIR + FILE_SEP; CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP; CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP; } }