/* * Copyright 2009 VoidSearch.com * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.voidsearch.voidbase.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.ConfigurationException; import com.voidsearch.voidbase.util.GenericUtil; import java.io.File; import java.util.*; public class VoidBaseConfig { XMLConfiguration config = null; protected static VoidBaseConfig container = null; protected static final Logger logger = LoggerFactory.getLogger(VoidBaseConfig.class.getName()); public static final String DEFAULT_PATH = "conf/"; protected VoidBaseConfig() { super(); } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public static synchronized VoidBaseConfig getInstance() throws ConfigException { if (container == null) { container = new VoidBaseConfig(); container.init(); } return container; } public static synchronized VoidBaseConfig getInstance(String files) throws ConfigException { if (container == null) { container = new VoidBaseConfig(); container.init(files); } return container; } public void init() throws ConfigException { init(null); } public void init(String files) throws ConfigException { List<String> fileList; // get file list if (files == null) { logger.info("Configuration not set - initialize from './conf' dir"); fileList = getConfigFiles(); } else { fileList = Arrays.asList(files.split(",")); } // santy check if (fileList == null || fileList.size() == 0) { throw new ConfigException("No valid configuration file."); } config = mergeConfiguration(fileList); } protected XMLConfiguration mergeConfiguration(List<String> files) throws ConfigException { XMLConfiguration config = new XMLConfiguration(); for (String file : files) { Iterator<String> keys; XMLConfiguration fragment; try { logger.info("Loading configuration file: " + file); fragment = new XMLConfiguration(file); keys = fragment.getKeys(); } catch (ConfigurationException e) { GenericUtil.logException(e); throw new ConfigException("Failed to load configuration from: " + file); } while (keys.hasNext()) { String key = keys.next(); // sanity check if (config.containsKey(key)) { throw new ConfigException("Collision of keys for: " + key); } // merge configuration config.addProperty(key, fragment.getProperty(key)); } } return config; } protected void setXMLConfig(XMLConfiguration config) { this.config = config; } protected XMLConfiguration getXMLConfig() { return config; } public String getString(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return config.getString(path.toString()); } public Double getDouble(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return config.getDouble(path.toString()); } public Integer getInteger(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return config.getInt(path.toString()); } public Boolean getBoolean(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return config.getBoolean(path.toString()); } public String getAttribute(String name, String key, String attribute) { String path = getPath(name, key); // sanity check if (path == null) return null; return getAttribute(path.toString(), attribute); } public List<String> getAttributes(String name, String key, String attribute) { String path = getPath(name, key); // sanity check if (path == null) return null; return getAttributes(path.toString(), attribute); } public String getString(String key) { if (key == null) return null; return config.getString(key); } public Double getDouble(String key) { if (key == null) return null; return config.getDouble(key); } public Integer getInteger(String key) { if (key == null) return null; return config.getInt(key); } public Boolean getBoolean(String key) { if (key == null) return null; return config.getBoolean(key); } public List<String> getList(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return getList(path.toString()); } public Set<String> getKeys(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return getKeys(path.toString()); } public Map<String, String> getMap(String name, String key) { String path = getPath(name, key); // sanity check if (path == null) return null; return getMap(path.toString()); } public List<String> getList(String key) { Iterator iterator; ArrayList<String> list = new ArrayList<String>(); if (key == null) return null; iterator = config.getKeys(key); while (iterator.hasNext()) { Integer rpos = 0; String newKey = null; String subKey = (String) iterator.next(); // sanity check if (!subKey.startsWith(key)) { logger.error("Bad key: " + key); continue; } else if (subKey.length() <= key.length()) { continue; } // get key cutoff rpos = subKey.indexOf(".", key.length() + 1); rpos = rpos < 0 ? subKey.length() : rpos; newKey = subKey.substring(key.length() + 1, rpos); if (!list.contains(newKey)) { list.add(newKey); } } return list; } public Set<String> getKeys(String key) { Iterator iterator; Set<String> list = new HashSet<String>(); if (key == null) return null; iterator = config.getKeys(key); while (iterator.hasNext()) { String subKey = cleanKey((String) iterator.next()); list.add(subKey); } return list; } public Map<String, String> getMap(String key) { Iterator iterator; HashMap<String, String> map = new HashMap<String, String>(); if (key == null) return null; iterator = config.getKeys(key); while (iterator.hasNext()) { String subKey = (String) iterator.next(); List elements = config.getList(subKey); for (Object element : elements) { map.put(cleanKey(subKey), element.toString()); } } return map; } public String getAttribute(String key, String attribute) { StringBuilder attributeKey = new StringBuilder(key); if (key == null) return null; attributeKey.append("[@").append(attribute).append("]"); return config.getString(attributeKey.toString()); } public List<String> getAttributes(String key, String attribute) { Iterator iterator; ArrayList<String> list = new ArrayList<String>(); StringBuilder attributeKey = new StringBuilder(key); if (key == null) return null; attributeKey.append("@").append(attribute); iterator = config.getKeys(attributeKey.toString()); while (iterator.hasNext()) { String subKey = (String) iterator.next(); List elements = config.getList(subKey); for (Object element : elements) { list.add(element.toString()); } } return list; } protected String getPath(String name, String key) { StringBuilder path = new StringBuilder(); // sanity check if (name == null || key == null) { logger.debug("'name' or 'key' are null"); return null; } if (config == null) { logger.warn("Configuration not initialized."); return null; } // build a path path.append(name).append(".") .append(key); return path.toString(); } protected ArrayList<String> getConfigFiles() { File dir = new File(DEFAULT_PATH); ArrayList<String> files = new ArrayList<String>(); for (File file : dir.listFiles()) { if (file.isFile()) { files.add(file.getAbsolutePath()); } } return files; } protected String cleanKey(String key) { Integer lpos; Integer rpos; if (key == null) return null; lpos = key.lastIndexOf("."); if (lpos < 0) return key; if (lpos == key.length()) return ""; rpos = key.indexOf("["); if (rpos < 0) return key.substring(lpos + 1, key.length()); return key.substring(lpos + 1, rpos); } }