ingo@1122: package de.intevation.gnv.geobackend.config;
ingo@1122:
ingo@1122: import de.intevation.gnv.geobackend.base.connectionpool.ConnectionPoolFactory;
ingo@1122:
ingo@1122: import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory;
ingo@1122:
ingo@1122: import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException;
ingo@1122:
ingo@1122: import de.intevation.gnv.geobackend.util.XMLUtils;
ingo@1122:
ingo@1122: import java.io.FileInputStream;
ingo@1122: import java.io.FileNotFoundException;
ingo@1122: import java.io.IOException;
ingo@1122: import java.io.InputStream;
ingo@1122:
ingo@1122: import java.util.Properties;
ingo@1122:
ingo@1122: import javax.xml.xpath.XPathConstants;
ingo@1122:
ingo@1122: import org.apache.log4j.Logger;
ingo@1122:
ingo@1122: import org.w3c.dom.Document;
ingo@1122: import org.w3c.dom.Node;
ingo@1122: import org.w3c.dom.NodeList;
ingo@1122:
ingo@1122: /**
ingo@1122: * @author Ingo Weinzierl
ingo@1122: */
ingo@1122: public final class Configuration {
ingo@1122:
ingo@1122: public static final String CONFIGURATION_ROOT = "geo-backend";
ingo@1122: public static final String XPATH_QUERIES = "query-configuration";
ingo@1122: public static final String XPATH_BACKEND = "backend-configuration";
ingo@1122: public static final String XPATH_CACHE = "cache";
ingo@1122: public static final String XPATH_CACHE_ENABLED = "@enabled";
ingo@1122: public static final String XPATH_CACHE_CONFIG = "configuration";
ingo@1122:
ingo@1122: private static Logger logger = Logger.getLogger(Configuration.class);
ingo@1122:
ingo@1122: private static Configuration instance;
ingo@1122:
ingo@1122: private Node config;
ingo@1122: private String configDir;
ingo@1122: private String placeholder;
ingo@1122:
ingo@1122: private boolean cacheEnabled;
ingo@1122: private String cacheConfiguration;
ingo@1122:
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Returns an instance of Configuration.
ingo@1122: *
ingo@1122: * @return an instance of Configuration.
ingo@1122: */
ingo@1122: public static Configuration getInstance() {
ingo@1122: if (instance == null)
ingo@1122: instance = new Configuration();
ingo@1122:
ingo@1122: return instance;
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Constructor that creates a new Configuration object with disabled cache.
ingo@1122: */
ingo@1122: public Configuration() {
ingo@1122: cacheEnabled = false;
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Initialize the geo-backend before it is ready to be used. This method
ingo@1122: * calls other init* methods.
ingo@1122: *
ingo@1122: * @param conf A configuration document. This document should contain a node
ingo@1122: * geo-backend. If there are more nodes named geo-backend, the
ingo@1122: * first node is used.
ingo@1122: * @param configDir The path to the root configuration directory.
ingo@1122: * @param placeholder The placeholder used in the configuration document for
ingo@1122: * the root configuration directory.
ingo@1122: */
ingo@1122: public void init(Document conf, String configDir, String placeholder)
ingo@1122: throws QueryContainerException, FileNotFoundException, IOException
ingo@1122: {
ingo@1122: this.config = conf;
ingo@1122: this.configDir = configDir;
ingo@1122: this.placeholder = placeholder;
ingo@1122:
ingo@1122: NodeList root = conf.getElementsByTagName(CONFIGURATION_ROOT);
ingo@1122: if (root == null || root.getLength() == 0) {
ingo@1122: logger.error("No valid configuration for this geobackend given!");
ingo@1122: return;
ingo@1122: }
ingo@1122:
ingo@1122: initQueries(root.item(0));
ingo@1122: initConnection(root.item(0));
ingo@1122: initCache(root.item(0));
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Initialize sql statements.
ingo@1122: *
ingo@1122: * @param conf The geo-backend configuration node.
ingo@1122: */
ingo@1122: protected void initQueries(Node conf)
ingo@1122: throws FileNotFoundException, IOException, QueryContainerException
ingo@1122: {
ingo@1122: String queriesFile = (String) XMLUtils.xpath(
ingo@1122: conf, XPATH_QUERIES, XPathConstants.STRING, null);
ingo@1122:
ingo@1122: queriesFile = replaceConfigDir(queriesFile);
ingo@1122: logger.info("Initialize queries: " + queriesFile);
ingo@1122:
ingo@1122: Properties queries = getProperties(queriesFile);
ingo@1122: QueryContainerFactory qcf = QueryContainerFactory.getInstance();
ingo@1122: qcf.initializeQueryContainer(queries);
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Initialize necessary objects used for the database connection.
ingo@1122: *
ingo@1122: * @param connection The geo-backend configuration node.
ingo@1122: */
ingo@1122: protected void initConnection(Node connection)
ingo@1122: throws FileNotFoundException, IOException
ingo@1122: {
ingo@1122: String config = (String)XMLUtils.xpath(
ingo@1122: connection, XPATH_BACKEND, XPathConstants.STRING, null);
ingo@1122:
ingo@1122: config = replaceConfigDir(config);
ingo@1122: logger.info("Initialize database connection: " + config);
ingo@1122:
ingo@1122: Properties properties = getProperties(config);
ingo@1122: ConnectionPoolFactory cpf = ConnectionPoolFactory.getInstance();
ingo@1122: cpf.initializeConnectionPool(properties);
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Initialize necessary objects used for the sql cache.
ingo@1122: *
ingo@1122: * @param conf The geo-backend configuration node.
ingo@1122: */
ingo@1122: protected void initCache(Node conf) {
ingo@1122: Node cache = (Node) XMLUtils.xpath(
ingo@1122: conf, XPATH_CACHE, XPathConstants.NODE, null);
ingo@1122:
ingo@1122: String on = (String) XMLUtils.xpath(
ingo@1122: cache, XPATH_CACHE_ENABLED, XPathConstants.STRING, null);
ingo@1122:
ingo@1122: boolean enabled = Boolean.parseBoolean(on);
ingo@1122:
ingo@1122: if (enabled) {
ingo@1122: String config = (String) XMLUtils.xpath(
ingo@1122: cache, XPATH_CACHE_CONFIG, XPathConstants.STRING, null);
ingo@1122:
ingo@1122: if (config != null && config.length() > 0) {
ingo@1122: config = replaceConfigDir(config);
ingo@1122: logger.info("Initialize sql cache with config: " + config);
ingo@1122:
ingo@1122: this.cacheConfiguration = config;
ingo@1122: this.cacheEnabled = true;
ingo@1122: }
ingo@1122: else {
ingo@1122: logger.error("SQL cache is enabled, " +
ingo@1122: "but no configuration was found.");
ingo@1122: }
ingo@1122: }
ingo@1122: else {
ingo@1122: logger.info("SQL cache is disabled.");
ingo@1122: }
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Replace placeholder in the configuration. Placeholder are used for the
ingo@1122: * base configuration directory.
ingo@1122: *
ingo@1122: * @param path A string that might contain placeholders.
ingo@1122: *
ingo@1122: * @return path with replaced placeholder.
ingo@1122: */
ingo@1122: protected String replaceConfigDir(String path) {
ingo@1122: return path.replace(placeholder, configDir);
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Read a file that contains properties and return a Java Properties object.
ingo@1122: *
ingo@1122: * @param path Path to a properties file.
ingo@1122: *
ingo@1122: * @return the properties contained in the file.
ingo@1122: */
ingo@1122: protected Properties getProperties(String path)
ingo@1122: throws FileNotFoundException, IOException
ingo@1122: {
ingo@1122: InputStream inputStream = null;
ingo@1122:
ingo@1122: try {
ingo@1122: inputStream = new FileInputStream(path);
ingo@1122: Properties properties = new Properties();
ingo@1122: properties.load(inputStream);
ingo@1122:
ingo@1122: return properties;
ingo@1122: }
ingo@1122: finally {
ingo@1122: if (inputStream != null) {
ingo@1122: try {
ingo@1122: inputStream.close();
ingo@1122: }
ingo@1122: catch (IOException ioe) {
ingo@1122: }
ingo@1122: }
ingo@1122: }
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Returns the state of the cache.
ingo@1122: *
ingo@1122: * @return true if sql queries are cache, otherwise false.
ingo@1122: */
ingo@1122: public boolean isCacheEnabled() {
ingo@1122: return cacheEnabled;
ingo@1122: }
ingo@1122:
ingo@1122:
ingo@1122: /**
ingo@1122: * Returns the path of the cache configuration file.
ingo@1122: *
ingo@1122: * @return configuration path.
ingo@1122: */
ingo@1122: public String getCacheConfiguration() {
ingo@1122: return cacheConfiguration;
ingo@1122: }
ingo@1122: }
ingo@1122: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :