/*
$Header: /cvsroot/xorm/xorm/src/org/xorm/util/AppConfig.java,v 1.5 2003/05/14 20:03:22 dcheckoway Exp $
This file is part of XORM.
XORM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
XORM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with XORM; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.xorm.util;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
/** Generic JDO application configuration. This object encapsulates the
basic functionality required to instantiate a set of properties and
a JDO persistence manager factory.
@author Dan Checkoway
@see AppConfigFactory
*/
public class AppConfig {
public static final String DEFAULT_CONNECTION_NAME = "__DEFAULT__";
protected Logger logger = Logger.getLogger(this.getClass().getName());
protected Properties props = new Properties();
protected Hashtable pmFactoriesByName = new Hashtable();
/** Constructor */
public AppConfig() {}
/** Constructor from Properties
@param props the Properties to clone and use
*/
public AppConfig(Properties props) {
this.props.putAll(props);
}
/** Load properties from a file or resource
@param propertyFileOrResource the file or resource path to the given
properties file; the file system is checked first, falling back on
the classpath
*/
protected void loadProperties(String propertyFileOrResource) {
logger.fine("Loading properties from file: " + propertyFileOrResource);
InputStream istream = null;
try {
// Try to read the file directly
istream = new FileInputStream(propertyFileOrResource);
}
catch (FileNotFoundException e) {
// Try to load it via the class path
istream = getClass().getResourceAsStream(propertyFileOrResource);
if (istream == null) {
logger.warning("Unable to load configuration file: " +
propertyFileOrResource);
return;
}
}
// Load properties from the stream
try {
props.load(istream);
}
catch (IOException e) {
logger.log(Level.WARNING,
"Error loading config file " + propertyFileOrResource,
e);
}
}
/** Load and absorb a set of properties
@param newProps the properties to absorb
*/
protected void loadProperties(Properties newProps) {
Iterator iter = props.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
props.setProperty((String)entry.getKey(), (String)entry.getValue());
}
}
/** Get a property value
@param propName the name of the value to get
@return the property value or null if not found
*/
public String getProperty(String propName) {
return props.getProperty(propName);
}
/** Get a property value with a default
@param propName the name of the value to get
@param defaultValue the value to return if the given property
was not explicitly set
@return the property value or the default value
*/
public String getProperty(String propName, String defaultValue) {
return props.getProperty(propName, defaultValue);
}
/** Get the underlying properties that this object wraps
@return the underlying properties
*/
public Properties getProperties() {
return props;
}
/** Get the default persistence manager factory
@return the default persistence manager factory
@see PersistenceManagerFactory
*/
public PersistenceManagerFactory getPersistenceManagerFactory() {
return getPersistenceManagerFactory(null);
}
/** Get the associated persistence manager factory
@param name the name of the connection, used as a property prefix
@return the persistence manager factory identified by the given name
@see PersistenceManagerFactory
*/
public PersistenceManagerFactory getPersistenceManagerFactory(String name)
{
String connName;
boolean useDefault = true;
if (name == null || name.equals("")) {
connName = DEFAULT_CONNECTION_NAME;
}
else {
connName = name;
useDefault = false;
}
PersistenceManagerFactory pmf = (PersistenceManagerFactory)
pmFactoriesByName.get(connName);
if (pmf == null) {
synchronized (this) {
Properties useProps;
if (useDefault) {
// Use the default connection properties
useProps = props;
}
else {
// Use name-prefixed connection properties
String prefix = name + ".";
useProps = new Properties();
Enumeration keys = props.keys();
// What we do here is find all of the properties that
// start with the given prefix and set the non-prefixed
// property to the prefixed property's value. For example,
// if we found:
// myConn.javax.jdo.option.ConnectionUserName somebody
// ...then we'll set:
// javax.jdo.option.ConnectionUserName somebody
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
String value = props.getProperty(key);
// First just copy the property as-is
useProps.setProperty(key, value);
// If it starts with the given connection prefix, then
// ditch the prefix and set it without the prefix.
if (key.startsWith(prefix) &&
key.length() > prefix.length()) {
String newKey = key.substring(prefix.length());
useProps.setProperty(newKey, value);
}
}
}
pmf = JDOHelper.getPersistenceManagerFactory(useProps);
pmFactoriesByName.put(connName, pmf);
}
}
return pmf;
}
/** Convenience method to get a persistence manager
@return a new persistence manager from the default persistence
manager factory
@see PersistenceManager
*/
public PersistenceManager getPersistenceManager() {
return getPersistenceManager(null);
}
/** Convenience method to get a persistence manager
@param name the name of the connection, used as a property prefix
@return a new persistence manager from the persistence manager factory
identified by the given name
@see PersistenceManager
*/
public PersistenceManager getPersistenceManager(String name) {
return getPersistenceManagerFactory(name).getPersistenceManager();
}
/** This is called by the JRE or servlet engine resource manager.
The propertiesFile, usually a parameter to the JNDI resource,
should point to the properties file to be loaded.
*/
public void setPropertiesFile(String propertiesFile) {
loadProperties(propertiesFile);
}
/**
* Convenience method for getting a new AppConfig instance.
* Internally, this constructs an AppConfigFactory and returns
* its configuration.
*/
public static AppConfig getAppConfig(String jndiConfigResource,
String configFileSystemProperty,
String defaultConfigFile)
{
return getAppConfig(jndiConfigResource,
configFileSystemProperty,
defaultConfigFile,
AppConfig.class);
}
/**
* Convenience method for getting a new AppConfig instance.
* Internally, this constructs an AppConfigFactory and returns
* its configuration.
*/
public static AppConfig getAppConfig(String jndiConfigResource,
String configFileSystemProperty,
String defaultConfigFile,
Class appConfigClass) {
return new AppConfigFactory(jndiConfigResource,
configFileSystemProperty,
defaultConfigFile,
appConfigClass).getAppConfig();
}
}