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

📄 cfg.java

📁 培训考试系统代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.huawei.icd30.agt.util;

import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
import java.util.*;
import org.xml.sax.*;
import java.net.*;

/**
 * 基于XML格式的配置文件读写类。和JDK1.4的Preferences类用法类似。
 * @author InternetTeam3
 * @version 1.01
 */
public class Cfg
{

    /** XML解析器工厂。*/
    private static DocumentBuilderFactory factory;

    /** XML解析器。*/
    private static DocumentBuilder builder;

    /** XML头。*/
    private static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"" +
                                 System.getProperty("file.encoding") + "\"?>";

    /** 缩进前缀。*/
    private static String indent = "  ";

    /** 该配置内存中数据是否与配置文件内容一致,不一致则为脏。*/
    private boolean isDirty;

    /** 代表该配置文件的文档类。*/
    private Document doc;

    /** 配置根节点。*/
    private Element root;

    /** 配置文件名。*/
    private String file;

    /**
     * 创建配置读取对象。
     * @param url 保存配置信息的XML文件路径。
     */
    public Cfg(String url) throws IOException
    {
        this(url,false);
    }

    /**
     * 创建配置读取对象。
     * @param url 保存配置信息的XML文件路径。
     * @param create 当配置文件不存在时,是否允许新建文件。
     * @throws IOException 配置文件访问或内容解析异常。
     */
    public Cfg(String url, boolean create) throws IOException
    {

        //得到配置信息
        if (url==null)
        {
            throw new IllegalArgumentException("url is null");
        }
        if (url.indexOf(':')>1)
        {
            this.file = url;
        }
        else
        {
            this.file = new File(url).toURL().toString();
        }

        //为了检查参数file的合法性,如传的参数不合法,则抛出异常,调用者对其进行出错处理
        new URL(this.file);  //创建文件对象
        try
        {
            load(); //读取配置文件
        }
        catch (FileNotFoundException ex)
        {
            if(!create)
            { //文件不存在,且不允许新建
                throw ex;
            }
            else
            { //文件不存在,但允许新建
                loadXMLParser(); //加载XML解析器
                doc = builder.newDocument(); //创建空文档对象
                root = doc.createElement("config");
                doc.appendChild(root); //增加根节点
                isDirty = true;
                flush(); //保存到文件
                return;
            }
        }
    }

    /**
     * 取得某节点的一组子节点值。
     * @param key 父节点的路径。
     */
    public Args getArgs(String key)
    {
        Map args = new HashMap();
        String[] children = childrenNames(key);
        for (int i=0;i<children.length;i++)
        {
            args.put(children[i],get(key+'/'+children[i],null));
        }
        return new Args(args);
    }

    /**
     * 输出缩进空格。
     * @param pw 输出目的地。
     * @param level 缩进深度。
     */
    private static void writeIndent(PrintWriter pw,int level)
    {
        for (int i=0;i<level;i++)
        {
            pw.print(indent);
        }
    }

    /**
     * 以XML格式递归输出一个节点。
     * @param node 输出起始节点。
     * @param pw 输出目的地。
     * @param 递归调用的深度标记,请输入0。
     */
    private static void writeNode(Node node, PrintWriter pw, int deep)
    {
        switch (node.getNodeType())
        {
            case Node.COMMENT_NODE: //注释节点
                writeIndent(pw,deep);
                pw.print("<!--");
                pw.print(node.getNodeValue());
                pw.println("-->");
                return;
            case Node.TEXT_NODE: //文本节点
                String value = node.getNodeValue().trim(); //文本trim防止破坏缩进格式
                if (value.length()==0)
                {
                    return;
                }
                writeIndent(pw,deep);
                for (int i=0;i<value.length();i++)
                {
                    char c = value.charAt(i);
                    switch(c)
                    {
                        case '<':
                            pw.print("&lt;");
                            break;
                        case '>':
                            pw.print("&lt;");
                            break;
                        case '&':
                            pw.print("&amp;");
                            break;
                        case '\'':
                            pw.print("&apos;");
                            break;
                        case '\"':
                            pw.print("&quot;");
                            break;
                        default:
                            pw.print(c);
                    }
                }
                pw.println();
                return;
            case Node.ELEMENT_NODE: //标记节点
                if (!node.hasChildNodes())
                {
                    return;
                }
                for (int i=0;i<deep;i++)
                {
                    pw.print(indent);
                }
                String nodeName = node.getNodeName();
                pw.print('<');
                pw.print(nodeName);

                //输出属性
                NamedNodeMap nnm = node.getAttributes();
                if (nnm!=null)
                {
                    for (int i=0; i<nnm.getLength(); i++)
                    {
                        Node attr = nnm.item(i);
                        pw.print(' ');
                        pw.print(attr.getNodeName());
                        pw.print("=\"");
                        pw.print(attr.getNodeValue());
                        pw.print('\"');
                    }
                }

                //输出子节点
                if (node.hasChildNodes())
                {
                    NodeList children = node.getChildNodes();
                    if (children.getLength()==0)
                    {
                        pw.print('<');
                        pw.print(nodeName);
                        pw.println("/>");
                        return;
                    }
                    if (children.getLength()==1)
                    {
                        Node n = children.item(0);
                        if(n.getNodeType()==Node.TEXT_NODE)
                        {
                            String v = n.getNodeValue();
                            if (v!=null)
                            {
                                v = v.trim();
                            }
                        if (v==null||v.length()==0)
                        {
                            pw.println(" />");
                            return;
                        }
                        else
                        {
                            pw.print('>');
                            pw.print(v);
                            pw.print("</");
                            pw.print(nodeName);
                            pw.println('>');
                            return;
                        }
                    }
                }
                pw.println(">");
                for (int i=0;i<children.getLength();i++)
                {
                    writeNode(children.item(i),pw,deep+1);
                }
                for (int i=0;i<deep;i++)
                {
                    pw.print(indent);
                }
                pw.print("</");
                pw.print(nodeName);
                pw.println(">");
                }
                else
                {
                    pw.println("/>");
                }
                return;
            case Node.DOCUMENT_NODE: //文档节点
                pw.println(XML_HEAD);
                NodeList nl= node.getChildNodes();
                for (int i=0;i<nl.getLength();i++)
                {
                    writeNode(nl.item(i),pw,0);
                }
                return;
        }
    }

    /**
     * 根据key指定的关键字查找节点,在查找的过程中顺便将不存在的节点创建出来。
     * @param key 所查找节点的关键字。
     * @return 返回查到的节点,没查到则返回null。
     */
    private Node findNode(String key)
    {
        Node ancestor = root;
        for (StringTokenizer st = new StringTokenizer(key,"/");
             st.hasMoreTokens();)
        {
            String nodeName = st.nextToken();
            NodeList nl = ancestor.getChildNodes();
            for (int i=0; i<nl.getLength(); i++)
            {
                Node n = nl.item(i);
                if (nodeName.equals(n.getNodeName()))
                {
                    ancestor = n;

                    //到达key的最低一级了
                    if (!st.hasMoreTokens())
                    {
                        return n;
                    }
                    break;
                }
            }
        }
        return null;
    }

    /**
     * 根据key指定的关键字创建节点,将会把key代表的整个路径上的节点都创建出来。
     * @param key 所查找节点的关键字。
     * @return 返回最底层节点,即使已经存在,没有创建新节点。
     */
    private Node createNode(String key)
    {
        Node ancestor = root;
        token:
        for (StringTokenizer st = new StringTokenizer(key,"/");
            st.hasMoreTokens();)
        {
            String nodeName = st.nextToken();
            NodeList nl = ancestor.getChildNodes();
            for (int i=0; i<nl.getLength(); i++)
            {
                Node n = nl.item(i);

                //该级子节点存在则继续找下一级子节点
                if (nodeName.equals(n.getNodeName()))
                {
                    ancestor = n;
                    if (st.hasMoreTokens())
                    {
                        continue token;
                    }
                    else
                    {
                        return ancestor;
                    }
                }
            }

            //该级子节点不存在
            for(;;) //死循环
            {
                Node n = doc.createElement(nodeName);
                ancestor.appendChild(n);
                ancestor = n;
                if(!st.hasMoreTokens())
                {
                    return ancestor;
                }
                nodeName = st.nextToken();
            }
        }
        return null; //不可能执行到这里
    }

    /**
     * 根据key指定的关键字查找节点,在查找的过程中顺便将不存在的节点创建出来。
     * @param ancestor 以该节点为祖先开始查找。
     * @param key 所查找节点的关键字。
     * @return 返回查到的节点,没查到则返回null。
     */
    private Node createNode(Node ancestor, String key)
    {

        searchToken: //用来跳出两层循环用的标记
        for (StringTokenizer st = new StringTokenizer(key,"/");
             st.hasMoreTokens();)
        {
            String nodeName = st.nextToken();
            NodeList nl = ancestor.getChildNodes();
            for (int i=0; i<nl.getLength(); i++)
            {
                if (nodeName.equals(nl.item(i).getNodeName()))
                {
                    ancestor = nl.item(i);
                    continue searchToken;
                }
            }
            return null;
        }
        return ancestor;
    }

    /**
     * 取名字为key的节点的值。如果该节点存在,但无内容则返回空字符串:""
     * @param key 和该关键字关联的配置项的值将被返回。
     * @param def 若key对应的配置项不存在,则返回该值。
     * @exception NullPointerException key值为null。
     */
    public String get(String key, String def)
    {
        if (key == null)
        {
            throw new NullPointerException("parameter key is null");
        }

        Node node = findNode(key);
        if (node==null) //节点不存在返回空
        {
            return def;
        }
        NodeList nl = node.getChildNodes();
        for (int i=0;i<nl.getLength();i++)
        {
            if (nl.item(i).getNodeType()==Node.TEXT_NODE)
            {
                return nl.item(i).getNodeValue().trim();
            }
        }
        node.appendChild(doc.createTextNode(def));
        return def;
    }

    /**
     * 设名字为key的节点的值。
     * @param key 设值节点对象的名字。
     * @param value 所设的值。
     * @exception NullPointerException 传入的key或value为null。
     */
    public void put(String key, String value)
    {
        if (key == null)
        {
              throw new NullPointerException("parameter key is null");
        }
        if (value == null)
        {
            throw new NullPointerException("parameter value is null");
        }
        value = value.trim();
        Node node = createNode(key);

        //node节点的第一个文本子节点(不包括trim后为空的)放置该节点的值
        NodeList nl = node.getChildNodes();
        for (int i=0;i<nl.getLength();i++)
        {
            Node child = nl.item(i);
            if (child.getNodeType()==Node.TEXT_NODE) //遇到第一个文本子节点
            {
                String childValue = child.getNodeValue();
                if (childValue==null)
                {
                    continue;
                }
                childValue = childValue.trim();
                if (childValue.length()==0)
                {
                    continue;
                }

                //put的值和原来一样,直接返回即可
                if (childValue.equals(value))
                {
                    return;
                }
                else
                {
                    child.setNodeValue(value);
                    isDirty = true;
                    return;
                }
            }
        }

        //没有trim后还有内容的文本子节点
        if (nl.getLength()==0) //节点为空
        {
            node.appendChild(doc.createTextNode(value));

⌨️ 快捷键说明

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