欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis框架基础支持层——解析器模块(2)

程序员文章站 2022-04-18 15:23:26
解析器模块,核心类XPathParser ......

解析器模块,核心类xpathparser

/**
 * 封装了用于xml解析的类xpath、document和entityresolver
 */
public class xpathparser {
    /**
     * 将xml文件读入内存,并构建一棵树,
     * 通过树结构对各个节点node进行操作
     */
    private document document;
    /**
     * 是否开启xml文本格式验证
     */
    private boolean validation;
    /**
     * 用于加载本地dtd文件
     *
     * 默认情况下,对xml文档进行验证时,会根据xml文件开始
     * 位置指定的网址加载对应的dtd或xsd文件,当由于网络原因,易导致验证过慢,
     * 在实践中往往会提前设置entityresolver接口对象加载本地的dtd文件,
     * 从而避免联网加载;
     *
     * xmlmapperentityresolver implement entityresolver
     */
    private entityresolver entityresolver;
    /**
     * mybatis核心配置文件中标签<properties>定义的键值对
     */
    private properties variables;
    /**
     * 为查询xml文本而设计的语言,配合document使用
     * xpath之于xml好比sql之于database
     */
    private xpath xpath;

    public xpathparser(string xml) {
        commonconstructor(false, null, null);
        this.document = createdocument(new inputsource(new stringreader(xml)));
    }
    //...一系列构造方法(略)

    public void setvariables(properties variables) {
        this.variables = variables;
    }

    /**
     * xpath提供的一系列eval*()方法用于解析boolean、short、int、string、node等类型信息,
     * 通过调用xpath.evaluate()方法查找指定路径的节点或者属性,并进行相应的类型转换
     */
    public string evalstring(string expression) {
        return evalstring(document, expression);
    }

    public string evalstring(object root, string expression) {
        string result = (string) evaluate(expression, root, xpathconstants.string);
        result = propertyparser.parse(result, variables);
        return result;
    }

    public boolean evalboolean(string expression) {
        return evalboolean(document, expression);
    }

    public boolean evalboolean(object root, string expression) {
        return (boolean) evaluate(expression, root, xpathconstants.boolean);
    }

    public short evalshort(string expression) {
        return evalshort(document, expression);
    }

    public short evalshort(object root, string expression) {
        return short.valueof(evalstring(root, expression));
    }

    public integer evalinteger(string expression) {
        return evalinteger(document, expression);
    }

    public integer evalinteger(object root, string expression) {
        return integer.valueof(evalstring(root, expression));
    }

    public long evallong(string expression) {
        return evallong(document, expression);
    }

    public long evallong(object root, string expression) {
        return long.valueof(evalstring(root, expression));
    }

    public float evalfloat(string expression) {
        return evalfloat(document, expression);
    }

    public float evalfloat(object root, string expression) {
        return float.valueof(evalstring(root, expression));
    }

    public double evaldouble(string expression) {
        return evaldouble(document, expression);
    }

    public double evaldouble(object root, string expression) {
        return (double) evaluate(expression, root, xpathconstants.number);
    }

    public list<xnode> evalnodes(string expression) {
        return evalnodes(document, expression);
    }

    public list<xnode> evalnodes(object root, string expression) {
        list<xnode> xnodes = new arraylist<xnode>();
        nodelist nodes = (nodelist) evaluate(expression, root, xpathconstants.nodeset);
        for (int i = 0; i < nodes.getlength(); i++) {
            xnodes.add(new xnode(this, nodes.item(i), variables));
        }
        return xnodes;
    }

    public xnode evalnode(string expression) {
        return evalnode(document, expression);
    }

    public xnode evalnode(object root, string expression) {
        node node = (node) evaluate(expression, root, xpathconstants.node);
        if (node == null) {
            return null;
        }
        return new xnode(this, node, variables);
    }

    private object evaluate(string expression, object root, qname returntype) {
        try {
            return xpath.evaluate(expression, root, returntype);
        } catch (exception e) {
            throw new builderexception("error evaluating xpath.  cause: " + e, e);
        }
    }

    /**
     * 创建dom对象,调用此方法之前必须调用commonconstructor方法完成xpathparser初始化
     */
    private document createdocument(inputsource inputsource) {
        // important: this must only be called after common constructor
        try {
            //创建documentbuilderfactory对象
            documentbuilderfactory factory = documentbuilderfactory.newinstance();
            /**
             * 对documentbuilderfactory对象进行一系列参数配置
             */
            factory.setvalidating(validation);
            factory.setnamespaceaware(false);
            factory.setignoringcomments(true);
            factory.setignoringelementcontentwhitespace(false);
            factory.setcoalescing(false);
            factory.setexpandentityreferences(true);

            //创建documentbuilder对象
            documentbuilder builder = factory.newdocumentbuilder();
            /**
             * 对documentbuilder对象进行一系列参数配置
             */
            builder.setentityresolver(entityresolver);
            builder.seterrorhandler(new errorhandler() {
                @override
                public void error(saxparseexception exception) throws saxexception {
                    throw exception;
                }

                @override
                public void fatalerror(saxparseexception exception) throws saxexception {
                    throw exception;
                }

                @override
                public void warning(saxparseexception exception) throws saxexception {
                }
            });
            //加载xml文件
            return builder.parse(inputsource);
        } catch (exception e) {
            throw new builderexception("error creating document instance.  cause: " + e, e);
        }
    }

    /**
     * 初始化xpathparser
     */
    private void commonconstructor(boolean validation, properties variables, entityresolver entityresolver) {
        this.validation = validation;
        this.entityresolver = entityresolver;
        this.variables = variables;
        xpathfactory factory = xpathfactory.newinstance();
        this.xpath = factory.newxpath();
    }

}