⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractconfiguration.java

📁 一个留言板 系统平台: JSP+SQLServer 支持开通无限个数的留言板
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * AbstractConfiguration.java * * Created on 2006年7月18日, 下午12:16 * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */package tot.xml;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.List;import java.util.NoSuchElementException;import java.util.Properties;import java.util.StringTokenizer;import java.util.Vector;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * Abstract configuration class. Provide basic functionality but does not * store any data. If you want to write your own Configuration class * then you should implement only abstract methods from this class. * * @author <a href="mailto:ksh@scand.com">Konstantin Shaposhnikov</a> * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a> * @version $Id: AbstractConfiguration.java,v 1.4 2004/06/01 13:25:39 skoehler Exp $ */public abstract class AbstractConfiguration implements Configuration{    /** how big the initial arraylist for splitting up name value pairs */    private static final int INITIAL_LIST_SIZE = 2;    private static Log log = LogFactory.getLog(AbstractConfiguration.class);    /**     * stores the configuration key-value pairs     */    protected Configuration defaults = null;    /** start token */    protected static final String START_TOKEN = "${";    /** end token */    protected static final String END_TOKEN = "}";    /**     * Empty constructor.     */    public AbstractConfiguration()    {    }    /**     * Creates an empty AbstractConfiguration object with     * a Super-Object which is queries for every key.     *     * @param defaults Configuration defaults to use if key not in file     */    public AbstractConfiguration(Configuration defaults)    {        this();        this.defaults = defaults;    }    /**     * Add a property to the configuration. If it already exists then the value     * stated here will be added to the configuration entry. For example, if     *     * resource.loader = file     *     * is already present in the configuration and you     *     * addProperty("resource.loader", "classpath")     *     * Then you will end up with a Vector like the following:     *     * ["file", "classpath"]     *     * @param key The Key to add the property to.     * @param token The Value to add.     */    public void addProperty(String key, Object token)    {        if (token instanceof String)        {            for(Iterator it = processString((String) token).iterator();            it.hasNext();)            {                addPropertyDirect(key, it.next());            }        }        else if (token instanceof Collection)        {            for (Iterator it = ((Collection) token).iterator(); it.hasNext();)            {                addProperty(key, it.next());            }        }        else        {            addPropertyDirect(key, token);        }    }    /**     * Read property. Should return <code>null</code> if the key doesn't     * map to an existing object.     *     * @param key key to use for mapping     *     * @return object associated with the given configuration key.     */    protected abstract Object getPropertyDirect(String key);    /**     * Adds a key/value pair to the Configuration. Override this method to     * provide write acces to underlying Configuration store.     *     * @param key key to use for mapping     * @param obj object to store     */    protected abstract void addPropertyDirect(String key, Object obj);    /**     * interpolate key names to handle ${key} stuff     *     * @param base string to interpolate     *     * @return returns the key name with the ${key} substituted     */    protected String interpolate(String base)    {        return (interpolateHelper(base, null));    }    /**     * Recursive handler for multple levels of interpolation.     *     * When called the first time, priorVariables should be null.     *     * @param base string with the ${key} variables     * @param priorVariables serves two purposes: to allow checking for     * loops, and creating a meaningful exception message should a loop     * occur.  It's 0'th element will be set to the value of base from     * the first call.  All subsequent interpolated variables are added     * afterward.     *     * @return the string with the interpolation taken care of     */    protected String interpolateHelper(String base, List priorVariables)    {        if (base == null)        {            return null;        }        // on the first call initialize priorVariables        // and add base as the first element        if (priorVariables == null)        {            priorVariables = new ArrayList();            priorVariables.add(base);        }        int begin = -1;        int end = -1;        int prec = 0 - END_TOKEN.length();        String variable = null;        StringBuffer result = new StringBuffer();        // FIXME: we should probably allow the escaping of the start token        while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length()))            > -1)            && ((end = base.indexOf(END_TOKEN, begin)) > -1))        {            result.append(base.substring(prec + END_TOKEN.length(), begin));            variable = base.substring(begin + START_TOKEN.length(), end);            // if we've got a loop, create a useful exception message and throw            if (priorVariables.contains(variable))            {                String initialBase = priorVariables.remove(0).toString();                priorVariables.add(variable);                StringBuffer priorVariableSb = new StringBuffer();                // create a nice trace of interpolated variables like so:                // var1->var2->var3                for (Iterator it = priorVariables.iterator(); it.hasNext();)                {                    priorVariableSb.append(it.next());                    if (it.hasNext())                    {                        priorVariableSb.append("->");                    }                }                throw new IllegalStateException(                    "infinite loop in property interpolation of "                        + initialBase                        + ": "                        + priorVariableSb.toString());            }            // otherwise, add this variable to the interpolation list.            else            {                priorVariables.add(variable);            }            //QUESTION: getProperty or getPropertyDirect            Object value = getProperty(variable);            if (value != null)            {                result.append(interpolateHelper(value.toString(),                    priorVariables));                // pop the interpolated variable off the stack                // this maintains priorVariables correctness for                // properties with multiple interpolations, e.g.                // prop.name=${some.other.prop1}/blahblah/${some.other.prop2}                priorVariables.remove(priorVariables.size() - 1);            }            else if (defaults != null && defaults.getString(variable,                null) != null)            {                result.append(defaults.getString(variable));            }            else            {                //variable not defined - so put it back in the value                result.append(START_TOKEN).append(variable).append(END_TOKEN);            }            prec = end;        }        result.append(base.substring(prec + END_TOKEN.length(), base.length()));        return result.toString();    }    /**     * Returns a Vector of Strings built from the supplied     * String. Splits up CSV lists. If no commas are in the     * String, simply returns a Vector with the String as its     * first element     *     * @param token The String to tokenize     *     * @return A List of Strings     */    protected List processString(String token)    {        List retList = new ArrayList(INITIAL_LIST_SIZE);        if (token.indexOf(PropertiesTokenizer.DELIMITER) > 0)        {            PropertiesTokenizer tokenizer =                new PropertiesTokenizer(token);            while (tokenizer.hasMoreTokens())            {                String value = tokenizer.nextToken();                retList.add(value);            }        }        else        {            retList.add(token);        }        //        // We keep the sequence of the keys here and        // we also keep it in the Container. So the        // Keys are added to the store in the sequence that        // is given in the properties        return retList;    }    /**     * Test whether the string represent by value maps to a boolean     * value or not. We will allow <code>true</code>, <code>on</code>,     * and <code>yes</code> for a <code>true</code> boolean value, and     * <code>false</code>, <code>off</code>, and <code>no</code> for     * <code>false</code> boolean values. Case of value to test for     * boolean status is ignored.     *     * @param value The value to test for boolean state.     * @return <code>true</code> or <code>false</code> if the supplied     * text maps to a boolean value, or <code>null</code> otherwise.     */    protected final Boolean testBoolean(String value)    {        String s = value.toLowerCase();        if (s.equals("true") || s.equals("on") || s.equals("yes"))        {            return Boolean.TRUE;        }        else if (s.equals("false") || s.equals("off") || s.equals("no"))        {            return Boolean.FALSE;        }        else        {            return null;        }    }    /**     * Create an BaseConfiguration object that is a subset     * of this one.     *     * @param prefix prefix string for keys     *     * @return subset of configuration if there is keys, that match     * given prefix, or <code>null</code> if there is no such keys.     */    public Configuration subset(String prefix)    {        BaseConfiguration c = new BaseConfiguration();        Iterator keys = this.getKeys();        boolean validSubset = false;        while (keys.hasNext())        {            Object key = keys.next();            if (key instanceof String && ((String) key).startsWith(prefix))            {                if (!validSubset)                {                    validSubset = true;                }                String newKey = null;                /*                 * Check to make sure that c.subset(prefix) doesn't blow up when                 * there is only a single property with the key prefix. This is                 * not a useful subset but it is a valid subset.                 */                if (((String) key).length() == prefix.length())                {                    newKey = prefix;                }                else                {                    newKey = ((String) key).substring(prefix.length() + 1);                }                /*                 * use addPropertyDirect() - this will plug the data as is into                 * the Map, but will also do the right thing re key accounting                 *                 * QUESTION: getProperty or getPropertyDirect                 */                Object value = getProperty((String) key);                if (value instanceof String)                {                    c.addPropertyDirect(newKey, interpolate((String) value));                }                else                {                    c.addProperty(newKey, value);                }            }        }        if (validSubset)        {            return c;        }        else        {            return null;        }    }    /**     * Check if the configuration is empty     *     * @return <code>true</code> if Configuration is empty,     * <code>false</code> otherwise.     */    public abstract boolean isEmpty();    /**     * check if the configuration contains the key     *     * @param key the configuration key     *     * @return <code>true</code> if Configuration contain given key,     * <code>false</code> otherwise.     */    public abstract boolean containsKey(String key);    /**     * Set a property, this will replace any previously     * set values. Set values is implicitly a call     * to clearProperty(key), addProperty(key,value).     *     * @param key the configuration key     * @param value the property value     */    public void setProperty(String key, Object value)    {        clearProperty(key);        addProperty(key, value); // QUESTION: or addPropertyDirect?    }    /**     * Clear a property in the configuration.     *     * @param key the key to remove along with corresponding value.     */    public  abstract void clearProperty(String key);    /**     * Get the list of the keys contained in the configuration     * repository.     *     * @return An Iterator.     */    public abstract Iterator getKeys();    /**     * Get the list of the keys contained in the configuration     * repository that match the specified prefix.     *     * @param prefix The prefix to test against.     *     * @return An Iterator of keys that match the prefix.     */    public Iterator getKeys(String prefix)    {        Iterator keys = getKeys();        ArrayList matchingKeys = new ArrayList();        while (keys.hasNext())        {            Object key = keys.next();            if (key instanceof String && ((String) key).startsWith(prefix))            {                matchingKeys.add(key);            }        }        return matchingKeys.iterator();    }    /**     * Get a list of properties associated with the given     * configuration key.     *     * @param key The configuration key.     *     * @return The associated properties if key is found.     *     * @throws ClassCastException is thrown if the key maps to an     * object that is not a String/Vector.     * @throws IllegalArgumentException if one of the tokens is     * malformed (does not contain an equals sign).     *     * @see #getProperties(String, Properties)     */    public Properties getProperties(String key)    {        return getProperties(key, null);    }    /**     * Get a list of properties associated with the given     * configuration key.     *     * @param key The configuration key.     * @param defaults Any default values for the returned     * <code>Properties</code> object.  Ignored if <code>null</code>.     *     * @return The associated properties if key is found.     *     * @throws ClassCastException is thrown if the key maps to an     * object that is not a String/Vector of Strings.     * @throws IllegalArgumentException if one of the tokens is     * malformed (does not contain an equals sign).     */    public Properties getProperties(String key, Properties defaults)    {        /*         * Grab an array of the tokens for this key.         */        String[] tokens = getStringArray(key);        /*         * Each token is of the form 'key=value'.         */        Properties props =            (defaults == null ? new Properties() : new Properties(defaults));        for (int i = 0; i < tokens.length; i++)        {            String token = tokens[i];            int equalSign = token.indexOf('=');            if (equalSign > 0)            {                String pkey = token.substring(0, equalSign).trim();                String pvalue = token.substring(equalSign + 1).trim();                props.put(pkey, pvalue);            }            else if (tokens.length == 1 && "".equals(token))            {                // Semantically equivalent to an empty Properties                // object.                break;            }            else            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -