sascha@206: /* sascha@206: * Copyright (c) 2010 by Intevation GmbH sascha@206: * sascha@206: * This program is free software under the LGPL (>=v2.1) sascha@206: * Read the file LGPL.txt coming with the software for details sascha@206: * or visit http://www.gnu.org/licenses/ if it does not exist. sascha@206: */ sascha@206: teichmann@475: package org.dive4elements.artifacts.common.utils; sascha@206: sascha@206: import java.io.File; sascha@206: import java.io.IOException; sascha@206: sascha@206: import javax.xml.namespace.QName; sascha@206: sascha@206: import javax.xml.parsers.DocumentBuilderFactory; sascha@206: import javax.xml.parsers.ParserConfigurationException; sascha@206: sascha@206: import javax.xml.xpath.XPathConstants; sascha@206: tom@570: import org.apache.logging.log4j.Logger; tom@570: import org.apache.logging.log4j.LogManager; sascha@206: sascha@206: import org.w3c.dom.Document; sascha@206: import org.w3c.dom.Node; sascha@206: import org.w3c.dom.NodeList; sascha@206: sascha@206: import org.xml.sax.SAXException; sascha@206: sascha@206: /** sascha@206: * The central access to the configuration of the artifact database. sascha@206: * This class provides some static methods to access the central sascha@206: * configuration XML file via XPath. sascha@206: * sascha@206: * @author Sascha L. Teichmann sascha@206: */ sascha@206: public final class Config sascha@206: { tom@570: private static Logger logger = LogManager.getLogger(Config.class); sascha@206: sascha@206: /** sascha@206: * System property name where to find the configuration directory. sascha@206: */ sascha@206: public static final String CONFIG_DIR = "artifact.database.dir"; sascha@206: sascha@206: /** sascha@206: * Default path to the configuration directory if none sascha@206: * was specified by the CONFIG_DIR system property. sascha@206: */ sascha@206: public static final File CONFIG_DIR_DEFAULT = sascha@206: new File(new File(System.getProperty("user.home", sascha@206: System.getProperty("user.dir", "."))), ".artifactdb"); sascha@206: sascha@206: /** sascha@206: * Name of the central configuration XML file. sascha@206: */ sascha@206: public static final String CONFIG_FILE = "conf.xml"; sascha@206: sascha@206: /** sascha@206: * Name of the configuration filename alias to be use sascha@206: * within the configuration. This alias is replaced by sascha@206: * the real path. sascha@206: */ sascha@206: public static final String CONFIG_DIR_PLACEHOLDER = sascha@206: "${artifacts.config.dir}"; sascha@206: sascha@206: private static Document config; sascha@206: sascha@206: private Config() { sascha@206: } sascha@206: sascha@206: /** sascha@206: * Singleton access to the central XML configuration document. sascha@206: * @return The central XML configuration document. sascha@206: */ sascha@206: public static synchronized final Document getConfig() { sascha@206: if (config == null) { sascha@206: config = loadConfig(); sascha@206: } sascha@206: return config; sascha@206: } sascha@206: sascha@206: /** sascha@206: * Returns the path to the configuartion directory. If a path sascha@206: * was specified via the CONFIG_DIR system property this one sascha@206: * is used. Else it falls back to default configuration path. sascha@206: * @return The path to the configuartion directory. sascha@206: */ sascha@206: public static File getConfigDirectory() { sascha@206: String configDirString = System.getProperty(CONFIG_DIR); sascha@206: sascha@206: File configDir = configDirString != null sascha@206: ? new File(configDirString) sascha@206: : CONFIG_DIR_DEFAULT; sascha@206: sascha@206: if (!configDir.isDirectory()) { sascha@206: logger.warn("'" + configDir + "' is not a directory."); sascha@206: configDir = CONFIG_DIR_DEFAULT; sascha@206: } sascha@206: sascha@206: return configDir; sascha@206: } sascha@206: sascha@206: /** sascha@206: * Replaces the CONFIG_DIR_PLACEHOLDER alias with the real path sascha@206: * of the configuration directory. sascha@206: * @param path The path containing the CONFIG_DIR_PLACEHOLDER placeholder. sascha@206: * @return The path where the CONFIG_DIR_PLACEHOLDER placeholders are sascha@206: * replaced by the real path name. sascha@206: */ sascha@206: public static String replaceConfigDir(String path) { sascha@206: String configDir = getConfigDirectory().getAbsolutePath(); sascha@206: return path.replace(CONFIG_DIR_PLACEHOLDER, configDir); sascha@206: } sascha@206: sascha@206: private static Document loadConfig() { sascha@206: sascha@206: File configDir = getConfigDirectory(); sascha@206: sascha@206: File file = new File(configDir, CONFIG_FILE); sascha@206: sascha@206: if (!file.canRead() && !file.isFile()) { sascha@206: logger.error("Cannot read config file '" sascha@206: + file + "'."); sascha@206: return null; sascha@206: } sascha@206: sascha@206: try { sascha@206: DocumentBuilderFactory factory = sascha@206: DocumentBuilderFactory.newInstance(); sascha@206: factory.setValidating(false); // XXX: This may change in future. sascha@206: return factory.newDocumentBuilder().parse(file); sascha@206: } sascha@206: catch (SAXException se) { sascha@206: logger.error(se.getLocalizedMessage(), se); sascha@206: } sascha@206: catch (ParserConfigurationException pce) { sascha@206: logger.error(pce.getLocalizedMessage(), pce); sascha@206: } sascha@206: catch (IOException ioe) { sascha@206: logger.error(ioe.getLocalizedMessage()); sascha@206: } sascha@206: sascha@206: return null; sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search within a given document tree via XPath. sascha@206: * See {@link XMLUtils#xpath(Object, String, QName) } for details. sascha@206: * @param root The object which is used as the root of the tree to sascha@206: * be searched in. sascha@206: * @param query The XPath query. sascha@206: * @param returnType The type of the result. sascha@206: * @return The result of type 'returnTyp' or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final Object getXPath( sascha@206: Object root, String query, QName returnType sascha@206: ) { sascha@206: return XMLUtils.xpath(root, query, returnType); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search within the central configuration via XPath. sascha@206: * See {@link XMLUtils#xpath(Object, String, QName) } for details. sascha@206: * @param query The XPath query. sascha@206: * @param returnType The type of the result. sascha@206: * @return The result of type 'returnTyp' or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final Object getXPath(String query, QName returnType) { sascha@206: return XMLUtils.xpath(getConfig(), query, returnType); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a node list within the central sascha@206: * configuation document via XPath. sascha@206: * @param query The XPath query. sascha@206: * @return The queried node list or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final NodeList getNodeSetXPath(String query) { sascha@206: return (NodeList)getXPath(query, XPathConstants.NODESET); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a node within the central sascha@206: * configuation document via XPath. sascha@206: * @param query The XPath query. sascha@206: * @return The queried node or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final Node getNodeXPath(String query) { sascha@206: return (Node)getXPath(query, XPathConstants.NODE); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a string within the central sascha@206: * configuation document via XPath. sascha@206: * @param xpath The XPath query. sascha@206: * @return The queried string or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final String getStringXPath(String xpath) { sascha@206: return getStringXPath(xpath, null); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a string within the central sascha@206: * configuation document via XPath. sascha@206: * @param query The XPath query. sascha@206: * @param def The string to be returned if the search has no results. sascha@206: * @return The queried string or the default value if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final String getStringXPath(String query, String def) { sascha@206: String s = (String)getXPath(query, XPathConstants.STRING); sascha@206: return s == null || s.length() == 0 sascha@206: ? def sascha@206: : s; sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a node list within a given tree sascha@206: * via XPath. sascha@206: * @param root The root of the tree to be searched in. sascha@206: * @param query The XPath query. sascha@206: * @return The queried node list or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final NodeList getNodeSetXPath(Object root, String query) { sascha@206: return (NodeList)getXPath(root, query, XPathConstants.NODESET); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a node within a given tree sascha@206: * via XPath. sascha@206: * @param root The root of the tree to be searched in. sascha@206: * @param query The XPath query. sascha@206: * @return The queried node or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final Node getNodeXPath(Object root, String query) { sascha@206: return (Node)getXPath(root, query, XPathConstants.NODE); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a string within a given tree sascha@206: * via XPath. sascha@206: * @param root The root of the tree to be searched in. sascha@206: * @param xpath The XPath query. sascha@206: * @return The queried string or null if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final String getStringXPath(Object root, String xpath) { sascha@206: return getStringXPath(root, xpath, null); sascha@206: } sascha@206: sascha@206: /** sascha@206: * Convenience method to search for a string within a given tree sascha@206: * via XPath. sascha@206: * @param root The root of the tree to be searched in. sascha@206: * @param query xpath The XPath query. sascha@206: * @param def The string to be returned if the search has no results. sascha@206: * @return The queried string or the default value if something went sascha@206: * wrong during XPath evaluation. sascha@206: */ sascha@206: public static final String getStringXPath( sascha@206: Object root, String query, String def sascha@206: ) { sascha@206: String s = (String)getXPath(root, query, XPathConstants.STRING); sascha@206: return s == null || s.length() == 0 sascha@206: ? def sascha@206: : s; sascha@206: } sascha@206: } sascha@206: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :