Mybatis工作机制源码分析—初始化—sax解析

     本文以解析Mybatis config配置文件中"/configuration"元素为例进行说明Mybatis是如何进行sax解析工作的。

Mybatis配置文件解析流程图


时序图


相关源码

/** XMLConfigBuilder.java */
// 以解析Mybatis config配置文件"/configuration"元素为例说明sax解析机制:
parser.evalNode("/configuration");

/** XPathParser.java */
// 解析"/configuration"根节点为XNode
public XNode evalNode(String expression) {
	return evalNode(document, expression);
}

public XNode evalNode(Object root, String expression) {
	// NODE = new QName("http://www.w3.org/1999/XSL/Transform", "NODE");
	// 解析"/configuration"根节点为Node
	Node node = (Node) evaluate(expression, root, XPathConstants.NODE);
	if (node == null) {
	  return null;
	}
	// 包装为XNode
	return new XNode(this, node, variables);
}

// 利用Xpath类解析
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);
	}
}

/** XPathImpl.java */
// XPathImpl解析实现
public Object evaluate(String expression, Object item, QName returnType)
		throws XPathExpressionException {
	if ( expression == null ) {
		String fmsg = XSLMessages.createXPATHMessage(
				XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
				new Object[] {"XPath expression"} );
		throw new NullPointerException ( fmsg );
	}
	if ( returnType == null ) {
		String fmsg = XSLMessages.createXPATHMessage(
				XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
				new Object[] {"returnType"} );
		throw new NullPointerException ( fmsg );
	}
	// Checking if requested returnType is supported. returnType need to
	// be defined in XPathConstants
	if ( !isSupported ( returnType ) ) {
		String fmsg = XSLMessages.createXPATHMessage(
				XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
				new Object[] { returnType.toString() } );
		throw new IllegalArgumentException ( fmsg );
	}

	try {
		// Xpath实际解析
		XObject resultObject = eval( expression, item );
		// 返回Node节点
		return getResultAsType( resultObject, returnType );
	} catch ( java.lang.NullPointerException npe ) {
		// If VariableResolver returns null Or if we get
		// NullPointerException at this stage for some other reason
		// then we have to reurn XPathException
		throw new XPathExpressionException ( npe );
	} catch ( javax.xml.transform.TransformerException te ) {
		Throwable nestedException = te.getException();
		if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
			throw (javax.xml.xpath.XPathFunctionException)nestedException;
		} else {
			// For any other exceptions we need to throw
			// XPathExpressionException ( as per spec )
			throw new XPathExpressionException ( te );
		}
	}

}

private XObject eval(String expression, Object contextItem)
	throws javax.xml.transform.TransformerException {
	// 构造XPath
	com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
		null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
	com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
	if ( functionResolver != null ) {
		JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
				functionResolver, featureSecureProcessing, featureManager );
		xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
	} else {
		xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
	}

	XObject xobj = null;

	xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));

	// If item is null, then we will create a a Dummy contextNode
	if ( contextItem instanceof Node ) {
		// 实例利用XPath解析xml元素为Node节点
		xobj = xpath.execute (xpathSupport, (Node)contextItem,
				prefixResolver );
	} else {
		xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
	}

	return xobj;
}

// 根据返回的解析类型获取结果
private Object getResultAsType( XObject resultObject, QName returnType )
	throws javax.xml.transform.TransformerException {
	// XPathConstants.STRING
	if ( returnType.equals( XPathConstants.STRING ) ) {
		return resultObject.str();
	}
	// XPathConstants.NUMBER
	if ( returnType.equals( XPathConstants.NUMBER ) ) {
		return new Double ( resultObject.num());
	}
	// XPathConstants.BOOLEAN
	if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
		return new Boolean( resultObject.bool());
	}
	// XPathConstants.NODESET ---ORdered, UNOrdered???
	if ( returnType.equals( XPathConstants.NODESET ) ) {
		return resultObject.nodelist();
	}
	// XPathConstants.NODE
	// 返回Node节点
	if ( returnType.equals( XPathConstants.NODE ) ) {
		NodeIterator ni = resultObject.nodeset();
		//Return the first node, or null
		return ni.nextNode();
	}
	String fmsg = XSLMessages.createXPATHMessage(
			XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
			new Object[] { returnType.toString()});
	throw new IllegalArgumentException( fmsg );
}

/** XNode.java */
// XNode构造函数
public XNode(XPathParser xpathParser, Node node, Properties variables) {
	this.xpathParser = xpathParser;
	this.node = node;
	this.name = node.getNodeName();
	this.variables = variables;
	// 获取node节点的属性Properties
	this.attributes = parseAttributes(node);
	// 获取node节点的Content
	this.body = parseBody(node);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值