# HG changeset patch # User Ingo Weinzierl # Date 1275571867 0 # Node ID 1985d5db0feb02f702f0b56f17f7a1e4a5f1d2af # Parent 9d530f9137298259954c26ad97448fc3dac43d13 Implemented a global configuration that should be used to initialize the geobackend. geo-backend/trunk@1149 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 9d530f913729 -r 1985d5db0feb geo-backend/ChangeLog --- a/geo-backend/ChangeLog Thu Jun 03 12:35:35 2010 +0000 +++ b/geo-backend/ChangeLog Thu Jun 03 13:31:07 2010 +0000 @@ -1,3 +1,26 @@ +2010-06-03 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/geobackend/config/Configuration.java: A + global configuration for this geo-backend. Before using the geo-backend, + it is now necessary to create an instance of this class and call its + initialize(.) method. This method currently takes the following arguments: + + - conf: an xml document that should contain a node named 'geo-backend' + that contains all configurations required by the geo-backend. + - configDir: the absolute path to the root configuration directory that + might contain further configuration files. + - placeholder: the placeholder string that is used in the central config + file to replace the path to the configuration directory. + + Furthermore, this Configuration is used to initialize the so-called + 'sql-cache' that caches sql statements - it has been configured via system + properties until now. + + * src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java, + src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java: + The sql-cache configuration is not read from system properties but from + global configuration now. + 2010-06-03 Ingo Weinzierl * src/main/java/de/intevation/gnv/geobackend/util/XMLUtils.java: Some diff -r 9d530f913729 -r 1985d5db0feb geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java --- a/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java Thu Jun 03 12:35:35 2010 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java Thu Jun 03 13:31:07 2010 +0000 @@ -11,6 +11,7 @@ import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.geobackend.base.query.cache.CacheCleaner; +import de.intevation.gnv.geobackend.config.Configuration; /** * @author Sascha L. Teichmann @@ -18,7 +19,6 @@ public class CachingQueryExecutorFactory extends QueryExecutorFactory { - public static final String QUERY_EXECUTOR_FACTORY = "caching.query.executor.config"; public static final String CACHE_NAME = "sql.cache"; private static Logger log = Logger.getLogger(CachingQueryExecutorFactory.class); @@ -27,13 +27,27 @@ public CachingQueryExecutorFactory() { log.info("using SQL cache"); - String configFile = System.getProperty(QUERY_EXECUTOR_FACTORY); - manager = configFile != null - ? new CacheManager(configFile) - : new CacheManager(); - manager.addCache(CACHE_NAME); - CacheCleaner cc = new CacheCleaner(); - cc.start(); + + init(); + } + + private void init() { + Configuration config = Configuration.getInstance(); + + if (config == null) { + log.error("No geobackend configuration found. " + + "Wasn't able to initialize cache."); + return; + } + else { + String configFile = config.getCacheConfiguration(); + manager = configFile != null + ? new CacheManager(configFile) + : new CacheManager(); + manager.addCache(CACHE_NAME); + CacheCleaner cc = new CacheCleaner(); + cc.start(); + } } public QueryExecutor getQueryExecutor() { diff -r 9d530f913729 -r 1985d5db0feb geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java --- a/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java Thu Jun 03 12:35:35 2010 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java Thu Jun 03 13:31:07 2010 +0000 @@ -1,5 +1,7 @@ package de.intevation.gnv.geobackend.base.query; +import de.intevation.gnv.geobackend.config.Configuration; + import org.apache.log4j.Logger; /** @@ -34,32 +36,18 @@ */ public static synchronized QueryExecutorFactory getInstance(){ if (instance == null) { - String className = System.getProperty(QUERY_EXECUTOR_FACTORY); - if (className != null) { - try { - Class clazz = Class.forName(className); - final QueryExecutorFactory factory = - (QueryExecutorFactory)clazz.newInstance(); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - factory.shutdown(); - } - }); - return instance = factory; - } - catch (ClassNotFoundException cnfe) { - log.error(cnfe); - } - catch (InstantiationException ie) { - log.error(ie); - } - catch(IllegalAccessException iae) { - log.error(iae); - } - catch (ClassCastException cce) { - log.error(cce); - } + Configuration config = Configuration.getInstance(); + + if (config.isCacheEnabled()) { + final QueryExecutorFactory factory = + new CachingQueryExecutorFactory(); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + factory.shutdown(); + } + }); + return instance = factory; } instance = new QueryExecutorFactory(); diff -r 9d530f913729 -r 1985d5db0feb geo-backend/src/main/java/de/intevation/gnv/geobackend/config/Configuration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/config/Configuration.java Thu Jun 03 13:31:07 2010 +0000 @@ -0,0 +1,241 @@ +package de.intevation.gnv.geobackend.config; + +import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory; + +import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory; + +import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException; + +import de.intevation.gnv.geobackend.util.XMLUtils; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.util.Properties; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * @author Ingo Weinzierl + */ +public final class Configuration { + + public static final String CONFIGURATION_ROOT = "geo-backend"; + public static final String XPATH_QUERIES = "query-configuration"; + public static final String XPATH_BACKEND = "backend-configuration"; + public static final String XPATH_CACHE = "cache"; + public static final String XPATH_CACHE_ENABLED = "@enabled"; + public static final String XPATH_CACHE_CONFIG = "configuration"; + + private static Logger logger = Logger.getLogger(Configuration.class); + + private static Configuration instance; + + private Node config; + private String configDir; + private String placeholder; + + private boolean cacheEnabled; + private String cacheConfiguration; + + + + /** + * Returns an instance of Configuration. + * + * @return an instance of Configuration. + */ + public static Configuration getInstance() { + if (instance == null) + instance = new Configuration(); + + return instance; + } + + + /** + * Constructor that creates a new Configuration object with disabled cache. + */ + public Configuration() { + cacheEnabled = false; + } + + + /** + * Initialize the geo-backend before it is ready to be used. This method + * calls other init* methods. + * + * @param conf A configuration document. This document should contain a node + * geo-backend. If there are more nodes named geo-backend, the + * first node is used. + * @param configDir The path to the root configuration directory. + * @param placeholder The placeholder used in the configuration document for + * the root configuration directory. + */ + public void init(Document conf, String configDir, String placeholder) + throws QueryContainerException, FileNotFoundException, IOException + { + this.config = conf; + this.configDir = configDir; + this.placeholder = placeholder; + + NodeList root = conf.getElementsByTagName(CONFIGURATION_ROOT); + if (root == null || root.getLength() == 0) { + logger.error("No valid configuration for this geobackend given!"); + return; + } + + initQueries(root.item(0)); + initConnection(root.item(0)); + initCache(root.item(0)); + } + + + /** + * Initialize sql statements. + * + * @param conf The geo-backend configuration node. + */ + protected void initQueries(Node conf) + throws FileNotFoundException, IOException, QueryContainerException + { + String queriesFile = (String) XMLUtils.xpath( + conf, XPATH_QUERIES, XPathConstants.STRING, null); + + queriesFile = replaceConfigDir(queriesFile); + logger.info("Initialize queries: " + queriesFile); + + Properties queries = getProperties(queriesFile); + QueryContainerFactory qcf = QueryContainerFactory.getInstance(); + qcf.initializeQueryContainer(queries); + } + + + /** + * Initialize necessary objects used for the database connection. + * + * @param connection The geo-backend configuration node. + */ + protected void initConnection(Node connection) + throws FileNotFoundException, IOException + { + String config = (String)XMLUtils.xpath( + connection, XPATH_BACKEND, XPathConstants.STRING, null); + + config = replaceConfigDir(config); + logger.info("Initialize database connection: " + config); + + Properties properties = getProperties(config); + ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance(); + cpf.initializeConnectionPool(properties); + } + + + /** + * Initialize necessary objects used for the sql cache. + * + * @param conf The geo-backend configuration node. + */ + protected void initCache(Node conf) { + Node cache = (Node) XMLUtils.xpath( + conf, XPATH_CACHE, XPathConstants.NODE, null); + + String on = (String) XMLUtils.xpath( + cache, XPATH_CACHE_ENABLED, XPathConstants.STRING, null); + + boolean enabled = Boolean.parseBoolean(on); + + if (enabled) { + String config = (String) XMLUtils.xpath( + cache, XPATH_CACHE_CONFIG, XPathConstants.STRING, null); + + if (config != null && config.length() > 0) { + config = replaceConfigDir(config); + logger.info("Initialize sql cache with config: " + config); + + this.cacheConfiguration = config; + this.cacheEnabled = true; + } + else { + logger.error("SQL cache is enabled, " + + "but no configuration was found."); + } + } + else { + logger.info("SQL cache is disabled."); + } + } + + + /** + * Replace placeholder in the configuration. Placeholder are used for the + * base configuration directory. + * + * @param path A string that might contain placeholders. + * + * @return path with replaced placeholder. + */ + protected String replaceConfigDir(String path) { + return path.replace(placeholder, configDir); + } + + + /** + * Read a file that contains properties and return a Java Properties object. + * + * @param path Path to a properties file. + * + * @return the properties contained in the file. + */ + protected Properties getProperties(String path) + throws FileNotFoundException, IOException + { + InputStream inputStream = null; + + try { + inputStream = new FileInputStream(path); + Properties properties = new Properties(); + properties.load(inputStream); + + return properties; + } + finally { + if (inputStream != null) { + try { + inputStream.close(); + } + catch (IOException ioe) { + } + } + } + } + + + /** + * Returns the state of the cache. + * + * @return true if sql queries are cache, otherwise false. + */ + public boolean isCacheEnabled() { + return cacheEnabled; + } + + + /** + * Returns the path of the cache configuration file. + * + * @return configuration path. + */ + public String getCacheConfiguration() { + return cacheConfiguration; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :