001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.persistence.engines.jdbcengine.variants;
051:
052: import org.apache.log4j.Logger;
053: import java.util.PropertyResourceBundle;
054: import java.util.MissingResourceException;
055: import java.util.*;
056:
057: /** This class manages all the access to the properties of the various database variants.
058: * Each database variant will have its own property file in this package. For eg. a variant 'xxx' will have a 'xxx.properties' file in this package.
059: * If the file does not exist, or if a particular property does not exist in the variant, then the 'default.properties' will be used.
060: * Each property will have a static name associated with it.
061: *
062: * @author GautamJ
063: * @version 1.0
064: */
065: public class Variant {
066: private static Logger log = Logger.getLogger(Variant.class);
067:
068: /** This will hold Variant-PropertyResourceBundle pairs. */
069: private static Map c_cache = new WeakHashMap();
070:
071: /** The prefix used to locate the properties file for a variant. */
072: private static final String VARIANT_RESOURCE_PREFIX = "org.jaffa.persistence.engines.jdbcengine.variants.";
073:
074: /** The default resource. */
075: private static final String DEFAULT_RESOURCE_NAME = VARIANT_RESOURCE_PREFIX
076: + "default";
077: private static PropertyResourceBundle c_defaultResource = null;
078: static {
079: try {
080: c_defaultResource = (PropertyResourceBundle) PropertyResourceBundle
081: .getBundle(DEFAULT_RESOURCE_NAME);
082: } catch (MissingResourceException e) {
083: String str = "Can't load the resource file: "
084: + DEFAULT_RESOURCE_NAME + ".properties";
085: log.fatal(str, e);
086: throw new RuntimeException(str, e);
087: }
088: }
089:
090: // **** List static names for all the properties ***
091: /** Static : The LOCK construct in a SELECT statement */
092: public static final String PROP_LOCK_CONSTRUCT_IN_SELECT_STATEMENT = "lockConstructInSelectStatement";
093:
094: /** Static : The LOCK construct in the fROM portion if a SELECT statement */
095: public static final String PROP_LOCK_CONSTRUCT_IN_FROM_SELECT_STATEMENT = "lockConstructInFromSelectStatement";
096:
097: /** Static : This indicates if the to_date SQL function is used when querying Date fields */
098: public static final String PROP_USE_TO_DATE_SQL_FUNCTION = "useToDateSqlFunction";
099:
100: /** Static : This is used to get the default packing code for boolean fields in a DBMS. Can be one of BOOLEAN_BIT, BOOLEAN_TF, BOOLEAN_YN, BOOLEAN_10 */
101: public static final String PROP_DEFAULT_PACKING_CODE_FOR_BOOLEAN = "defaultPackingCodeForBoolean";
102:
103: /** Returns the value of a property, for a given variant. The default resource will be used, in case the variant resource is not found or if the variant does not have the given property.
104: * @param variant the name of the variant. If a null value is passed, then the default will be used.
105: * @param key the name of the property.
106: * @throws MissingResourceException if the property is not found in both the variant and the default resource files.
107: * @return the value of a property.
108: */
109: public static String getProperty(String variant, String key)
110: throws MissingResourceException {
111: String value = null;
112:
113: PropertyResourceBundle resource = null;
114: if (variant != null) {
115: variant = VARIANT_RESOURCE_PREFIX + variant;
116: // no need to find the resource if 'default' is passed in
117: if (!variant.equals(DEFAULT_RESOURCE_NAME)) {
118: if (c_cache.containsKey(variant))
119: resource = (PropertyResourceBundle) c_cache
120: .get(variant);
121: else
122: resource = loadResource(variant);
123: }
124:
125: if (resource == null) {
126: resource = c_defaultResource;
127: if (log.isDebugEnabled())
128: log
129: .debug("Resource file not found for the variant: "
130: + variant
131: + ". Will use the default resource");
132: }
133: } else {
134: resource = c_defaultResource;
135: }
136:
137: // Now get the property from the resource
138: try {
139: value = resource.getString(key);
140: } catch (MissingResourceException e) {
141: // check if the key is present in the default resource
142: if (resource != c_defaultResource) {
143: if (log.isDebugEnabled())
144: log
145: .debug("Key '"
146: + key
147: + "' not found in the variant resource file '"
148: + variant
149: + "'. Will check the default resource");
150: try {
151: value = c_defaultResource.getString(key);
152: } catch (MissingResourceException e1) {
153: String str = "Key '"
154: + key
155: + "' not found in the default resource file";
156: log.error(str, e1);
157: throw e1;
158: }
159: } else {
160: String str = "Key '" + key
161: + "' not found in the default resource file";
162: log.error(str, e);
163: throw e;
164: }
165: }
166:
167: return value;
168: }
169:
170: private synchronized static PropertyResourceBundle loadResource(
171: String variant) {
172: PropertyResourceBundle resource = null;
173: if (c_cache.containsKey(variant))
174: resource = (PropertyResourceBundle) c_cache.get(variant);
175: else {
176: try {
177: resource = (PropertyResourceBundle) PropertyResourceBundle
178: .getBundle(variant);
179: c_cache.put(variant, resource);
180: } catch (MissingResourceException e) {
181: // Add a null object for the variant into the cache. This will avoid repeated searches for the variant resource.
182: c_cache.put(variant, null);
183: }
184: }
185: return resource;
186: }
187:
188: }
|