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

📄 xmlproperties.java

📁 基于Jabber协议的即时消息服务器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * $RCSfile$ * $Revision: 5867 $ * $Date: 2006-10-26 16:53:30 -0700 (Thu, 26 Oct 2006) $ * * Copyright (C) 2004 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution. */package org.jivesoftware.util;import org.dom4j.CDATA;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.Node;import org.dom4j.io.OutputFormat;import org.dom4j.io.SAXReader;import java.io.*;import java.util.*;/** * Provides the the ability to use simple XML property files. Each property is * in the form X.Y.Z, which would map to an XML snippet of: * <pre> * &lt;X&gt; *     &lt;Y&gt; *         &lt;Z&gt;someValue&lt;/Z&gt; *     &lt;/Y&gt; * &lt;/X&gt; * </pre> * <p/> * The XML file is passed in to the constructor and must be readable and * writtable. Setting property values will automatically persist those value * to disk. The file encoding used is UTF-8. * * @author Derek DeMoro * @author Iain Shigeoka */public class XMLProperties {    private File file;    private Document document;    /**     * Parsing the XML file every time we need a property is slow. Therefore,     * we use a Map to cache property values that are accessed more than once.     */    private Map<String, String> propertyCache = new HashMap<String, String>();    /**     * Creates a new XMLPropertiesTest object.     *     * @param fileName the full path the file that properties should be read from     *                 and written to.     * @throws IOException if an error occurs loading the properties.     */    public XMLProperties(String fileName) throws IOException {        this(new File(fileName));    }    /**     * Loads XML properties from a stream.     *     * @param in the input stream of XML.     * @throws IOException if an exception occurs when reading the stream.     */    public XMLProperties(InputStream in) throws IOException {        Reader reader = new BufferedReader(new InputStreamReader(in));        buildDoc(reader);    }    /**     * Creates a new XMLPropertiesTest object.     *     * @param file the file that properties should be read from and written to.     * @throws IOException if an error occurs loading the properties.     */    public XMLProperties(File file) throws IOException {        this.file = file;        if (!file.exists()) {            // Attempt to recover from this error case by seeing if the            // tmp file exists. It's possible that the rename of the            // tmp file failed the last time Jive was running,            // but that it exists now.            File tempFile;            tempFile = new File(file.getParentFile(), file.getName() + ".tmp");            if (tempFile.exists()) {                Log.error("WARNING: " + file.getName() + " was not found, but temp file from " +                        "previous write operation was. Attempting automatic recovery." +                        " Please check file for data consistency.");                tempFile.renameTo(file);            }            // There isn't a possible way to recover from the file not            // being there, so throw an error.            else {                throw new FileNotFoundException("XML properties file does not exist: "                        + file.getName());            }        }        // Check read and write privs.        if (!file.canRead()) {            throw new IOException("XML properties file must be readable: " + file.getName());        }        if (!file.canWrite()) {            throw new IOException("XML properties file must be writable: " + file.getName());        }        FileReader reader = new FileReader(file);        buildDoc(reader);    }    /**     * Returns the value of the specified property.     *     * @param name the name of the property to get.     * @return the value of the specified property.     */    public synchronized String getProperty(String name) {        String value = propertyCache.get(name);        if (value != null) {            return value;        }        String[] propName = parsePropertyName(name);        // Search for this property by traversing down the XML heirarchy.        Element element = document.getRootElement();        for (int i = 0; i < propName.length; i++) {            element = element.element(propName[i]);            if (element == null) {                // This node doesn't match this part of the property name which                // indicates this property doesn't exist so return null.                return null;            }        }        // At this point, we found a matching property, so return its value.        // Empty strings are returned as null.        value = element.getTextTrim();        if ("".equals(value)) {            return null;        }        else {            // Add to cache so that getting property next time is fast.            propertyCache.put(name, value);            return value;        }    }    /**     * Return all values who's path matches the given property     * name as a String array, or an empty array if the if there     * are no children. This allows you to retrieve several values     * with the same property name. For example, consider the     * XML file entry:     * <pre>     * &lt;foo&gt;     *     &lt;bar&gt;     *         &lt;prop&gt;some value&lt;/prop&gt;     *         &lt;prop&gt;other value&lt;/prop&gt;     *         &lt;prop&gt;last value&lt;/prop&gt;     *     &lt;/bar&gt;     * &lt;/foo&gt;     * </pre>     * If you call getProperties("foo.bar.prop") will return a string array containing     * {"some value", "other value", "last value"}.     *     * @param name the name of the property to retrieve     * @return all child property values for the given node name.     */    public String[] getProperties(String name) {        String[] propName = parsePropertyName(name);        // Search for this property by traversing down the XML heirarchy,        // stopping one short.        Element element = document.getRootElement();        for (int i = 0; i < propName.length - 1; i++) {            element = element.element(propName[i]);            if (element == null) {                // This node doesn't match this part of the property name which                // indicates this property doesn't exist so return empty array.                return new String[]{};            }        }        // We found matching property, return names of children.        Iterator iter = element.elementIterator(propName[propName.length - 1]);        List<String> props = new ArrayList<String>();        String value;        while (iter.hasNext()) {            // Empty strings are skipped.            value = ((Element)iter.next()).getTextTrim();            if (!"".equals(value)) {                props.add(value);            }        }        String[] childrenNames = new String[props.size()];        return props.toArray(childrenNames);    }    /**     * Return all values who's path matches the given property     * name as a String array, or an empty array if the if there     * are no children. This allows you to retrieve several values     * with the same property name. For example, consider the     * XML file entry:     * <pre>     * &lt;foo&gt;     *     &lt;bar&gt;     *         &lt;prop&gt;some value&lt;/prop&gt;     *         &lt;prop&gt;other value&lt;/prop&gt;     *         &lt;prop&gt;last value&lt;/prop&gt;     *     &lt;/bar&gt;     * &lt;/foo&gt;     * </pre>     * If you call getProperties("foo.bar.prop") will return a string array containing     * {"some value", "other value", "last value"}.     *     * @param name the name of the property to retrieve     * @return all child property values for the given node name.     */    public Iterator getChildProperties(String name) {        String[] propName = parsePropertyName(name);        // Search for this property by traversing down the XML heirarchy,        // stopping one short.        Element element = document.getRootElement();        for (int i = 0; i < propName.length - 1; i++) {            element = element.element(propName[i]);            if (element == null) {                // This node doesn't match this part of the property name which                // indicates this property doesn't exist so return empty array.                return Collections.EMPTY_LIST.iterator();            }        }        // We found matching property, return values of the children.        Iterator iter = element.elementIterator(propName[propName.length - 1]);        ArrayList<String> props = new ArrayList<String>();        while (iter.hasNext()) {            props.add(((Element)iter.next()).getText());        }        return props.iterator();    }    /**     * Returns the value of the attribute of the given property name or <tt>null</tt>     * if it doesn't exist. Note, this     *     * @param name the property name to lookup - ie, "foo.bar"     * @param attribute the name of the attribute, ie "id"     * @return the value of the attribute of the given property or <tt>null</tt> if     *      it doesn't exist.     */    public String getAttribute(String name, String attribute) {        if (name == null || attribute == null) {            return null;        }        String[] propName = parsePropertyName(name);        // Search for this property by traversing down the XML heirarchy.        Element element = document.getRootElement();        for (int i = 0; i < propName.length; i++) {            String child = propName[i];            element = element.element(child);            if (element == null) {                // This node doesn't match this part of the property name which                // indicates this property doesn't exist so return empty array.                break;            }        }        if (element != null) {            // Get its attribute values            return element.attributeValue(attribute);        }        return null;    }    /**     * Sets a property to an array of values. Multiple values matching the same property     * is mapped to an XML file as multiple elements containing each value.     * For example, using the name "foo.bar.prop", and the value string array containing     * {"some value", "other value", "last value"} would produce the following XML:     * <pre>     * &lt;foo&gt;     *     &lt;bar&gt;     *         &lt;prop&gt;some value&lt;/prop&gt;     *         &lt;prop&gt;other value&lt;/prop&gt;     *         &lt;prop&gt;last value&lt;/prop&gt;     *     &lt;/bar&gt;     * &lt;/foo&gt;     * </pre>     *     * @param name the name of the property.     * @param values the values for the property (can be empty but not null).     */    public void setProperties(String name, List<String> values) {        String[] propName = parsePropertyName(name);        // Search for this property by traversing down the XML heirarchy,        // stopping one short.        Element element = document.getRootElement();        for (int i = 0; i < propName.length - 1; i++) {            // If we don't find this part of the property in the XML heirarchy            // we add it as a new node            if (element.element(propName[i]) == null) {                element.addElement(propName[i]);            }            element = element.element(propName[i]);        }

⌨️ 快捷键说明

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