View Javadoc

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 }