/** * '$RCSfile: Config.java,v $' * * '$Author: barseghian $' * '$Date: 2007/10/11 00:36:37 $' * '$Revision: 1.22 $' * * For Details: http://kepler.ecoinformatics.org * * Copyright (c) 2003 The Regents of the University of California. * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY * OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ package org.ecoinformatics.util; import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Vector; import javax.xml.transform.TransformerException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xpath.XPathAPI; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import edu.ucsb.nceas.configxml.ConfigXML; import edu.ucsb.nceas.configxml.exception.ElementNotFoundException; import edu.ucsb.nceas.configxml.exception.IndexTooLargeException; import java.net.URL; /** * * configuration file routines * */ public class Config { //private static final String configfilename = "kepler/config.xml"; private static final String configfilename = "config.xml"; private static final String settingsdir = ".kepler"; // Define useful static strings. At some point in time, these could be moved // into the config.xml file, environment variable, or something else // which could move this directory to another location. // KEPLER_USER_DIR is returned by Config.getUserDirPath(). private static final String KEPLER_USER_DIR = System.getProperty("user.home") + File.separator + settingsdir + File.separator; // KEPLER_CACHE_DIR is returned by Config.getCacheDirPath(). private static final String KEPLER_CACHE_DIR = KEPLER_USER_DIR + "cache" + File.separator; /** * The singleton instance. */ private static Config configure ; static { configure = new Config(); } private static Log log; static { log = LogFactory.getLog("org.ecoinformatics.util.Config"); } // Instance variables. /** * The underlying ConfigXML object. */ private ConfigXML config; /** * Error indicator. Set to true if ConfigXML has problems. */ private boolean error = false; /** * Method for get object as a singleton class * @return Config */ public static Config getInstance() { return configure; } /* * Constructor for ConfigDatasource. * @throws FileNotFoundException * @throws Exception */ private Config() { try { InputStream is = this.getClass().getClassLoader().getResourceAsStream(configfilename); if (is == null) { throw new FileNotFoundException("Failed to find \"" + configfilename + "\" as a resource"); } URL configFileURL = this.getClass().getClassLoader().getSystemResource(configfilename); File configFile = new File(configFileURL.toURI()); config = new ConfigXML( is, configFile.getAbsolutePath() ); //config = new ConfigXML(configfilename); } catch(FileNotFoundException fnfe) { error = true; throw new RuntimeException("Config file not found at " + configfilename, fnfe ); } catch(Exception e) { error = true; throw new RuntimeException("Unspecified error creating config object: ", e ); } } /** * Method to get a string value from config.xml base on given element path * @param path String * @return String */ public static String getValue(String path) { Config configInstance = Config.getInstance(); return configInstance.getValueFromPath(path); } private String getValueFromPath(String path) { String value = null; if ( error ) { return value; } if ( path == null ) { return value; } try { Vector valueVector = config.getValuesForPath(path); value = (String) valueVector.elementAt(0); } catch ( ElementNotFoundException e1 ) { log.debug("Element " + path + " not found"); } catch ( Exception e2 ) { log.error("Exception occurred:", e2 ); } log.debug("The value for path " + path + " in config.xml is " + ((value==null) ? "null" : value) ); return value; }//getValues /** * Method returns an unmodifiable list of values from config.xml base on given path. * If the argument is null or not found in config.xml, return EMPTY_LIST. * * @param path String * @return Vector */ public static List getList(String path) { Config configInstance = Config.getInstance(); return configInstance.getListFromPath(path); } private List getListFromPath(String path) { List value = Collections.EMPTY_LIST; if ( error ) { return value; } if ( path == null ) { return value; } try { value = Collections.unmodifiableList(config.getValuesForPath(path)); } catch ( ElementNotFoundException e1 ) { log.debug("Element " + path + " not found"); } catch ( Exception e2 ) { log.error("Exception occurred:", e2 ); } return value; }//getList /** * Method to get unmodifiable map for some given pathes in config.xml. * If the arguments are invalid (either null) or not found, return an empty map. * Here is the segment of config.xml: * * key1 * value1 * * * key2 * value2 * * The parentPath can be "//parentElement", keyPath should be "./keyElement", * and valuePath should be "./valuePath". * @param parentPath String * @param keyPath String * @param valuePath String * @throws ElementNotFoundException * @throws Exception * @return Hashtable */ public static Map getMap(String parentPath, String keyPath, String valuePath) { Config configInstance = Config.getInstance(); return configInstance.getMapFromPath(parentPath, keyPath, valuePath); } private Map getMapFromPath(String parentPath, String keyPath, String valuePath) { Map map = Collections.EMPTY_MAP; if ( error ) { return map; } if ( parentPath == null || keyPath == null || valuePath == null ) { return map; } NodeList nl = null; try { nl = config.getPathContent(parentPath); } catch ( ElementNotFoundException e1 ) { log.debug("Element " + parentPath + " not found"); return map; } catch ( TransformerException e2 ) { log.error("Transfomer Exception when reading parentPath " + parentPath, e2); return map; } // At this point nl != null because we didn't get an ElementNotFoundException map = new Hashtable(); try { for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); Node keyNode = XPathAPI.selectSingleNode(n, keyPath); Node valueNode = XPathAPI.selectSingleNode(n, valuePath); if (keyNode == null || valueNode == null) { log.debug("keyNode or valueNode not found at iteration " + i); continue; } String keyNodeValue = keyNode.getFirstChild().getNodeValue(); String valueNodeValue = valueNode.getFirstChild().getNodeValue(); if (keyNodeValue == null || valueNodeValue == null) { log.debug("keyNodeValue or valueNodeValue is null at iteration " + i); continue; } log.debug("The value of " + keyPath + " " + keyNodeValue + " and " + " the value of " + valuePath + " " + valueNodeValue + " are put into mapping"); map.put(keyNodeValue, valueNodeValue); } //for } catch ( TransformerException e ) { log.error("Transfomer Exception in loop ", e); } return Collections.unmodifiableMap(map); }//getMap /** * Get a node list base on the given xpath in config file * @param path String the xpath * @return NodeList */ public static NodeList getNodeListFromPath(String path) { Config configInstance = Config.getInstance(); return configInstance.getNodeListFromXPath(path); } /* * This method will get a node list from config file */ private NodeList getNodeListFromXPath(String xpath) { NodeList list = null; if ( error ) { return list; } try { list = config.getPathContent(xpath); } catch (ElementNotFoundException e) { log.debug("Element Not found for " + xpath ); } catch ( TransformerException e2 ) { log.error( "Transformer Exception for " + xpath ); } return list; } /** * Method to get error state */ public boolean getErrorState() { return error; } /** * Returns the path of the Kepler hidden working directory terminated with File.seperator. * This directory is current coded to be ${system.home}/.kepler. * * @return the path to the .kepler directory. */ public static String getUserDirPath() { return KEPLER_USER_DIR; } /** * Returns the path to a subdirectory of the working directory. * The pathname is normalized to use the system style File.separator. * * * @param path a subdirectory of the working directory * @return normalized pathname of the subdirectory. */ public static String getUserDirPath( String path ) { String pdir = path; // In the config file we use unix style separators. // Convert them to windows if on windows. if ( '/' != File.separatorChar ) { pdir.replace('/', File.separatorChar ); } pdir = KEPLER_USER_DIR + path; if ( pdir.endsWith(File.separator) ) { return pdir; } else { return pdir + File.separator; } } /** * Returns the path to the Cache working directory terminated with File.seperator. * This directory is currently in getUserDirPath() + "cache". * * @return the path to the cache directory */ public static String getCacheDirPath() { return KEPLER_CACHE_DIR; } /** * Method save. - pass through to ConfigXML member * @throws Exception */ public void save() throws Exception { config.save(); } /** * Method set. - pass through to ConfigXML member * @param arg1 * @param arg2 * @param arg3 * @throws ElementNotFoundException */ public void set(String arg1, int arg2, String arg3) throws ElementNotFoundException { config.set(arg1, arg2, arg3); } /** * Method deleteSubFields. - pass through to ConfigXML member * @param parentName * @param i * @throws IndexTooLargeException */ public void deleteSubFields(String parentName, int i) throws IndexTooLargeException { config.deleteSubFields(parentName, i); } /** * Method addSubFields. - pass through to ConfigXML member * @param parentName * @param i * @param childName * @param value * @throws IndexTooLargeException */ public void addSubField(String parentName, int i, String childName, String value) throws IndexTooLargeException { config.addSubField(parentName, i, childName, value); } }