changeset 1122:1985d5db0feb

Implemented a global configuration that should be used to initialize the geobackend. geo-backend/trunk@1149 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 03 Jun 2010 13:31:07 +0000
parents 9d530f913729
children f76541120bcb
files geo-backend/ChangeLog geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/CachingQueryExecutorFactory.java geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/QueryExecutorFactory.java geo-backend/src/main/java/de/intevation/gnv/geobackend/config/Configuration.java
diffstat 4 files changed, 300 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- 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 <ingo.weinzierl@intevation.de>
+
+	* 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 <ingo.weinzierl@intevation.de>
 
 	* src/main/java/de/intevation/gnv/geobackend/util/XMLUtils.java: Some
--- 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 <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
@@ -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() {
--- 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();
--- /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 <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+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 <i>init*</i> methods.
+     *
+     * @param conf A configuration document. This document should contain a node
+     * <i>geo-backend</i>. If there are more nodes named <i>geo-backend</i>, 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 <i>path</i> 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 :

http://dive4elements.wald.intevation.org