001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.rm.config;
020:
021: import java.sql.*;
022: import java.util.*;
023: import java.util.logging.*;
024:
025: import org.openharmonise.commons.dsi.*;
026: import org.openharmonise.rm.dsi.*;
027:
028: /**
029: * Singleton class to provide interface to Harmonise configuration settings.
030: *
031: * @author Matt Treanor
032: * @author Michael Bell
033: * @version $Revision: 1.2 $
034: *
035: */
036: public class ConfigSettings {
037:
038: /**
039: * The singleton instance of this class
040: */
041: private static ConfigSettings m_instance = null;
042:
043: /**
044: * Separator string used to separate values if stored in a list
045: */
046: private static String m_value_separator = ";";
047:
048: /**
049: * Database table which holds the configuration settings
050: */
051: private static String TBL_OH_PROP = "oh_prop";
052:
053: /**
054: * Map which provides an in-memory cache of config property values
055: */
056: private static Map m_props = null;
057:
058: /**
059: * Data store interface for this class
060: */
061: private static AbstractDataStoreInterface m_dsi = null;
062:
063: /**
064: * Logger for this class
065: */
066: private static final Logger m_logger = Logger
067: .getLogger(ConfigSettings.class.getName());
068:
069: private static boolean m_bIsInitialised = false;
070:
071: /**
072: * Constructs a configuration settings instance.
073: *
074: * @throws ConfigException if an error occurs during initialisation
075: */
076: private ConfigSettings() throws ConfigException {
077: initialise();
078: }
079:
080: /**
081: * Initialises the cache of properties and values.
082: *
083: * @throws ConfigException if an error occurs accessing data from
084: * database
085: */
086: private synchronized static void initialise()
087: throws ConfigException {
088: ResultSet rs = null;
089: m_props = new HashMap();
090: try {
091:
092: m_dsi = DataStoreInterfaceFactory.getDataStoreInterface();
093:
094: rs = m_dsi.executeQuery("select * from " + TBL_OH_PROP);
095: while (rs.next()) {
096: String sKey = rs.getString(2);
097: String sValue = rs.getString(3);
098:
099: m_props.put(sKey, sValue);
100:
101: if (m_logger.isLoggable(Level.CONFIG)) {
102: m_logger.log(Level.CONFIG, "Config value pair: "
103: + sKey + " = " + sValue);
104: }
105: }
106:
107: m_bIsInitialised = true;
108:
109: } catch (SQLException e) {
110: m_logger.log(Level.WARNING,
111: "Error initialising CongigSettings", e);
112: throw new ConfigException(e);
113: } catch (DataStoreException e) {
114: m_logger.log(Level.WARNING,
115: "Error initialising CongigSettings", e);
116: throw new ConfigException(e);
117: } finally {
118: try {
119: if (rs != null) {
120: rs.close();
121: }
122: } catch (Exception e) {
123: if (m_logger.isLoggable(Level.WARNING)) {
124: m_logger.log(Level.WARNING,
125: "Exception thrown when closing result set",
126: e);
127: }
128: }
129: }
130: }
131:
132: /**
133: * Returns the singleton instance of this class.
134: *
135: * @return the singleton instance of this class
136: * @throws ConfigException if an error occurs constructing the singleton instance
137: */
138: synchronized public static ConfigSettings getInstance()
139: throws ConfigException {
140: if (m_instance == null) {
141: m_instance = new ConfigSettings();
142: }
143:
144: return m_instance;
145: }
146:
147: /**
148: * Returns the <code>String</code> value which corresponds to the property name.
149: * If no property exists a null is returned.
150: *
151: * @param property_name the property
152: * @return the <code>String</code> value which corresponds to the property name
153: * @throws ConfigException if an error occurs accessing the property value
154: */
155: public static final String getProperty(String property_name)
156: throws ConfigException {
157: return getProperty(property_name, null);
158: }
159:
160: /**
161: * Returns the <code>String</code> value which corresponds to the property name.
162: * If no property exists the default value is returned.
163: *
164: * @param property_name the property name
165: * @param default_value the default value
166: * @return the <code>String</code> value which corresponds to the property name
167: * @throws ConfigException if an error occurs accessing the property value
168: */
169: public static final String getProperty(String property_name,
170: String default_value) throws ConfigException {
171: if (isInitialised() == false) {
172: initialise();
173: }
174: String sVal = default_value;
175:
176: if (m_props.containsKey(property_name) == true) {
177: sVal = (String) m_props.get(property_name);
178: }
179:
180: return sVal;
181: }
182:
183: /**
184: * Returns <code>true</code> if the local cache of properties is
185: * initialised.
186: *
187: * @return <code>true</code> if the local cache of properties is
188: * initialised
189: */
190: private static boolean isInitialised() {
191:
192: return m_bIsInitialised;
193: }
194:
195: /**
196: * Adds a new property and property value.
197: *
198: * @param property_name the property name
199: * @param property_value the property value
200: * @throws ConfigException if any errors occur, either due to
201: * there already being a property of the specified name or a problem
202: * inserting the data in to the database
203: */
204: public static void insertProperty(String property_name,
205: String property_value) throws ConfigException {
206: if (property_name == null || property_value == null) {
207: throw new ConfigException(
208: "Must have values for both property name and value");
209: }
210: if (isInitialised() == false || m_dsi == null) {
211: initialise();
212: }
213: if (m_props.containsKey(property_name)) {
214: throw new ConfigException("Property name already exists");
215: }
216: try {
217: int nId = m_dsi.getSequenceNextValue("seq_oh_prop");
218: String sSql = "insert into oh_prop values(" + nId + ",'"
219: + property_name + "','" + property_value + "')";
220: if (m_logger.isLoggable(Level.CONFIG)) {
221: m_logger.logp(Level.CONFIG, ConfigSettings.class
222: .getName(), "insertProperty", sSql);
223: }
224:
225: m_dsi.execute(sSql);
226: //update the props
227: initialise();
228: } catch (DataStoreException e) {
229: throw new ConfigException(e);
230: } catch (SQLException e) {
231: throw new ConfigException(e);
232: }
233:
234: }
235:
236: /**
237: * Sets a new value for the specified configuration property.
238: *
239: * @param property_name the property name
240: * @param property_value the property value
241: * @throws ConfigException if the specified property does not exist
242: * or there is a problem updating the database
243: */
244: public static void setProperty(String property_name,
245: String property_value) throws ConfigException {
246: String sPropVal = property_value;
247: if (isInitialised() == false || m_dsi == null) {
248: initialise();
249: }
250: if (m_props.containsKey(property_name) == false) {
251: throw new ConfigException("Property " + property_name
252: + " does not exist");
253: }
254:
255: String sSql = "update oh_prop set prop_value='"
256: + property_value + "' where prop_name ='"
257: + property_name + "'";
258: try {
259: m_dsi.execute(sSql);
260: } catch (DataStoreException e) {
261: throw new ConfigException(e);
262: }
263: //update the props
264: initialise();
265:
266: }
267:
268: /**
269: * Removes the specified configuration property.
270: *
271: * @param prop_name the property name
272: * @throws ConfigException if there is an error updating the database
273: */
274: public static void removeProperty(String prop_name)
275: throws ConfigException {
276: if (m_dsi == null) {
277: initialise();
278: }
279: String sSql = "delete from oh_prop where prop_name ='"
280: + prop_name + "'";
281: if (m_logger.isLoggable(Level.CONFIG)) {
282: m_logger.logp(Level.CONFIG, ConfigSettings.class.getName(),
283: "removeProperty", sSql);
284: }
285:
286: try {
287: // update the props
288: m_dsi.execute(sSql);
289: } catch (DataStoreException e) {
290: throw new ConfigException(e);
291: }
292:
293: initialise();
294:
295: }
296:
297: /**
298: * Returns a comma serparated list of the property names.
299: *
300: * @return a comma serparated list of the property names
301: * @throws ConfigException if an error occurs initialising this class
302: */
303: public static String getPropertyNames() throws ConfigException {
304: String props = "";
305: if (m_props == null || m_dsi == null) {
306: initialise();
307: }
308: Set keyset = m_props.keySet();
309: Object[] keys = keyset.toArray();
310: for (int i = 0; i < keys.length; i++) {
311: if (i != 0) {
312: props += ",";
313: }
314: props += keys[i];
315: }
316: return props;
317: }
318:
319: /**
320: * Returns a comma serparated list of the property names.
321: *
322: * @return a comma serparated list of the property names
323: * @throws ConfigException if an error occurs initialising this class
324: */
325: public static List getPropertyNameArray() throws ConfigException {
326: String props = "";
327: if (m_props == null || m_dsi == null) {
328: initialise();
329: }
330: Set keyset = m_props.keySet();
331:
332: ArrayList list = new ArrayList();
333:
334: Iterator iter = keyset.iterator();
335:
336: while (iter.hasNext()) {
337: String sName = (String) iter.next();
338: list.add(sName);
339: }
340:
341: return list;
342: }
343:
344: /**
345: * Returns a list of values for the specified property.
346: *
347: * @param property_name the property name
348: * @return a list of values for the specified property
349: * @throws ConfigException if there is a problem accessing the property value
350: */
351: public static final List getMultiValuedProperty(String property_name)
352: throws ConfigException {
353: Vector vec = new Vector();
354:
355: String property_value = getProperty(property_name, "");
356:
357: StringTokenizer tokenizer = new StringTokenizer(property_value,
358: m_value_separator);
359:
360: while (tokenizer.hasMoreTokens() == true) {
361: vec.add(tokenizer.nextToken());
362: }
363:
364: return vec;
365: }
366:
367: /**
368: * Returns the <code>int</code> value which corresponds to the property
369: * name. If no property exists, the default value is returned.
370: *
371: * @param property_name the property name
372: * @param default_value the default value
373: * @return the <code>int</code> value of the property
374: * @throws ConfigException if an error occurs accessing the property value
375: */
376: public static final int getIntProperty(String property_name,
377: String default_value) throws ConfigException {
378: String sVal = null;
379: int property_value = -1;
380:
381: try {
382: sVal = getProperty(property_name, default_value);
383: property_value = Integer.parseInt(sVal);
384:
385: } catch (NumberFormatException ne) {
386: throw new ConfigException("Cannot cast property with name:"
387: + property_name + ", and value:" + sVal
388: + " to an integer");
389: }
390:
391: return property_value;
392: }
393:
394: /**
395: * Returns the <code>boolean</code> value which corresponds to the
396: * property name. If no property exists the default value is returned.
397: *
398: * @param property_name the property name
399: * @param default_value the default value
400: * @return the <code>boolean</code> value of the property
401: * @throws ConfigException if an error occurs accessing the property value
402: */
403: public static final boolean getBoolProperty(String property_name,
404: String default_value) throws ConfigException {
405: boolean property_value;
406:
407: String property_value_str = (String) getProperty(property_name,
408: default_value);
409:
410: if (property_value_str.equalsIgnoreCase("" + true)) {
411: property_value = true;
412: } else if (property_value_str.equalsIgnoreCase("" + false)) {
413: property_value = false;
414: } else {
415: throw new ConfigException("Cannot cast property with name:"
416: + property_name + ", and value:"
417: + property_value_str + " to a boolean");
418: }
419:
420: return property_value;
421: }
422: }
|