001: /*
002: $Header: /cvsroot/xorm/xorm/src/org/xorm/util/AppConfig.java,v 1.5 2003/05/14 20:03:22 dcheckoway Exp $
003:
004: This file is part of XORM.
005:
006: XORM is free software; you can redistribute it and/or modify
007: it under the terms of the GNU General Public License as published by
008: the Free Software Foundation; either version 2 of the License, or
009: (at your option) any later version.
010:
011: XORM is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU General Public License for more details.
015:
016: You should have received a copy of the GNU General Public License
017: along with XORM; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package org.xorm.util;
022:
023: import java.io.FileInputStream;
024: import java.io.FileNotFoundException;
025: import java.io.InputStream;
026: import java.io.IOException;
027: import java.util.Enumeration;
028: import java.util.Hashtable;
029: import java.util.Iterator;
030: import java.util.Map;
031: import java.util.Properties;
032: import java.util.logging.Logger;
033: import java.util.logging.Level;
034: import javax.jdo.JDOHelper;
035: import javax.jdo.PersistenceManager;
036: import javax.jdo.PersistenceManagerFactory;
037:
038: /** Generic JDO application configuration. This object encapsulates the
039: basic functionality required to instantiate a set of properties and
040: a JDO persistence manager factory.
041: @author Dan Checkoway
042: @see AppConfigFactory
043: */
044: public class AppConfig {
045: public static final String DEFAULT_CONNECTION_NAME = "__DEFAULT__";
046:
047: protected Logger logger = Logger.getLogger(this .getClass()
048: .getName());
049: protected Properties props = new Properties();
050: protected Hashtable pmFactoriesByName = new Hashtable();
051:
052: /** Constructor */
053: public AppConfig() {
054: }
055:
056: /** Constructor from Properties
057: @param props the Properties to clone and use
058: */
059: public AppConfig(Properties props) {
060: this .props.putAll(props);
061: }
062:
063: /** Load properties from a file or resource
064: @param propertyFileOrResource the file or resource path to the given
065: properties file; the file system is checked first, falling back on
066: the classpath
067: */
068: protected void loadProperties(String propertyFileOrResource) {
069: logger.fine("Loading properties from file: "
070: + propertyFileOrResource);
071: InputStream istream = null;
072: try {
073: // Try to read the file directly
074: istream = new FileInputStream(propertyFileOrResource);
075: } catch (FileNotFoundException e) {
076: // Try to load it via the class path
077: istream = getClass().getResourceAsStream(
078: propertyFileOrResource);
079: if (istream == null) {
080: logger.warning("Unable to load configuration file: "
081: + propertyFileOrResource);
082: return;
083: }
084: }
085:
086: // Load properties from the stream
087: try {
088: props.load(istream);
089: } catch (IOException e) {
090: logger.log(Level.WARNING, "Error loading config file "
091: + propertyFileOrResource, e);
092: }
093: }
094:
095: /** Load and absorb a set of properties
096: @param newProps the properties to absorb
097: */
098: protected void loadProperties(Properties newProps) {
099: Iterator iter = props.entrySet().iterator();
100: while (iter.hasNext()) {
101: Map.Entry entry = (Map.Entry) iter.next();
102: props.setProperty((String) entry.getKey(), (String) entry
103: .getValue());
104: }
105: }
106:
107: /** Get a property value
108: @param propName the name of the value to get
109: @return the property value or null if not found
110: */
111: public String getProperty(String propName) {
112: return props.getProperty(propName);
113: }
114:
115: /** Get a property value with a default
116: @param propName the name of the value to get
117: @param defaultValue the value to return if the given property
118: was not explicitly set
119: @return the property value or the default value
120: */
121: public String getProperty(String propName, String defaultValue) {
122: return props.getProperty(propName, defaultValue);
123: }
124:
125: /** Get the underlying properties that this object wraps
126: @return the underlying properties
127: */
128: public Properties getProperties() {
129: return props;
130: }
131:
132: /** Get the default persistence manager factory
133: @return the default persistence manager factory
134: @see PersistenceManagerFactory
135: */
136: public PersistenceManagerFactory getPersistenceManagerFactory() {
137: return getPersistenceManagerFactory(null);
138: }
139:
140: /** Get the associated persistence manager factory
141: @param name the name of the connection, used as a property prefix
142: @return the persistence manager factory identified by the given name
143: @see PersistenceManagerFactory
144: */
145: public PersistenceManagerFactory getPersistenceManagerFactory(
146: String name) {
147: String connName;
148: boolean useDefault = true;
149: if (name == null || name.equals("")) {
150: connName = DEFAULT_CONNECTION_NAME;
151: } else {
152: connName = name;
153: useDefault = false;
154: }
155:
156: PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmFactoriesByName
157: .get(connName);
158: if (pmf == null) {
159: synchronized (this ) {
160: Properties useProps;
161: if (useDefault) {
162: // Use the default connection properties
163: useProps = props;
164: } else {
165: // Use name-prefixed connection properties
166: String prefix = name + ".";
167: useProps = new Properties();
168: Enumeration keys = props.keys();
169: // What we do here is find all of the properties that
170: // start with the given prefix and set the non-prefixed
171: // property to the prefixed property's value. For example,
172: // if we found:
173: // myConn.javax.jdo.option.ConnectionUserName somebody
174: // ...then we'll set:
175: // javax.jdo.option.ConnectionUserName somebody
176: while (keys.hasMoreElements()) {
177: String key = (String) keys.nextElement();
178: String value = props.getProperty(key);
179: // First just copy the property as-is
180: useProps.setProperty(key, value);
181:
182: // If it starts with the given connection prefix, then
183: // ditch the prefix and set it without the prefix.
184: if (key.startsWith(prefix)
185: && key.length() > prefix.length()) {
186: String newKey = key.substring(prefix
187: .length());
188: useProps.setProperty(newKey, value);
189: }
190: }
191: }
192: pmf = JDOHelper.getPersistenceManagerFactory(useProps);
193: pmFactoriesByName.put(connName, pmf);
194: }
195: }
196: return pmf;
197: }
198:
199: /** Convenience method to get a persistence manager
200: @return a new persistence manager from the default persistence
201: manager factory
202: @see PersistenceManager
203: */
204: public PersistenceManager getPersistenceManager() {
205: return getPersistenceManager(null);
206: }
207:
208: /** Convenience method to get a persistence manager
209: @param name the name of the connection, used as a property prefix
210: @return a new persistence manager from the persistence manager factory
211: identified by the given name
212: @see PersistenceManager
213: */
214: public PersistenceManager getPersistenceManager(String name) {
215: return getPersistenceManagerFactory(name)
216: .getPersistenceManager();
217: }
218:
219: /** This is called by the JRE or servlet engine resource manager.
220: The propertiesFile, usually a parameter to the JNDI resource,
221: should point to the properties file to be loaded.
222: */
223: public void setPropertiesFile(String propertiesFile) {
224: loadProperties(propertiesFile);
225: }
226:
227: /**
228: * Convenience method for getting a new AppConfig instance.
229: * Internally, this constructs an AppConfigFactory and returns
230: * its configuration.
231: */
232: public static AppConfig getAppConfig(String jndiConfigResource,
233: String configFileSystemProperty, String defaultConfigFile) {
234: return getAppConfig(jndiConfigResource,
235: configFileSystemProperty, defaultConfigFile,
236: AppConfig.class);
237: }
238:
239: /**
240: * Convenience method for getting a new AppConfig instance.
241: * Internally, this constructs an AppConfigFactory and returns
242: * its configuration.
243: */
244: public static AppConfig getAppConfig(String jndiConfigResource,
245: String configFileSystemProperty, String defaultConfigFile,
246: Class appConfigClass) {
247: return new AppConfigFactory(jndiConfigResource,
248: configFileSystemProperty, defaultConfigFile,
249: appConfigClass).getAppConfig();
250: }
251: }
|