1 /* 2 * db2sa: DB2 Syntax Assistant 3 * Copyright (C) Andres Gomez Casanova 4 * 5 * This file is part of db2sa. 6 * 7 * db2sa is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * db2sa is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, see <http://www.gnu.org/licenses/>. 19 * 20 * Contact: 21 * a n g o c a at y a h o o dot c o m 22 * Cra. 45 No 61 - 31, Bogota, Colombia. 23 * 24 * Author: $LastChangedBy: angoca $: 25 * Date: $LastChangedDate: 2009-07-08 19:56:43 +0200 (Wed, 08 Jul 2009) $: 26 * Revision: $LastChangedRevision: 357 $: 27 * URL: $HeadURL: https://db2sa.svn.sourceforge.net/svnroot/db2sa/branches/db2sa_beta/source-code/src/main/java/name/angoca/db2sa/Configurator.java $: 28 */ 29 package name.angoca.db2sa; 30 31 import java.util.Properties; 32 33 import name.angoca.db2sa.messages.Messages; 34 import name.angoca.db2sa.readers.ConfigurationReader; 35 import name.angoca.db2sa.readers.exceptions.AbstractReaderException; 36 37 import org.slf4j.Logger; 38 import org.slf4j.LoggerFactory; 39 40 /** 41 * This class loads the configuration of the application. The implementation is 42 * with a singleton. The name of the configuration file is in a Constant 43 * (DB2SA_CONF_XML = db2sa_conf.xml) <br/> 44 * This class defines all the default values in a set of constants; their names 45 * are in the Constants interface.<br/> 46 * <b>Control Version</b><br /> 47 * <ul> 48 * <li>0.0.1 Class creation.</li> 49 * <li>0.1.0 Singleton and get method.</li> 50 * <li>0.1.1 Basic configuration and new values.</li> 51 * <li>0.2.0 Destroy instance and set property.</li> 52 * <li>0.2.1 Warn level when file problem.</li> 53 * <li>0.2.2 Use of constants.</li> 54 * <li>0.2.3 getInstance synchronized.</li> 55 * <li>0.3.0 Remove of circular dependencies.</li> 56 * <li>0.3.1 Include file name in log.</li> 57 * <li>0.3.2 Log the filename.</li> 58 * <li>1.0.0 Moved to version 1.</li> 59 * </ul> 60 * 61 * @author Andres Gomez Casanova <a 62 * href="mailto:a n g o c a at y a h o o dot c o m">(AngocA)</a> 63 * @version 1.0.0 2009-07-19 64 */ 65 public final class Configurator { 66 67 /** 68 * Value for the grammar file. 69 */ 70 static final String GRAMMAR_FILE_NAME = "grammar.xml"; //$NON-NLS-1$ 71 /** 72 * Value for the prompt. 73 */ 74 static final String PROMPT = "db2>"; //$NON-NLS-1$ 75 /** 76 * Value for the exit. 77 */ 78 static final String EXIT = "exit"; //$NON-NLS-1$ 79 /** 80 * Property: About token. 81 */ 82 static final String ABOUT_TOKEN = "about"; //$NON-NLS-1$ 83 /** 84 * Property: Help token. 85 */ 86 static final String HELP_TOKEN = "?"; //$NON-NLS-1$ 87 /** 88 * Property: Delimiters. 89 */ 90 static final String DELIMITERS = " ,()"; //$NON-NLS-1$ 91 /** 92 * Logger. 93 */ 94 private static final Logger LOGGER = LoggerFactory 95 .getLogger(Configurator.class); 96 /** 97 * Singleton instance. 98 */ 99 private static Configurator s_instance; 100 101 /** 102 * Set of properties. 103 */ 104 private Properties m_prop; 105 106 /** 107 * Default constructor. 108 */ 109 private Configurator() { 110 // Loads the XML properties file in a Properties structure. 111 // Tries to retrieve a filename in the system properties. It's for 112 // unit test. 113 final String fileName = System.getProperty(Constants.DB2SA_CONF_XML); 114 try { 115 if (fileName == null) { 116 if (Configurator.LOGGER.isDebugEnabled()) { 117 Configurator.LOGGER.debug("Properties from: " //$NON-NLS-1$ 118 + Constants.DB2SA_CONF_XML); 119 } 120 121 this.loadXMLFile(Constants.DB2SA_CONF_XML); 122 123 } else { 124 if (Configurator.LOGGER.isDebugEnabled()) { 125 Configurator.LOGGER.debug("Properties from: " + fileName); //$NON-NLS-1$ 126 } 127 this.loadXMLFile(fileName); 128 } 129 } catch (AbstractReaderException e) { 130 if (fileName == null) { 131 Configurator.LOGGER.warn(Messages.getString("Configurator."//$NON-NLS-1$ 132 + "PROBLEM_READING_THE_CONFIGURATION_FILE."//$NON-NLS-1$ 133 + "_LOADING_DEFAULT_PROPERTIES"), //$NON-NLS-1$ 134 Constants.DB2SA_CONF_XML + " (Default file)"); //$NON-NLS-1$ 135 } else { 136 Configurator.LOGGER.warn(Messages.getString("Configurator."//$NON-NLS-1$ 137 + "PROBLEM_READING_THE_CONFIGURATION_FILE."//$NON-NLS-1$ 138 + "_LOADING_DEFAULT_PROPERTIES"), //$NON-NLS-1$ 139 fileName); 140 } 141 Configurator.LOGGER.debug(Messages.getString("Configurator." + //$NON-NLS-1$ 142 "FILES_PROBLEM"), e); //$NON-NLS-1$ 143 144 this.loadDefaults(); 145 } 146 147 // If Debug level then show the properties. 148 if (Configurator.LOGGER.isDebugEnabled()) { 149 this.m_prop.list(System.out); 150 } 151 } 152 153 /** 154 * This is the singleton implementation. This method returns the sole 155 * instance of this class. 156 * 157 * @return The sole instance of the Configurator class. 158 */ 159 public static Configurator getInstance() { 160 synchronized (Configurator.LOGGER) { 161 if (Configurator.s_instance == null) { 162 Configurator.s_instance = new Configurator(); 163 } 164 } 165 return Configurator.s_instance; 166 } 167 168 /** 169 * Destroys the sole instance. Useful for testing purposes. 170 */ 171 public static void destroyInstance() { 172 if (Configurator.s_instance != null) { 173 Configurator.s_instance.m_prop.clear(); 174 Configurator.s_instance.m_prop = null; 175 } 176 Configurator.s_instance = null; 177 } 178 179 /** 180 * Defines a set of defaults properties. 181 */ 182 private void loadDefaults() { 183 this.m_prop = new Properties(); 184 this.m_prop.setProperty(Constants.GRAMMAR_FILE_NAME, 185 Configurator.GRAMMAR_FILE_NAME); 186 this.m_prop.setProperty(Constants.PROMPT, Configurator.PROMPT); 187 this.m_prop.setProperty(Constants.EXIT, Configurator.EXIT); 188 this.m_prop 189 .setProperty(Constants.ABOUT_TOKEN, Configurator.ABOUT_TOKEN); 190 this.m_prop.setProperty(Constants.HELP_TOKEN, Configurator.HELP_TOKEN); 191 this.m_prop.setProperty(Constants.DELIMITERS, Configurator.DELIMITERS); 192 } 193 194 /** 195 * Loads the properties that are in a XML file. 196 * 197 * @param fileName 198 * Name of configuration file. 199 * @throws AbstractReaderException 200 * If there is a problem with the file (when finding or 201 * reading.) 202 */ 203 private void loadXMLFile(final String/* ! */fileName) 204 throws AbstractReaderException { 205 this.m_prop = ConfigurationReader.readFile(fileName); 206 } 207 208 /** 209 * Retrieves a property from the load properties. 210 * 211 * @param key 212 * Name of the property to load. 213 * @return Value of the property. Null if there is no value with that name. 214 */ 215 public String /* ? */getProperty(final String/* ! */key) { 216 return this.m_prop.getProperty(key); 217 } 218 219 /** 220 * Set a property after the properties file has been read. This is for 221 * testing purposes, because the configuration is not the same for all 222 * cases. 223 * 224 * @param key 225 * Name of the property. 226 * @param value 227 * Value of the property. 228 */ 229 public void setProperty(final String /* ! */key, final String /* ! */value) { 230 this.m_prop.setProperty(key, value); 231 } 232 }