iBatis2 Source Analysis (1) - xml parsing module

Like with most of the ORM framework, iBatis2 is described with Xml ORM mapping information (before the appearance of the annotations), then the XML parsing configuration information is then how? Oh, most people see here might say: This Yousha difficult, parsing xml using DOM or SAX is very easy! IBatis xml parsing does nothing less than the methods that either, but carefully read the iBatis source code parsing XML, I found that iBatis xml parsing code which we can learn ... ...

iBatis the most important interface is SqlMapClient, first look at how the procedure is the same kind had been SqlMapClient object configuration files:

  static {
                try {
                        String resource = "com/ppsoft/ibatis/test/config/SqlMapConfig.xml";
                        Reader reader = Resources.getResourceAsReader (resource);
                        sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
                } catch (Exception e) {
                        throw new RuntimeException ("Error initializing MyAppSqlConfig class. Cause:"+e);

Class SqlMapClientBuilder provides several static methods for reading configuration files and create SqlMapClient iBatis object, this chapter is to analyze how to read iBatis configuration file, so also look at some of parsing xml files that look buildSqlMapClient method has done both:

  public static SqlMapClient buildSqlMapClient(Reader reader) {
        return new SqlMapConfigParser().parse(reader);

First create a SqlMapConfigParser, call the newly created parser object SqlMapConfigParser method, xml parsing, and creating

SqlMapClient entrusted to the SqlMapConfigParser object. So then look at the parse methods SqlMapConfigParser done some


  public SqlMapClient parse(Reader reader) {
    try {
      usingStreams = false;
      return state.getConfig().getClient();
    } catch (Exception e) {
      throw new RuntimeException("Error occurred.  Cause: " + e, e);

Oh, see here you will find, in fact, the parse method did not SqlMapConfigParser Anythin only analytical work will be entrusted to SqlMapConfigParser a parser property to see SqlMapConfigParser the parser property is valid and things:

  protected final NodeletParser parser = new NodeletParser();
  //state Used to store all the information analytical
  private XmlParserState state = new XmlParserState();

The original property is a NodeletParser parser object, xml is parsed by the NodeletParser this class, the class focused on the following analysis. Then let us look at NodeletParser parse this class is how to parse xml's:

  public void parse(Reader reader) throws NodeletException {
    try {
      Document doc = createDocument(reader);
    } catch (Exception e) {
      throw new NodeletException("Error parsing XML.  Cause: " + e, e);

First create a document object (called JAXP created and tested under the DTD file is correct xml format) and then call another overloaded NodeletParser in the parse method:

  public void parse(Node node) {
    Path path = new Path();
    processNodelet(node, "/");
    process(node, path);

First create a Path object (Path is defined NodeletParser an internal class), then call processNodelet method, and finally calls the process (node, path); first look processNodelet method doing wrong?

private void processNodelet(Node node, String pathString) {
    Nodelet nodelet = (Nodelet) letMap.get(pathString);
    if (nodelet != null) {
      try {
      } catch (Exception e) {
        throw new RuntimeException("Error parsing XPath '" + pathString + "'.  Cause: " + e, e);

Parameter pathString fact is xpath string, you can see from this code have letMap NodeletParser property is a Map, to xpath as the key, Nodelet object to value. The code logic is: According to the introduction of the xpath search letMap have no corresponding Nodelet object, if the object to call the corresponding process Nodelet method parameters to deal with the Node. Well, this Nodelet in the end is what is it? Look at the code will know then:

public interface Nodelet {
    void process (Node node) throws Exception;

Interfaces to the original just would abstract out the processing nodes, the design very clear: the node approach into Nodelet abstract interfaces, sqlMap stored in the processing of Nodelet each Node object (we can call it Node processor), key for the Node of the xpath, if we specify a good processor for each Node object, then only need to traverse all the nodes, and to find the corresponding Nodelet sqlMap object call its process method to complete the analytical processing of the xml.

Here we analyze the next process (node, path) method done things. See the code before this method in this class come to see why Path:

  private static class Path {
    private List nodeList = new ArrayList();
    public Path() {
    public Path(String xpath) {
      StringTokenizer parser = new StringTokenizer(path, "/", false);
      while (parser.hasMoreTokens()) {
    public void add(String node) {

    // Remove xpath path to the last node in the
    public void remove() {
      nodeList.remove(nodeList.size() - 1);

    public String toString() {
      StringBuffer buffer = new StringBuffer("/");
      for (int i = 0; i < nodeList.size(); i++) {
        if (i < nodeList.size() - 1) {
      return buffer.toString();

Look at source, we know that this class is really just used to describe the xpath of, xpath all the nodes are sequentially placed in a List of, and replication of the toString method will be converted to Xpath string List, other, Path class provides two important ways add and remove, add to add a child node, if the original xpath is / root, called add ("element1"), after, path becomes / root/element1; remove method is used to remove the path in the last node, and add the opposite.

Further analysis of the next process (node, path) code, the code is as follows:

  private void process(Node node, Path path) {
    if (node instanceof Element) {
      // Element
      String elementName = node.getNodeName();
      processNodelet(node, path.toString());
      processNodelet(node, new StringBuffer("//").append(elementName).toString());
      //  All of the processing node  Attribute
      NamedNodeMap attributes = node.getAttributes();
      int n = attributes.getLength();
      for (int i = 0; i < n; i++) {
        Node att = attributes.item(i);
        String attrName = att.getNodeName();
        path.add("@" + attrName);
        processNodelet(att, path.toString());
        processNodelet(node, new StringBuffer("//@").append(attrName).toString());

      //  Recursive traversal of all node  Children
      NodeList children = node.getChildNodes();
      for (int i = 0; i < children.getLength(); i++) {
        process(children.item(i), path);

      //node As well as its child nodes at the end of the call  node By  end() Processor
      processNodelet(node, path.toString());
    } else if (node instanceof Text) {
      //  If it is  Text
      processNodelet(node, path.toString());
      processNodelet(node, "//text()");

Code, plus some brief notes, a closer look will understand, process (Node node, Path path) method of recursive traversal of the node, node attributes and node all the all the child nodes, and call processNodelet, which also confirms previous speculation the correctness (see the previous method of analysis of the processNodelet).

Based on the above analysis, we know that each Node xml processing of information (previously mentioned information processing abstraction for the interface Node Nodelet) are to Node of the xpath for the key stored in NodeletParser class letMap, then how we Registration for each Node Processor (Nodelet object) do?

Let us look back SqlMapConfigParser code, first look at SqlMapConfigParser the constructor:

  public SqlMapConfigParser() {
    // Set the DTD files  classpath Map
    parser.setEntityResolver(new SqlMapClasspathEntityResolver());
    // Registered Node processor

Can see the constructor above one half of the code is addXXX form, this is the xml document to the Node Registration processor (Nodelet object)

We had a quick look at a addXXX methods to see how the registered Node inside the processor, to see SqlMapConfigParser of addTypeAliasNodelets () method of it:

   *  Registered typeAlias processor
  private void addTypeAliasNodelets() {
    parser.addNodelet("/sqlMapConfig/typeAlias", new Nodelet() {
      public void process(Node node) throws Exception {
        Properties prop = NodeletUtils.parseAttributes(node, state.getGlobalProps());
        String alias = prop.getProperty("alias");
        String type = prop.getProperty("type");
        state.getConfig().getTypeHandlerFactory().putTypeAlias(alias, type);

Here the parser calls the class SqlMapConfigParser attributes (here's parser in front of said property is an instance of NodeletParser) of addNodelet method, originally called this method the node to the xml registration processor. NodeletParser method addNodelet the first parameter is a xpath, xml is used to represent the Node; the second parameter is the node processor (Nodelet object), designated to handle xpath xml nodes, where Nodelet is to use anonymous inner classes implementation; we look NodeletParser the addNodelet method code:

  public void addNodelet(String xpath, Nodelet nodelet) {
    letMap.put(xpath, nodelet);

Nodelet object is letMap the map!

Look here / sqlMapConfig / typeAlias how the deal:

  1. First of all, the parseAttribute calculated by NodeletUtils out / sqlMapConfig / typeAlias all the attribute values of nodes to return Properties object, attribute named key, attribute value value, where property values will with $ () This expression value out.
  2. Attribute values from the returned Properties object access / sqlMapConfig / typeAlias node alias and type attributes.
  3. The extracted information into TypeHanderFactory typeAlias alias mapping table.

Other Node in the same way the processor register NodeletParser object. Object to NodeletParser registered after all the required Nodelet processor, called NodeletParser the parser method can be xml parsing out the specific treatment of each node is how is our own designated, NodeletParser only defines how to traverse all the nodes in xml method.

NodeletParser application of the Template Method Pattern in fact the idea, in NodeletParser defines how to traverse all the nodes in xml the method, but does not define how the node is, but by using the specified Node's Nodelet processor, when the node when traversing to call the corresponding Nodelet the process methods to achieve code reuse, so that has nothing to do with specific xml file.

there is a category under com.ibatis.sqlmap.engine.builder.xml package SqlMapParser, used SqlMap file parsing, parsing the same manner and SqlMapConfigParser is through NodeletParser, NodeletParser object to the registration Nodelet processor files on SqlMap analysis.

The following class diagram is analytic SqlMapConfig iBatis files and files of several of the most SqlMap core of the relationship between several classes:

iBatis2 Source Analysis (1) - xml parsing module

The basic iBatis xml parsing module has been very clear, carefully analyzing the code, I first felt good to see other people's code, designed the fun, plan to continue reading later iBatis source code, of course, I will write down the flu Wu ~

分类:Java 时间:2010-09-22 人气:182
blog comments powered by Disqus


  • Jetty6 Guide Book Chapter 4 Jetty service configuration file 2010-03-29

    EDITORIAL: Use the jetty has been a long time, it is a very good web containers and tools to share in this special jetty6 knowledge. Network, there are some information on the jetty, but it used outdated and does not have a systematic, resulting in a

  • Ruby On Rails-2.0.2 source code analysis (1)-Rails Start 2010-11-09

    Preface This article is for Ruby On Rails 2.0.2 source code analysis, learning and research. The tools used NetBean 6.1 Beta, WEBRick, SciTE, ruby-debug-base (0.10.0), ruby-debug-ide (0.1.10). Ruby version is 1.8.6. How analysis should be summarized,

  • Android source code editor with all the operations related to introduction 2010-12-02

    Android source code editor with all the operations related to introduction Android source code related to Note: The following is carried out in the ubuntu 10.04. The birth of this article, my internship at the Meizu learned the past two months, who h

  • Tomcat6 source code analysis 2011-04-19

    As a Java programmer, if you do not come into contact with open source software, project, or framework, I am afraid some weird. Vigorous open source movement originated in the Linux operating system, Apache Foundation, which played a crucial role, th

  • JAVA source code of arbitrary structure builder CodeMaster v1.0 Beta 2009-01-27

    Download See attachment struts attached minimum system to run. CodeMaster is an intelligent code generation gadgets, using pure java development, small and simple but in many cases very useful, in theory, any structure can generate java source code,

  • Sample OpenVPN 2.0 config file configuration file of a simple translation 2010-06-22

    Reprinted from: http://kb.cnblogs.com/a/1322186/ Sample OpenVPN 2.0 config file configuration file of a simple translation: Frodo Source: garden blog ################################################# # Sample OpenVPN 2.0 config file for # # Multi-cli

  • android sdk compile - how to add the source code android.jar, and make the principle 2010-11-05

    http://zhuyonghui116.blog.hexun.com/53467491_d.html The first is the question how to modify. In the / frameworks / base / Android.mk, locate the following line: packages_to_document: = In the final assignment of the variable to add xxxxx (This is the

  • Analog Spring, java classes to read through the configuration file 2010-11-20

    Keywords: Analog Spring, java classes to read through the configuration file Implementation steps: 1, the new Xml file, "applicationContext.xml", note the name, can not be wrong. Need to be oh so 2, the configuration file as follows: Note: The n

  • Struts2.2.1 a core source code analysis 2010-11-30

    I. Overview Struts2 is the core of a Filter, Action from the web container can be, then what makes http request and the action associated with, the following source code to our in-depth analysis of how the work under the Struts2. FilterDispatcher API

  • ndroid sdk compile - how to add the source code android.jar, and make the principle 2011-01-10

    Transfer from: http://raindays619.bokee.com/viewdiary.220437410.html The first is the question how to modify. In the / frameworks / base / Android.mk, locate the following line: packages_to_document: = In the final assignment of the variable to add x

iOS 开发

Android 开发

Python 开发



PHP 开发

Ruby 开发






Javascript 开发

.NET 开发



Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 闽ICP备15018612号

processed in 0.121 (s). 10 q(s)